mercurial/extensions.py
author Pierre-Yves David <pierre-yves.david@fb.com>
Tue, 20 Oct 2015 15:55:04 +0200
changeset 26795 dff05b3f47d2
parent 26781 1aee2ab0f902
child 27111 9de814b35808
permissions -rw-r--r--
applybundle: take url as argument We allow specifying the url to carry it to hooks. This gets us closer to 'bundle1.apply(...)' and will allow us to remove regressions in multiple place where we forget to pass the url to hooks.
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
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     8
from __future__ import absolute_import
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    10
import imp
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
import os
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    12
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
from .i18n import (
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
    _,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    15
    gettext,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    16
)
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    17
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    18
from . import (
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    19
    cmdutil,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    20
    error,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    21
    util,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    22
)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
_extensions = {}
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
    25
_aftercallbacks = {}
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    26
_order = []
20622
352abbb0be88 extensions: remove the inotify extension (BC)
Matt Mackall <mpm@selenic.com>
parents: 19777
diff changeset
    27
_ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg', 'inotify']
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    28
19777
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    29
def extensions(ui=None):
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    30
    if ui:
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    31
        def enabled(name):
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    32
            for format in ['%s', 'hgext.%s']:
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    33
                conf = ui.config('extensions', format % name)
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    34
                if conf is not None and not conf.startswith('!'):
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    35
                    return True
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    36
    else:
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    37
        enabled = lambda name: True
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    38
    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
    39
        module = _extensions[name]
19777
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
    40
        if module and enabled(name):
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
    41
            yield name, module
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
def find(name):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
    '''return module with given extension name'''
14415
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
    45
    mod = None
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    try:
14415
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
    47
        mod =  _extensions[name]
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
    except KeyError:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
        for k, v in _extensions.iteritems():
4560
3daed3680554 extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents: 4558
diff changeset
    50
            if k.endswith('.' + name) or k.endswith('/' + name):
14415
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
    51
                mod = v
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
    52
                break
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
    53
    if not mod:
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
        raise KeyError(name)
14415
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
    55
    return mod
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    57
def loadpath(path, module_name):
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    58
    module_name = module_name.replace('.', '_')
20645
7d83c3b6e8d9 extensions: use normpath to allow trailing '\' on Windows (issue4187)
Ed Morley <emorley@mozilla.com>
parents: 20622
diff changeset
    59
    path = util.normpath(util.expandpath(path))
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    60
    if os.path.isdir(path):
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    61
        # module/__init__.py style
20645
7d83c3b6e8d9 extensions: use normpath to allow trailing '\' on Windows (issue4187)
Ed Morley <emorley@mozilla.com>
parents: 20622
diff changeset
    62
        d, f = os.path.split(path)
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    63
        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
    64
        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
    65
    else:
17217
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 16709
diff changeset
    66
        try:
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 16709
diff changeset
    67
            return imp.load_source(module_name, path)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25364
diff changeset
    68
        except IOError as exc:
17217
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 16709
diff changeset
    69
            if not exc.filename:
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 16709
diff changeset
    70
                exc.filename = path # python does not fill this
1b2b727a885f hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents: 16709
diff changeset
    71
            raise
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    72
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
def load(ui, name, path):
7011
7da76778dbd7 Do not try to load extensions twice (issue811)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6212
diff changeset
    74
    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
    75
        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
    76
    else:
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    77
        shortname = name
13349
0d3f35394af4 extensions: add an ignore list for old extensions
Matt Mackall <mpm@selenic.com>
parents: 13191
diff changeset
    78
    if shortname in _ignore:
0d3f35394af4 extensions: add an ignore list for old extensions
Matt Mackall <mpm@selenic.com>
parents: 13191
diff changeset
    79
        return None
5031
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
    80
    if shortname in _extensions:
12779
891ddf76b73e extensions.load: return module
Erik Zielke <ez@aragost.com>
parents: 11521
diff changeset
    81
        return _extensions[shortname]
5087
b3cc62268a91 Cache extension load failures.
Brendan Cully <brendan@kublai.com>
parents: 4635
diff changeset
    82
    _extensions[shortname] = None
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
    if path:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
        # the module will be loaded in sys.modules
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
        # 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
    86
        # conflicts with other modules
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
    87
        mod = loadpath(path, 'hgext.%s' % name)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
    else:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
        def importh(name):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
            mod = __import__(name)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
            components = name.split('.')
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
            for comp in components[1:]:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
                mod = getattr(mod, comp)
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
            return mod
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
        try:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    96
            mod = importh("hgext.%s" % name)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25364
