mercurial/extensions.py
author Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
Thu, 10 Jun 2010 11:48:15 +0200
changeset 11335 3201ff1459dd
parent 10364 de1e7099d100
child 11402 367ce8514da0
permissions -rw-r--r--
dagparser: parses and formats DAGs as concise text As discussed during the sprint. See the doc comment and doctests for specification and examples. This is used in subsequent patches to export revlog and changelog DAGs, and to generate a repo with a given changelog DAG.
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
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8206
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9679
diff changeset
     6
# GNU General Public License version 2 or any later version.
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
8896
b793ce68f082 extensions: remove import rendered unnecessary by e4e22a310b62
Cédric Duval <cedricduval@free.fr>
parents: 8878
diff changeset
     8
import imp, os
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
     9
import util, cmdutil, help, error
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
    10
from i18n import _, gettext
4544
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 = {}
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    13
_order = []
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    14
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    15
def extensions():
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    16
    for name in _order:
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    17
        module = _extensions[name]
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    18
        if module:
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    19
            yield name, module
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
def find(name):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
    '''return module with given extension name'''
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
    try:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
        return _extensions[name]
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
    except KeyError:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
        for k, v in _extensions.iteritems():
4560
3daed3680554 extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents: 4558
diff changeset
    27
            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
    28
                return v
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
        raise KeyError(name)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    31
def loadpath(path, module_name):
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    32
    module_name = module_name.replace('.', '_')
9610
d78fe60f6bda make path expanding more consistent
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9410
diff changeset
    33
    path = util.expandpath(path)
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    34
    if os.path.isdir(path):
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    35
        # module/__init__.py style
7960
5c794e7331e7 extensions loading: don't fail if path to extension ends with a '/'
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7916
diff changeset
    36
        d, f = os.path.split(path.rstrip('/'))
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    37
        fd, fpath, desc = imp.find_module(f, [d])
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    38
        return imp.load_module(module_name, fd, fpath, desc)
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    39
    else:
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    40
        return imp.load_source(module_name, path)
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    41
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
def load(ui, name, path):
9410
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
    43
    # unused ui argument kept for backwards compatibility
7011
7da76778dbd7 Do not try to load extensions twice (issue811)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6212
diff changeset
    44
    if name.startswith('hgext.') or name.startswith('hgext/'):
5031
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    45
        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
    46
    else:
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    47
        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
    48
    if shortname in _extensions:
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
        return
5087
b3cc62268a91 Cache extension load failures.
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    50
    _extensions[shortname] = None
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
    if path:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
        # the module will be loaded in sys.modules
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
        # 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
    54
        # conflicts with other modules
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    55
        mod = loadpath(path, 'hgext.%s' % name)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
    else:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
        def importh(name):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
            mod = __import__(name)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
            components = name.split('.')
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
            for comp in components[1:]:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
                mod = getattr(mod, comp)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
            return mod
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
        try:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
            mod = importh("hgext.%s" % name)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
        except ImportError:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
            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
    67
    _extensions[shortname] = mod
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    68
    _order.append(shortname)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
def loadall(ui):
4617
669e76b7df24 extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents: 4582
diff changeset
    71
    result = ui.configitems("extensions")
9410
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
    72
    newindex = len(_order)
7876
53c72ba36c2b cleanup: drop enumerate() when index is not used
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7644
diff changeset
    73
    for (name, path) in result:
4617
669e76b7df24 extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents: 4582
diff changeset
    74
        if path:
5469
b12432b1c2c7 Allow explicit disabling of extensions
Steve Borho <steve@borho.org>
parents: 5192
diff changeset
    75
            if path[0] == '!':
b12432b1c2c7 Allow explicit disabling of extensions
Steve Borho <steve@borho.org>
parents: 5192
diff changeset
    76
                continue
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)
7644
182b7114d35a error: move SignalInterrupt
Matt Mackall <mpm@selenic.com>
parents: 7388
diff changeset
    79
        except KeyboardInterrupt:
4544
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:
6204
f8a86ea7521b When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents: 5469
diff changeset
    82
            if path:
f8a86ea7521b When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents: 5469
diff changeset
    83
                ui.warn(_("*** failed to import extension %s from %s: %s\n")
f8a86ea7521b When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents: 5469
diff changeset
    84
                        % (name, path, inst))
f8a86ea7521b When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents: 5469
diff changeset
    85
            else:
f8a86ea7521b When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents: 5469
diff changeset
    86
                ui.warn(_("*** failed to import extension %s: %s\n")
f8a86ea7521b When failing to load an extension, show where Hg tried to load it from.
Jesse Glick <jesse.glick@sun.com>
parents: 5469
diff changeset
    87
                        % (name, inst))
8206
cce63ef1045b ui: print_exc() -> traceback()
Matt Mackall <mpm@selenic.com>
parents: 7960
diff changeset
    88
            if ui.traceback():
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
                return 1
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
9410
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
    91
    for name in _order[newindex:]:
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
    92
        uisetup = getattr(_extensions[name], 'uisetup', None)
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
    93
        if uisetup:
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
    94
            uisetup(ui)
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
    95
9660
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
    96
    for name in _order[newindex:]:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
    97
        extsetup = getattr(_extensions[name], 'extsetup', None)
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
    98
        if extsetup:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
    99
            try:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   100
                extsetup(ui)
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   101
            except TypeError:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   102
                if extsetup.func_code.co_argcount != 0:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   103
                    raise
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   104
                extsetup() # old extsetup with no ui argument
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   105
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   106
def wrapcommand(table, command, wrapper):
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   107
    aliases, entry = cmdutil.findcmd(command, table)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   108
    for alias, e in table.iteritems():
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   109
        if e is entry:
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   110
            key = alias
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   111
            break
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   112
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   113
    origfn = entry[0]
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   114
    def wrap(*args, **kwargs):
