1
# Copyright (C) 2004, 2005, 2007 Canonical Ltd
1
# Copyright (C) 2004, 2005, 2007, 2008 Canonical Ltd
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
28
28
BZR_PLUGIN_PATH is also honoured for any plugins imported via
29
'import bzrlib.plugins.PLUGINNAME', as long as set_plugins_path has been
29
'import bzrlib.plugins.PLUGINNAME', as long as set_plugins_path has been
36
from bzrlib import osutils
36
38
from bzrlib.lazy_import import lazy_import
37
40
lazy_import(globals(), """
70
73
Future calls to load_plugins() will be ignored.
72
# TODO: jam 20060131 This should probably also disable
78
78
def _strip_trailing_sep(path):
79
79
return path.rstrip("\\/")
82
def set_plugins_path():
83
"""Set the path for plugins to be loaded from."""
82
def set_plugins_path(path=None):
83
"""Set the path for plugins to be loaded from.
85
:param path: The list of paths to search for plugins. By default,
86
path will be determined using get_standard_plugins_path.
87
if path is [], no plugins can be loaded.
90
path = get_standard_plugins_path()
91
_mod_plugins.__path__ = path
95
def get_standard_plugins_path():
96
"""Determine a plugin path suitable for general use."""
84
97
path = os.environ.get('BZR_PLUGIN_PATH',
85
98
get_default_plugin_path()).split(os.pathsep)
99
# Get rid of trailing slashes, since Python can't handle them when
100
# it tries to import modules.
101
path = map(_strip_trailing_sep, path)
86
102
bzr_exe = bool(getattr(sys, 'frozen', None))
87
103
if bzr_exe: # expand path for bzr.exe
88
104
# We need to use relative path to system-wide plugin
97
113
# so relative path is ../../../plugins
98
114
path.append(osutils.abspath(osutils.pathjoin(
99
115
osutils.dirname(__file__), '../../../plugins')))
100
# Get rid of trailing slashes, since Python can't handle them when
101
# it tries to import modules.
102
path = map(_strip_trailing_sep, path)
103
116
if not bzr_exe: # don't look inside library.zip
104
117
# search the plugin path before the bzrlib installed dir
105
118
path.append(os.path.dirname(_mod_plugins.__file__))
117
130
if archless_path not in path:
118
131
path.append(archless_path)
119
_mod_plugins.__path__ = path
135
def load_plugins(path=None):
124
136
"""Load bzrlib plugins.
126
138
The environment variable BZR_PLUGIN_PATH is considered a delimited
131
143
load_from_dirs() provides the underlying mechanism and is called with
132
144
the default directory list to provide the normal behaviour.
146
:param path: The list of paths to search for plugins. By default,
147
path will be determined using get_standard_plugins_path.
148
if path is [], no plugins can be loaded.
206
if getattr(_mod_plugins, f, None):
223
continue # We don't load __init__.py again in the plugin dir
224
elif getattr(_mod_plugins, f, None):
207
225
trace.mutter('Plugin name %s already loaded', f)
209
227
# trace.mutter('add plugin name %s', f)
210
228
plugin_names.add(f)
212
230
for name in plugin_names:
214
232
exec "import bzrlib.plugins.%s" % name in {}
269
287
if name.startswith(prefix)]
271
289
trace.mutter('Names in archive: %r', namelist)
273
291
for name in namelist:
274
292
if not name or name.endswith('/'):
277
295
# '/' is used to separate pathname components inside zip archives
278
296
ix = name.rfind('/')
296
314
plugin_name = base
300
318
if not plugin_name:
302
320
if getattr(_mod_plugins, plugin_name, None):
303
321
trace.mutter('Plugin name %s already loaded', plugin_name)
307
325
exec "import bzrlib.plugins.%s" % plugin_name in {}
308
326
trace.mutter('Load plugin %s from zip %r', plugin_name, zip_name)
379
397
result = self.module.__doc__
380
398
if result[-1] != '\n':
382
# there is code duplicated here and in bzrlib/help_topic.py's
400
# there is code duplicated here and in bzrlib/help_topic.py's
383
401
# matching Topic code. This should probably be factored in
384
402
# to a helper function and a common base class.
385
403
if additional_see_also is not None:
451
469
def version_info(self):
452
470
"""Return the plugin's version_tuple or None if unknown."""
453
471
version_info = getattr(self.module, 'version_info', None)
454
if version_info is not None and len(version_info) == 3:
455
version_info = tuple(version_info) + ('final', 0)
472
if version_info is not None:
474
if isinstance(version_info, types.StringType):
475
version_info = version_info.split('.')
476
elif len(version_info) == 3:
477
version_info = tuple(version_info) + ('final', 0)
479
# The given version_info isn't even iteratible
480
trace.log_exception_quietly()
481
version_info = (version_info,)
456
482
return version_info
458
484
def _get__version__(self):
459
485
version_info = self.version_info()
460
if version_info is None:
486
if version_info is None or len(version_info) == 0:
462
if version_info[3] == 'final':
463
version_string = '%d.%d.%d' % version_info[:3]
465
version_string = '%d.%d.%d%s%d' % version_info
489
version_string = _format_version_tuple(version_info)
490
except (ValueError, TypeError, IndexError), e:
491
trace.log_exception_quietly()
492
# try to return something usefull for bad plugins, in stead of
494
version_string = '.'.join(map(str, version_info))
466
495
return version_string
468
497
__version__ = property(_get__version__)