~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugin.py

  • Committer: Martin Pool
  • Date: 2005-08-12 15:28:37 UTC
  • Revision ID: mbp@sourcefrog.net-20050812152837-9f0bee4b51498c0e
- change default log format back to long
  (looks better with -v)

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
 
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
 
43
26
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
 
from bzrlib.osutils import pathjoin
53
 
 
54
 
DEFAULT_PLUGIN_PATH = pathjoin(config_dir(), 'plugins')
 
27
from bzrlib.osutils import config_dir
 
28
DEFAULT_PLUGIN_PATH = os.path.join(config_dir(), 'plugins')
55
29
 
56
30
all_plugins = []
57
31
_loaded = False
58
32
 
59
33
 
60
34
def load_plugins():
61
 
    """Find all python plugins and load them.
 
35
    """
 
36
    Find all python plugins and load them.
62
37
 
63
38
    Loading a plugin means importing it into the python interpreter.
64
39
    The plugin is expected to make calls to register commands when
80
55
        #raise BzrError("plugins already initialized")
81
56
    _loaded = True
82
57
 
83
 
    dirs = os.environ.get('BZR_PLUGIN_PATH', DEFAULT_PLUGIN_PATH).split(os.pathsep)
84
 
    dirs.insert(0, os.path.dirname(plugins.__file__))
 
58
    import sys, os, imp
 
59
    
 
60
    from bzrlib.trace import log_error, mutter, log_exception
 
61
    from bzrlib.errors import BzrError
 
62
 
 
63
    bzrpath = os.environ.get('BZR_PLUGIN_PATH', DEFAULT_PLUGIN_PATH)
85
64
 
86
65
    # The problem with imp.get_suffixes() is that it doesn't include
87
66
    # .pyo which is technically valid
91
70
    suffixes = imp.get_suffixes()
92
71
    suffixes.append(('.pyo', 'rb', imp.PY_COMPILED))
93
72
    package_entries = ['__init__.py', '__init__.pyc', '__init__.pyo']
94
 
    for d in dirs:
 
73
    for d in bzrpath.split(os.pathsep):
95
74
        # going through them one by one allows different plugins with the same
96
75
        # filename in different directories in the path
97
 
        mutter('looking for plugins in %s', d)
 
76
        mutter('looking for plugins in %s' % d)
98
77
        if not d:
99
78
            continue
100
79
        plugin_names = set()
101
80
        if not os.path.isdir(d):
102
81
            continue
103
82
        for f in os.listdir(d):
104
 
            path = pathjoin(d, f)
 
83
            path = os.path.join(d, f)
105
84
            if os.path.isdir(path):
106
85
                for entry in package_entries:
107
86
                    # This directory should be a package, and thus added to
108
87
                    # the list
109
 
                    if os.path.isfile(pathjoin(path, entry)):
 
88
                    if os.path.isfile(os.path.join(path, entry)):
110
89
                        break
111
90
                else: # This directory is not a package
112
91
                    continue
119
98
                        break
120
99
                else:
121
100
                    continue
122
 
            mutter('add plugin name %s', f)
 
101
            mutter('add plugin name %s' % f)
123
102
            plugin_names.add(f)
124
103
 
125
104
        plugin_names = list(plugin_names)
127
106
        for name in plugin_names:
128
107
            try:
129
108
                plugin_info = imp.find_module(name, [d])
130
 
                mutter('load plugin %r', plugin_info)
 
109
                mutter('load plugin %r' % (plugin_info,))
131
110
                try:
132
 
                    plugin = imp.load_module('bzrlib.plugins.' + name,
 
111
                    plugin = imp.load_module('bzrlib.plugin.' + name,
133
112
                                             *plugin_info)
134
113
                    all_plugins.append(plugin)
135
 
                    setattr(bzrlib.plugins, name, plugin)
136
114
                finally:
137
115
                    if plugin_info[0] is not None:
138
116
                        plugin_info[0].close()
139
 
 
140
 
                mutter('loaded succesfully')
141
 
            except KeyboardInterrupt:
142
 
                raise
143
117
            except Exception, e:
144
 
                ## import pdb; pdb.set_trace()
145
 
                warning('Unable to load plugin %r from %r' % (name, d))
146
 
                log_exception_quietly()
 
118
                log_error('Unable to load plugin %r from %r' % (name, d))
 
119
                log_error(str(e))
 
120
                log_exception()
 
121