7388
5751631246de dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents: 7373
diff changeset
   115
        return util.checksignature(wrapper)(
5751631246de dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents: 7373
diff changeset
   116
            util.checksignature(origfn), *args, **kwargs)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   117
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   118
    wrap.__doc__ = getattr(origfn, '__doc__')
7373
d9e9dd2b00fb extensions: copy __module__ for wrapped commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7215
diff changeset
   119
    wrap.__module__ = getattr(origfn, '__module__')
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   120
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   121
    newentry = list(entry)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   122
    newentry[0] = wrap
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   123
    table[key] = tuple(newentry)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   124
    return entry
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   125
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   126
def wrapfunction(container, funcname, wrapper):
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   127
    def wrap(*args, **kwargs):
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   128
        return wrapper(origfn, *args, **kwargs)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   129
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   130
    origfn = getattr(container, funcname)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   131
    setattr(container, funcname, wrap)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   132
    return origfn
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   133
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   134
def _disabledpaths(strip_init=False):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   135
    '''find paths of disabled extensions. returns a dict of {name: path}
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   136
    removes /__init__.py from packages if strip_init is True'''
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   137
    import hgext
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   138
    extpath = os.path.dirname(os.path.abspath(hgext.__file__))
8964
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   139
    try: # might not be a filesystem path
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   140
        files = os.listdir(extpath)
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   141
    except OSError:
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   142
        return {}
8964
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   143
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   144
    exts = {}
8964
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   145
    for e in files:
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   146
        if e.endswith('.py'):
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   147
            name = e.rsplit('.', 1)[0]
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   148
            path = os.path.join(extpath, e)
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   149
        else:
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   150
            name = e
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   151
            path = os.path.join(extpath, e, '__init__.py')
8877
08636e18268f extensions: check for path existence only when necessary
Cédric Duval <cedricduval@free.fr>
parents: 8876
diff changeset
   152
            if not os.path.exists(path):
08636e18268f extensions: check for path existence only when necessary
Cédric Duval <cedricduval@free.fr>
parents: 8876
diff changeset
   153
                continue
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   154
            if strip_init:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   155
                path = os.path.dirname(path)
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   156
        if name in exts or name in _order or name == '__init__':
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   157
            continue
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   158
        exts[name] = path
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   159
    return exts
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   160
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   161
def _disabledhelp(path):
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   162
    '''retrieve help synopsis of a disabled extension (without importing)'''
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   163
    try:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   164
        file = open(path)
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   165
    except IOError:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   166
        return
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   167
    else:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   168
        doc = help.moduledoc(file)
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   169
        file.close()
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   170
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   171
    if doc: # extracting localized synopsis
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   172
        return gettext(doc).splitlines()[0]
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   173
    else:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   174
        return _('(no help text available)')
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   175
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   176
def disabled():
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   177
    '''find disabled extensions from hgext
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   178
    returns a dict of {name: desc}, and the max name length'''
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   179
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   180
    paths = _disabledpaths()
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   181
    if not paths:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   182
        return None, 0
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   183
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   184
    exts = {}
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   185
    maxlength = 0
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   186
    for name, path in paths.iteritems():
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   187
        doc = _disabledhelp(path)
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   188
        if not doc:
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   189
            continue
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   190
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   191
        exts[name] = doc
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   192
        if len(name) > maxlength:
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   193
            maxlength = len(name)
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   194
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   195
    return exts, maxlength
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   196
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   197
def disabledext(name):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   198
    '''find a specific disabled extension from hgext. returns desc'''
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   199
    paths = _disabledpaths()
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   200
    if name in paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   201
        return _disabledhelp(paths[name])
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   202
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   203
def disabledcmd(cmd, strict=False):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   204
    '''import disabled extensions until cmd is found.
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   205
    returns (cmdname, extname, doc)'''
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   206
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   207
    paths = _disabledpaths(strip_init=True)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   208
    if not paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   209
        raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   210
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   211
    def findcmd(cmd, name, path):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   212
        try:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   213
            mod = loadpath(path, 'hgext.%s' % name)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   214
        except Exception:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   215
            return
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   216
        try:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   217
            aliases, entry = cmdutil.findcmd(cmd,
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   218
                getattr(mod, 'cmdtable', {}), strict)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   219
        except (error.AmbiguousCommand, error.UnknownCommand):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   220
            return
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   221
        for c in aliases:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   222
            if c.startswith(cmd):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   223
                cmd = c
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   224
                break
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   225
        else:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   226
            cmd = aliases[0]
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   227
        return (cmd, name, mod)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   228
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   229
    # first, search for an extension with the same name as the command
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   230
    path = paths.pop(cmd, None)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   231
    if path:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   232
        ext = findcmd(cmd, cmd, path)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   233
        if ext:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   234
            return ext
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   235
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   236
    # otherwise, interrogate each extension until there's a match
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   237
    for name, path in paths.iteritems():
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   238
        ext = findcmd(cmd, name, path)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   239
        if ext:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   240
            return ext
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   241
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   242
    raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   243
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   244
def enabled():
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   245
    '''return a dict of {name: desc} of extensions, and the max name length'''
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   246
    exts = {}
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   247
    maxlength = 0
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   248
    for ename, ext in extensions():
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   249
        doc = (gettext(ext.__doc__) or _('(no help text available)'))
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   250
        ename = ename.split('.')[-1]
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   251
        maxlength = max(len(ename), maxlength)
9136
31177742f54a for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9020
diff changeset
   252
        exts[ename] = doc.splitlines()[0].strip()
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   253
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   254
    return exts, maxlength