Mercurial > mozilla > hg > ProfileManager
comparison profilemanager/command.py @ 0:7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Sun, 04 Apr 2010 18:49:55 -0400 |
parents | |
children | 979315ed0816 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:7301d534bc6c |
---|---|
1 """ | |
2 a command-line interface to the command line, a la pythonpaste | |
3 """ | |
4 | |
5 import inspect | |
6 import sys | |
7 from optparse import OptionParser | |
8 | |
9 if 'commands' not in globals(): | |
10 commands = {} | |
11 | |
12 def command(function): | |
13 # XXX should get bound/unbound state from function (how?) | |
14 global commands | |
15 name = function.func_name | |
16 doc = inspect.cleandoc(function.__doc__) | |
17 argspec = inspect.getargspec(function) | |
18 defaults = argspec.defaults | |
19 if defaults: | |
20 args = argspec.args[1:-len(defaults)] | |
21 optional = dict(zip(argspec.args[-len(defaults):], defaults)) | |
22 else: | |
23 args = argspec.args[1:] | |
24 optional = None | |
25 commands[name] = { 'doc': doc, | |
26 'args': args, | |
27 'optional': optional, | |
28 'varargs': argspec.varargs | |
29 } | |
30 return function | |
31 | |
32 def commandargs2str(command): | |
33 if isinstance(command, basestring): | |
34 command = commands[command] | |
35 retval = [] | |
36 retval.extend(['<%s>' % arg for arg in command['args']]) | |
37 varargs = command['varargs'] | |
38 if varargs: | |
39 retval.append('<%s> [%s] [...]' % (varargs, varargs)) | |
40 if command['optional']: | |
41 retval.append('[options]') | |
42 return ' '.join(retval) | |
43 | |
44 def list_commands(): | |
45 for command in sorted(commands.keys()): | |
46 print '%s %s' % (command, commandargs2str(command)) | |
47 print '\n%s\n' % commands[command]['doc'] | |
48 | |
49 def doc2arghelp(docstring, decoration='-', delimeter=':'): | |
50 """ | |
51 Parse a docstring and get at the section describing arguments | |
52 - decoration: decoration character | |
53 - delimeter: delimter character | |
54 | |
55 Yields a tuple of the stripped docstring and the arguments help | |
56 dictionary | |
57 """ | |
58 lines = [ i.strip() for i in docstring.split('\n') ] | |
59 argdict = {} | |
60 doc = [] | |
61 option = None | |
62 for line in lines: | |
63 if not line and option: # blank lines terminate | |
64 break | |
65 if line.startswith(decoration) and delimeter in line: | |
66 name, description = line.split(delimeter, 1) | |
67 name = name.lstrip(decoration).strip() | |
68 description = description.strip() | |
69 argdict[name] = [ description ] | |
70 option = name | |
71 else: | |
72 if option: | |
73 argdict[name].append(line) | |
74 else: | |
75 doc.append(line) | |
76 argdict = dict([(key, ' '.join(value)) | |
77 for key, value in argdict.items()]) | |
78 return ('\n'.join(doc), argdict) | |
79 | |
80 def command2parser(command): | |
81 doc, argdict = doc2arghelp(commands[command]['doc']) | |
82 parser = OptionParser('%%prog %s %s' % (command, commandargs2str(command)), | |
83 description=doc, add_help_option=False) | |
84 if commands[command]['optional']: | |
85 for key, value in commands[command]['optional'].items(): | |
86 help = argdict.get(key) | |
87 if value is True: | |
88 parser.add_option('--no-%s' % key, dest=key, | |
89 action='store_false', default=True, | |
90 help=help) | |
91 elif value is False: | |
92 parser.add_option('--%s' % key, action='store_true', | |
93 default=False, help=help) | |
94 else: | |
95 parser.add_option('--%s' % key, help=help) | |
96 | |
97 return parser | |
98 |