comparison profilemanager/command.py @ 1:979315ed0816

mucho cleanup on optionparser stuff
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 05 Apr 2010 08:55:44 -0700
parents 7301d534bc6c
children 4d1cd60dd2a1
comparison
equal deleted inserted replaced
0:7301d534bc6c 1:979315ed0816
39 retval.append('<%s> [%s] [...]' % (varargs, varargs)) 39 retval.append('<%s> [%s] [...]' % (varargs, varargs))
40 if command['optional']: 40 if command['optional']:
41 retval.append('[options]') 41 retval.append('[options]')
42 return ' '.join(retval) 42 return ' '.join(retval)
43 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 44
49 def doc2arghelp(docstring, decoration='-', delimeter=':'): 45 def doc2arghelp(docstring, decoration='-', delimeter=':'):
50 """ 46 """
51 Parse a docstring and get at the section describing arguments 47 Parse a docstring and get at the section describing arguments
52 - decoration: decoration character 48 - decoration: decoration character
94 else: 90 else:
95 parser.add_option('--%s' % key, help=help) 91 parser.add_option('--%s' % key, help=help)
96 92
97 return parser 93 return parser
98 94
95 class CommandParser(OptionParser):
96 def __init__(self, commands, description=None, setup=None):
97 usage = '%prog [options] command [command-options]'
98 OptionParser.__init__(self, description=description)
99 for _command in commands:
100 command(_command)
101 self.disable_interspersed_args()
102 self.setup = setup
103
104 def print_help(self):
105 OptionParser.print_help(self)
106 # short descriptions for commands
107 command_descriptions = [dict(name=i,
108 description=commands[i]['doc'].strip().split('\n',1)[0])
109 for i in sorted(commands.keys())]
110 max_len = max([len(i['name']) for i in command_descriptions])
111 description = "Commands: \n%s" % ('\n'.join([' %s%s %s' % (description['name'], ' ' * (max_len - len(description['name'])), description['description'])
112 for description in command_descriptions]))
113
114 print
115 print description
116
117 def parse(self, args=sys.argv[1:]):
118 """global parse step"""
119
120 self.options, args = self.parse_args(args)
121
122 # help/sanity check -- should probably be separated
123 if not len(args):
124 self.print_help()
125 sys.exit(0)
126 if args[0] == 'help':
127 if len(args) == 2:
128 if args[1] in commands:
129 name = args[1]
130 commandparser = command2parser(name)
131 commandparser.print_help()
132 else:
133 self.error("No command '%s'" % args[1])
134 else:
135 self.print_help()
136 sys.exit(0)
137 command = args[0]
138 if command not in commands:
139 self.error("No command '%s'" % command)
140 return command, args[1:]
141
142 def invoke(self, args=sys.argv[1:]):
143 """
144 invoke
145 """
146
147 # parse
148 name, args = self.parse(args)
149
150 # setup
151 _object = self.setup(self, self.options)
152
153 # command specific args
154 command = commands[name]
155 commandparser = command2parser(name)
156 command_options, command_args = commandparser.parse_args(args)
157 if len(command_args) < len(command['args']):
158 commandparser.error("Not enough arguments given")
159 if len(command_args) != len(command['args']) and not command['varargs']:
160 commandparser.error("Too many arguments given")
161
162 # invoke the command
163 getattr(_object, name)(*command_args, **command_options.__dict__)
164