diff changeset
    97
        except ImportError as err:
15199
56da00994067 extensions: print some debug info on import failure
Greg Ward <greg@gerg.ca>
parents: 14943
diff changeset
    98
            ui.debug('could not import hgext.%s (%s): trying %s\n'
56da00994067 extensions: print some debug info on import failure
Greg Ward <greg@gerg.ca>
parents: 14943
diff changeset
    99
                     % (name, err, name))
25364
de23a552fc23 extensions: show traceback on load failure if --traceback flag is set
Yuya Nishihara <yuya@tcha.org>
parents: 24950
diff changeset
   100
            if ui.debugflag:
de23a552fc23 extensions: show traceback on load failure if --traceback flag is set
Yuya Nishihara <yuya@tcha.org>
parents: 24950
diff changeset
   101
                ui.traceback()
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
            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
   103
    _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
   104
    _order.append(shortname)
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   105
    for fn in _aftercallbacks.get(shortname, []):
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   106
        fn(loaded=True)
12779
891ddf76b73e extensions.load: return module
Erik Zielke <ez@aragost.com>
parents: 11521
diff changeset
   107
    return mod
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   108
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   109
def loadall(ui):
4617
669e76b7df24 extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents: 4582
diff changeset
   110
    result = ui.configitems("extensions")
9410
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
   111
    newindex = len(_order)
7876
53c72ba36c2b cleanup: drop enumerate() when index is not used
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7644
diff changeset
   112
    for (name, path) in result:
4617
669e76b7df24 extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents: 4582
diff changeset
   113
        if path:
5469
b12432b1c2c7 Allow explicit disabling of extensions
Steve Borho <steve@borho.org>
parents: 5192
diff changeset
   114
            if path[0] == '!':
b12432b1c2c7 Allow explicit disabling of extensions
Steve Borho <steve@borho.org>
parents: 5192
diff changeset
   115
                continue
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   116
        try:
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
            load(ui, name, path)
7644
182b7114d35a error: move SignalInterrupt
Matt Mackall <mpm@selenic.com>
parents: 7388
diff changeset
   118
        except KeyboardInterrupt:
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   119
            raise
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25364
diff changeset
   120
        except Exception as 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
   121
            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
   122
                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
   123
                        % (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
   124
            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
   125
                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
   126
                        % (name, inst))
25364
de23a552fc23 extensions: show traceback on load failure if --traceback flag is set
Yuya Nishihara <yuya@tcha.org>
parents: 24950
diff changeset
   127
            ui.traceback()
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
9410
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
   129
    for name in _order[newindex:]:
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
   130
        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
   131
        if uisetup:
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
   132
            uisetup(ui)
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
   133
9660
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   134
    for name in _order[newindex:]:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   135
        extsetup = getattr(_extensions[name], 'extsetup', None)
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   136
        if extsetup:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   137
            try:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   138
                extsetup(ui)
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   139
            except TypeError:
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   140
                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
   141
                    raise
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
   142
                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
   143
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   144
    # Call aftercallbacks that were never met.
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   145
    for shortname in _aftercallbacks:
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   146
        if shortname in _extensions:
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   147
            continue
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   148
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   149
        for fn in _aftercallbacks[shortname]:
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   150
            fn(loaded=False)
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   151
24950
e6e7d1cce04d extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24734
diff changeset
   152
    # loadall() is called multiple times and lingering _aftercallbacks
e6e7d1cce04d extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24734
diff changeset
   153
    # entries could result in double execution. See issue4646.
e6e7d1cce04d extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24734
diff changeset
   154
    _aftercallbacks.clear()
e6e7d1cce04d extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24734
diff changeset
   155
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   156
def afterloaded(extension, callback):
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   157
    '''Run the specified function after a named extension is loaded.
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   158
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   159
    If the named extension is already loaded, the callback will be called
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   160
    immediately.
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   161
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   162
    If the named extension never loads, the callback will be called after
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   163
    all extensions have been loaded.
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   164
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   165
    The callback receives the named argument ``loaded``, which is a boolean
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   166
    indicating whether the dependent extension actually loaded.
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   167
    '''
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   168
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   169
    if extension in _extensions:
