@@ 45,6 45,27 @@ class HelpWanted(cli.CliError):
self.args = args
+def main(globalopts, cmdtable, arguments, generichelp=None):
+ """Launch a subcommand based on the given arguments, automatically
+ handling help and cli parsing errors. Will return the
+ result of a real command or exit when an error or help
+ request is encountered.
+
+ * ``globalopts`` - an options table common to all sub commands
+ * ``cmdtable`` - a commands table
+ * ``arguments`` - the command line arguments
+ * ``generichelp`` - application help callback function
+ """
+ try:
+ return launch(globalopts, cmdtable, arguments)
+ except HelpWanted, herr:
+ handlehelp(herr, globalopts, cmdtable)
+ sys.exit(0)
+ except cli.CliError, err:
+ sys.stderr.write('error: %s\n' % err)
+ sys.exit(2)
+
+
def launch(globalopts, cmdtable, arguments, autohelp=True):
"""Launch a subcommand based on the given arguments, return the
result of the launched function.
@@ 96,6 117,18 @@ def parse(globalopts, cmdtable, argument
def handlehelp(helperr, globalopts, cmdtable, output=None, generic=None):
+ """Handle a HelpWanted excpetion by writing usage information
+ into the ``output`` object, which is stdout by default.
+ Pass a ``generic`` callback function to produce a generic
+ application wide help text. Generic accepts a cmdtable argument
+ and must return a generator.
+
+ * ``helperr`` - an instance of HelpWanted
+ * ``globalopts`` - an options table common to all sub commands
+ * ``cmdtable`` - a commands table
+ * ``output`` - an file-like object opened for writing
+ * ``generic`` - application help callback function
+ """
if output is None:
output = sys.stdout
if not generic:
@@ 121,6 154,9 @@ def handlehelp(helperr, globalopts, cmdt
def generic_usage(cmdtable):
+ """Generic help text generator for all subcommands in the
+ application (cmdtable).
+ """
yield 'Application Subcommands:'
yield ''
for cmd in sorted(cmdtable):
@@ 130,6 166,12 @@ def generic_usage(cmdtable):
def usage(cmd, short=False, prefix=''):
+ """Generate command usage.
+
+ * ``cmd`` - generate usage for command
+ * ``short`` - generate short usage if true
+ * ``prefix`` - string prepended before subcommand name
+ """
if short:
yield cmd.docstring().splitlines()[0]
return
@@ 164,12 206,16 @@ class Command(object):
return self.target(*args, **opts)
def aliaslist(self):
+ """Return a list of command aliases.
+ """
if self.aliases:
return self.aliases.split('|')
else:
return []
def docstring(self):
+ """Return a documentation string for the command.
+ """
if self.target and hasattr(self.target, '__doc__'):
return self.target.__doc__ or 'No usage available'
else:
@@ 180,6 226,9 @@ class Command(object):
@classmethod
def convert(cls, obj):
+ """Convert a tuple, dictionary or existing command object
+ to a command.
+ """
if isinstance(obj, cls):
return obj
if hasattr(obj, 'keys'):
@@ 274,35 323,3 @@ class CommandTable(object):
HELP = Command('help', None, None, [], 'display command help')
HELPOPT = cli.Option('help', 'h', None, 'display command help')
-
-'''
-
-
-def parsecommand(opttable, cmdtable, arguments, getopts=None):
- """Parse a command line into an command function, an
- options dict and an arguments list.
- """
- if getopts is None:
- getopts = (_getopt.getopt, _getopt.gnu_getopt)
- cmds = CommandTable(opttable, cmdtable)
- short, long = (cmds.opts().shortoptspec(), cmds.opts().longoptspec())
- try:
- raw, args = getopts[0](arguments, short, long)
- except _getopt.GetoptError, ee:
- raise InvalidOption(str(ee))
- if not args:
- return (None, cmds.opts().assemble(raw), [])
- label, args = args[0], args[1:]
- (func, id, opts, desc) = cmds.get(label)
- raw2, args = getopts[1](args, opts.shortoptspec(), opts.longoptspec())
- return (func, opts.assemble(raw+raw2), args)
-
-
-def listcommands(cmdtable):
- cmds = CommandTable([], cmdtable)
- disp = list(cmds.firstlabels())
- disp.sort()
- for label in disp:
- desc = cmds.get(label)[3]
- yield (label, desc)
-'''