24
24
# Those objects can specify the expected type of the argument, which
25
25
# would help with validation and shell completion.
27
# TODO: "--profile=cum", to change sort order. Is there any value in leaving
28
# the profile output behind so it can be interactively examined?
28
# TODO: Help messages for options.
30
# TODO: Define arguments by objects, rather than just using names.
31
# Those objects can specify the expected type of the argument, which
32
# would help with validation and shell completion.
35
# TODO: Help messages for options.
37
# TODO: Define arguments by objects, rather than just using names.
38
# Those objects can specify the expected type of the argument, which
39
# would help with validation and shell completion.
32
45
from warnings import warn
33
46
from inspect import getdoc
37
49
import bzrlib.trace
69
80
return cmd[4:].replace('_','-')
83
def _parse_revision_str(revstr):
84
"""This handles a revision string -> revno.
86
This always returns a list. The list will have one element for
89
>>> _parse_revision_str('234')
90
[<RevisionSpec_int 234>]
91
>>> _parse_revision_str('234..567')
92
[<RevisionSpec_int 234>, <RevisionSpec_int 567>]
93
>>> _parse_revision_str('..')
94
[<RevisionSpec None>, <RevisionSpec None>]
95
>>> _parse_revision_str('..234')
96
[<RevisionSpec None>, <RevisionSpec_int 234>]
97
>>> _parse_revision_str('234..')
98
[<RevisionSpec_int 234>, <RevisionSpec None>]
99
>>> _parse_revision_str('234..456..789') # Maybe this should be an error
100
[<RevisionSpec_int 234>, <RevisionSpec_int 456>, <RevisionSpec_int 789>]
101
>>> _parse_revision_str('234....789') # Error?
102
[<RevisionSpec_int 234>, <RevisionSpec None>, <RevisionSpec_int 789>]
103
>>> _parse_revision_str('revid:test@other.com-234234')
104
[<RevisionSpec_revid revid:test@other.com-234234>]
105
>>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
106
[<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
107
>>> _parse_revision_str('revid:test@other.com-234234..23')
108
[<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_int 23>]
109
>>> _parse_revision_str('date:2005-04-12')
110
[<RevisionSpec_date date:2005-04-12>]
111
>>> _parse_revision_str('date:2005-04-12 12:24:33')
112
[<RevisionSpec_date date:2005-04-12 12:24:33>]
113
>>> _parse_revision_str('date:2005-04-12T12:24:33')
114
[<RevisionSpec_date date:2005-04-12T12:24:33>]
115
>>> _parse_revision_str('date:2005-04-12,12:24:33')
116
[<RevisionSpec_date date:2005-04-12,12:24:33>]
117
>>> _parse_revision_str('-5..23')
118
[<RevisionSpec_int -5>, <RevisionSpec_int 23>]
119
>>> _parse_revision_str('-5')
120
[<RevisionSpec_int -5>]
121
>>> _parse_revision_str('123a')
122
Traceback (most recent call last):
124
BzrError: No namespace registered for string: '123a'
125
>>> _parse_revision_str('abc')
126
Traceback (most recent call last):
128
BzrError: No namespace registered for string: 'abc'
131
old_format_re = re.compile('\d*:\d*')
132
m = old_format_re.match(revstr)
135
warning('Colon separator for revision numbers is deprecated.'
137
for rev in revstr.split(':'):
139
revs.append(RevisionSpec(int(rev)))
141
revs.append(RevisionSpec(None))
143
for x in revstr.split('..'):
145
revs.append(RevisionSpec(None))
147
revs.append(RevisionSpec(x))
72
151
def _builtin_commands():
73
152
import bzrlib.builtins
178
256
if self.__doc__ == Command.__doc__:
179
257
warn("No help message set for %r" % self)
182
"""Return dict of valid options for this command.
184
Maps from long option name to option object."""
186
r['help'] = Option.OPTIONS['help']
187
for o in self.takes_options:
188
if not isinstance(o, Option):
189
o = Option.OPTIONS[o]
193
260
def run_argv(self, argv):
194
261
"""Parse command line and run."""
195
args, opts = parse_args(self, argv)
262
args, opts = parse_args(argv)
196
264
if 'help' in opts: # e.g. bzr add --help
197
265
from bzrlib.help import help_on_command
198
266
help_on_command(self.name())
200
# XXX: This should be handled by the parser
201
allowed_names = self.options().keys()
269
# check options are reasonable
270
allowed = self.takes_options
202
271
for oname in opts:
203
if oname not in allowed_names:
272
if oname not in allowed:
204
273
raise BzrCommandError("option '--%s' is not allowed for command %r"
205
274
% (oname, self.name()))
206
276
# mix arguments and options into one dictionary
207
277
cmdargs = _match_argform(self.name(), self.takes_args, args)
268
339
parsed = [spec, None]
271
def parse_args(command, argv):
343
# list of all available options; the rhs can be either None for an
344
# option that takes no argument, or a constructor function that checks
358
'revision': _parse_revision_str,
383
def parse_args(argv):
272
384
"""Parse command line.
274
386
Arguments and options are parsed at this level before being passed
275
387
down to specific command handlers. This routine knows, from a
276
388
lookup table, something about the available options, what optargs
277
389
they take, and which commands will accept them.
391
>>> parse_args('--help'.split())
393
>>> parse_args('help -- --invalidcmd'.split())
394
(['help', '--invalidcmd'], {})
395
>>> parse_args('--version'.split())
396
([], {'version': True})
397
>>> parse_args('status --all'.split())
398
(['status'], {'all': True})
399
>>> parse_args('commit --message=biter'.split())
400
(['commit'], {'message': u'biter'})
401
>>> parse_args('log -r 500'.split())
402
(['log'], {'revision': [<RevisionSpec_int 500>]})
403
>>> parse_args('log -r500..600'.split())
404
(['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
405
>>> parse_args('log -vr500..600'.split())
406
(['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
407
>>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
408
(['log'], {'revision': [<RevisionSpec_revno revno:500>, <RevisionSpec_int 600>]})
279
# TODO: chop up this beast; make it a method of the Command
283
cmd_options = command.options()
291
# We've received a standalone -- No more flags
416
if not argsover and a[0] == '-':
295
417
# option names must not be unicode
422
# We've received a standalone -- No more flags
299
425
mutter(" got option %r" % a)
301
427
optname, optarg = a[2:].split('=', 1)
304
if optname not in cmd_options:
305
raise BzrCommandError('unknown long option %r for command %s'
306
% (a, command.name()))
430
if optname not in OPTIONS:
431
raise BzrError('unknown long option %r' % a)
309
if shortopt in Option.SHORT_OPTIONS:
434
if shortopt in SHORT_OPTIONS:
310
435
# Multi-character options must have a space to delimit
312
# ^^^ what does this mean? mbp 20051014
313
optname = Option.SHORT_OPTIONS[shortopt].name
437
optname = SHORT_OPTIONS[shortopt]
315
439
# Single character short options, can be chained,
316
440
# and have their value appended to their name
317
441
shortopt = a[1:2]
318
if shortopt not in Option.SHORT_OPTIONS:
442
if shortopt not in SHORT_OPTIONS:
319
443
# We didn't find the multi-character name, and we
320
444
# didn't find the single char name
321
445
raise BzrError('unknown short option %r' % a)
322
optname = Option.SHORT_OPTIONS[shortopt].name
446
optname = SHORT_OPTIONS[shortopt]
325
449
# There are extra things on this option
326
450
# see if it is the value, or if it is another
328
optargfn = Option.OPTIONS[optname].type
452
optargfn = OPTIONS[optname]
329
453
if optargfn is None:
330
454
# This option does not take an argument, so the
331
455
# next entry is another short option, pack it back