24145
28af978c8f13 extensions: indicate loaded for an immediately called afterload callback
Matt Harbison <matt_harbison@yahoo.com>
parents: 24124
diff changeset
   170
        callback(loaded=True)
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   171
    else:
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   172
        _aftercallbacks.setdefault(extension, []).append(callback)
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
   173
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   174
def bind(func, *args):
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   175
    '''Partial function application
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   176
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   177
      Returns a new function that is the partial application of args and kwargs
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   178
      to func.  For example,
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   179
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   180
          f(1, 2, bar=3) === bind(f, 1)(2, bar=3)'''
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   181
    assert callable(func)
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   182
    def closure(*a, **kw):
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   183
        return func(*(args + a), **kw)
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   184
    return closure
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   185
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   186
def wrapcommand(table, command, wrapper, synopsis=None, docstring=None):
11519
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   187
    '''Wrap the command named `command' in table
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   188
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   189
    Replace command in the command table with wrapper. The wrapped command will
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   190
    be inserted into the command table specified by the table argument.
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   191
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   192
    The wrapper will be called like
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   193
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   194
      wrapper(orig, *args, **kwargs)
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   195
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   196
    where orig is the original (wrapped) function, and *args, **kwargs
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   197
    are the arguments passed to it.
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   198
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   199
    Optionally append to the command synopsis and docstring, used for help.
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   200
    For example, if your extension wraps the ``bookmarks`` command to add the
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   201
    flags ``--remote`` and ``--all`` you might call this function like so:
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   202
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   203
      synopsis = ' [-a] [--remote]'
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   204
      docstring = """
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   205
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   206
      The ``remotenames`` extension adds the ``--remote`` and ``--all`` (``-a``)
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   207
      flags to the bookmarks command. Either flag will show the remote bookmarks
26781
1aee2ab0f902 spelling: trivial spell checking
Mads Kiilerich <madski@unity3d.com>
parents: 25946
diff changeset
   208
      known to the repository; ``--remote`` will also suppress the output of the
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   209
      local bookmarks.
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   210
      """
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   211
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   212
      extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   213
                             synopsis, docstring)
11519
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
   214
    '''
21795
711498bb4ff5 extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21229
diff changeset
   215
    assert callable(wrapper)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   216
    aliases, entry = cmdutil.findcmd(command, table)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   217
    for alias, e in table.iteritems():
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   218
        if e is entry:
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   219
            key = alias
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   220
            break
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   221
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   222
    origfn = entry[0]
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   223
    wrap = bind(util.checksignature(wrapper), util.checksignature(origfn))
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   224
7373
d9e9dd2b00fb extensions: copy __module__ for wrapped commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7215
diff changeset
   225
    wrap.__module__ = getattr(origfn, '__module__')
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   226
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   227
    doc = getattr(origfn, '__doc__')
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   228
    if docstring is not None:
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   229
        doc += docstring
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   230
    wrap.__doc__ = doc
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   231
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   232
    newentry = list(entry)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   233
    newentry[0] = wrap
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   234
    if synopsis is not None:
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
   235
        newentry[2] += synopsis
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   236
    table[key] = tuple(newentry)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   237
    return entry
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   238
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   239
def wrapfunction(container, funcname, wrapper):
11402
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   240
    '''Wrap the function named funcname in container
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   241
11520
94b3bbc886cf extensions: improve language for wrapfunction() docstring.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11519
diff changeset
   242
    Replace the funcname member in the given container with the specified
94b3bbc886cf extensions: improve language for wrapfunction() docstring.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11519
diff changeset
   243
    wrapper. The container is typically a module, class, or instance.
11402
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   244
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   245
    The wrapper will be called like
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   246
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   247
      wrapper(orig, *args, **kwargs)
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   248
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   249
    where orig is the original (wrapped) function, and *args, **kwargs
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   250
    are the arguments passed to it.
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   251
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   252
    Wrapping methods of the repository object is not recommended since
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   253
    it conflicts with extensions that extend the repository by
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   254
    subclassing. All extensions that need to extend methods of
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   255
    localrepository should use this subclassing trick: namely,
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   256
    reposetup() should look like
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   257
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   258
      def reposetup(ui, repo):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   259
          class myrepo(repo.__class__):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   260
              def whatever(self, *args, **kwargs):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   261
                  [...extension stuff...]
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   262
                  super(myrepo, self).whatever(*args, **kwargs)
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   263
                  [...extension stuff...]
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   264
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   265
          repo.__class__ = myrepo
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   266
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   267
    In general, combining wrapfunction() with subclassing does not
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   268
    work. Since you cannot control what other extensions are loaded by
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   269
    your end users, you should play nicely with others by using the
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   270
    subclass trick.
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
   271
    '''
