~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: John Arbash Meinel
  • Date: 2008-10-28 19:39:57 UTC
  • mfrom: (3804 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3805.
  • Revision ID: john@arbash-meinel.com-20081028193957-zg2eygq5cgz2bnpu
Merge bzr.dev 3804

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 Canonical Ltd
 
1
# Copyright (C) 2006, 2008 Canonical Ltd
2
2
#
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
53
53
from bzrlib.option import Option
54
54
 
55
55
 
56
 
plugin_cmds = {}
 
56
class CommandInfo(object):
 
57
    """Information about a command."""
 
58
 
 
59
    def __init__(self, aliases):
 
60
        """The list of aliases for the command."""
 
61
        self.aliases = aliases
 
62
 
 
63
    @classmethod
 
64
    def from_command(klass, command):
 
65
        """Factory to construct a CommandInfo from a command."""
 
66
        return klass(command.aliases)
 
67
 
 
68
 
 
69
class CommandRegistry(registry.Registry):
 
70
 
 
71
    @staticmethod
 
72
    def _get_name(command_name):
 
73
        if command_name.startswith("cmd_"):
 
74
            return _unsquish_command_name(command_name)
 
75
        else:
 
76
            return command_name
 
77
 
 
78
    def register(self, cmd, decorate=False):
 
79
        """Utility function to help register a command
 
80
 
 
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.
 
85
        """
 
86
        k = cmd.__name__
 
87
        k_unsquished = self._get_name(k)
 
88
        try:
 
89
            previous = self.get(k_unsquished)
 
90
        except KeyError:
 
91
            previous = _builtin_commands().get(k_unsquished)
 
92
        info = CommandInfo.from_command(cmd)
 
93
        try:
 
94
            registry.Registry.register(self, k_unsquished, cmd,
 
95
                                       override_existing=decorate, info=info)
 
96
        except KeyError:
 
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__])
 
102
        return previous
 
103
 
 
104
    def register_lazy(self, command_name, aliases, module_name):
 
105
        """Register a command without loading its module.
 
106
 
 
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.
 
110
        """
 
111
        key = self._get_name(command_name)
 
112
        registry.Registry.register_lazy(self, key, module_name, command_name,
 
113
                                        info=CommandInfo(aliases))
 
114
 
 
115
 
 
116
plugin_cmds = CommandRegistry()
57
117
 
58
118
 
59
119
def register_command(cmd, decorate=False):
60
 
    """Utility function to help register a command
61
 
 
62
 
    :param cmd: Command subclass to register
63
 
    :param decorate: If true, allow overriding an existing command
64
 
        of the same name; the old command is returned by this function.
65
 
        Otherwise it is an error to try to override an existing command.
66
 
    """
67
120
    global plugin_cmds
68
 
    k = cmd.__name__
69
 
    if k.startswith("cmd_"):
70
 
        k_unsquished = _unsquish_command_name(k)
71
 
    else:
72
 
        k_unsquished = k
73
 
    if k_unsquished not in plugin_cmds:
74
 
        plugin_cmds[k_unsquished] = cmd
75
 
        ## trace.mutter('registered plugin command %s', k_unsquished)
76
 
        if decorate and k_unsquished in builtin_command_names():
77
 
            return _builtin_commands()[k_unsquished]
78
 
    elif decorate:
79
 
        result = plugin_cmds[k_unsquished]
80
 
        plugin_cmds[k_unsquished] = cmd
81
 
        return result
82
 
    else:
83
 
        trace.log_error('Two plugins defined the same command: %r' % k)
84
 
        trace.log_error('Not loading the one in %r' % sys.modules[cmd.__module__])
85
 
        trace.log_error('Previously this command was registered from %r' %
86
 
                        sys.modules[plugin_cmds[k_unsquished].__module__])
 
121
    return plugin_cmds.register(cmd, decorate)
87
122
 
88
123
 
89
124
def _squish_command_name(cmd):
118
153
    """Return name->class mapping for all commands."""
119
154
    d = _builtin_commands()
120
155
    if plugins_override:
121
 
        d.update(plugin_cmds)
 
156
        d.update(plugin_cmds.iteritems())
122
157
    return d
123
158
 
124
159
    
150
185
    # In the future, we may actually support Unicode command names.
151
186
 
152
187
    # first look up this command under the specified name
153
 
    cmds = _get_cmd_dict(plugins_override=plugins_override)
 
188
    if plugins_override:
 
189
        try:
 
190
            return plugin_cmds.get(cmd_name)()
 
191
        except KeyError:
 
192
            pass
 
193
    cmds = _get_cmd_dict(plugins_override=False)
154
194
    try:
155
195
        return cmds[cmd_name]()
156
196
    except KeyError:
157
197
        pass
158
 
 
 
198
    if plugins_override:
 
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)()
159
203
    # look for any command which claims this as an alias
160
204
    for real_cmd_name, cmd_class in cmds.iteritems():
161
205
        if cmd_name in cmd_class.aliases: