261
262
from bzrlib.help import help_on_command
262
263
help_on_command(self.name())
264
# XXX: This should be handled by the parser
265
allowed_names = self.options().keys()
267
if oname not in allowed_names:
268
raise BzrOptionError("option '--%s' is not allowed for"
269
" command %r" % (oname, self.name()))
270
265
# mix arguments and options into one dictionary
271
266
cmdargs = _match_argform(self.name(), self.takes_args, args)
346
341
parsed = [spec, None]
345
class OptionParser(optparse.OptionParser):
346
"""OptionParser that raises exceptions instead of exiting"""
348
DEFAULT_VALUE = "DEFAULT"
350
def error(self, message):
351
raise BzrCommandError(message)
354
def get_optparser(options):
355
"""Generate an optparse parser for bzrlib-style options"""
356
def type_callback(option, opt, value, parser, name, optargfn):
357
setattr(parser.values, name, optargfn(value))
359
parser = OptionParser()
360
parser.remove_option('--help')
361
short_options = dict((k.name, (v, k)) for v, k in
362
Option.SHORT_OPTIONS.iteritems())
363
for name, option in options.iteritems():
364
option_strings = ['--%s' % name]
365
if name in short_options:
366
short_name, short_option = short_options[name]
367
option_strings.append('-%s' % short_name)
368
optargfn = option.type
370
parser.add_option(action='store_true', dest=name,
371
default=OptionParser.DEFAULT_VALUE,
374
parser.add_option(action='callback', callback=type_callback,
376
default=OptionParser.DEFAULT_VALUE,
377
callback_args=(name, optargfn), *option_strings)
349
381
def parse_args(command, argv, alias_argv=None):
350
382
"""Parse command line.
354
386
lookup table, something about the available options, what optargs
355
387
they take, and which commands will accept them.
357
# TODO: chop up this beast; make it a method of the Command
362
cmd_options = command.options()
389
# TODO: make it a method of the Command?
390
parser = get_optparser(command.options())
364
proc_aliasarg = True # Are we processing alias_argv now?
365
for proc_argv in alias_argv, argv:
375
# We've received a standalone -- No more flags
379
# option names must not be unicode
383
mutter(" got option %r", a)
385
optname, optarg = a[2:].split('=', 1)
388
if optname not in cmd_options:
389
raise BzrCommandError('unknown option "%s"' % a)
392
if shortopt in Option.SHORT_OPTIONS:
393
# Multi-character options must have a space to delimit
395
# ^^^ what does this mean? mbp 20051014
396
optname = Option.SHORT_OPTIONS[shortopt].name
398
# Single character short options, can be chained,
399
# and have their value appended to their name
401
if shortopt not in Option.SHORT_OPTIONS:
402
# We didn't find the multi-character name, and we
403
# didn't find the single char name
404
raise BzrCommandError('unknown option "%s"' % a)
405
optname = Option.SHORT_OPTIONS[shortopt].name
392
if alias_argv is not None:
393
args = alias_argv + argv
408
# There are extra things on this option
409
# see if it is the value, or if it is another
411
optargfn = Option.OPTIONS[optname].type
413
# This option does not take an argument, so the
414
# next entry is another short option, pack it
416
proc_argv.insert(0, '-' + a[2:])
418
# This option takes an argument, so pack it
421
if optname not in cmd_options:
422
raise BzrCommandError('unknown option "%s"' % shortopt)
424
# XXX: Do we ever want to support this, e.g. for -r?
426
raise BzrCommandError('repeated option %r' % a)
427
elif optname in alias_opts:
428
# Replace what's in the alias with what's in the real
430
del alias_opts[optname]
432
proc_argv.insert(0, a)
435
raise BzrCommandError('repeated option %r' % a)
437
option_obj = cmd_options[optname]
438
optargfn = option_obj.type
442
raise BzrCommandError('option %r needs an argument' % a)
444
optarg = proc_argv.pop(0)
445
opts[optname] = optargfn(optarg)
447
alias_opts[optname] = optargfn(optarg)
450
raise BzrCommandError('option %r takes no argument' % optname)
453
alias_opts[optname] = True
456
proc_aliasarg = False # Done with alias argv
397
options, args = parser.parse_args(args)
398
opts = dict([(k, v) for k, v in options.__dict__.iteritems() if
399
v is not OptionParser.DEFAULT_VALUE])
457
400
return args, opts