21795
711498bb4ff5 extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21229
diff changeset
   272
    assert callable(wrapper)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   273
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   274
    origfn = getattr(container, funcname)
21795
711498bb4ff5 extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21229
diff changeset
   275
    assert callable(origfn)
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
   276
    setattr(container, funcname, bind(wrapper, origfn))
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
   277
    return origfn
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   278
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   279
def _disabledpaths(strip_init=False):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   280
    '''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
   281
    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
   282
    import hgext
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   283
    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
   284
    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
   285
        files = os.listdir(extpath)
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   286
    except OSError:
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   287
        return {}
8964
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   288
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   289
    exts = {}
8964
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
   290
    for e in files:
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   291
        if e.endswith('.py'):
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   292
            name = e.rsplit('.', 1)[0]
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   293
            path = os.path.join(extpath, e)
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   294
        else:
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   295
            name = e
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   296
            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
   297
            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
   298
                continue
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   299
            if strip_init:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   300
                path = os.path.dirname(path)
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   301
        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
   302
            continue
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   303
        exts[name] = path
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   304
    return exts
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
   305
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   306
def _moduledoc(file):
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   307
    '''return the top-level python documentation for the given file
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   308
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   309
    Loosely inspired by pydoc.source_synopsis(), but rewritten to
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   310
    handle triple quotes and to return the whole text instead of just
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   311
    the synopsis'''
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   312
    result = []
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   313
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   314
    line = file.readline()
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   315
    while line[:1] == '#' or not line.strip():
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   316
        line = file.readline()
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   317
        if not line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   318
            break
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   319
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   320
    start = line[:3]
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   321
    if start == '"""' or start == "'''":
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   322
        line = line[3:]
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   323
        while line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   324
            if line.rstrip().endswith(start):
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   325
                line = line.split(start)[0]
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   326
                if line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   327
                    result.append(line)
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   328
                break
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   329
            elif not line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   330
                return None # unmatched delimiter
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   331
            result.append(line)
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   332
            line = file.readline()
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   333
    else:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   334
        return None
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   335
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   336
    return ''.join(result)
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   337
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   338
def _disabledhelp(path):
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   339
    '''retrieve help synopsis of a disabled extension (without importing)'''
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   340
    try:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   341
        file = open(path)
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   342
    except IOError:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   343
        return
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   344
    else:
14318
1f46be4689ed help: consolidate topic hooks in help.py
Matt Mackall <mpm@selenic.com>
parents: 14317
diff changeset
   345
        doc = _moduledoc(file)
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   346
        file.close()
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   347
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   348
    if doc: # extracting localized synopsis
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   349
        return gettext(doc).splitlines()[0]
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   350
    else:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   351
        return _('(no help text available)')
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   352
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   353
def disabled():
14530
cd31a1cc1521 extensions: update doc of enabled() and disabled() according to d5b525697ddb
Yuya Nishihara <yuya@tcha.org>
parents: 14415
diff changeset
   354
    '''find disabled extensions from hgext. returns a dict of {name: desc}'''
14539
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   355
    try:
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   356
        from hgext import __index__
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   357
        return dict((name, gettext(desc))
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   358
                    for name, desc in __index__.docs.iteritems()
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   359
                    if name not in _order)
21229
54d7657d7d1e setup.py, make: avoid problems with outdated, existing hgext/__index__.py*
Thomas Arendsen Hein <thomas@intevation.de>
parents: 20645
diff changeset
   360
    except (ImportError, AttributeError):
14539
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   361
        pass
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   362
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   363
    paths = _disabledpaths()
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   364
    if not paths:
16709
9eca39a91964 extensions.disabled: return {} instead of None no extensions are disabled
Augie Fackler <raf@durin42.com>
parents: 16667
diff changeset
   365
        return {}
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   366
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   367
    exts = {}
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   368
    for name, path in paths.iteritems():
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
   369
        doc = _disabledhelp(path)
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
   370
        if doc:
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
   371
            exts[name] = doc
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   372
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
   373
    return exts
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   374
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   375
def disabledext(name):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   376
    '''find a specific disabled extension from hgext. returns desc'''
