32
32
from warnings import warn
33
33
from inspect import getdoc
36
37
import bzrlib.trace
37
from bzrlib.trace import mutter, note, log_error, warning
38
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
38
from bzrlib.trace import mutter, note, log_error, warning, be_quiet
39
from bzrlib.errors import (BzrError,
39
44
from bzrlib.revisionspec import RevisionSpec
40
45
from bzrlib import BZRDIR
46
from bzrlib.option import Option
45
def register_command(cmd):
51
def register_command(cmd, decorate=False):
46
52
"Utility function to help register a command"
67
79
return cmd[4:].replace('_','-')
70
def _parse_revision_str(revstr):
71
"""This handles a revision string -> revno.
73
This always returns a list. The list will have one element for
76
>>> _parse_revision_str('234')
77
[<RevisionSpec_int 234>]
78
>>> _parse_revision_str('234..567')
79
[<RevisionSpec_int 234>, <RevisionSpec_int 567>]
80
>>> _parse_revision_str('..')
81
[<RevisionSpec None>, <RevisionSpec None>]
82
>>> _parse_revision_str('..234')
83
[<RevisionSpec None>, <RevisionSpec_int 234>]
84
>>> _parse_revision_str('234..')
85
[<RevisionSpec_int 234>, <RevisionSpec None>]
86
>>> _parse_revision_str('234..456..789') # Maybe this should be an error
87
[<RevisionSpec_int 234>, <RevisionSpec_int 456>, <RevisionSpec_int 789>]
88
>>> _parse_revision_str('234....789') # Error?
89
[<RevisionSpec_int 234>, <RevisionSpec None>, <RevisionSpec_int 789>]
90
>>> _parse_revision_str('revid:test@other.com-234234')
91
[<RevisionSpec_revid revid:test@other.com-234234>]
92
>>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
93
[<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
94
>>> _parse_revision_str('revid:test@other.com-234234..23')
95
[<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_int 23>]
96
>>> _parse_revision_str('date:2005-04-12')
97
[<RevisionSpec_date date:2005-04-12>]
98
>>> _parse_revision_str('date:2005-04-12 12:24:33')
99
[<RevisionSpec_date date:2005-04-12 12:24:33>]
100
>>> _parse_revision_str('date:2005-04-12T12:24:33')
101
[<RevisionSpec_date date:2005-04-12T12:24:33>]
102
>>> _parse_revision_str('date:2005-04-12,12:24:33')
103
[<RevisionSpec_date date:2005-04-12,12:24:33>]
104
>>> _parse_revision_str('-5..23')
105
[<RevisionSpec_int -5>, <RevisionSpec_int 23>]
106
>>> _parse_revision_str('-5')
107
[<RevisionSpec_int -5>]
108
>>> _parse_revision_str('123a')
109
Traceback (most recent call last):
111
BzrError: No namespace registered for string: '123a'
112
>>> _parse_revision_str('abc')
113
Traceback (most recent call last):
115
BzrError: No namespace registered for string: 'abc'
118
old_format_re = re.compile('\d*:\d*')
119
m = old_format_re.match(revstr)
122
warning('Colon separator for revision numbers is deprecated.'
124
for rev in revstr.split(':'):
126
revs.append(RevisionSpec(int(rev)))
128
revs.append(RevisionSpec(None))
130
for x in revstr.split('..'):
132
revs.append(RevisionSpec(None))
134
revs.append(RevisionSpec(x))
138
82
def _builtin_commands():
139
83
import bzrlib.builtins
224
168
List of argument forms, marked with whether they are optional,
173
['to_location', 'from_branch?', 'file*']
175
'to_location' is required
176
'from_branch' is optional
177
'file' can be specified 0 or more times
228
List of options that may be given for this command.
180
List of options that may be given for this command. These can
181
be either strings, referring to globally-defined options,
182
or option objects. Retrieve through options().
231
185
If true, this command isn't advertised. This is typically
232
186
for commands intended for expert users.
237
190
takes_options = []
243
196
if self.__doc__ == Command.__doc__:
244
197
warn("No help message set for %r" % self)
200
"""Return dict of valid options for this command.
202
Maps from long option name to option object."""
204
r['help'] = Option.OPTIONS['help']
205
for o in self.takes_options:
206
if not isinstance(o, Option):
207
o = Option.OPTIONS[o]
247
211
def run_argv(self, argv):
248
212
"""Parse command line and run."""
249
args, opts = parse_args(argv)
213
args, opts = parse_args(self, argv)
251
214
if 'help' in opts: # e.g. bzr add --help
252
215
from bzrlib.help import help_on_command
253
216
help_on_command(self.name())
256
# check options are reasonable
257
allowed = self.takes_options
218
# XXX: This should be handled by the parser
219
allowed_names = self.options().keys()
258
220
for oname in opts:
259
if oname not in allowed:
221
if oname not in allowed_names:
260
222
raise BzrCommandError("option '--%s' is not allowed for command %r"
261
223
% (oname, self.name()))
263
224
# mix arguments and options into one dictionary
264
225
cmdargs = _match_argform(self.name(), self.takes_args, args)
326
286
parsed = [spec, None]
330
# list of all available options; the rhs can be either None for an
331
# option that takes no argument, or a constructor function that checks
345
'revision': _parse_revision_str,
370
def parse_args(argv):
289
def parse_args(command, argv):
371
290
"""Parse command line.
373
292
Arguments and options are parsed at this level before being passed
374
293
down to specific command handlers. This routine knows, from a
375
294
lookup table, something about the available options, what optargs
376
295
they take, and which commands will accept them.
378
>>> parse_args('--help'.split())
380
>>> parse_args('help -- --invalidcmd'.split())
381
(['help', '--invalidcmd'], {})
382
>>> parse_args('--version'.split())
383
([], {'version': True})
384
>>> parse_args('status --all'.split())
385
(['status'], {'all': True})
386
>>> parse_args('commit --message=biter'.split())
387
(['commit'], {'message': u'biter'})
388
>>> parse_args('log -r 500'.split())
389
(['log'], {'revision': [<RevisionSpec_int 500>]})
390
>>> parse_args('log -r500..600'.split())
391
(['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
392
>>> parse_args('log -vr500..600'.split())
393
(['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
394
>>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
395
(['log'], {'revision': [<RevisionSpec_revno revno:500>, <RevisionSpec_int 600>]})
297
# TODO: chop up this beast; make it a method of the Command
301
cmd_options = command.options()
403
if not argsover and a[0] == '-':
309
# We've received a standalone -- No more flags
404
313
# option names must not be unicode
409
# We've received a standalone -- No more flags
412
mutter(" got option %r" % a)
317
mutter(" got option %r", a)
414
319
optname, optarg = a[2:].split('=', 1)
417
if optname not in OPTIONS:
418
raise BzrError('unknown long option %r' % a)
322
if optname not in cmd_options:
323
raise BzrOptionError('unknown long option %r for command %s'
324
% (a, command.name()))
421
if shortopt in SHORT_OPTIONS:
327
if shortopt in Option.SHORT_OPTIONS:
422
328
# Multi-character options must have a space to delimit
424
optname = SHORT_OPTIONS[shortopt]
330
# ^^^ what does this mean? mbp 20051014
331
optname = Option.SHORT_OPTIONS[shortopt].name
426
333
# Single character short options, can be chained,
427
334
# and have their value appended to their name
428
335
shortopt = a[1:2]
429
if shortopt not in SHORT_OPTIONS:
336
if shortopt not in Option.SHORT_OPTIONS:
430
337
# We didn't find the multi-character name, and we
431
338
# didn't find the single char name
432
339
raise BzrError('unknown short option %r' % a)
433
optname = SHORT_OPTIONS[shortopt]
340
optname = Option.SHORT_OPTIONS[shortopt].name
436
343
# There are extra things on this option
437
344
# see if it is the value, or if it is another
439
optargfn = OPTIONS[optname]
346
optargfn = Option.OPTIONS[optname].type
440
347
if optargfn is None:
441
348
# This option does not take an argument, so the
442
349
# next entry is another short option, pack it back
601
520
if not opt_no_plugins:
602
521
from bzrlib.plugin import load_plugins
524
from bzrlib.plugin import disable_plugins
605
527
cmd = str(argv.pop(0))
607
529
cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
610
ret = apply_profiled(cmd_obj.run_argv, argv)
612
ret = cmd_obj.run_argv(argv)
533
ret = apply_lsprofiled(cmd_obj.run_argv, argv)
535
ret = apply_profiled(cmd_obj.run_argv, argv)
537
ret = cmd_obj.run_argv(argv)
540
# reset, in case we may do other commands later within the same process
543
def display_command(func):
544
"""Decorator that suppresses pipe/interrupt errors."""
545
def ignore_pipe(*args, **kwargs):
547
result = func(*args, **kwargs)
551
if not hasattr(e, 'errno'):
553
if e.errno != errno.EPIPE:
556
except KeyboardInterrupt:
563
from bzrlib.ui.text import TextUIFactory
564
## bzrlib.trace.enable_default_logging()
618
565
bzrlib.trace.log_startup(argv)
619
bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
621
return run_bzr_catch_errors(argv[1:])
566
bzrlib.ui.ui_factory = TextUIFactory()
567
ret = run_bzr_catch_errors(argv[1:])
568
mutter("return code %d", ret)
624
572
def run_bzr_catch_errors(argv):
630
# do this here inside the exception wrappers to catch EPIPE
632
#wrap common errors as CommandErrors.
633
except (NotBranchError,), e:
634
raise BzrCommandError(str(e))
635
except BzrCommandError, e:
636
# command line syntax error, etc
640
bzrlib.trace.log_exception()
642
except AssertionError, e:
643
bzrlib.trace.log_exception('assertion failed: ' + str(e))
645
except KeyboardInterrupt, e:
646
bzrlib.trace.log_exception('interrupted')
577
# do this here inside the exception wrappers to catch EPIPE
648
579
except Exception, e:
580
# used to handle AssertionError and KeyboardInterrupt
581
# specially here, but hopefully they're handled ok by the logger now
650
583
if (isinstance(e, IOError)
651
584
and hasattr(e, 'errno')
652
585
and e.errno == errno.EPIPE):
653
586
bzrlib.trace.note('broken pipe')
656
589
bzrlib.trace.log_exception()
590
if os.environ.get('BZR_PDB'):
591
print '**** entering debugger'
593
pdb.post_mortem(sys.exc_traceback)
659
596
if __name__ == '__main__':
660
597
sys.exit(main(sys.argv))