1
# Copyright (C) 2005-2010 Canonical Ltd
1
# Copyright (C) 2006, 2008 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
# TODO: probably should say which arguments are candidates for glob
19
# expansion on windows and do that at the command level.
18
21
# TODO: Define arguments by objects, rather than just using names.
19
22
# Those objects can specify the expected type of the argument, which
20
23
# would help with validation and shell completion. They could also provide
49
52
from bzrlib.hooks import HookPoint, Hooks
50
53
# Compatibility - Option used to be in commands.
51
54
from bzrlib.option import Option
52
from bzrlib.plugin import disable_plugins, load_plugins
53
55
from bzrlib import registry
54
56
from bzrlib.symbol_versioning import (
55
57
deprecated_function,
60
suppress_deprecation_warnings,
74
77
class CommandRegistry(registry.Registry):
75
"""Special registry mapping command names to command classes.
77
:ivar overridden_registry: Look in this registry for commands being
78
overridden by this registry. This can be used to tell plugin commands
79
about the builtin they're decorating.
83
registry.Registry.__init__(self)
84
self.overridden_registry = None
85
# map from aliases to the real command that implements the name
88
def get(self, command_name):
89
real_name = self._alias_dict.get(command_name, command_name)
90
return registry.Registry.get(self, real_name)
93
80
def _get_name(command_name):
110
97
previous = self.get(k_unsquished)
113
if self.overridden_registry:
115
previous = self.overridden_registry.get(k_unsquished)
99
previous = _builtin_commands().get(k_unsquished)
118
100
info = CommandInfo.from_command(cmd)
120
102
registry.Registry.register(self, k_unsquished, cmd,
125
107
sys.modules[cmd.__module__])
126
108
trace.warning('Previously this command was registered from %r' %
127
109
sys.modules[previous.__module__])
128
for a in cmd.aliases:
129
self._alias_dict[a] = k_unsquished
132
112
def register_lazy(self, command_name, aliases, module_name):
139
119
key = self._get_name(command_name)
140
120
registry.Registry.register_lazy(self, key, module_name, command_name,
141
121
info=CommandInfo(aliases))
143
self._alias_dict[a] = key
146
124
plugin_cmds = CommandRegistry()
147
builtin_command_registry = CommandRegistry()
148
plugin_cmds.overridden_registry = builtin_command_registry
151
127
def register_command(cmd, decorate=False):
152
"""Register a plugin command.
154
Should generally be avoided in favor of lazy registration.
156
128
global plugin_cmds
157
129
return plugin_cmds.register(cmd, decorate)
165
137
return cmd[4:].replace('_','-')
168
@deprecated_function(deprecated_in((2, 2, 0)))
169
140
def _builtin_commands():
170
"""Return a dict of {name: cmd_class} for builtin commands.
172
:deprecated: Use the builtin_command_registry registry instead
174
# return dict(name: cmd_class)
175
return dict(builtin_command_registry.items())
178
def _register_builtin_commands():
179
if builtin_command_registry.keys():
182
141
import bzrlib.builtins
183
for cmd_class in _scan_module_for_commands(bzrlib.builtins).values():
184
builtin_command_registry.register(cmd_class)
185
bzrlib.builtins._register_lazy_builtins()
142
return _scan_module_for_commands(bzrlib.builtins)
188
145
def _scan_module_for_commands(module):
197
154
def _list_bzr_commands(names):
198
"""Find commands from bzr's core and plugins.
200
This is not the public interface, just the default hook called by all_command_names.
155
"""Find commands from bzr's core and plugins."""
202
156
# to eliminate duplicates
203
157
names.update(builtin_command_names())
204
158
names.update(plugin_command_names())
222
176
Use of all_command_names() is encouraged rather than builtin_command_names
223
177
and/or plugin_command_names.
225
return builtin_command_registry.keys()
179
return _builtin_commands().keys()
228
182
def plugin_command_names():
230
184
return plugin_cmds.keys()
187
@deprecated_function(deprecated_in((1, 17, 0)))
188
def get_all_cmds(plugins_override=False):
189
"""Return canonical name and class for most commands.
191
NB: This does not return all commands since the introduction of
192
command hooks, and returning the class is not sufficient to
193
get correctly setup commands, which is why it is deprecated.
195
Use 'all_command_names' + 'get_cmd_object' instead.
197
d = _builtin_commands()
199
d.update(plugin_cmds.iteritems())
200
for k, v in d.iteritems():
233
204
def get_cmd_object(cmd_name, plugins_override=True):
234
205
"""Return the command object for a command.
242
213
raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
245
def _get_cmd_object(cmd_name, plugins_override=True, check_missing=True):
216
def _get_cmd_object(cmd_name, plugins_override=True):
246
217
"""Get a command object.
248
219
:param cmd_name: The name of the command.
249
220
:param plugins_override: Allow plugins to override builtins.
250
:param check_missing: Look up commands not found in the regular index via
251
the get_missing_command hook.
252
221
:return: A Command object instance
253
222
:raises KeyError: If no command is found.
307
276
def _get_bzr_command(cmd_or_None, cmd_name):
308
277
"""Get a command from bzr's core."""
278
cmds = _builtin_commands()
310
cmd_class = builtin_command_registry.get(cmd_name)
280
return cmds[cmd_name]()
283
# look for any command which claims this as an alias
284
for real_cmd_name, cmd_class in cmds.iteritems():
285
if cmd_name in cmd_class.aliases:
315
287
return cmd_or_None
397
369
will not mangled.
399
371
:cvar hooks: An instance of CommandHooks.
400
:ivar __doc__: The help shown by 'bzr help command' for this command.
401
This is set by assigning explicitly to __doc__ so that -OO can
405
__doc__ = "My help goes here"
414
380
def __init__(self):
415
381
"""Construct an instance of this command."""
382
if self.__doc__ == Command.__doc__:
383
warn("No help message set for %r" % self)
416
384
# List of standard options directly supported
417
385
self.supported_std_options = []
420
def add_cleanup(self, cleanup_func, *args, **kwargs):
421
"""Register a function to call after self.run returns or raises.
423
Functions will be called in LIFO order.
425
self._operation.add_cleanup(cleanup_func, *args, **kwargs)
427
def cleanup_now(self):
428
"""Execute and empty pending cleanup functions immediately.
430
After cleanup_now all registered cleanups are forgotten. add_cleanup
431
may be called again after cleanup_now; these cleanups will be called
432
after self.run returns or raises (or when cleanup_now is next called).
434
This is useful for releasing expensive or contentious resources (such
435
as write locks) before doing further work that does not require those
436
resources (such as writing results to self.outf). Note though, that
437
as it releases all resources, this may release locks that the command
438
wants to hold, so use should be done with care.
440
self._operation.cleanup_now()
442
387
@deprecated_method(deprecated_in((2, 1, 0)))
443
388
def _maybe_expand_globs(self, file_list):
486
431
message explaining how to obtain full help.
488
433
doc = self.help()
490
doc = "No help for this command."
435
raise NotImplementedError("sorry, no detailed help yet for %r" % self.name())
492
437
# Extract the summary (purpose) and sections out from the text
493
438
purpose,sections,order = self._get_help_parts(doc)
565
510
# so don't create a real link
566
511
see_also_links.append(item)
568
# Use a Sphinx link for this entry
569
link_text = ":doc:`%s <%s-help>`" % (item, item)
570
see_also_links.append(link_text)
513
# Use a reST link for this entry
514
see_also_links.append("`%s`_" % (item,))
571
515
see_also = see_also_links
572
516
result += ':See also: '
573
517
result += ', '.join(see_also) + '\n'
652
596
def _setup_outf(self):
653
597
"""Return a file linked to stdout, which has proper encoding."""
654
self.outf = ui.ui_factory.make_output_stream(
655
encoding_type=self.encoding_type)
598
# Originally I was using self.stdout, but that looks
599
# *way* too much like sys.stdout
600
if self.encoding_type == 'exact':
601
# force sys.stdout to be binary stream on win32
602
if sys.platform == 'win32':
603
fileno = getattr(sys.stdout, 'fileno', None)
606
msvcrt.setmode(fileno(), os.O_BINARY)
607
self.outf = sys.stdout
610
output_encoding = osutils.get_terminal_encoding()
612
self.outf = codecs.getwriter(output_encoding)(sys.stdout,
613
errors=self.encoding_type)
614
# For whatever reason codecs.getwriter() does not advertise its encoding
615
# it just returns the encoding of the wrapped file, which is completely
616
# bogus. So set the attribute, so we can find the correct encoding later.
617
self.outf.encoding = output_encoding
657
619
def run_argv_aliases(self, argv, alias_argv=None):
658
620
"""Parse the command line and run with extra aliases in alias_argv."""
622
warn("Passing None for [] is deprecated from bzrlib 0.10",
623
DeprecationWarning, stacklevel=2)
659
625
args, opts = parse_args(self, argv, alias_argv)
661
627
# Process the standard options
689
655
return self.run(**all_cmd_args)
691
def _setup_run(self):
692
"""Wrap the defined run method on self with a cleanup.
694
This is called by __init__ to make the Command be able to be run
695
by just calling run(), as it could be before cleanups were added.
697
If a different form of cleanups are in use by your Command subclass,
698
you can override this method.
701
def run(*args, **kwargs):
702
self._operation = cleanup.OperationWithCleanups(class_run)
704
return self._operation.run_simple(*args, **kwargs)
709
@deprecated_method(deprecated_in((2, 2, 0)))
710
def run_direct(self, *args, **kwargs):
711
"""Deprecated thunk from bzrlib 2.1."""
712
return self.run(*args, **kwargs)
715
658
"""Actually run the command.
720
663
Return 0 or None if the command was successful, or a non-zero
721
664
shell error code if not. It's OK for this method to allow
722
665
an exception to raise up.
724
This method is automatically wrapped by Command.__init__ with a
725
cleanup operation, stored as self._operation. This can be used
726
via self.add_cleanup to perform automatic cleanups at the end of
729
The argument for run are assembled by introspection. So for instance,
730
if your command takes an argument files, you would declare::
732
def run(self, files=None):
735
667
raise NotImplementedError('no implementation of command %r'
956
@deprecated_function(deprecated_in((2, 2, 0)))
957
888
def shlex_split_unicode(unsplit):
958
return cmdline.split(unsplit)
890
return [u.decode('utf-8') for u in shlex.split(unsplit.encode('utf-8'))]
961
893
def get_alias(cmd, config=None):
973
905
config = bzrlib.config.GlobalConfig()
974
906
alias = config.get_alias(cmd)
976
return cmdline.split(alias)
908
return shlex_split_unicode(alias)
980
def run_bzr(argv, load_plugins=load_plugins, disable_plugins=disable_plugins):
981
913
"""Execute a command.
983
:param argv: The command-line arguments, without the program name from
984
argv[0] These should already be decoded. All library/test code calling
985
run_bzr should be passing valid strings (don't need decoding).
986
:param load_plugins: What function to call when triggering plugin loading.
987
This function should take no arguments and cause all plugins to be
989
:param disable_plugins: What function to call when disabling plugin
990
loading. This function should take no arguments and cause all plugin
991
loading to be prohibited (so that code paths in your application that
992
know about some plugins possibly being present will fail to import
993
those plugins even if they are installed.)
994
:return: Returns a command exit code or raises an exception.
916
The command-line arguments, without the program name from argv[0]
917
These should already be decoded. All library/test code calling
918
run_bzr should be passing valid strings (don't need decoding).
920
Returns a command status or raises an exception.
996
922
Special master options: these must come before the command because
997
923
they control how the command is interpreted.
1063
988
debug.set_debug_flags_from_config()
992
from bzrlib.builtins import cmd_help
993
cmd_help().run_argv_aliases([])
996
if argv[0] == '--version':
997
from bzrlib.builtins import cmd_version
998
cmd_version().run_argv_aliases([])
1065
1001
if not opt_no_plugins:
1002
from bzrlib.plugin import load_plugins
1005
from bzrlib.plugin import disable_plugins
1068
1006
disable_plugins()
1072
get_cmd_object('help').run_argv_aliases([])
1075
if argv[0] == '--version':
1076
get_cmd_object('version').run_argv_aliases([])
1079
1008
alias_argv = None
1081
1010
if not opt_no_aliases:
1082
1011
alias_argv = get_alias(argv[0])
1013
user_encoding = osutils.get_user_encoding()
1014
alias_argv = [a.decode(user_encoding) for a in alias_argv]
1084
1015
argv[0] = alias_argv.pop(0)
1086
1017
cmd = argv.pop(0)
1018
# We want only 'ascii' command names, but the user may have typed
1019
# in a Unicode name. In that case, they should just get a
1020
# 'command not found' error later.
1087
1022
cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
1088
1023
run = cmd_obj.run_argv_aliases
1089
1024
run_argv = [argv, alias_argv]
1153
1088
"bzr plugin-provider-db check")
1157
def _specified_or_unicode_argv(argv):
1158
# For internal or testing use, argv can be passed. Otherwise, get it from
1159
# the process arguments in a unicode-safe way.
1091
def main(argv=None):
1092
"""Main entry point of command-line interface.
1094
:param argv: list of unicode command-line arguments similar to sys.argv.
1095
argv[0] is script name usually, it will be ignored.
1096
Don't pass here sys.argv because this list contains plain strings
1097
and not unicode; pass None instead.
1099
:return: exit code of bzr command.
1102
bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
1103
sys.stdin, sys.stdout, sys.stderr)
1105
# Is this a final release version? If so, we should suppress warnings
1106
if bzrlib.version_info[3] == 'final':
1107
suppress_deprecation_warnings(override=True)
1160
1108
if argv is None:
1161
return osutils.get_unicode_argv()
1109
argv = osutils.get_unicode_argv()
1170
1118
new_argv.append(a.decode('ascii'))
1171
1119
except UnicodeDecodeError:
1172
1120
raise errors.BzrError("argv should be list of unicode strings.")
1176
def main(argv=None):
1177
"""Main entry point of command-line interface.
1179
Typically `bzrlib.initialize` should be called first.
1181
:param argv: list of unicode command-line arguments similar to sys.argv.
1182
argv[0] is script name usually, it will be ignored.
1183
Don't pass here sys.argv because this list contains plain strings
1184
and not unicode; pass None instead.
1186
:return: exit code of bzr command.
1188
argv = _specified_or_unicode_argv(argv)
1189
_register_builtin_commands()
1190
1122
ret = run_bzr_catch_errors(argv)
1191
bzrlib.ui.ui_factory.log_transport_activity(
1192
display=('bytes' in debug.debug_flags))
1193
1123
trace.mutter("return code %d", ret)
1124
osutils.report_extension_load_failures()
1200
1131
This function assumed that that UI layer is setup, that symbol deprecations
1201
1132
are already applied, and that unicode decoding has already been performed on argv.
1203
# done here so that they're covered for every test run
1204
1134
install_bzr_command_hooks()
1205
1135
return exception_to_return_code(run_bzr, argv)
1211
1141
This is used for the test suite, and might be useful for other programs
1212
1142
that want to wrap the commandline interface.
1214
# done here so that they're covered for every test run
1215
1144
install_bzr_command_hooks()
1217
1146
return run_bzr(argv)
1240
1169
if topic and topic.startswith(self.prefix):
1241
1170
topic = topic[len(self.prefix):]
1243
cmd = _get_cmd_object(topic, check_missing=False)
1172
cmd = _get_cmd_object(topic)
1244
1173
except KeyError: