piranha/opster — pull request #27 by oscarbenjamin (2012-05-08 13:26:16+00:00)
Title: Support for nested subcommands

Hi again,

You're response in GH-26 was too quick for me!

This patch adds support for nested subcommands. What do you think?

This code adds about 20 lines to ```opster.py```. I think that it could be done more simply if there was a ```Command``` class for the entries in the cmdtable (that would probably simplify a lot of the code).

The first commit fixes the tests on windows: the problem is that paths on windows can contain backslashes or forward slashes, and ```cram``` environment uses unix-style paths that don't match ```os.sep```.

The second commit adds a ```scriptname``` parameter to ```Dispatcher.dispatch()``` and ```main.command()``` so that the script name can be explicitly set by an opster-based script at the point where argv is passed in.

The third commit adds a ```Dispatcher.add_dispatcher()``` function that can be used to add a dispatcher as a subcommand, making use of the scriptname parameter to call ```dispatch``` recursively when a subcommand is a sub-dispatcher.

There's also a load of tests for the ```scriptname``` parameter and the nested subcommands behaviour.

AFAICT the only thing that does not work properly is something like:

from opster import command

@command()
def main():
main.print_help()

main.command(scriptname='name')

Here the print_help function will still think that the script is called ```main```. The only way to make the above work would be to modify the ```print_help``` function after the ```main.command``` call but before the call to ```main```, which is not very clean. An alternative approach wouldn't have this problem. What do you think about:

from opster import command

@command()
def main():
raise command.PrintHelp()

main.command(scriptname='name')