fancyopts: testing facilities
authorAlexander Solovyov <piranha@piranha.org.ua>
Sun, 31 May 2009 15:31:56 +0300
changeset 1 64bd6c430858
parent 0 cbb132cade5c
child 2 0b61a739804a
fancyopts: testing facilities
fancyopts.py
--- a/fancyopts.py	Sun May 31 15:04:40 2009 +0300
+++ b/fancyopts.py	Sun May 31 15:31:56 2009 +0300
@@ -2,19 +2,80 @@
 '''Fancy option parser
 '''
 
-import getopt, types
+import getopt, types, textwrap
+
+def fancyopts(cmd, args, options):
+    if not args:
+        help_(cmd, options)
+    else:
+        opts, args = parse(args, options)
+        cmd(*args, **opts)
 
-def fancyopts(args, options):
-    '''
+def help_(cmd, options):
+    '''show help for given command
+
+    >>> def test(*args, **opts):
+    ...     """test [-l HOST] [NAME]"""
     >>> opts = [('l', 'listen', 'localhost',
-    ...          'ip to listen on (default: localhost)'),
+    ...          'ip to listen on'),
     ...         ('p', 'port', 8000,
-    ...          'port to listen on (default: 8000)'),
+    ...          'port to listen on'),
     ...         ('d', 'daemonize', False,
     ...          'daemonize process'),
     ...         ('', 'pid-file', '',
     ...          'name of file to write process ID to')]
-    >>> print fancyopts(['-l', '0.0.0.0', '--pi', 'test', 'all'], opts)
+    >>> help_(test, opts)
+    test [-l HOST] [NAME]
+    <BLANKLINE>
+    options:
+    <BLANKLINE>
+     -l --listen     ip to listen on (default: localhost)
+    <BLANKLINE>
+     -p --port       port to listen on (default: 8000)
+    <BLANKLINE>
+     -d --daemonize  daemonize process
+    <BLANKLINE>
+        --pid-file   name of file to write process ID to
+    <BLANKLINE>
+    '''
+    doc = cmd.__doc__
+    if not doc:
+        doc = '(no help text available)'
+    print '%s\n' % doc.strip()
+    print '\n'.join(help_options(options))
+
+
+def help_options(options):
+    yield 'options:\n'
+    output = []
+    for short, name, default, desc in options:
+        default = default and ' (default: %s)' % default or ''
+        output.append(('%2s%s' % (short and '-%s' % short,
+                                  name and ' --%s' % name),
+                       '%s%s' % (desc, default)))
+
+    opts_len = max([len(f) for f, s in output if s] or [0])
+    for first, second in output:
+        if second:
+            # wrap description at 70 chars
+            second = textwrap.wrap(second, width=70 - opts_len - 3)
+            pad = '\n' + ' ' * (opts_len + 3)
+            yield ' %-*s  %s\n' % (opts_len, first, pad.join(second))
+        else:
+            yield '%s\n' % first
+
+
+def parse(args, options):
+    '''
+    >>> opts = [('l', 'listen', 'localhost',
+    ...          'ip to listen on'),
+    ...         ('p', 'port', 8000,
+    ...          'port to listen on'),
+    ...         ('d', 'daemonize', False,
+    ...          'daemonize process'),
+    ...         ('', 'pid-file', '',
+    ...          'name of file to write process ID to')]
+    >>> print parse(['-l', '0.0.0.0', '--pi', 'test', 'all'], opts)
     ({'pid_file': 'test', 'daemonize': False, 'port': 8000, 'listen': '0.0.0.0'}, ['all'])
 
     '''