15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
"""bzr python plugin support
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.
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.
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
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.
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.
47
from bzrlib.config import config_dir
48
from bzrlib.trace import log_error, mutter, log_exception, warning, \
50
from bzrlib.errors import BzrError
51
from bzrlib import plugins
52
from bzrlib.osutils import pathjoin
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')
60
34
def load_plugins():
61
"""Find all python plugins and load them.
36
Find all python plugins and load them.
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")
83
dirs = os.environ.get('BZR_PLUGIN_PATH', DEFAULT_PLUGIN_PATH).split(os.pathsep)
84
dirs.insert(0, os.path.dirname(plugins.__file__))
60
from bzrlib.trace import log_error, mutter, log_exception
61
from bzrlib.errors import BzrError
63
bzrpath = os.environ.get('BZR_PLUGIN_PATH', DEFAULT_PLUGIN_PATH)
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']
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)
100
79
plugin_names = set()
101
80
if not os.path.isdir(d):
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
109
if os.path.isfile(pathjoin(path, entry)):
88
if os.path.isfile(os.path.join(path, entry)):
111
90
else: # This directory is not a package
127
106
for name in plugin_names:
129
108
plugin_info = imp.find_module(name, [d])
130
mutter('load plugin %r', plugin_info)
109
mutter('load plugin %r' % (plugin_info,))
132
plugin = imp.load_module('bzrlib.plugins.' + name,
111
plugin = imp.load_module('bzrlib.plugin.' + name,
134
113
all_plugins.append(plugin)
135
setattr(bzrlib.plugins, name, plugin)
137
115
if plugin_info[0] is not None:
138
116
plugin_info[0].close()
140
mutter('loaded succesfully')
141
except KeyboardInterrupt:
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))