/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/plugin.py

  • Committer: John Arbash Meinel
  • Date: 2011-03-15 10:28:20 UTC
  • mto: This revision was merged to the branch mainline in revision 5725.
  • Revision ID: john@arbash-meinel.com-20110315102820-51wy8wjre5ol34mu
'bzr export' needs to use 'exact' encoding.

If we are going to be writing binary bites out of stdout, then it needs to
be in binary mode, or it will corrupt the data stream.
Oddly enough, it only seemed to fail if we set '--verbose'. I didn't
bother to track into that bug.

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
 
83
125
 
 
126
def _get_specific_plugin_paths(paths):
 
127
    """Returns the plugin paths from a string describing the associations.
 
128
 
 
129
    :param paths: A string describing the paths associated with the plugins.
 
130
 
 
131
    :returns: A list of (plugin name, path) tuples.
 
132
 
 
133
    For example, if paths is my_plugin@/test/my-test:her_plugin@/production/her,
 
134
    [('my_plugin', '/test/my-test'), ('her_plugin', '/production/her')] 
 
135
    will be returned.
 
136
 
 
137
    Note that ':' in the example above depends on the os.
 
138
    """
 
139
    if not paths:
 
140
        return []
 
141
    specs = []
 
142
    for spec in paths.split(os.pathsep):
 
143
        try:
 
144
            name, path = spec.split('@')
 
145
        except ValueError:
 
146
            raise errors.BzrCommandError(
 
147
                '"%s" is not a valid <plugin_name>@<plugin_path> description '
 
148
                % spec)
 
149
        specs.append((name, path))
 
150
    return specs
 
151
 
 
152
 
84
153
def set_plugins_path(path=None):
85
154
    """Set the path for plugins to be loaded from.
86
155
 
98
167
        for name in disabled_plugins.split(os.pathsep):
99
168
            PluginImporter.blacklist.add('bzrlib.plugins.' + name)
100
169
    # Set up a the specific paths for plugins
101
 
    specific_plugins = os.environ.get('BZR_PLUGINS_AT', None)
102
 
    if specific_plugins is not None:
103
 
        for spec in specific_plugins.split(os.pathsep):
104
 
            plugin_name, plugin_path = spec.split('@')
 
170
    for plugin_name, plugin_path in _get_specific_plugin_paths(os.environ.get(
 
171
            'BZR_PLUGINS_AT', None)):
105
172
            PluginImporter.specific_paths[
106
173
                'bzrlib.plugins.%s' % plugin_name] = plugin_path
107
174
    return path
302
369
    return None, None, (None, None, None)
303
370
 
304
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
 
305
377
def _load_plugin_module(name, dir):
306
378
    """Load plugin name from dir.
307
379
 
315
387
    except KeyboardInterrupt:
316
388
        raise
317
389
    except errors.IncompatibleAPI, e:
318
 
        trace.warning("Unable to load plugin %r. It requested API version "
 
390
        warning_message = (
 
391
            "Unable to load plugin %r. It requested API version "
319
392
            "%s of module %s but the minimum exported version is %s, and "
320
393
            "the maximum is %s" %
321
394
            (name, e.wanted, e.api, e.minimum, e.current))
 
395
        record_plugin_warning(name, warning_message)
322
396
    except Exception, e:
323
397
        trace.warning("%s" % e)
324
398
        if re.search('\.|-| ', name):
329
403
                    "file path isn't a valid module name; try renaming "
330
404
                    "it to %r." % (name, dir, sanitised_name))
331
405
        else:
332
 
            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))
333
409
        trace.log_exception_quietly()
334
410
        if 'error' in debug.debug_flags:
335
411
            trace.print_exception(sys.exc_info(), sys.stderr)
562
638
        # We are called only for specific paths
563
639
        plugin_path = self.specific_paths[fullname]
564
640
        loading_path = None
565
 
        package = False
566
641
        if os.path.isdir(plugin_path):
567
642
            for suffix, mode, kind in imp.get_suffixes():
568
643
                if kind not in (imp.PY_SOURCE, imp.PY_COMPILED):
570
645
                    continue
571
646
                init_path = osutils.pathjoin(plugin_path, '__init__' + suffix)
572
647
                if os.path.isfile(init_path):
573
 
                    loading_path = init_path
574
 
                    package = True
 
648
                    # We've got a module here and load_module needs specific
 
649
                    # parameters.
 
650
                    loading_path = plugin_path
 
651
                    suffix = ''
 
652
                    mode = ''
 
653
                    kind = imp.PKG_DIRECTORY
575
654
                    break
576
655
        else:
577
656
            for suffix, mode, kind in imp.get_suffixes():
581
660
        if loading_path is None:
582
661
            raise ImportError('%s cannot be loaded from %s'
583
662
                              % (fullname, plugin_path))
584
 
        f = open(loading_path, mode)
 
663
        if kind is imp.PKG_DIRECTORY:
 
664
            f = None
 
665
        else:
 
666
            f = open(loading_path, mode)
585
667
        try:
586
668
            mod = imp.load_module(fullname, f, loading_path,
587
669
                                  (suffix, mode, kind))
588
 
            if package:
589
 
                # The plugin can contain modules, so be ready
590
 
                mod.__path__ = [plugin_path]
591
670
            mod.__package__ = fullname
592
671
            return mod
593
672
        finally:
594
 
            f.close()
 
673
            if f is not None:
 
674
                f.close()
595
675
 
596
676
 
597
677
# Install a dedicated importer for plugins requiring special handling