1
2
3
4
5
6 """
7 Command class.
8 """
9
10 import optparse
11 import sys
12
13
52
53
55 """
56 I parse options as usual, but I explicitly allow setting stdout
57 so that our print_help() method (invoked by default with -h/--help)
58 defaults to writing there.
59
60 I also override exit() so that I can be used in interactive shells.
61
62 @ivar help_printed: whether help was printed during parsing
63 @ivar usage_printed: whether usage was printed during parsing
64 """
65 help_printed = False
66 usage_printed = False
67
68 _stdout = sys.stdout
69
72
77
78
79 __pychecker__ = 'no-shadowbuiltin'
80
88
92
93 - def exit(self, status=0, msg=None):
94 if msg:
95 sys.stderr.write(msg)
96
97
99 """
100 I am a class that handles a command for a program.
101 Commands can be nested underneath a command for further processing.
102
103 @cvar name: name of the command, lowercase;
104 defaults to the lowercase version of the class name
105 @cvar aliases: list of alternative lowercase names recognized
106 @type aliases: list of str
107 @cvar usage: short one-line usage string;
108 %command gets expanded to a sub-command or [commands]
109 as appropriate. Don't specify the command name itself,
110 it will be added automatically. If not set, defaults
111 to name.
112 @cvar summary: short one-line summary of the command
113 @cvar description: longer paragraph explaining the command
114 @cvar subCommands: dict of name -> commands below this command
115 @type subCommands: dict of str -> L{Command}
116 @cvar parser: the option parser used for parsing
117 @type parser: L{optparse.OptionParser}
118 """
119 name = None
120 aliases = None
121 usage = None
122 summary = None
123 description = None
124 parentCommand = None
125 subCommands = None
126 subCommandClasses = None
127 aliasedSubCommands = None
128 parser = None
129
130 - def __init__(self, parentCommand=None, stdout=sys.stdout,
131 stderr=sys.stderr):
204
206 """
207 Override me to add options to the parser.
208 """
209 pass
210
211 - def do(self, args):
212 """
213 Override me to implement the functionality of the command.
214 """
215 pass
216
218 """
219 Parse the given arguments and act on them.
220
221 @param argv: list of arguments to parse
222 @type argv: list of str
223
224 @rtype: int
225 @returns: an exit code, or None if no actual action was taken.
226 """
227
228
229 self.options, args = self.parser.parse_args(argv)
230 self.debug('parse_args called')
231
232
233 if self.parser.usage_printed or self.parser.help_printed:
234 return None
235
236
237
238 ret = self.handleOptions(self.options)
239 if ret:
240 return ret
241
242
243 if args and args[0] == 'help':
244 self.debug('Asked for help, args %r' % args)
245
246
247 if len(args) == 1:
248 self.outputHelp()
249 return 0
250
251
252
253 if not self.subCommands:
254 self.stderr.write('No subcommands defined.')
255 self.parser.print_usage(file=self.stderr)
256 self.stderr.write(
257 "Use --help to get more information about this command.\n")
258 return 1
259
260
261
262
263 args = [args[1], args[0]]
264
265
266 if not self.subCommands:
267 ret = self.do(args)
268
269
270 if not ret:
271 ret = 0
272
273 return ret
274
275
276 try:
277 command = args[0]
278 except IndexError:
279 self.parser.print_usage(file=self.stderr)
280 self.stderr.write(
281 "Use --help to get a list of commands.\n")
282 return 1
283
284 if command in self.subCommands.keys():
285 return self.subCommands[command].parse(args[1:])
286
287 if self.aliasedSubCommands:
288 if command in self.aliasedSubCommands.keys():
289 return self.aliasedSubCommands[command].parse(args[1:])
290
291 self.stderr.write("Unknown command '%s'.\n" % command)
292 self.parser.print_usage(file=self.stderr)
293 return 1
294
296 """
297 Handle the parsed options.
298 """
299 pass
300
307
309 """
310 Output usage information.
311 Used when the options or arguments were missing or wrong.
312 """
313 self.debug('outputUsage')
314 self.parser.print_usage(file=self.stderr)
315
317 """
318 Return the top-level command, which is typically the program.
319 """
320 c = self
321 while c.parentCommand:
322 c = c.parentCommand
323 return c
324
325 - def debug(self, format, *args):
326 """
327 Override me to handle debug output from this class.
328 """
329 pass
330