51
from bzrlib import registry
52
from bzrlib.symbol_versioning import (
53
57
from bzrlib.option import Option
56
class CommandInfo(object):
57
"""Information about a command."""
59
def __init__(self, aliases):
60
"""The list of aliases for the command."""
61
self.aliases = aliases
64
def from_command(klass, command):
65
"""Factory to construct a CommandInfo from a command."""
66
return klass(command.aliases)
69
class CommandRegistry(registry.Registry):
72
def _get_name(command_name):
73
if command_name.startswith("cmd_"):
74
return _unsquish_command_name(command_name)
78
def register(self, cmd, decorate=False):
79
"""Utility function to help register a command
81
:param cmd: Command subclass to register
82
:param decorate: If true, allow overriding an existing command
83
of the same name; the old command is returned by this function.
84
Otherwise it is an error to try to override an existing command.
87
k_unsquished = self._get_name(k)
89
previous = self.get(k_unsquished)
91
previous = _builtin_commands().get(k_unsquished)
92
info = CommandInfo.from_command(cmd)
94
registry.Registry.register(self, k_unsquished, cmd,
95
override_existing=decorate, info=info)
97
trace.log_error('Two plugins defined the same command: %r' % k)
98
trace.log_error('Not loading the one in %r' %
99
sys.modules[cmd.__module__])
100
trace.log_error('Previously this command was registered from %r' %
101
sys.modules[previous.__module__])
104
def register_lazy(self, command_name, aliases, module_name):
105
"""Register a command without loading its module.
107
:param command_name: The primary name of the command.
108
:param aliases: A list of aliases for the command.
109
:module_name: The module that the command lives in.
111
key = self._get_name(command_name)
112
registry.Registry.register_lazy(self, key, module_name, command_name,
113
info=CommandInfo(aliases))
116
plugin_cmds = CommandRegistry()
119
63
def register_command(cmd, decorate=False):
64
"""Utility function to help register a command
66
:param cmd: Command subclass to register
67
:param decorate: If true, allow overriding an existing command
68
of the same name; the old command is returned by this function.
69
Otherwise it is an error to try to override an existing command.
120
71
global plugin_cmds
121
return plugin_cmds.register(cmd, decorate)
73
if k.startswith("cmd_"):
74
k_unsquished = _unsquish_command_name(k)
77
if k_unsquished not in plugin_cmds:
78
plugin_cmds[k_unsquished] = cmd
79
## trace.mutter('registered plugin command %s', k_unsquished)
80
if decorate and k_unsquished in builtin_command_names():
81
return _builtin_commands()[k_unsquished]
83
result = plugin_cmds[k_unsquished]
84
plugin_cmds[k_unsquished] = cmd
87
trace.log_error('Two plugins defined the same command: %r' % k)
88
trace.log_error('Not loading the one in %r' % sys.modules[cmd.__module__])
89
trace.log_error('Previously this command was registered from %r' %
90
sys.modules[plugin_cmds[k_unsquished].__module__])
124
93
def _squish_command_name(cmd):
185
154
# In the future, we may actually support Unicode command names.
187
156
# first look up this command under the specified name
190
return plugin_cmds.get(cmd_name)()
193
cmds = _get_cmd_dict(plugins_override=False)
157
cmds = _get_cmd_dict(plugins_override=plugins_override)
195
159
return cmds[cmd_name]()
199
for key in plugin_cmds.keys():
200
info = plugin_cmds.get_info(key)
201
if cmd_name in info.aliases:
202
return plugin_cmds.get(key)()
203
163
# look for any command which claims this as an alias
204
164
for real_cmd_name, cmd_class in cmds.iteritems():
205
165
if cmd_name in cmd_class.aliases:
837
795
ret = apply_coveraged(opt_coverage_dir, run, *run_argv)
839
797
ret = run(*run_argv)
840
if 'memory' in debug.debug_flags:
841
trace.debug_memory('Process status after command:', short=False)
844
# reset, in case we may do other commands later within the same
845
# process. Commands that want to execute sub-commands must propagate
846
# --verbose in their own way.
847
option._verbosity_level = saved_verbosity_level
800
# reset, in case we may do other commands later within the same process
801
option._verbosity_level = 0
849
803
def display_command(func):
850
804
"""Decorator that suppresses pipe/interrupt errors."""
871
825
from bzrlib.ui.text import TextUIFactory
872
826
bzrlib.ui.ui_factory = TextUIFactory()
874
828
# Is this a final release version? If so, we should suppress warnings
875
829
if bzrlib.version_info[3] == 'final':
876
830
from bzrlib import symbol_versioning
877
831
symbol_versioning.suppress_deprecation_warnings(override=False)
879
user_encoding = osutils.get_user_encoding()
880
argv = [a.decode(user_encoding) for a in argv[1:]]
833
argv = [a.decode(bzrlib.user_encoding) for a in argv[1:]]
881
834
except UnicodeDecodeError:
882
835
raise errors.BzrError(("Parameter '%r' is unsupported by the current "
883
836
"encoding." % a))