Overriding commands in plugins
Matt Nordhoff
mnordhoff at mattnordhoff.com
Mon Mar 8 15:34:52 GMT 2010
Michael Gliwinski wrote:
> Hi all,
>
> What is the best/proper/right/working way to override some functionality of a
> command in a plugin?
>
> Let's say for example that I want to change 'switch' to print a nice message
> before it goes on doing its work :)
>
> From looking at some of the examples I did:
>
> class cmd_switch(bzrlib.builtins.cmd_switch):
> __doc__ = bzrlib.builtins.cmd_switch.__doc__
> def run(**kwargs):
> self.outf.write('Hello World!'\n)
> super(cmd_switch, self).run(**kwargs)
>
> but it seems to me that doesn't take into account the fact that switch may be
> overriden by other plugins. So it seems the result of that may be a bit
> random, depending on which plugin is loaded first?
>
> Then I also saw this done in the loom plugin:
>
> class cmd_switch(bzrlib.builtins.cmd_switch):
> def run_argv_aliases(self, argv, alias_argv=None):
> try:
> super(cmd_switch, self).run_argv_aliases(list(argv), alias_argv)
> except (errors.MustUseDecorated, errors.BzrOptionsError):
> if self._original_command is None:
> raise
> self._original_command().run_argv_aliases(argv, alias_argv)
>
> so, IIUC this uses the original command (returned by
> bzrlib.commands.plugin_cmds.register) stored in _original_command attribute,
> tries to run the overriden command and in case of problems falls back to
> original command, yes?
>
> Is this the more "proper" way? Does it have to be done in run_argv_aliases?
> I.e. if I'm only adding certain functionality it would be bit more convenient
> to do it in run.
>
> I'll try to update http://doc.bazaar.canonical.com/plugins/en/plugin-
> development.html#extending-an-existing-command if I can figure out something
> solid to add there.
>
> Thanks,
> Michael
I know of another way, using bzrlib.commands.get_command_object(), and I
/think/ it's the best way. As an example, this is what Loggerhead does:
import bzrlib.builtins
from bzrlib.commands import get_cmd_object, register_command
from bzrlib.option import Option
_original_command = get_cmd_object('serve')
class cmd_serve(bzrlib.builtins.cmd_serve):
__doc__ = _original_command.__doc__
takes_options = _original_command.takes_options + [
Option('http', help=HELP)]
def run(self, *args, **kw):
if 'http' in kw:
# ... snip ...
else:
super(cmd_serve, self).run(*args, **kw)
<http://bazaar.launchpad.net/~loggerhead-team/loggerhead/trunk-rich/annotate/head%3A/__init__.py#L91>
(<http://xrl.us/bgxved>)
--
Matt Nordhoff
More information about the bazaar
mailing list