/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-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

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 = ''
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):
439
415
            trace.print_exception(sys.exc_info(), sys.stderr)
440
416
        # GZ 2017-06-02: Move this name checking up a level, no point trying
441
417
        # to import things with bad names.
442
 
        if re.search('\\.|-| ', name):
 
418
        if re.search('\.|-| ', name):
443
419
            sanitised_name = re.sub('[-. ]', '_', name)
444
420
            if sanitised_name.startswith('brz_'):
445
421
                sanitised_name = sanitised_name[len('brz_'):]
446
422
            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))
 
423
                    "file path isn't a valid module name; try renaming "
 
424
                    "it to %r." % (name, dir, sanitised_name))
449
425
        else:
450
426
            return record_plugin_warning(
451
427
                'Unable to load plugin %r from %r: %s' % (name, dir, e))
460
436
    for fullname in sys.modules:
461
437
        if fullname.startswith(_MODULE_PREFIX):
462
438
            name = fullname[len(_MODULE_PREFIX):]
463
 
            if "." not in name and sys.modules[fullname] is not None:
 
439
            if not "." in name and sys.modules[fullname] is not None:
464
440
                result[name] = PlugIn(name, sys.modules[fullname])
465
441
    return result
466
442
 
467
443
 
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
444
def format_concise_plugin_list(state=None):
483
445
    """Return a string holding a concise list of plugins and their version.
484
446
    """
485
447
    if state is None:
486
 
        state = breezy.get_global_state()
 
448
        state = breezy.global_state
487
449
    items = []
488
 
    for name, a_plugin in sorted(getattr(state, 'plugins', {}).items()):
 
450
    for name, a_plugin in sorted(state.plugins.items()):
489
451
        items.append("%s[%s]" %
490
 
                     (name, a_plugin.__version__))
 
452
            (name, a_plugin.__version__))
491
453
    return ', '.join(items)
492
454
 
493
455