144
def all_command_names():
145
"""Return a list of all command names."""
146
# to eliminate duplicates
147
names = set(builtin_command_names())
148
names.update(plugin_command_names())
149
for hook in Command.hooks['list_commands']:
150
new_names = hook(names)
151
if new_names is None:
152
raise AssertionError(
153
'hook %s returned None' % Command.hooks.get_hook_name(hook))
144
158
def builtin_command_names():
145
"""Return list of builtin command names."""
159
"""Return list of builtin command names.
161
Use of all_command_names() is encouraged rather than builtin_command_names
162
and/or plugin_command_names.
146
164
return _builtin_commands().keys()
149
167
def plugin_command_names():
168
"""Returns command names from commands registered by plugins."""
150
169
return plugin_cmds.keys()
167
186
def get_cmd_object(cmd_name, plugins_override=True):
168
"""Return the canonical name and command class for a command.
187
"""Return the command object for a command.
171
190
If true, plugin commands can override builtins.
174
cmd = _get_cmd_object(cmd_name, plugins_override)
175
# Allow plugins to extend commands
176
for hook in Command.hooks['extend_command']:
193
return _get_cmd_object(cmd_name, plugins_override)
180
195
raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
183
198
def _get_cmd_object(cmd_name, plugins_override=True):
199
"""Get a command object.
201
:param cmd_name: The name of the command.
202
:param plugins_override: Allow plugins to override builtins.
203
:return: A Command object instance
204
:raises: KeyError if no command is found.
206
# Pre-hook command lookup logic.
207
cmd = __get_cmd_object(cmd_name, plugins_override)
208
# Allow hooks to supply/replace commands:
209
for hook in Command.hooks['get_command']:
210
cmd = hook(cmd, cmd_name)
213
plugin_metadata, provider = probe_for_provider(cmd_name)
214
raise errors.CommandAvailableInPlugin(cmd_name,
215
plugin_metadata, provider)
216
except errors.NoPluginAvailable:
220
# Allow plugins to extend commands
221
for hook in Command.hooks['extend_command']:
226
def probe_for_provider(cmd_name):
227
"""Look for a provider for cmd_name.
229
:param cmd_name: The command name.
230
:return: plugin_metadata, provider for getting cmd_name.
231
:raises NoPluginAvailable: When no provider can supply the plugin.
233
# look for providers that provide this command but aren't installed
234
for provider in command_providers_registry:
236
return provider.plugin_for_command(cmd_name), provider
237
except errors.NoPluginAvailable:
239
raise errors.NoPluginAvailable(cmd_name)
242
def __get_cmd_object(cmd_name, plugins_override):
184
243
"""Worker for get_cmd_object which raises KeyError rather than BzrCommandError."""
185
244
from bzrlib.externalcommand import ExternalCommand
213
272
cmd_obj = ExternalCommand.find_command(cmd_name)
217
# look for plugins that provide this command but aren't installed
218
for provider in command_providers_registry:
220
plugin_metadata = provider.plugin_for_command(cmd_name)
221
except errors.NoPluginAvailable:
224
raise errors.CommandAvailableInPlugin(cmd_name,
225
plugin_metadata, provider)
229
278
class Command(object):
595
644
"Called after creating a command object to allow modifications "
596
645
"such as adding or removing options, docs etc. Called with the "
597
646
"new bzrlib.commands.Command object.", (1, 13), None))
647
self.create_hook(HookPoint('get_command',
648
"Called when creating a single command. Called with "
649
"(cmd_or_None, command_name). get_command should either return "
650
"the cmd_or_None parameter, or a replacement Command object that "
651
"should be used for the command.", (1, 14), None))
652
self.create_hook(HookPoint('list_commands',
653
"Called when enumerating commands. Called with a dict of "
654
"cmd_name: cmd_class tuples for all the commands found "
655
"so far. This dict is safe to mutate - to remove a command or "
656
"to replace it with another (eg plugin supplied) version. "
657
"list_commands should return the updated dict of commands.",
599
660
Command.hooks = CommandHooks()