~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugin.py

  • Committer: Martin Pool
  • Date: 2005-06-22 09:08:43 UTC
  • Revision ID: mbp@sourcefrog.net-20050622090843-78fe9c62da9ed167
- add john's changeset plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
"""bzr python plugin support
19
 
 
20
 
Any python module in $BZR_PLUGIN_PATH will be imported upon initialization of
21
 
bzrlib. The module will be imported as 'bzrlib.plugins.$BASENAME(PLUGIN)'.
22
 
In the plugin's main body, it should update any bzrlib registries it wants to
23
 
extend; for example, to add new commands, import bzrlib.commands and add your
24
 
new command to the plugin_cmds variable.
25
 
"""
26
 
 
27
 
# TODO: Refactor this to make it more testable.  The main problem at the
28
 
# moment is that loading plugins affects the global process state -- for bzr
29
 
# in general use it's a reasonable assumption that all plugins are loaded at
30
 
# startup and then stay loaded, but this is less good for testing.
31
 
32
 
# Several specific issues:
33
 
#  - plugins can't be unloaded and will continue to effect later tests
34
 
#  - load_plugins does nothing if called a second time
35
 
#  - plugin hooks can't be removed
36
 
#
37
 
# Our options are either to remove these restrictions, or work around them by
38
 
# loading the plugins into a different space than the one running the tests.
39
 
# That could be either a separate Python interpreter or perhaps a new
40
 
# namespace inside this interpreter.
41
 
 
42
 
import imp
43
 
import os
44
 
import sys
45
 
 
46
 
import bzrlib
47
 
from bzrlib.config import config_dir
48
 
from bzrlib.trace import log_error, mutter, log_exception, warning, \
49
 
        log_exception_quietly
50
 
from bzrlib.errors import BzrError
51
 
from bzrlib import plugins
52
 
 
53
 
DEFAULT_PLUGIN_PATH = os.path.join(config_dir(), 'plugins')
 
18
# This module implements plug-in support.
 
19
# Any python module in $BZR_PLUGIN_PATH will be imported upon initialization
 
20
# of bzrlib (and then forgotten about).  In the plugin's main body, it should
 
21
# update any bzrlib registries it wants to extend; for example, to add new
 
22
# commands, import bzrlib.commands and add your new command to the
 
23
# plugin_cmds variable.
 
24
 
 
25
 
 
26
DEFAULT_PLUGIN_PATH = '~/.bzr.conf/plugins'
54
27
 
55
28
all_plugins = []
56
 
_loaded = False
57
29
 
58
30
 
59
31
def load_plugins():
60
 
    """Find all python plugins and load them.
 
32
    """
 
33
    Find all python plugins and load them.
61
34
 
62
35
    Loading a plugin means importing it into the python interpreter.
63
36
    The plugin is expected to make calls to register commands when
72
45
    such as *.pyd).
73
46
    """
74
47
 
75
 
    global all_plugins, _loaded
76
 
    if _loaded:
77
 
        # People can make sure plugins are loaded, they just won't be twice
78
 
        return
79
 
        #raise BzrError("plugins already initialized")
80
 
    _loaded = True
81
 
 
82
 
    dirs = os.environ.get('BZR_PLUGIN_PATH', DEFAULT_PLUGIN_PATH).split(os.pathsep)
83
 
    dirs.insert(0, os.path.dirname(plugins.__file__))
 
48
    import sys, os, imp
 
49
    try:
 
50
        set
 
51
    except NameError:
 
52
        from sets import Set as set         # python2.3
 
53
 
 
54
    from bzrlib.trace import log_error, mutter, log_exception
 
55
    from bzrlib.errors import BzrError
 
56
 
 
57
    bzrpath = os.environ.get('BZR_PLUGIN_PATH')
 
58
    if not bzrpath:
 
59
        bzrpath = os.path.expanduser(DEFAULT_PLUGIN_PATH)
 
60
 
 
61
    global all_plugins
 
62
    if all_plugins:
 
63
        raise BzrError("plugins already initialized")
84
64
 
85
65
    # The problem with imp.get_suffixes() is that it doesn't include
86
66
    # .pyo which is technically valid
90
70
    suffixes = imp.get_suffixes()
91
71
    suffixes.append(('.pyo', 'rb', imp.PY_COMPILED))
92
72
    package_entries = ['__init__.py', '__init__.pyc', '__init__.pyo']
93
 
    for d in dirs:
 
73
    for d in bzrpath.split(os.pathsep):
94
74
        # going through them one by one allows different plugins with the same
95
75
        # filename in different directories in the path
96
 
        mutter('looking for plugins in %s', d)
 
76
        mutter('looking for plugins in %s' % d)
97
77
        if not d:
98
78
            continue
99
79
        plugin_names = set()
118
98
                        break
119
99
                else:
120
100
                    continue
121
 
            mutter('add plugin name %s', f)
 
101
            mutter('add plugin name' + f)
122
102
            plugin_names.add(f)
123
103
 
124
104
        plugin_names = list(plugin_names)
126
106
        for name in plugin_names:
127
107
            try:
128
108
                plugin_info = imp.find_module(name, [d])
129
 
                mutter('load plugin %r', plugin_info)
 
109
                mutter('load plugin %r' % (plugin_info,))
130
110
                try:
131
 
                    plugin = imp.load_module('bzrlib.plugins.' + name,
 
111
                    plugin = imp.load_module('bzrlib.plugin.' + name,
132
112
                                             *plugin_info)
133
 
                    all_plugins.append(plugin)
134
 
                    setattr(bzrlib.plugins, name, plugin)
 
113
                    all_plugins.append(plugin_info)
135
114
                finally:
136
115
                    if plugin_info[0] is not None:
137
116
                        plugin_info[0].close()
138
 
 
139
 
                mutter('loaded succesfully')
140
 
            except KeyboardInterrupt:
141
 
                raise
142
117
            except Exception, e:
143
 
                ## import pdb; pdb.set_trace()
144
 
                warning('Unable to load plugin %r from %r' % (name, d))
145
 
                log_exception_quietly()
 
118
                log_error('Unable to load plugin %r from %r' % (name, d))
 
119
                log_error(str(e))
 
120
                log_exception()
 
121