1
# Copyright (C) 2004, 2005, 2007 Canonical Ltd
1
# Copyright (C) 2004, 2005 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
194
194
"""Load all the plugins in a zip."""
195
195
valid_suffixes = ('.py', '.pyc', '.pyo') # only python modules/packages
197
if '.zip' not in zip_name:
199
index = zip_name.rindex('.zip')
200
ziobj = zipimport.zipimporter(zip_name)
201
except zipimport.ZipImportError:
202
archive = zip_name[:index+4]
203
prefix = zip_name[index+5:]
205
204
mutter('Looking for plugins in %r', zip_name)
207
208
# use zipfile to get list of files/dirs inside zip
209
z = zipfile.ZipFile(archive)
210
namelist = z.namelist()
212
except zipfile.error:
217
prefix = prefix.replace('\\','/')
218
if prefix[-1] != '/':
209
z = zipfile.ZipFile(ziobj.archive)
210
namelist = z.namelist()
214
prefix = ziobj.prefix.replace('\\','/')
221
216
namelist = [name[ix:]
222
217
for name in namelist
223
218
if name.startswith(prefix)]
225
220
mutter('Names in archive: %r', namelist)
227
222
for name in namelist:
261
exec "import bzrlib.plugins.%s" % plugin_name in {}
256
plugin = ziobj.load_module(plugin_name)
257
setattr(plugins, plugin_name, plugin)
262
258
mutter('Load plugin %s from zip %r', plugin_name, zip_name)
259
except zipimport.ZipImportError, e:
260
mutter('Unable to load plugin %r from %r: %s',
261
plugin_name, zip_name, str(e))
263
263
except KeyboardInterrupt:
265
265
except Exception, e:
267
267
warning('Unable to load plugin %r from %r'
268
268
% (name, zip_name))
269
269
log_exception_quietly()
272
class PluginsHelpIndex(object):
273
"""A help index that returns help topics for plugins."""
276
self.prefix = 'plugins/'
278
def get_topics(self, topic):
279
"""Search for topic in the loaded plugins.
281
This will not trigger loading of new plugins.
283
:param topic: A topic to search for.
284
:return: A list which is either empty or contains a single
285
RegisteredTopic entry.
289
if topic.startswith(self.prefix):
290
topic = topic[len(self.prefix):]
291
plugin_module_name = 'bzrlib.plugins.%s' % topic
293
module = sys.modules[plugin_module_name]
297
return [ModuleHelpTopic(module)]
300
class ModuleHelpTopic(object):
301
"""A help topic which returns the docstring for a module."""
303
def __init__(self, module):
306
:param module: The module for which help should be generated.
310
def get_help_text(self, additional_see_also=None):
311
"""Return a string with the help for this topic.
313
:param additional_see_also: Additional help topics to be
316
if not self.module.__doc__:
317
result = "Plugin '%s' has no docstring.\n" % self.module.__name__
319
result = self.module.__doc__
320
if result[-1] != '\n':
322
# there is code duplicated here and in bzrlib/help_topic.py's
323
# matching Topic code. This should probably be factored in
324
# to a helper function and a common base class.
325
if additional_see_also is not None:
326
see_also = sorted(set(additional_see_also))
330
result += 'See also: '
331
result += ', '.join(see_also)
335
def get_help_topic(self):
336
"""Return the modules help topic - its __name__ after bzrlib.plugins.."""
337
return self.module.__name__[len('bzrlib.plugins.'):]