argparsetree
============
Package for creating complex command line argument trees using argparse.
Basic Usage
-----------
You can create a single command by creating a class extending ``argparsetree.BaseCommand``
and overriding the ``add_arguments`` and ``action_methods``. For example::
from argparsetree import BaseCommand
class MyCommand(BaseCommand):
def add_arguments(parser):
parser.add_arguments('foo', help='Some description of "foo"')
def action(args):
print(args.foo)
The ``parser`` argument passed to ``add_arguments`` is an ``argparse.ArgumentParser`` object. Similarly
the ``args`` parameter passed to the ``action`` method is a ``argparse.Namespace`` object generated by
calling ``parse_args`` on the generated argument parser.
Additionally the description property can be set on the command class, this will be used when building
the help message.
If a return value other than ``None`` is returned from ``action`` this will be used as the return code from the
``run`` function. If no value is returned (or the value is ``None``) the value is assumed to be 0.
Once you have created your command you can use it by creating a script similar to::
#!/usr/bin/env python
import sys
from mycli import MyCommand
if __name__ == '__main__':
sys.exit(MyCommand().run())
Nested Usage
------------
Child commands can also be added to a command by specifying the ``sub_commands`` property. This is a dictionary
that maps command names to command classes. For example::
#!/usr/bin/env python
import sys
from argparsetree import BaseCommand
class CleanFooCommand(BaseCommand):
description = 'Cleans up the foo object'
def add_args(self, parser):
parser.add_argument('target', help='The foo file to clean up')
parser.add_argument('-y', '--yes', help='Automatic answer yes to prompts', action='store_true')
def action(self, args):
# do cleaning
return 0
class CheckFooCommand(BaseCommand):
description = 'Checks the integrity of a foo object'
def add_args(self, parser):
parser.add_argument('target', help='The foo file to clean up')
parser.add_argument('-y', '--yes', help='Automatic answer yes to prompts', action='store_true')
def action(self, args):
# do cleaning
return 0
class FooCommand(BaseCommand):
description = 'Do things with foos'
sub_commands = {
'check': CheckFooCommand,
'clean': CleanFooCommand,
# more sub commands here
}
class RootCommand(BaseCommand):
description = 'My fancy CLI'
sub_commands = {
'foo': FooCommand,
# more sub commands here
}
if __name__ == '__main__':
sys.exit(RootCommand().run())
Running ``./example.py`` would give the following output::
usage: My fancy CLI [-h] {foo} ...
positional arguments:
{foo}
foo Do things with foos
optional arguments:
-h, --help show this help message and exit
And running ``./example.py foo`` gives::
usage: Do things with foos [-h] {check,clean} ...
positional arguments:
{check,clean}
check Checks the integrity of a foo object
clean Cleans up the foo object
optional arguments:
-h, --help show this help message and exit
An extended help message for each command (and sub-command) can be printed by adding the ``--help`` flag,
So running ``./example.py foo check --help`` gives::
usage: My fancy CLI foo check [-h] [-y] target
Checks the integrity of a foo object
positional arguments:
target The foo file to clean up
optional arguments:
-h, --help show this help message and exit
-y, --yes Automatic answer yes to prompts