# HG changeset patch # User John Mulligan # Date 1257117258 18000 # Sun Nov 01 18:14:18 2009 -0500 # Node ID 06bae9da75a5797b6d325c72a2a2d3a7fee69e8f # Parent 3e309b038e01ad8df371c256af5693c53517bdfc commander: add main(...) function and some docstrings diff --git a/vanity/commander.py b/vanity/commander.py --- a/vanity/commander.py +++ b/vanity/commander.py @@ -45,6 +45,27 @@ 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 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 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 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 @@ 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 @@ @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 @@ 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) -'''