--- a/finaloption.py Tue Aug 04 17:04:08 2009 +0300
+++ b/finaloption.py Tue Aug 04 20:30:02 2009 +0300
@@ -84,14 +84,16 @@
return wrapper
-def dispatch(args=None, cmdtable=None, globalopts=None):
+def dispatch(args=None, cmdtable=None, globaloptions=None,
+ middleware=lambda x: x):
'''Dispatch command arguments based on subcommands.
- ``args``: list of arguments, default: ``sys.argv[1:]``
- ``cmdtable``: dict of commands in format described below.
If not supplied, will use functions decorated with ``@command``.
- - ``globalopts``: list of options which are applied to all
- commands, if not supplied will contain ``--help`` option
+ - ``globaloptions``: list of options which are applied to all
+ commands, will contain ``--help`` option at least.
+ - ``middleware``: global decorator for all commands.
cmdtable format description::
@@ -108,18 +110,18 @@
args = args or sys.argv[1:]
cmdtable = cmdtable or CMDTABLE
- globalopts = globalopts or []
- globalopts.append(('h', 'help', False, 'display help'))
+ globaloptions = globaloptions or []
+ globaloptions.append(('h', 'help', False, 'display help'))
- cmdtable['help'] = (help_(cmdtable, globalopts), [], '[TOPIC]')
+ cmdtable['help'] = (help_(cmdtable, globaloptions), [], '[TOPIC]')
help_func = cmdtable['help'][0]
try:
name, func, args, kwargs = catcher(
- lambda: _dispatch(args, cmdtable, globalopts),
+ lambda: _dispatch(args, cmdtable, globaloptions),
help_func)
return catcher(
- lambda: call_cmd(name, func, *args, **kwargs),
+ lambda: call_cmd(name, middleware(func), *args, **kwargs),
help_func)
except Abort:
pass
@@ -130,7 +132,7 @@
# --------
def help_(cmdtable, globalopts):
- def inner(name=None):
+ def help_inner(name=None):
'''Show help for a given help topic or a help overview
With no arguments, print a list of commands with short help messages.
@@ -175,7 +177,7 @@
return help_cmd(cmd,
replace_name(usage, sysname() + ' ' + aliases[0]),
options + globalopts)
- return inner
+ return help_inner
def help_cmd(func, usage, options):
'''show help for given command
--- a/test.py Tue Aug 04 17:04:08 2009 +0300
+++ b/test.py Tue Aug 04 20:30:02 2009 +0300
@@ -6,18 +6,20 @@
@command(usage='[-t]', shortlist=True)
-def simple(test=('t', False, 'just test execution')):
+def simple(ui,
+ test=('t', False, 'just test execution')):
'''Just simple command to do nothing.
I assure you! Nothing to look here. ;-)
'''
- print locals()
+ ui.write(str(locals()))
+ ui.write('\n')
cplx_opts = [('p', 'pass', False, 'don\'t run the command'),
('', 'exit', 0, 'exit with supplied code (default: 0)')]
@command(cplx_opts, usage='[-p] [--exit value] ...', name='complex', hide=True)
-def complex_(*args, **opts):
+def complex_(ui, *args, **opts):
'''That's more complex command indented to do something
Let's try to do that (what?!)
@@ -25,8 +27,59 @@
if opts.get('pass'):
return
# test ui
+ ui.write('preved\n')
if opts.get('exit'):
sys.exit(opts['exit'])
+def ui_middleware(func):
+ if func.__name__ == 'help_inner':
+ return func
+ def extract_dict(source, *keys):
+ dest = {}
+ for k in keys:
+ dest[k] = source.pop(k, None)
+ return dest
+
+ def inner(*args, **kwargs):
+ ui = UI(**extract_dict(kwargs, 'verbose', 'quiet'))
+ return func(ui, *args, **kwargs)
+ return inner
+
+class UI(object):
+ '''User interface helper.
+
+ Intended to ease handling of quiet/verbose output and more.
+
+ You have three methods to handle program messages output:
+
+ - ``UI.info`` is printed by default, but hidden with quiet option
+ - ``UI.note`` is printed only if output is verbose
+ - ``UI.write`` is printed in any case
+
+ Additionally there is ``UI.warn`` method, which prints to stderr.
+ '''
+
+ options = [('v', 'verbose', False, 'enable additional output'),
+ ('q', 'quiet', False, 'suppress output')]
+
+ def __init__(self, verbose=False, quiet=False):
+ self.verbose = verbose
+ # disabling quiet in favor of verbose is more safe
+ self.quiet = (not verbose and quiet)
+
+ def write(self, *messages):
+ for m in messages:
+ sys.stdout.write(m)
+
+ def warn(self, *messages):
+ for m in messages:
+ sys.stderr.write(m)
+
+ info = lambda self, *m: not self.quiet and self.write(*m)
+ note = lambda self, *m: self.verbose and self.write(*m)
+
+
if __name__ == '__main__':
- dispatch()
+ dispatch(globaloptions=UI.options, middleware=ui_middleware)
+
+