14539
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   377
    try:
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   378
        from hgext import __index__
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   379
        if name in _order:  # enabled
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   380
            return
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   381
        else:
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   382
            return gettext(__index__.docs.get(name))
21229
54d7657d7d1e setup.py, make: avoid problems with outdated, existing hgext/__index__.py*
Thomas Arendsen Hein <thomas@intevation.de>
parents: 20645
diff changeset
   383
    except (ImportError, AttributeError):
14539
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   384
        pass
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
   385
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   386
    paths = _disabledpaths()
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   387
    if name in paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   388
        return _disabledhelp(paths[name])
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   389
13191
1aea66b71f4f extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents: 12779
diff changeset
   390
def disabledcmd(ui, cmd, strict=False):
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   391
    '''import disabled extensions until cmd is found.
16666
b9bef21cd214 extensions: fix documentation of disabledcmd return value
Augie Fackler <raf@durin42.com>
parents: 15199
diff changeset
   392
    returns (cmdname, extname, module)'''
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   393
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   394
    paths = _disabledpaths(strip_init=True)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   395
    if not paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   396
        raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   397
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   398
    def findcmd(cmd, name, path):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   399
        try:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   400
            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
   401
        except Exception:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   402
            return
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   403
        try:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   404
            aliases, entry = cmdutil.findcmd(cmd,
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   405
                getattr(mod, 'cmdtable', {}), strict)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   406
        except (error.AmbiguousCommand, error.UnknownCommand):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   407
            return
13191
1aea66b71f4f extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents: 12779
diff changeset
   408
        except Exception:
1aea66b71f4f extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents: 12779
diff changeset
   409
            ui.warn(_('warning: error finding commands in %s\n') % path)
1aea66b71f4f extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents: 12779
diff changeset
   410
            ui.traceback()
1aea66b71f4f extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents: 12779
diff changeset
   411
            return
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   412
        for c in aliases:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   413
            if c.startswith(cmd):
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   414
                cmd = c
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   415
                break
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   416
        else:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   417
            cmd = aliases[0]
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   418
        return (cmd, name, mod)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   419
16667
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   420
    ext = None
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   421
    # 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
   422
    path = paths.pop(cmd, None)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   423
    if path:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   424
        ext = findcmd(cmd, cmd, path)
16667
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   425
    if not ext:
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   426
        # otherwise, interrogate each extension until there's a match
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   427
        for name, path in paths.iteritems():
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   428
            ext = findcmd(cmd, name, path)
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   429
            if ext:
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   430
                break
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   431
    if ext and 'DEPRECATED' not in ext.__doc__:
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
   432
        return ext
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   433
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   434
    raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
   435
19769
83d79a00cc24 help: use full name of extensions to look up them for keyword search
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18692
diff changeset
   436
def enabled(shortname=True):
14530
cd31a1cc1521 extensions: update doc of enabled() and disabled() according to d5b525697ddb
Yuya Nishihara <yuya@tcha.org>
parents: 14415
diff changeset
   437
    '''return a dict of {name: desc} of extensions'''
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   438
    exts = {}
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   439
    for ename, ext in extensions():
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
   440
        doc = (gettext(ext.__doc__) or _('(no help text available)'))
19769
83d79a00cc24 help: use full name of extensions to look up them for keyword search
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18692
diff changeset
   441
        if shortname:
83d79a00cc24 help: use full name of extensions to look up them for keyword search
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18692
diff changeset
   442
            ename = ename.split('.')[-1]
9136
31177742f54a for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9020
diff changeset
   443
        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
   444
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
   445
    return exts
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   446
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   447
def moduleversion(module):
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   448
    '''return version information from given module as a string'''
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   449
    if (util.safehasattr(module, 'getversion')
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   450
          and callable(module.getversion)):
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   451
        version = module.getversion()
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   452
    elif util.safehasattr(module, '__version__'):
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   453
        version = module.__version__
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   454
    else:
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   455
        version = ''
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   456
    if isinstance(version, (list, tuple)):
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   457
        version = '.'.join(str(o) for o in version)
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
   458
    return version