~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Martin Pool
  • Date: 2005-06-10 02:21:14 UTC
  • Revision ID: mbp@sourcefrog.net-20050610022114-8f49c9244a5b8e2f
- improved external-command patch from john

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
        revs = int(revstr)
69
69
    return revs
70
70
 
71
 
def get_all_cmds():
72
 
    """Return canonical name and class for all registered commands."""
 
71
def _find_plugins():
 
72
    """Find all python files which are plugins, and load their commands
 
73
    to add to the list of "all commands"
 
74
 
 
75
    The environment variable BZRPATH is considered a delimited set of
 
76
    paths to look through. Each entry is searched for *.py files.
 
77
    If a directory is found, it is also searched, but they are 
 
78
    not searched recursively. This allows you to revctl the plugins.
 
79
    
 
80
    Inside the plugin should be a series of cmd_* function, which inherit from
 
81
    the bzrlib.commands.Command class.
 
82
    """
 
83
    bzrpath = os.environ.get('BZRPLUGINPATH', '')
 
84
 
 
85
    plugin_cmds = {} 
 
86
    if not bzrpath:
 
87
        return plugin_cmds
 
88
    _platform_extensions = {
 
89
        'win32':'.pyd',
 
90
        'cygwin':'.dll',
 
91
        'darwin':'.dylib',
 
92
        'linux2':'.so'
 
93
        }
 
94
    if _platform_extensions.has_key(sys.platform):
 
95
        platform_extension = _platform_extensions[sys.platform]
 
96
    else:
 
97
        platform_extension = None
 
98
    for d in bzrpath.split(os.pathsep):
 
99
        plugin_names = {} # This should really be a set rather than a dict
 
100
        for f in os.listdir(d):
 
101
            if f.endswith('.py'):
 
102
                f = f[:-3]
 
103
            elif f.endswith('.pyc') or f.endswith('.pyo'):
 
104
                f = f[:-4]
 
105
            elif platform_extension and f.endswith(platform_extension):
 
106
                f = f[:-len(platform_extension)]
 
107
                if f.endswidth('module'):
 
108
                    f = f[:-len('module')]
 
109
            else:
 
110
                continue
 
111
            if not plugin_names.has_key(f):
 
112
                plugin_names[f] = True
 
113
 
 
114
        plugin_names = plugin_names.keys()
 
115
        plugin_names.sort()
 
116
        try:
 
117
            sys.path.insert(0, d)
 
118
            for name in plugin_names:
 
119
                try:
 
120
                    old_module = None
 
121
                    try:
 
122
                        if sys.modules.has_key(name):
 
123
                            old_module = sys.modules[name]
 
124
                            del sys.modules[name]
 
125
                        plugin = __import__(name, locals())
 
126
                        for k in dir(plugin):
 
127
                            if k.startswith('cmd_'):
 
128
                                k_unsquished = _unsquish_command_name(k)
 
129
                                if not plugin_cmds.has_key(k_unsquished):
 
130
                                    plugin_cmds[k_unsquished] = getattr(plugin, k)
 
131
                                else:
 
132
                                    log_error('Two plugins defined the same command: %r' % k)
 
133
                                    log_error('Not loading the one in %r in dir %r' % (name, d))
 
134
                    finally:
 
135
                        if old_module:
 
136
                            sys.modules[name] = old_module
 
137
                except ImportError, e:
 
138
                    log_error('Unable to load plugin: %r from %r\n%s' % (name, d, e))
 
139
        finally:
 
140
            sys.path.pop(0)
 
141
    return plugin_cmds
 
142
 
 
143
def _get_cmd_dict(include_plugins=True):
 
144
    d = {}
73
145
    for k, v in globals().iteritems():
74
146
        if k.startswith("cmd_"):
75
 
            yield _unsquish_command_name(k), v
76
 
 
77
 
def get_cmd_class(cmd):
 
147
            d[_unsquish_command_name(k)] = v
 
148
    if include_plugins:
 
149
        d.update(_find_plugins())
 
150
    return d
 
151
    
 
152
def get_all_cmds(include_plugins=True):
 
153
    """Return canonical name and class for all registered commands."""
 
154
    for k, v in _get_cmd_dict(include_plugins=include_plugins).iteritems():
 
155
        yield k,v
 
156
 
 
157
 
 
158
def get_cmd_class(cmd,include_plugins=True):
78
159
    """Return the canonical name and command class for a command.
79
160
    """
80
161
    cmd = str(cmd)                      # not unicode
81
162
 
82
163
    # first look up this command under the specified name
 
164
    cmds = _get_cmd_dict(include_plugins=include_plugins)
83
165
    try:
84
 
        return cmd, globals()[_squish_command_name(cmd)]
 
166
        return cmd, cmds[cmd]
85
167
    except KeyError:
86
168
        pass
87
169
 
88
170
    # look for any command which claims this as an alias
89
 
    for cmdname, cmdclass in get_all_cmds():
 
171
    for cmdname, cmdclass in cmds.iteritems():
90
172
        if cmd in cmdclass.aliases:
91
173
            return cmdname, cmdclass
92
174
 
165
247
        import os.path
166
248
        bzrpath = os.environ.get('BZRPATH', '')
167
249
 
168
 
        for dir in bzrpath.split(':'):
 
250
        for dir in bzrpath.split(os.pathsep):
169
251
            path = os.path.join(dir, cmd)
170
252
            if os.path.isfile(path):
171
253
                return ExternalCommand(path)
1326
1408
    """
1327
1409
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
1328
1410
    
 
1411
    include_plugins=True
1329
1412
    try:
1330
1413
        args, opts = parse_args(argv[1:])
1331
1414
        if 'help' in opts:
1338
1421
        elif 'version' in opts:
1339
1422
            show_version()
1340
1423
            return 0
 
1424
        elif args and args[0] == 'builtin':
 
1425
            include_plugins=False
 
1426
            args = args[1:]
1341
1427
        cmd = str(args.pop(0))
1342
1428
    except IndexError:
1343
1429
        import help
1345
1431
        return 1
1346
1432
          
1347
1433
 
1348
 
    canonical_cmd, cmd_class = get_cmd_class(cmd)
 
1434
    canonical_cmd, cmd_class = get_cmd_class(cmd,include_plugins=include_plugins)
1349
1435
 
1350
1436
    # global option
1351
1437
    if 'profile' in opts: