/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 breezy/plugin.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-08 23:30:31 UTC
  • mto: This revision was merged to the branch mainline in revision 6690.
  • Revision ID: jelmer@jelmer.uk-20170608233031-3qavls2o7a1pqllj
Update imports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
plugins.
35
35
"""
36
36
 
 
37
from __future__ import absolute_import
 
38
 
37
39
import os
38
40
import re
39
41
import sys
44
46
from .lazy_import import lazy_import
45
47
lazy_import(globals(), """
46
48
import imp
 
49
import importlib
47
50
from importlib import util as importlib_util
48
51
 
49
52
from breezy import (
50
 
    bedding,
 
53
    config,
51
54
    debug,
 
55
    errors,
52
56
    help_topics,
53
57
    trace,
54
58
    )
55
59
""")
56
60
 
57
 
from . import (
58
 
    errors,
59
 
    )
60
 
 
61
61
 
62
62
_MODULE_PREFIX = "breezy.plugins."
63
63
 
64
 
COMPILED_EXT = ".pyc"
 
64
if __debug__ or sys.version_info > (3,):
 
65
    COMPILED_EXT = ".pyc"
 
66
else:
 
67
    COMPILED_EXT = ".pyo"
65
68
 
66
69
 
67
70
def disable_plugins(state=None):
72
75
    :param state: The library state object that records loaded plugins.
73
76
    """
74
77
    if state is None:
75
 
        state = breezy.get_global_state()
 
78
        state = breezy.global_state
76
79
    state.plugins = {}
77
80
 
78
81
 
79
 
def load_plugins(path=None, state=None, warn_load_problems=True):
 
82
def load_plugins(path=None, state=None):
80
83
    """Load breezy plugins.
81
84
 
82
85
    The environment variable BRZ_PLUGIN_PATH is considered a delimited
89
92
    :param state: The library state object that records loaded plugins.
90
93
    """
91
94
    if state is None:
92
 
        state = breezy.get_global_state()
 
95
        state = breezy.global_state
93
96
    if getattr(state, 'plugins', None) is not None:
94
97
        # People can make sure plugins are loaded, they just won't be twice
95
98
        return
99
102
        from breezy.plugins import __path__ as path
100
103
 
101
104
    state.plugin_warnings = {}
102
 
    _load_plugins_from_path(state, path)
103
 
    if (None, 'entrypoints') in _env_plugin_path():
104
 
        _load_plugins_from_entrypoints(state)
 
105
    _load_plugins(state, path)
105
106
    state.plugins = plugins()
106
 
    if warn_load_problems:
107
 
        for plugin, errors in state.plugin_warnings.items():
108
 
            for error in errors:
109
 
                trace.warning('%s', error)
110
 
 
111
 
 
112
 
def _load_plugins_from_entrypoints(state):
113
 
    try:
114
 
        import pkg_resources
115
 
    except ImportError:
116
 
        # No pkg_resources, no entrypoints.
117
 
        pass
118
 
    else:
119
 
        for ep in pkg_resources.iter_entry_points('breezy.plugin'):
120
 
            fullname = _MODULE_PREFIX + ep.name
121
 
            if fullname in sys.modules:
122
 
                continue
123
 
            sys.modules[fullname] = ep.load()
124
107
 
125
108
 
126
109
def plugin_name(module_name):
193
176
def _env_disable_plugins(key='BRZ_DISABLE_PLUGINS'):
194
177
    """Gives list of names for plugins to disable from environ key."""
195
178
    disabled_names = []
196
 
    env = os.environ.get(key)
 
179
    env = osutils.path_from_environ(key)
197
180
    if env:
198
181
        for name in env.split(os.pathsep):
199
182
            name = _expect_identifier(name, key, env)
205
188
def _env_plugins_at(key='BRZ_PLUGINS_AT'):
206
189
    """Gives list of names and paths of specific plugins from environ key."""
207
190
    plugin_details = []
208
 
    env = os.environ.get(key)
 
191
    env = osutils.path_from_environ(key)
209
192
    if env:
210
193
        for pair in env.split(os.pathsep):
211
194
            if '@' in pair:
223
206
    """Gives list of paths and contexts for plugins from environ key.
224
207
 
225
208
    Each entry is either a specific path to load plugins from and the value
226
 
    'path', or None and one of the values 'user', 'core', 'entrypoints', 'site'.
 
209
    'path', or None and one of the three values 'user', 'core', 'site'.
227
210
    """
228
211
    path_details = []
229
 
    env = os.environ.get(key)
230
 
    defaults = {
231
 
        "user": not env,
232
 
        "core": True,
233
 
        "site": True,
234
 
        'entrypoints': False,
235
 
        }
 
212
    env = osutils.path_from_environ(key)
 
213
    defaults = {"user": not env, "core": True, "site": True}
236
214
    if env:
237
215
        # Add paths specified by user in order
238
216
        for p in env.split(os.pathsep):
245
223
                path_details.append((p, 'path'))
246
224
 
247
225
    # Add any remaining default paths
248
 
    for name in ('user', 'core', 'entrypoints', 'site'):
 
226
    for name in ('user', 'core', 'site'):
249
227
        if defaults[name]:
250
228
            path_details.append((None, name))
251
229
 
