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.
32
38
from warnings import warn
33
39
from inspect import getdoc
37
42
import bzrlib.trace
69
73
return cmd[4:].replace('_','-')
76
def _parse_revision_str(revstr):
77
"""This handles a revision string -> revno.
79
This always returns a list. The list will have one element for
82
>>> _parse_revision_str('234')
83
[<RevisionSpec_int 234>]
84
>>> _parse_revision_str('234..567')
85
[<RevisionSpec_int 234>, <RevisionSpec_int 567>]
86
>>> _parse_revision_str('..')
87
[<RevisionSpec None>, <RevisionSpec None>]
88
>>> _parse_revision_str('..234')
89
[<RevisionSpec None>, <RevisionSpec_int 234>]
90
>>> _parse_revision_str('234..')
91
[<RevisionSpec_int 234>, <RevisionSpec None>]
92
>>> _parse_revision_str('234..456..789') # Maybe this should be an error
93
[<RevisionSpec_int 234>, <RevisionSpec_int 456>, <RevisionSpec_int 789>]
94
>>> _parse_revision_str('234....789') # Error?
95
[<RevisionSpec_int 234>, <RevisionSpec None>, <RevisionSpec_int 789>]
96
>>> _parse_revision_str('revid:test@other.com-234234')
97
[<RevisionSpec_revid revid:test@other.com-234234>]
98
>>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
99
[<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
100
>>> _parse_revision_str('revid:test@other.com-234234..23')
101
[<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_int 23>]
102
>>> _parse_revision_str('date:2005-04-12')
103
[<RevisionSpec_date date:2005-04-12>]
104
>>> _parse_revision_str('date:2005-04-12 12:24:33')
105
[<RevisionSpec_date date:2005-04-12 12:24:33>]
106
>>> _parse_revision_str('date:2005-04-12T12:24:33')
107
[<RevisionSpec_date date:2005-04-12T12:24:33>]
108
>>> _parse_revision_str('date:2005-04-12,12:24:33')
109
[<RevisionSpec_date date:2005-04-12,12:24:33>]
110
>>> _parse_revision_str('-5..23')
111
[<RevisionSpec_int -5>, <RevisionSpec_int 23>]
112
>>> _parse_revision_str('-5')
113
[<RevisionSpec_int -5>]
114
>>> _parse_revision_str('123a')
115
Traceback (most recent call last):
117
BzrError: No namespace registered for string: '123a'
118
>>> _parse_revision_str('abc')
119
Traceback (most recent call last):
121
BzrError: No namespace registered for string: 'abc'
124
old_format_re = re.compile('\d*:\d*')
125
m = old_format_re.match(revstr)
128
warning('Colon separator for revision numbers is deprecated.'
130
for rev in revstr.split(':'):
132
revs.append(RevisionSpec(int(rev)))
134
revs.append(RevisionSpec(None))
136
for x in revstr.split('..'):
138
revs.append(RevisionSpec(None))
140
revs.append(RevisionSpec(x))
72
144
def _builtin_commands():
73
145
import bzrlib.builtins
178
249
if self.__doc__ == Command.__doc__:
179
250
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
253
def run_argv(self, argv):
194
254
"""Parse command line and run."""
195
args, opts = parse_args(self, argv)
255
args, opts = parse_args(argv)
196
257
if 'help' in opts: # e.g. bzr add --help
197
258
from bzrlib.help import help_on_command
198
259
help_on_command(self.name())
200
# XXX: This should be handled by the parser
201
allowed_names = self.options().keys()
262
# check options are reasonable
263
allowed = self.takes_options
202
264
for oname in opts:
203
if oname not in allowed_names:
265
if oname not in allowed:
204
266
raise BzrCommandError("option '--%s' is not allowed for command %r"
205
267
% (oname, self.name()))
206
269
# mix arguments and options into one dictionary
207
270
cmdargs = _match_argform(self.name(), self.takes_args, args)
268
332
parsed = [spec, None]
271
def parse_args(command, argv):
336
# list of all available options; the rhs can be either None for an
337
# option that takes no argument, or a constructor function that checks
351
'revision': _parse_revision_str,
376
def parse_args(argv):
272
377
"""Parse command line.
274
379
Arguments and options are parsed at this level before being passed
275
380
down to specific command handlers. This routine knows, from a
276
381
lookup table, something about the available options, what optargs
277
382
they take, and which commands will accept them.
384
>>> parse_args('--help'.split())
386
>>> parse_args('help -- --invalidcmd'.split())
387
(['help', '--invalidcmd'], {})
388
>>> parse_args('--version'.split())
389
([], {'version': True})
390
>>> parse_args('status --all'.split())
391
(['status'], {'all': True})
392
>>> parse_args('commit --message=biter'.split())
393
(['commit'], {'message': u'biter'})
394
>>> parse_args('log -r 500'.split())
395
(['log'], {'revision': [<RevisionSpec_int 500>]})
396
>>> parse_args('log -r500..600'.split())
397
(['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
398
>>> parse_args('log -vr500..600'.split())
399
(['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
400
>>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
401
(['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
409
if not argsover and a[0] == '-':
295
410
# option names must not be unicode
415
# We've received a standalone -- No more flags
299
418
mutter(" got option %r" % a)
301
420
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()))
423
if optname not in OPTIONS:
424
raise BzrError('unknown long option %r' % a)
309
if shortopt in Option.SHORT_OPTIONS:
427
if shortopt in SHORT_OPTIONS:
310
428
# Multi-character options must have a space to delimit
312
# ^^^ what does this mean? mbp 20051014
313
optname = Option.SHORT_OPTIONS[shortopt].name
430
optname = SHORT_OPTIONS[shortopt]
315
432
# Single character short options, can be chained,
316
433
# and have their value appended to their name
317
434
shortopt = a[1:2]
318
if shortopt not in Option.SHORT_OPTIONS:
435
if shortopt not in SHORT_OPTIONS:
319
436
# We didn't find the multi-character name, and we
320
437
# didn't find the single char name
321
438
raise BzrError('unknown short option %r' % a)
322
optname = Option.SHORT_OPTIONS[shortopt].name
439
optname = SHORT_OPTIONS[shortopt]
325
442
# There are extra things on this option
326
443
# see if it is the value, or if it is another
328
optargfn = Option.OPTIONS[optname].type
445
optargfn = OPTIONS[optname]
329
446
if optargfn is None:
330
447
# This option does not take an argument, so the
331
448
# next entry is another short option, pack it back