mercurial/extensions.py
author Brendan Cully <brendan@kublai.com>
Thu, 09 Aug 2007 11:37:47 -0700
changeset 5151 3edd6fedc33a
parent 5031 af0995261f02
parent 5087 b3cc62268a91
child 5152 4f648e95caca
permissions -rw-r--r--
Merge with crew-stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# extensions.py - extension handling for mercurial
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
4569
622d8ed78b47 extensions: load modules in module/__init__.py form.
Brendan Cully <brendan@kublai.com>
parents: 4558
diff changeset
     8
import imp, os
4818
616a5adbf402 extensions: untangle some recursive dependencies
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
     9
import util, sys
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
from i18n import _
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
_extensions = {}
4818
616a5adbf402 extensions: untangle some recursive dependencies
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    13
commandtable = {}
616a5adbf402 extensions: untangle some recursive dependencies
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    14
setuphooks = []
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
def find(name):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
    '''return module with given extension name'''
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
    try:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
        return _extensions[name]
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
    except KeyError:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
        for k, v in _extensions.iteritems():
4560
3daed3680554 extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents: 4558
diff changeset
    22
            if k.endswith('.' + name) or k.endswith('/' + name):
3daed3680554 extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents: 4558
diff changeset
    23
                return v
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
        raise KeyError(name)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
def load(ui, name, path):
5031
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    27
    if name.startswith('hgext.'):
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    28
        shortname = name[6:]
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    29
    else:
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    30
        shortname = name
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    31
    if shortname in _extensions:
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
        return
5087
b3cc62268a91 Cache extension load failures.
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    33
    _extensions[shortname] = None
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
    if path:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
        # the module will be loaded in sys.modules
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
        # choose an unique name so that it doesn't
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
        # conflicts with other modules
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
        module_name = "hgext_%s" % name.replace('.', '_')
4569
622d8ed78b47 extensions: load modules in module/__init__.py form.
Brendan Cully <brendan@kublai.com>
parents: 4558
diff changeset
    39
        if os.path.isdir(path):
622d8ed78b47 extensions: load modules in module/__init__.py form.
Brendan Cully <brendan@kublai.com>
parents: 4558
diff changeset
    40
            # module/__init__.py style
4580
b1716a8b32d3 extensions: fix load of module/__init__.py on OS X
Brendan Cully <brendan@kublai.com>
parents: 4569
diff changeset
    41
            d, f = os.path.split(path)
b1716a8b32d3 extensions: fix load of module/__init__.py on OS X
Brendan Cully <brendan@kublai.com>
parents: 4569
diff changeset
    42
            fd, fpath, desc = imp.find_module(f, [d])
4569
622d8ed78b47 extensions: load modules in module/__init__.py form.
Brendan Cully <brendan@kublai.com>
parents: 4558
diff changeset
    43
            mod = imp.load_module(module_name, fd, fpath, desc)
622d8ed78b47 extensions: load modules in module/__init__.py form.
Brendan Cully <brendan@kublai.com>
parents: 4558
diff changeset
    44
        else:
622d8ed78b47 extensions: load modules in module/__init__.py form.
Brendan Cully <brendan@kublai.com>
parents: 4558
diff changeset
    45
            mod = imp.load_source(module_name, path)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    else:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
        def importh(name):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
            mod = __import__(name)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
            components = name.split('.')
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
            for comp in components[1:]:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
                mod = getattr(mod, comp)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
            return mod
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
        try:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
            mod = importh("hgext.%s" % name)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
        except ImportError:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
            mod = importh(name)
5031
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    57
    _extensions[shortname] = mod
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
    uisetup = getattr(mod, 'uisetup', None)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
    if uisetup:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
        uisetup(ui)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
    reposetup = getattr(mod, 'reposetup', None)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
    if reposetup:
4818
616a5adbf402 extensions: untangle some recursive dependencies
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    64
        setuphooks.append(reposetup)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
    cmdtable = getattr(mod, 'cmdtable', {})
4818
616a5adbf402 extensions: untangle some recursive dependencies
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    66
    overrides = [cmd for cmd in cmdtable if cmd in commandtable]
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
    if overrides:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
        ui.warn(_("extension '%s' overrides commands: %s\n")
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
                % (name, " ".join(overrides)))
4818
616a5adbf402 extensions: untangle some recursive dependencies
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
    70
    commandtable.update(cmdtable)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
def loadall(ui):
4617
669e76b7df24 extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents: 4582
diff changeset
    73
    result = ui.configitems("extensions")
669e76b7df24 extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents: 4582
diff changeset
    74
    for i, (name, path) in enumerate(result):
669e76b7df24 extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents: 4582
diff changeset
    75
        if path:
4633
ff7253a0d1da Cleanup of whitespace, indentation and line continuation.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4617
diff changeset
    76
            path = os.path.expanduser(path)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
        try:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
            load(ui, name, path)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
        except (util.SignalInterrupt, KeyboardInterrupt):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
            raise
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
        except Exception, inst:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
            ui.warn(_("*** failed to import extension %s: %s\n") %
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
                    (name, inst))
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
            if ui.print_exc():
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
                return 1
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86