279
257
        sys.meta_path.insert(2, finder)
280
258
 
281
259
 
282
 
def _load_plugins_from_path(state, paths):
 
260
def _load_plugins(state, paths):
283
261
    """Do the importing all plugins from paths."""
284
262
    imported_names = set()
285
263
    for name, path in _iter_possible_plugins(paths):
354
332
    :returns: Iterator of text lines (including newlines.)
355
333
    """
356
334
    if state is None:
357
 
        state = breezy.get_global_state()
358
 
    loaded_plugins = getattr(state, 'plugins', {})
359
 
    plugin_warnings = set(getattr(state, 'plugin_warnings', []))
360
 
    all_names = sorted(set(loaded_plugins.keys()).union(plugin_warnings))
 
335
        state = breezy.global_state
 
336
    all_names = sorted(set(state.plugins).union(state.plugin_warnings))
361
337
    for name in all_names:
362
 
        if name in loaded_plugins:
363
 
            plugin = loaded_plugins[name]
 
338
        if name in state.plugins:
 
339
            plugin = state.plugins[name]
364
340
            version = plugin.__version__
365
341
            if version == 'unknown':
366
342
                version = ''
387
363
        # We need to use relative path to system-wide plugin
388
364
        # directory because breezy from standalone brz.exe
389
365
        # could be imported by another standalone program
390
 
        # (e.g. brz-config; or TortoiseBzr/Olive if/when they
 
366
        # (e.g. bzr-config; or TortoiseBzr/Olive if/when they
391
367
        # will become standalone exe). [bialix 20071123]
392
368
        # __file__ typically is
393
369
        # C:\Program Files\Bazaar\lib\library.zip\breezy\plugin.pyc
409
385
 
410
386
 
411
387
def get_user_plugin_path():
412
 
    return osutils.pathjoin(bedding.config_dir(), 'plugins')
 
388
    return osutils.pathjoin(config.config_dir(), 'plugins')
413
389
 
414
390
 
415
391
def record_plugin_warning(warning_message):
427
403
        return
428
404
    try:
429
405
        __import__(_MODULE_PREFIX + name)
430
 
    except errors.IncompatibleVersion as e:
 
406
    except errors.IncompatibleAPI as e:
431
407
        warning_message = (
432
 
            "Unable to load plugin %r. It supports %s "
433
 
            "versions %r but the current version is %s" %
434
 
            (name, e.api.__name__, e.wanted, e.current))
 
408
            "Unable to load plugin %r. It requested API version "
 
409
            "%s of module %s but the minimum exported version is %s, and "
 
410
            "the maximum is %s" %
 
411
            (name, e.wanted, e.api, e.minimum, e.current))
435
412
        return record_plugin_warning(warning_message)
436
413
    except Exception as e:
437
414
        trace.log_exception_quietly()
439
416
            trace.print_exception(sys.exc_info(), sys.stderr)
440
417
        # GZ 2017-06-02: Move this name checking up a level, no point trying
441
418
        # to import things with bad names.
442
 
        if re.search('\\.|-| ', name):
 
419
        if re.search('\.|-| ', name):
443
420
            sanitised_name = re.sub('[-. ]', '_', name)
444
421
            if sanitised_name.startswith('brz_'):
445
422
                sanitised_name = sanitised_name[len('brz_'):]
446
423
            trace.warning("Unable to load %r in %r as a plugin because the "
447
 
                          "file path isn't a valid module name; try renaming "
448
 
                          "it to %r." % (name, dir, sanitised_name))
 
424
                    "file path isn't a valid module name; try renaming "
 
425
                    "it to %r." % (name, dir, sanitised_name))
449
426
        else:
450
427
            return record_plugin_warning(
451
428
                'Unable to load plugin %r from %r: %s' % (name, dir, e))
460
437
    for fullname in sys.modules:
461
438
        if fullname.startswith(_MODULE_PREFIX):
462
439
            name = fullname[len(_MODULE_PREFIX):]
463
 
            if "." not in name and sys.modules[fullname] is not None:
 
440
            if not "." in name and sys.modules[fullname] is not None:
464
441
                result[name] = PlugIn(name, sys.modules[fullname])
465
442
    return result
466
443
 
467
444
 
468
 
def get_loaded_plugin(name):
469
 
    """Retrieve an already loaded plugin.
470
 
 
471
 
    Returns None if there is no such plugin loaded
472
 
    """
473
 
    try:
474
 
        module = sys.modules[_MODULE_PREFIX + name]
475
 
    except KeyError:
476
 
        return None
477
 
    if module is None:
478
 
        return None
479
 
    return PlugIn(name, module)
480
 
 
481
 
 
482
 
def format_concise_plugin_list(state=None):
 
445
def format_concise_plugin_list():
483
446
    """Return a string holding a concise list of plugins and their version.
484
447
    """
485
 
    if state is None:
486
 
        state = breezy.get_global_state()
487
448
    items = []
488
 
    for name, a_plugin in sorted(getattr(state, 'plugins', {}).items()):
 
449
    for name, a_plugin in sorted(plugins().items()):
489
450
        items.append("%s[%s]" %
490
 
                     (name, a_plugin.__version__))
 
451
            (name, a_plugin.__version__))
491
452
    return ', '.join(items)
492
453
 
493
454