139
134
def _builtin_commands():
140
135
import bzrlib.builtins
141
return _scan_module_for_commands(bzrlib.builtins)
144
def _scan_module_for_commands(module):
146
for name, obj in module.__dict__.iteritems():
137
builtins = bzrlib.builtins.__dict__
138
for name in builtins:
147
139
if name.startswith("cmd_"):
148
140
real_name = _unsquish_command_name(name)
141
r[real_name] = builtins[name]
153
def _list_bzr_commands(names):
154
"""Find commands from bzr's core and plugins."""
155
# to eliminate duplicates
156
names.update(builtin_command_names())
157
names.update(plugin_command_names())
161
def all_command_names():
162
"""Return a set of all command names."""
164
for hook in Command.hooks['list_commands']:
167
raise AssertionError(
168
'hook %s returned None' % Command.hooks.get_hook_name(hook))
172
145
def builtin_command_names():
173
"""Return list of builtin command names.
175
Use of all_command_names() is encouraged rather than builtin_command_names
176
and/or plugin_command_names.
146
"""Return list of builtin command names."""
178
147
return _builtin_commands().keys()
181
150
def plugin_command_names():
182
"""Returns command names from commands registered by plugins."""
183
151
return plugin_cmds.keys()
186
@deprecated_function(deprecated_in((1, 17, 0)))
187
def get_all_cmds(plugins_override=False):
188
"""Return canonical name and class for most commands.
190
NB: This does not return all commands since the introduction of
191
command hooks, and returning the class is not sufficient to
192
get correctly setup commands, which is why it is deprecated.
194
Use 'all_command_names' + 'get_cmd_object' instead.
154
def _get_cmd_dict(plugins_override=True):
155
"""Return name->class mapping for all commands."""
196
156
d = _builtin_commands()
197
157
if plugins_override:
198
158
d.update(plugin_cmds.iteritems())
199
for k, v in d.iteritems():
162
def get_all_cmds(plugins_override=True):
163
"""Return canonical name and class for all registered commands."""
164
for k, v in _get_cmd_dict(plugins_override=plugins_override).iteritems():
203
168
def get_cmd_object(cmd_name, plugins_override=True):
204
"""Return the command object for a command.
169
"""Return the canonical name and command class for a command.
207
172
If true, plugin commands can override builtins.
210
return _get_cmd_object(cmd_name, plugins_override)
175
cmd = _get_cmd_object(cmd_name, plugins_override)
176
# Allow plugins to extend commands
177
for hook in Command.hooks['extend_command']:
212
181
raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
215
184
def _get_cmd_object(cmd_name, plugins_override=True):
216
"""Get a command object.
185
"""Worker for get_cmd_object which raises KeyError rather than BzrCommandError."""
186
from bzrlib.externalcommand import ExternalCommand
218
:param cmd_name: The name of the command.
219
:param plugins_override: Allow plugins to override builtins.
220
:return: A Command object instance
221
:raises KeyError: If no command is found.
223
188
# We want only 'ascii' command names, but the user may have typed
224
189
# in a Unicode name. In that case, they should just get a
225
190
# 'command not found' error later.
226
191
# In the future, we may actually support Unicode command names.
229
for hook in Command.hooks['get_command']:
230
cmd = hook(cmd, cmd_name)
231
if cmd is not None and not plugins_override and not cmd.plugin_name():
232
# We've found a non-plugin command, don't permit it to be
236
for hook in Command.hooks['get_missing_command']:
243
# Allow plugins to extend commands
244
for hook in Command.hooks['extend_command']:
249
def _try_plugin_provider(cmd_name):
250
"""Probe for a plugin provider having cmd_name."""
252
plugin_metadata, provider = probe_for_provider(cmd_name)
253
raise errors.CommandAvailableInPlugin(cmd_name,
254
plugin_metadata, provider)
255
except errors.NoPluginAvailable:
259
def probe_for_provider(cmd_name):
260
"""Look for a provider for cmd_name.
262
:param cmd_name: The command name.
263
:return: plugin_metadata, provider for getting cmd_name.
264
:raises NoPluginAvailable: When no provider can supply the plugin.
266
# look for providers that provide this command but aren't installed
267
for provider in command_providers_registry:
193
# first look up this command under the specified name
269
return provider.plugin_for_command(cmd_name), provider
270
except errors.NoPluginAvailable:
196
return plugin_cmds.get(cmd_name)()
272
raise errors.NoPluginAvailable(cmd_name)
275
def _get_bzr_command(cmd_or_None, cmd_name):
276
"""Get a command from bzr's core."""
277
cmds = _builtin_commands()
199
cmds = _get_cmd_dict(plugins_override=False)
279
201
return cmds[cmd_name]()
205
for key in plugin_cmds.keys():
206
info = plugin_cmds.get_info(key)
207
if cmd_name in info.aliases:
208
return plugin_cmds.get(key)()
282
209
# look for any command which claims this as an alias
283
210
for real_cmd_name, cmd_class in cmds.iteritems():
284
211
if cmd_name in cmd_class.aliases:
285
212
return cmd_class()
289
def _get_external_command(cmd_or_None, cmd_name):
290
"""Lookup a command that is a shell script."""
291
# Only do external command lookups when no command is found so far.
292
if cmd_or_None is not None:
294
from bzrlib.externalcommand import ExternalCommand
295
214
cmd_obj = ExternalCommand.find_command(cmd_name)
300
def _get_plugin_command(cmd_or_None, cmd_name):
301
"""Get a command from bzr's plugins."""
303
return plugin_cmds.get(cmd_name)()
306
for key in plugin_cmds.keys():
307
info = plugin_cmds.get_info(key)
308
if cmd_name in info.aliases:
309
return plugin_cmds.get(key)()
218
# look for plugins that provide this command but aren't installed
219
for provider in command_providers_registry:
221
plugin_metadata = provider.plugin_for_command(cmd_name)
222
except errors.NoPluginAvailable:
225
raise errors.CommandAvailableInPlugin(cmd_name,
226
plugin_metadata, provider)
313
230
class Command(object):
695
608
"Called after creating a command object to allow modifications "
696
609
"such as adding or removing options, docs etc. Called with the "
697
610
"new bzrlib.commands.Command object.", (1, 13), None))
698
self.create_hook(HookPoint('get_command',
699
"Called when creating a single command. Called with "
700
"(cmd_or_None, command_name). get_command should either return "
701
"the cmd_or_None parameter, or a replacement Command object that "
702
"should be used for the command. Note that the Command.hooks "
703
"hooks are core infrastructure. Many users will prefer to use "
704
"bzrlib.commands.register_command or plugin_cmds.register_lazy.",
706
self.create_hook(HookPoint('get_missing_command',
707
"Called when creating a single command if no command could be "
708
"found. Called with (command_name). get_missing_command should "
709
"either return None, or a Command object to be used for the "
710
"command.", (1, 17), None))
711
self.create_hook(HookPoint('list_commands',
712
"Called when enumerating commands. Called with a set of "
713
"cmd_name strings for all the commands found so far. This set "
714
" is safe to mutate - e.g. to remove a command. "
715
"list_commands should return the updated set of command names.",
718
612
Command.hooks = CommandHooks()