14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from __future__ import absolute_import
18
19
# TODO: Define arguments by objects, rather than just using names.
19
20
# Those objects can specify the expected type of the argument, which
46
49
from bzrlib.hooks import Hooks
50
from bzrlib.i18n import gettext
47
51
# Compatibility - Option used to be in commands.
48
52
from bzrlib.option import Option
49
53
from bzrlib.plugin import disable_plugins, load_plugins
50
54
from bzrlib import registry
51
from bzrlib.symbol_versioning import (
58
57
class CommandInfo(object):
162
161
return cmd[4:].replace('_','-')
165
@deprecated_function(deprecated_in((2, 2, 0)))
166
def _builtin_commands():
167
"""Return a dict of {name: cmd_class} for builtin commands.
169
:deprecated: Use the builtin_command_registry registry instead
171
# return dict(name: cmd_class)
172
return dict(builtin_command_registry.items())
175
164
def _register_builtin_commands():
176
165
if builtin_command_registry.keys():
238
227
return _get_cmd_object(cmd_name, plugins_override)
240
raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
229
raise errors.BzrCommandError(gettext('unknown command "%s"') % cmd_name)
243
232
def _get_cmd_object(cmd_name, plugins_override=True, check_missing=True):
440
430
self._operation.cleanup_now()
442
@deprecated_method(deprecated_in((2, 1, 0)))
443
def _maybe_expand_globs(self, file_list):
444
"""Glob expand file_list if the platform does not do that itself.
446
Not used anymore, now that the bzr command-line parser globs on
449
:return: A possibly empty list of unicode paths.
451
Introduced in bzrlib 0.18.
455
432
def _usage(self):
456
433
"""Return single-line grammar for this command.
485
462
usage help (e.g. Purpose, Usage, Options) with a
486
463
message explaining how to obtain full help.
466
i18n.install() # Install i18n only for get_help_text for now.
488
467
doc = self.help()
490
doc = "No help for this command."
469
# Note: If self.gettext() translates ':Usage:\n', the section will
470
# be shown after "Description" section and we don't want to
471
# translate the usage string.
472
# Though, bzr export-pot don't exports :Usage: section and it must
474
doc = self.gettext(doc)
476
doc = gettext("No help for this command.")
492
478
# Extract the summary (purpose) and sections out from the text
493
479
purpose,sections,order = self._get_help_parts(doc)
501
487
# The header is the purpose and usage
503
result += ':Purpose: %s\n' % purpose
489
result += gettext(':Purpose: %s\n') % (purpose,)
504
490
if usage.find('\n') >= 0:
505
result += ':Usage:\n%s\n' % usage
491
result += gettext(':Usage:\n%s\n') % (usage,)
507
result += ':Usage: %s\n' % usage
493
result += gettext(':Usage: %s\n') % (usage,)
510
496
# Add the options
512
498
# XXX: optparse implicitly rewraps the help, and not always perfectly,
513
499
# so we get <https://bugs.launchpad.net/bzr/+bug/249908>. -- mbp
515
options = option.get_optparser(self.options()).format_option_help()
501
parser = option.get_optparser(self.options())
502
options = parser.format_option_help()
516
503
# FIXME: According to the spec, ReST option lists actually don't
517
504
# support options like --1.14 so that causes syntax errors (in Sphinx
518
505
# at least). As that pattern always appears in the commands that
522
509
if not plain and options.find(' --1.14 ') != -1:
523
510
options = options.replace(' format:\n', ' format::\n\n', 1)
524
511
if options.startswith('Options:'):
525
result += ':' + options
526
elif options.startswith('options:'):
527
# Python 2.4 version of optparse
528
result += ':Options:' + options[len('options:'):]
512
result += gettext(':Options:%s') % (options[len('options:'):],)
530
514
result += options
536
520
if sections.has_key(None):
537
521
text = sections.pop(None)
538
522
text = '\n '.join(text.splitlines())
539
result += ':%s:\n %s\n\n' % ('Description',text)
523
result += gettext(':Description:\n %s\n\n') % (text,)
541
525
# Add the custom sections (e.g. Examples). Note that there's no need
542
526
# to indent these as they must be indented already in the source.
544
528
for label in order:
545
if sections.has_key(label):
546
result += ':%s:\n%s\n' % (label,sections[label])
529
if label in sections:
530
result += ':%s:\n%s\n' % (label, sections[label])
549
result += ("See bzr help %s for more details and examples.\n\n"
533
result += (gettext("See bzr help %s for more details and examples.\n\n")
552
536
# Add the aliases, source (plug-in) and see also links, if any
554
result += ':Aliases: '
538
result += gettext(':Aliases: ')
555
539
result += ', '.join(self.aliases) + '\n'
556
540
plugin_name = self.plugin_name()
557
541
if plugin_name is not None:
558
result += ':From: plugin "%s"\n' % plugin_name
542
result += gettext(':From: plugin "%s"\n') % plugin_name
559
543
see_also = self.get_see_also(additional_see_also)
561
545
if not plain and see_also_as_links:
567
551
see_also_links.append(item)
569
553
# Use a Sphinx link for this entry
570
link_text = ":doc:`%s <%s-help>`" % (item, item)
554
link_text = gettext(":doc:`{0} <{1}-help>`").format(
571
556
see_also_links.append(link_text)
572
557
see_also = see_also_links
573
result += ':See also: '
574
result += ', '.join(see_also) + '\n'
558
result += gettext(':See also: %s') % ', '.join(see_also) + '\n'
576
560
# If this will be rendered as plain text, convert it
658
642
def run_argv_aliases(self, argv, alias_argv=None):
659
643
"""Parse the command line and run with extra aliases in alias_argv."""
660
644
args, opts = parse_args(self, argv, alias_argv)
662
647
# Process the standard options
663
648
if 'help' in opts: # e.g. bzr add --help
664
sys.stdout.write(self.get_help_text())
649
self.outf.write(self.get_help_text())
666
651
if 'usage' in opts: # e.g. bzr add --usage
667
sys.stdout.write(self.get_help_text(verbose=False))
652
self.outf.write(self.get_help_text(verbose=False))
669
654
trace.set_verbosity_level(option._verbosity_level)
670
655
if 'verbose' in self.supported_std_options:
675
660
opts['quiet'] = trace.is_quiet()
676
661
elif opts.has_key('quiet'):
677
662
del opts['quiet']
679
663
# mix arguments and options into one dictionary
680
664
cmdargs = _match_argform(self.name(), self.takes_args, args)
709
691
class_run = self.run
710
692
def run(*args, **kwargs):
693
for hook in Command.hooks['pre_command']:
711
695
self._operation = cleanup.OperationWithCleanups(class_run)
713
697
return self._operation.run_simple(*args, **kwargs)
715
699
del self._operation
700
for hook in Command.hooks['post_command']:
718
@deprecated_method(deprecated_in((2, 2, 0)))
719
def run_direct(self, *args, **kwargs):
720
"""Deprecated thunk from bzrlib 2.1."""
721
return self.run(*args, **kwargs)
724
705
"""Actually run the command.
752
733
return getdoc(self)
735
def gettext(self, message):
736
"""Returns the gettext function used to translate this command's help.
738
Commands provided by plugins should override this to use their
741
return i18n.gettext_per_paragraph(message)
755
744
"""Return the canonical name for this command.
803
792
" is safe to mutate - e.g. to remove a command. "
804
793
"list_commands should return the updated set of command names.",
795
self.add_hook('pre_command',
796
"Called prior to executing a command. Called with the command "
798
self.add_hook('post_command',
799
"Called after executing a command. Called with the command "
807
802
Command.hooks = CommandHooks()
828
823
options, args = parser.parse_args(args)
829
824
except UnicodeEncodeError,e:
830
raise errors.BzrCommandError('Only ASCII permitted in option names')
825
raise errors.BzrCommandError(
826
gettext('Only ASCII permitted in option names'))
832
828
opts = dict([(k, v) for k, v in options.__dict__.iteritems() if
833
829
v is not option.OptionParser.DEFAULT_VALUE])
851
847
argdict[argname + '_list'] = None
852
848
elif ap[-1] == '+':
854
raise errors.BzrCommandError("command %r needs one or more %s"
855
% (cmd, argname.upper()))
850
raise errors.BzrCommandError(gettext(
851
"command {0!r} needs one or more {1}").format(
852
cmd, argname.upper()))
857
854
argdict[argname + '_list'] = args[:]
859
856
elif ap[-1] == '$': # all but one
860
857
if len(args) < 2:
861
raise errors.BzrCommandError("command %r needs one or more %s"
862
% (cmd, argname.upper()))
858
raise errors.BzrCommandError(
859
gettext("command {0!r} needs one or more {1}").format(
860
cmd, argname.upper()))
863
861
argdict[argname + '_list'] = args[:-1]
866
864
# just a plain arg
869
raise errors.BzrCommandError("command %r requires argument %s"
870
% (cmd, argname.upper()))
867
raise errors.BzrCommandError(
868
gettext("command {0!r} requires argument {1}").format(
869
cmd, argname.upper()))
872
871
argdict[argname] = args.pop(0)
875
raise errors.BzrCommandError("extra argument to command %s: %s"
874
raise errors.BzrCommandError( gettext(
875
"extra argument to command {0}: {1}").format(
935
935
exitcode = trace.report_exception(exc_info, sys.stderr)
936
936
if os.environ.get('BZR_PDB'):
937
937
print '**** entering debugger'
940
if sys.version_info[:2] < (2, 6):
942
# pdb.post_mortem(tb)
943
# but because pdb.post_mortem gives bad results for tracebacks
944
# from inside generators, we do it manually.
945
# (http://bugs.python.org/issue4150, fixed in Python 2.6)
947
# Setup pdb on the traceback
950
p.setup(tb.tb_frame, tb)
951
# Point the debugger at the deepest frame of the stack
952
p.curindex = len(p.stack) - 1
953
p.curframe = p.stack[p.curindex][0]
954
# Start the pdb prompt.
955
p.print_stack_entry(p.stack[p.curindex])
939
pdb.post_mortem(exc_info[2])
963
943
def apply_lsprofiled(filename, the_callable, *args, **kwargs):
964
944
from bzrlib.lsprof import profile
965
ret, stats = profile(exception_to_return_code, the_callable, *args, **kwargs)
945
ret, stats = profile(exception_to_return_code, the_callable,
967
948
if filename is None:
970
951
stats.save(filename)
971
trace.note('Profile data written to "%s".', filename)
952
trace.note(gettext('Profile data written to "%s".'), filename)
975
@deprecated_function(deprecated_in((2, 2, 0)))
976
def shlex_split_unicode(unsplit):
977
return cmdline.split(unsplit)
980
956
def get_alias(cmd, config=None):
981
957
"""Return an expanded alias, or None if no alias exists.
1041
1017
argv = _specified_or_unicode_argv(argv)
1042
1018
trace.mutter("bzr arguments: %r", argv)
1044
opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = \
1045
opt_no_aliases = False
1020
opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = \
1021
opt_no_l10n = opt_no_aliases = False
1046
1022
opt_lsprof_file = opt_coverage_dir = None
1048
1024
# --no-plugins is handled specially at a very early stage. We need
1077
1056
pass # already handled in startup script Bug #588277
1078
1057
elif a.startswith('-D'):
1079
1058
debug.debug_flags.add(a[2:])
1059
elif a.startswith('-O'):
1060
override_config.append(a[2:])
1081
1062
argv_copy.append(a)
1065
if bzrlib.global_state is None:
1066
# FIXME: Workaround for users that imported bzrlib but didn't call
1067
# bzrlib.initialize -- vila 2012-01-19
1068
cmdline_overrides = config.CommandLineStore()
1070
cmdline_overrides = bzrlib.global_state.cmdline_overrides
1071
cmdline_overrides._from_cmdline(override_config)
1084
1073
debug.set_debug_flags_from_config()
1086
1075
if not opt_no_plugins:
1136
1127
if 'memory' in debug.debug_flags:
1137
1128
trace.debug_memory('Process status after command:', short=False)
1138
1129
option._verbosity_level = saved_verbosity_level
1130
# Reset the overrides
1131
cmdline_overrides._reset()
1141
1134
def display_command(func):
1170
1163
"bzr plugin commands")
1171
1164
Command.hooks.install_named_hook("get_command", _get_external_command,
1172
1165
"bzr external command lookup")
1173
Command.hooks.install_named_hook("get_missing_command", _try_plugin_provider,
1174
"bzr plugin-provider-db check")
1166
Command.hooks.install_named_hook("get_missing_command",
1167
_try_plugin_provider,
1168
"bzr plugin-provider-db check")