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
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))
149
82
def _builtin_commands():
150
83
import bzrlib.builtins
235
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
239
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().
242
185
If true, this command isn't advertised. This is typically
243
186
for commands intended for expert users.
248
190
takes_options = []
254
196
if self.__doc__ == Command.__doc__:
255
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]
258
211
def run_argv(self, argv):
259
212
"""Parse command line and run."""
260
args, opts = parse_args(argv)
213
args, opts = parse_args(self, argv)
262
214
if 'help' in opts: # e.g. bzr add --help
263
215
from bzrlib.help import help_on_command
264
216
help_on_command(self.name())
267
# check options are reasonable
268
allowed = self.takes_options
218
# XXX: This should be handled by the parser
219
allowed_names = self.options().keys()
269
220
for oname in opts:
270
if oname not in allowed:
221
if oname not in allowed_names:
271
222
raise BzrCommandError("option '--%s' is not allowed for command %r"
272
223
% (oname, self.name()))
274
224
# mix arguments and options into one dictionary
275
225
cmdargs = _match_argform(self.name(), self.takes_args, args)
337
286
parsed = [spec, None]
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
357
'revision': _parse_revision_str,
384
def parse_args(argv):
289
def parse_args(command, argv):
385
290
"""Parse command line.
387
292
Arguments and options are parsed at this level before being passed
388
293
down to specific command handlers. This routine knows, from a
389
294
lookup table, something about the available options, what optargs
390
295
they take, and which commands will accept them.
392
>>> parse_args('--help'.split())
394
>>> parse_args('help -- --invalidcmd'.split())
395
(['help', '--invalidcmd'], {})
396
>>> parse_args('--version'.split())
397
([], {'version': True})
398
>>> parse_args('status --all'.split())
399
(['status'], {'all': True})
400
>>> parse_args('commit --message=biter'.split())
401
(['commit'], {'message': u'biter'})
402
>>> parse_args('log -r 500'.split())
403
(['log'], {'revision': [<RevisionSpec_int 500>]})
404
>>> parse_args('log -r500..600'.split())
405
(['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
406
>>> parse_args('log -vr500..600'.split())
407
(['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
408
>>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
409
(['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()
417
if not argsover and a[0] == '-':
309
# We've received a standalone -- No more flags
418
313
# option names must not be unicode
423
# We've received a standalone -- No more flags
426
mutter(" got option %r" % a)
317
mutter(" got option %r", a)
428
319
optname, optarg = a[2:].split('=', 1)
431
if optname not in OPTIONS:
432
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()))
435
if shortopt in SHORT_OPTIONS:
327
if shortopt in Option.SHORT_OPTIONS:
436
328
# Multi-character options must have a space to delimit
438
optname = SHORT_OPTIONS[shortopt]
330
# ^^^ what does this mean? mbp 20051014
331
optname = Option.SHORT_OPTIONS[shortopt].name
440
333
# Single character short options, can be chained,
441
334
# and have their value appended to their name
442
335
shortopt = a[1:2]
443
if shortopt not in SHORT_OPTIONS:
336
if shortopt not in Option.SHORT_OPTIONS:
444
337
# We didn't find the multi-character name, and we
445
338
# didn't find the single char name
446
339
raise BzrError('unknown short option %r' % a)
447
optname = SHORT_OPTIONS[shortopt]
340
optname = Option.SHORT_OPTIONS[shortopt].name
450
343
# There are extra things on this option
451
344
# see if it is the value, or if it is another
453
optargfn = OPTIONS[optname]
346
optargfn = Option.OPTIONS[optname].type
454
347
if optargfn is None:
455
348
# This option does not take an argument, so the
456
349
# next entry is another short option, pack it back
621
526
cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
624
ret = apply_profiled(cmd_obj.run_argv, argv)
626
ret = cmd_obj.run_argv(argv)
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:
560
from bzrlib.ui.text import TextUIFactory
561
## bzrlib.trace.enable_default_logging()
632
562
bzrlib.trace.log_startup(argv)
633
bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
635
return run_bzr_catch_errors(argv[1:])
563
bzrlib.ui.ui_factory = TextUIFactory()
564
ret = run_bzr_catch_errors(argv[1:])
565
mutter("return code %d", ret)
638
569
def run_bzr_catch_errors(argv):
643
574
# do this here inside the exception wrappers to catch EPIPE
644
575
sys.stdout.flush()
645
except BzrCommandError, e:
646
# command line syntax error, etc
650
bzrlib.trace.log_exception()
652
except AssertionError, e:
653
bzrlib.trace.log_exception('assertion failed: ' + str(e))
655
except KeyboardInterrupt, e:
656
bzrlib.trace.log_exception('interrupted')
658
576
except Exception, e:
577
# used to handle AssertionError and KeyboardInterrupt
578
# specially here, but hopefully they're handled ok by the logger now
660
580
if (isinstance(e, IOError)
661
581
and hasattr(e, 'errno')
662
582
and e.errno == errno.EPIPE):
663
583
bzrlib.trace.note('broken pipe')
668
586
bzrlib.trace.log_exception()
587
if os.environ.get('BZR_PDB'):
588
print '**** entering debugger'
590
pdb.post_mortem(sys.exc_traceback)
671
593
if __name__ == '__main__':
672
594
sys.exit(main(sys.argv))