32
32
from warnings import warn
33
33
from inspect import getdoc
37
36
import bzrlib.trace
38
from bzrlib.trace import mutter, note, log_error, warning, be_quiet
39
from bzrlib.errors import (BzrError,
37
from bzrlib.trace import mutter, note, log_error, warning
38
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
44
39
from bzrlib.revisionspec import RevisionSpec
45
40
from bzrlib import BZRDIR
46
from bzrlib.option import Option
51
def register_command(cmd, decorate=False):
45
def register_command(cmd):
52
46
"Utility function to help register a command"
79
67
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
74
each revision specifier supplied.
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'
116
>>> _parse_revision_str('branch:../branch2')
117
[<RevisionSpec_branch branch:../branch2>]
120
old_format_re = re.compile('\d*:\d*')
121
m = old_format_re.match(revstr)
124
warning('Colon separator for revision numbers is deprecated.'
126
for rev in revstr.split(':'):
128
revs.append(RevisionSpec(int(rev)))
130
revs.append(RevisionSpec(None))
133
for x in revstr.split('..'):
135
revs.append(RevisionSpec(None))
137
# looks like a namespace:.. has happened
138
next_prefix = x + '..'
140
if next_prefix is not None:
142
revs.append(RevisionSpec(x))
144
if next_prefix is not None:
145
revs.append(RevisionSpec(next_prefix))
82
149
def _builtin_commands():
83
150
import bzrlib.builtins
168
235
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
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().
239
List of options that may be given for this command.
185
242
If true, this command isn't advertised. This is typically
186
243
for commands intended for expert users.
190
248
takes_options = []
196
254
if self.__doc__ == Command.__doc__:
197
255
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]
211
258
def run_argv(self, argv):
212
259
"""Parse command line and run."""
213
args, opts = parse_args(self, argv)
260
args, opts = parse_args(argv)
214
262
if 'help' in opts: # e.g. bzr add --help
215
263
from bzrlib.help import help_on_command
216
264
help_on_command(self.name())
218
# XXX: This should be handled by the parser
219
allowed_names = self.options().keys()
267
# check options are reasonable
268
allowed = self.takes_options
220
269
for oname in opts:
221
if oname not in allowed_names:
270
if oname not in allowed:
222
271
raise BzrCommandError("option '--%s' is not allowed for command %r"
223
272
% (oname, self.name()))
224
274
# mix arguments and options into one dictionary
225
275
cmdargs = _match_argform(self.name(), self.takes_args, args)
286
337
parsed = [spec, None]
289
def parse_args(command, argv):
341
# list of all available options; the rhs can be either None for an
342
# option that takes no argument, or a constructor function that checks
358
'revision': _parse_revision_str,
385
def parse_args(argv):
290
386
"""Parse command line.
292
388
Arguments and options are parsed at this level before being passed
293
389
down to specific command handlers. This routine knows, from a
294
390
lookup table, something about the available options, what optargs
295
391
they take, and which commands will accept them.
393
>>> parse_args('--help'.split())
395
>>> parse_args('help -- --invalidcmd'.split())
396
(['help', '--invalidcmd'], {})
397
>>> parse_args('--version'.split())
398
([], {'version': True})
399
>>> parse_args('status --all'.split())
400
(['status'], {'all': True})
401
>>> parse_args('commit --message=biter'.split())
402
(['commit'], {'message': u'biter'})
403
>>> parse_args('log -r 500'.split())
404
(['log'], {'revision': [<RevisionSpec_int 500>]})
405
>>> parse_args('log -r500..600'.split())
406
(['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
407
>>> parse_args('log -vr500..600'.split())
408
(['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
409
>>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
410
(['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()
309
# We've received a standalone -- No more flags
418
if not argsover and a[0] == '-':
313
419
# option names must not be unicode
317
mutter(" got option %r", a)
424
# We've received a standalone -- No more flags
427
mutter(" got option %r" % a)
319
429
optname, optarg = a[2:].split('=', 1)
322
if optname not in cmd_options:
323
raise BzrOptionError('unknown long option %r for command %s'
324
% (a, command.name()))
432
if optname not in OPTIONS:
433
raise BzrError('unknown long option %r' % a)
327
if shortopt in Option.SHORT_OPTIONS:
436
if shortopt in SHORT_OPTIONS:
328
437
# Multi-character options must have a space to delimit
330
# ^^^ what does this mean? mbp 20051014
331
optname = Option.SHORT_OPTIONS[shortopt].name
439
optname = SHORT_OPTIONS[shortopt]
333
441
# Single character short options, can be chained,
334
442
# and have their value appended to their name
335
443
shortopt = a[1:2]
336
if shortopt not in Option.SHORT_OPTIONS:
444
if shortopt not in SHORT_OPTIONS:
337
445
# We didn't find the multi-character name, and we
338
446
# didn't find the single char name
339
447
raise BzrError('unknown short option %r' % a)
340
optname = Option.SHORT_OPTIONS[shortopt].name
448
optname = SHORT_OPTIONS[shortopt]
343
451
# There are extra things on this option
344
452
# see if it is the value, or if it is another
346
optargfn = Option.OPTIONS[optname].type
454
optargfn = OPTIONS[optname]
347
455
if optargfn is None:
348
456
# This option does not take an argument, so the
349
457
# next entry is another short option, pack it back
514
622
cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
518
ret = apply_profiled(cmd_obj.run_argv, argv)
520
ret = cmd_obj.run_argv(argv)
523
# reset, in case we may do other commands later within the same process
526
def display_command(func):
527
"""Decorator that suppresses pipe/interrupt errors."""
528
def ignore_pipe(*args, **kwargs):
530
result = func(*args, **kwargs)
534
if not hasattr(e, 'errno'):
536
if e.errno != errno.EPIPE:
539
except KeyboardInterrupt:
625
ret = apply_profiled(cmd_obj.run_argv, argv)
627
ret = cmd_obj.run_argv(argv)
546
## bzrlib.trace.enable_default_logging()
547
633
bzrlib.trace.log_startup(argv)
548
634
bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
549
ret = run_bzr_catch_errors(argv[1:])
550
mutter("return code %d", ret)
636
return run_bzr_catch_errors(argv[1:])
554
639
def run_bzr_catch_errors(argv):
559
644
# do this here inside the exception wrappers to catch EPIPE
560
645
sys.stdout.flush()
646
except BzrCommandError, e:
647
# command line syntax error, etc
651
bzrlib.trace.log_exception()
653
except AssertionError, e:
654
bzrlib.trace.log_exception('assertion failed: ' + str(e))
656
except KeyboardInterrupt, e:
657
bzrlib.trace.log_exception('interrupted')
561
659
except Exception, e:
562
# used to handle AssertionError and KeyboardInterrupt
563
# specially here, but hopefully they're handled ok by the logger now
565
661
if (isinstance(e, IOError)
566
662
and hasattr(e, 'errno')
567
663
and e.errno == errno.EPIPE):
568
664
bzrlib.trace.note('broken pipe')
571
669
bzrlib.trace.log_exception()
572
if os.environ.get('BZR_PDB'):
573
print '**** entering debugger'
575
pdb.post_mortem(sys.exc_traceback)
578
672
if __name__ == '__main__':
579
673
sys.exit(main(sys.argv))