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
356
'revision': _parse_revision_str,
382
def parse_args(argv):
290
383
"""Parse command line.
292
385
Arguments and options are parsed at this level before being passed
293
386
down to specific command handlers. This routine knows, from a
294
387
lookup table, something about the available options, what optargs
295
388
they take, and which commands will accept them.
390
>>> parse_args('--help'.split())
392
>>> parse_args('help -- --invalidcmd'.split())
393
(['help', '--invalidcmd'], {})
394
>>> parse_args('--version'.split())
395
([], {'version': True})
396
>>> parse_args('status --all'.split())
397
(['status'], {'all': True})
398
>>> parse_args('commit --message=biter'.split())
399
(['commit'], {'message': u'biter'})
400
>>> parse_args('log -r 500'.split())
401
(['log'], {'revision': [<RevisionSpec_int 500>]})
402
>>> parse_args('log -r500..600'.split())
403
(['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
404
>>> parse_args('log -vr500..600'.split())
405
(['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
406
>>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
407
(['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
415
if not argsover and a[0] == '-':
313
416
# option names must not be unicode
317
mutter(" got option %r", a)
421
# We've received a standalone -- No more flags
424
mutter(" got option %r" % a)
319
426
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()))
429
if optname not in OPTIONS:
430
raise BzrError('unknown long option %r' % a)
327
if shortopt in Option.SHORT_OPTIONS:
433
if shortopt in SHORT_OPTIONS:
328
434
# Multi-character options must have a space to delimit
330
# ^^^ what does this mean? mbp 20051014
331
optname = Option.SHORT_OPTIONS[shortopt].name
436
optname = SHORT_OPTIONS[shortopt]
333
438
# Single character short options, can be chained,
334
439
# and have their value appended to their name
335
440
shortopt = a[1:2]
336
if shortopt not in Option.SHORT_OPTIONS:
441
if shortopt not in SHORT_OPTIONS:
337
442
# We didn't find the multi-character name, and we
338
443
# didn't find the single char name
339
444
raise BzrError('unknown short option %r' % a)
340
optname = Option.SHORT_OPTIONS[shortopt].name
445
optname = SHORT_OPTIONS[shortopt]
343
448
# There are extra things on this option
344
449
# see if it is the value, or if it is another
346
optargfn = Option.OPTIONS[optname].type
451
optargfn = OPTIONS[optname]
347
452
if optargfn is None:
348
453
# This option does not take an argument, so the
349
454
# next entry is another short option, pack it back
526
619
cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
530
ret = apply_lsprofiled(cmd_obj.run_argv, argv)
532
ret = apply_profiled(cmd_obj.run_argv, argv)
534
ret = cmd_obj.run_argv(argv)
537
# reset, in case we may do other commands later within the same process
540
def display_command(func):
541
"""Decorator that suppresses pipe/interrupt errors."""
542
def ignore_pipe(*args, **kwargs):
544
result = func(*args, **kwargs)
548
if not hasattr(e, 'errno'):
550
if e.errno != errno.EPIPE:
553
except KeyboardInterrupt:
622
ret = apply_profiled(cmd_obj.run_argv, argv)
624
ret = cmd_obj.run_argv(argv)
560
from bzrlib.ui.text import TextUIFactory
561
## bzrlib.trace.enable_default_logging()
562
630
bzrlib.trace.log_startup(argv)
563
bzrlib.ui.ui_factory = TextUIFactory()
564
ret = run_bzr_catch_errors(argv[1:])
565
mutter("return code %d", ret)
631
bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
633
return run_bzr_catch_errors(argv[1:])
569
636
def run_bzr_catch_errors(argv):
574
641
# do this here inside the exception wrappers to catch EPIPE
575
642
sys.stdout.flush()
643
except BzrCommandError, e:
644
# command line syntax error, etc
648
bzrlib.trace.log_exception()
650
except AssertionError, e:
651
bzrlib.trace.log_exception('assertion failed: ' + str(e))
653
except KeyboardInterrupt, e:
654
bzrlib.trace.log_exception('interrupted')
576
656
except Exception, e:
577
# used to handle AssertionError and KeyboardInterrupt
578
# specially here, but hopefully they're handled ok by the logger now
580
658
if (isinstance(e, IOError)
581
659
and hasattr(e, 'errno')
582
660
and e.errno == errno.EPIPE):
583
661
bzrlib.trace.note('broken pipe')
586
666
bzrlib.trace.log_exception()
587
if os.environ.get('BZR_PDB'):
588
print '**** entering debugger'
590
pdb.post_mortem(sys.exc_traceback)
593
669
if __name__ == '__main__':
594
670
sys.exit(main(sys.argv))