~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugin.py

merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
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
63
63
_plugins_disabled = False
64
64
 
65
65
 
 
66
plugin_warnings = {}
 
67
# Map from plugin name, to list of string warnings about eg plugin
 
68
# dependencies.
 
69
 
 
70
 
66
71
def are_plugins_disabled():
67
72
    return _plugins_disabled
68
73
 
77
82
    load_plugins([])
78
83
 
79
84
 
 
85
def describe_plugins(show_paths=False):
 
86
    """Generate text description of plugins.
 
87
 
 
88
    Includes both those that have loaded, and those that failed to 
 
89
    load.
 
90
 
 
91
    :param show_paths: If true,
 
92
    :returns: Iterator of text lines (including newlines.)
 
93
    """
 
94
    from inspect import getdoc
 
95
    loaded_plugins = plugins()
 
96
    all_names = sorted(list(set(
 
97
        loaded_plugins.keys() + plugin_warnings.keys())))
 
98
    for name in all_names:
 
99
        if name in loaded_plugins:
 
100
            plugin = loaded_plugins[name]
 
101
            version = plugin.__version__
 
102
            if version == 'unknown':
 
103
                version = ''
 
104
            yield '%s %s\n' % (name, version)
 
105
            d = getdoc(plugin.module)
 
106
            if d:
 
107
                doc = d.split('\n')[0]
 
108
            else:
 
109
                doc = '(no description)'
 
110
            yield ("  %s\n" % doc)
 
111
            if show_paths:
 
112
                yield ("   %s\n" % plugin.path())
 
113
            del plugin
 
114
        else:
 
115
            yield "%s (failed to load)\n" % name
 
116
        if name in plugin_warnings:
 
117
            for line in plugin_warnings[name]:
 
118
                yield "  ** " + line + '\n'
 
119
        yield '\n'
 
120
 
 
121
 
80
122
def _strip_trailing_sep(path):
81
123
    return path.rstrip("\\/")
82
124
 
327
369
    return None, None, (None, None, None)
328
370
 
329
371
 
 
372
def record_plugin_warning(plugin_name, warning_message):
 
373
    trace.mutter(warning_message)
 
374
    plugin_warnings.setdefault(plugin_name, []).append(warning_message)
 
375
 
 
376
 
330
377
def _load_plugin_module(name, dir):
331
378
    """Load plugin name from dir.
332
379
 
340
387
    except KeyboardInterrupt:
341
388
        raise
342
389
    except errors.IncompatibleAPI, e:
343
 
        trace.warning("Unable to load plugin %r. It requested API version "
 
390
        warning_message = (
 
391
            "Unable to load plugin %r. It requested API version "
344
392
            "%s of module %s but the minimum exported version is %s, and "
345
393
            "the maximum is %s" %
346
394
            (name, e.wanted, e.api, e.minimum, e.current))
 
395
        record_plugin_warning(name, warning_message)
347
396
    except Exception, e:
348
397
        trace.warning("%s" % e)
349
398
        if re.search('\.|-| ', name):
354
403
                    "file path isn't a valid module name; try renaming "
355
404
                    "it to %r." % (name, dir, sanitised_name))
356
405
        else:
357
 
            trace.warning('Unable to load plugin %r from %r' % (name, dir))
 
406
            record_plugin_warning(
 
407
                name,
 
408
                'Unable to load plugin %r from %r' % (name, dir))
358
409
        trace.log_exception_quietly()
359
410
        if 'error' in debug.debug_flags:
360
411
            trace.print_exception(sys.exc_info(), sys.stderr)