138
139
real_name = _unsquish_command_name(name)
139
140
r[real_name] = builtins[name]
143
144
def builtin_command_names():
144
145
"""Return list of builtin command names."""
145
146
return _builtin_commands().keys()
148
149
def plugin_command_names():
149
150
return plugin_cmds.keys()
170
171
If true, plugin commands can override builtins.
173
return _get_cmd_object(cmd_name, plugins_override)
174
cmd = _get_cmd_object(cmd_name, plugins_override)
175
# Allow plugins to extend commands
176
for hook in Command.hooks['extend_command']:
175
180
raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
216
221
except errors.NoPluginAvailable:
219
raise errors.CommandAvailableInPlugin(cmd_name,
224
raise errors.CommandAvailableInPlugin(cmd_name,
220
225
plugin_metadata, provider)
328
333
def get_help_text(self, additional_see_also=None, plain=True,
329
334
see_also_as_links=False):
330
335
"""Return a text string with help for this command.
332
337
:param additional_see_also: Additional help topics to be
333
338
cross-referenced.
334
339
:param plain: if False, raw help (reStructuredText) is
341
346
raise NotImplementedError("sorry, no detailed help yet for %r" % self.name())
343
348
# Extract the summary (purpose) and sections out from the text
344
purpose,sections = self._get_help_parts(doc)
349
purpose,sections,order = self._get_help_parts(doc)
346
351
# If a custom usage section was provided, use it
347
352
if sections.has_key('Usage'):
379
384
# Add the custom sections (e.g. Examples). Note that there's no need
380
385
# to indent these as they must be indented already in the source.
382
labels = sorted(sections.keys())
384
result += ':%s:\n%s\n\n' % (label,sections[label])
388
if sections.has_key(label):
389
result += ':%s:\n%s\n\n' % (label,sections[label])
386
391
# Add the aliases, source (plug-in) and see also links, if any
416
421
def _get_help_parts(text):
417
422
"""Split help text into a summary and named sections.
419
:return: (summary,sections) where summary is the top line and
424
:return: (summary,sections,order) where summary is the top line and
420
425
sections is a dictionary of the rest indexed by section name.
426
order is the order the section appear in the text.
421
427
A section starts with a heading line of the form ":xxx:".
422
428
Indented text on following lines is the section value.
423
429
All text found outside a named section is assigned to the
424
430
default section which is given the key of None.
426
def save_section(sections, label, section):
432
def save_section(sections, order, label, section):
427
433
if len(section) > 0:
428
434
if sections.has_key(label):
429
435
sections[label] += '\n' + section
431
438
sections[label] = section
433
440
lines = text.rstrip().splitlines()
434
441
summary = lines.pop(0)
436
444
label,section = None,''
437
445
for line in lines:
438
446
if line.startswith(':') and line.endswith(':') and len(line) > 2:
439
save_section(sections, label, section)
447
save_section(sections, order, label, section)
440
448
label,section = line[1:-1],''
441
449
elif (label is not None) and len(line) > 1 and not line[0].isspace():
442
save_section(sections, label, section)
450
save_section(sections, order, label, section)
443
451
label,section = None,line
445
453
if len(section) > 0:
446
454
section += '\n' + line
449
save_section(sections, label, section)
450
return summary, sections
457
save_section(sections, order, label, section)
458
return summary, sections, order
452
460
def get_help_topic(self):
453
461
"""Return the commands help topic - its name."""
456
464
def get_see_also(self, additional_terms=None):
457
465
"""Return a list of help topics that are related to this command.
459
467
The list is derived from the content of the _see_also attribute. Any
460
468
duplicates are removed and the result is in lexical order.
461
469
:param additional_terms: Additional help topics to cross-reference.
584
class CommandHooks(Hooks):
585
"""Hooks related to Command object creation/enumeration."""
588
"""Create the default hooks.
590
These are all empty initially, because by default nothing should get
594
self.create_hook(HookPoint('extend_command',
595
"Called after creating a command object to allow modifications "
596
"such as adding or removing options, docs etc. Called with the "
597
"new bzrlib.commands.Command object.", (1, 13), None))
599
Command.hooks = CommandHooks()
576
602
def parse_args(command, argv, alias_argv=None):
577
603
"""Parse command line.
579
605
Arguments and options are parsed at this level before being passed
580
606
down to specific command handlers. This routine knows, from a
581
607
lookup table, something about the available options, what optargs
645
671
tracer = trace.Trace(count=1, trace=0)
646
672
sys.settrace(tracer.globaltrace)
648
ret = the_callable(*args, **kwargs)
651
results = tracer.results()
652
results.write_results(show_missing=1, summary=False,
675
return exception_to_return_code(the_callable, *args, **kwargs)
678
results = tracer.results()
679
results.write_results(show_missing=1, summary=False,
656
683
def apply_profiled(the_callable, *args, **kwargs):
662
689
prof = hotshot.Profile(pfname)
664
ret = prof.runcall(the_callable, *args, **kwargs) or 0
691
ret = prof.runcall(exception_to_return_code, the_callable, *args,
667
695
stats = hotshot.stats.load(pfname)
676
704
os.remove(pfname)
707
def exception_to_return_code(the_callable, *args, **kwargs):
708
"""UI level helper for profiling and coverage.
710
This transforms exceptions into a return value of 3. As such its only
711
relevant to the UI layer, and should never be called where catching
712
exceptions may be desirable.
715
return the_callable(*args, **kwargs)
716
except (KeyboardInterrupt, Exception), e:
717
# used to handle AssertionError and KeyboardInterrupt
718
# specially here, but hopefully they're handled ok by the logger now
719
exc_info = sys.exc_info()
720
exitcode = trace.report_exception(exc_info, sys.stderr)
721
if os.environ.get('BZR_PDB'):
722
print '**** entering debugger'
725
if sys.version_info[:2] < (2, 6):
727
# pdb.post_mortem(tb)
728
# but because pdb.post_mortem gives bad results for tracebacks
729
# from inside generators, we do it manually.
730
# (http://bugs.python.org/issue4150, fixed in Python 2.6)
732
# Setup pdb on the traceback
735
p.setup(tb.tb_frame, tb)
736
# Point the debugger at the deepest frame of the stack
737
p.curindex = len(p.stack) - 1
738
p.curframe = p.stack[p.curindex][0]
739
# Start the pdb prompt.
740
p.print_stack_entry(p.stack[p.curindex])
679
748
def apply_lsprofiled(filename, the_callable, *args, **kwargs):
680
749
from bzrlib.lsprof import profile
681
ret, stats = profile(the_callable, *args, **kwargs)
750
ret, stats = profile(exception_to_return_code, the_callable, *args, **kwargs)
683
752
if filename is None:
719
788
The command-line arguments, without the program name from argv[0]
720
789
These should already be decoded. All library/test code calling
721
790
run_bzr should be passing valid strings (don't need decoding).
723
792
Returns a command status or raises an exception.
725
794
Special master options: these must come before the command because
846
917
# --verbose in their own way.
847
918
option._verbosity_level = saved_verbosity_level
849
921
def display_command(func):
850
922
"""Decorator that suppresses pipe/interrupt errors."""
851
923
def ignore_pipe(*args, **kwargs):
889
961
def run_bzr_catch_errors(argv):
890
# Note: The except clause logic below should be kept in sync with the
891
# profile() routine in lsprof.py.
894
except (KeyboardInterrupt, Exception), e:
895
# used to handle AssertionError and KeyboardInterrupt
896
# specially here, but hopefully they're handled ok by the logger now
897
exitcode = trace.report_exception(sys.exc_info(), sys.stderr)
898
if os.environ.get('BZR_PDB'):
899
print '**** entering debugger'
901
pdb.post_mortem(sys.exc_traceback)
962
"""Run a bzr command with parameters as described by argv.
964
This function assumed that that UI layer is setup, that symbol deprecations
965
are already applied, and that unicode decoding has already been performed on argv.
967
return exception_to_return_code(run_bzr, argv)
905
970
def run_bzr_catch_user_errors(argv):
948
1013
def plugin_for_command(self, cmd_name):
949
1014
'''Takes a command and returns the information for that plugin
951
:return: A dictionary with all the available information
1016
:return: A dictionary with all the available information
952
1017
for the requested plugin
954
1019
raise NotImplementedError