Mercurial > hg
annotate mercurial/extensions.py @ 34845:78d9a7b7cdb6
extensions: always include traceback when extension setup fails
I have spent a lot of time debugging extensions that failed to load
because we don't include a traceback and I didn't realize I could get
traceback for the extension failure with --traceback. Let's just turn
them on by default, since it should be rare that the user sees these
tracebacks anyway (and if they do, it's not so bad if the extra
traceback pushes them a little harder to report the problem).
Since we already had a test case with --traceback and one without, I
just removed the one with the flag.
Differential Revision: https://phab.mercurial-scm.org/D1164
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Tue, 17 Oct 2017 10:31:44 -0700 |
parents | 4c5730c21523 |
children | 646002338365 |
rev | line source |
---|---|
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 | 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 |
34087
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
10 import functools |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
11 import imp |
31263
d79761fe697f
extensions: use inspect module instead of func_code.co_argcount
Augie Fackler <raf@durin42.com>
parents:
31074
diff
changeset
|
12 import inspect |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
13 import os |
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 from .i18n import ( |
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 gettext, |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
18 ) |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
19 |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
20 from . import ( |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 cmdutil, |
33132
c467d13334ee
configitems: add an official API for extensions to register config item
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
33052
diff
changeset
|
22 configitems, |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
23 error, |
30570
c4c51fd0e11d
py3: use pycompat.sysstr() in __import__()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30306
diff
changeset
|
24 pycompat, |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
25 util, |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
26 ) |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
27 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
28 _extensions = {} |
29895
b1ebc767563d
help: show content for explicitly disabled extension (issue5228)
liscju <piotr.listkiewicz@gmail.com>
parents:
29841
diff
changeset
|
29 _disabledextensions = {} |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
30 _aftercallbacks = {} |
5192
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
31 _order = [] |
33526
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
32 _builtin = { |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
33 'hbisect', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
34 'bookmarks', |
33527
6a3e83781c6e
color: drop the now useless color extension
Boris Feld <boris.feld@octobus.net>
parents:
33526
diff
changeset
|
35 'color', |
33526
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
36 'parentrevspec', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
37 'progress', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
38 'interhg', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
39 'inotify', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
40 'hgcia' |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
41 } |
5192
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
42 |
19777
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
43 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
|
44 if ui: |
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
45 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
|
46 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
|
47 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
|
48 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
|
49 return True |
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
50 else: |
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
51 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
|
52 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
|
53 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
|
54 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
|
55 yield name, module |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
56 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
57 def find(name): |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
58 '''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
|
59 mod = None |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
60 try: |
27637
b502138f5faa
cleanup: remove superfluous space after space after equals (python)
timeless <timeless@mozdev.org>
parents:
27142
diff
changeset
|
61 mod = _extensions[name] |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
62 except KeyError: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
63 for k, v in _extensions.iteritems(): |
4560
3daed3680554
extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents:
4558
diff
changeset
|
64 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
|
65 mod = v |
c238b12a1ed4
extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents:
14318
diff
changeset
|
66 break |
c238b12a1ed4
extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents:
14318
diff
changeset
|
67 if not mod: |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
68 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
|
69 return mod |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
70 |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
71 def loadpath(path, module_name): |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
72 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
|
73 path = util.normpath(util.expandpath(path)) |
30575
5ffbaba9acac
py3: use pycompat.fsdecode() to pass to imp.* functions
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30570
diff
changeset
|
74 module_name = pycompat.fsdecode(module_name) |
5ffbaba9acac
py3: use pycompat.fsdecode() to pass to imp.* functions
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30570
diff
changeset
|
75 path = pycompat.fsdecode(path) |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
76 if os.path.isdir(path): |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
77 # module/__init__.py style |
20645
7d83c3b6e8d9
extensions: use normpath to allow trailing '\' on Windows (issue4187)
Ed Morley <emorley@mozilla.com>
parents:
20622
diff
changeset
|
78 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
|
79 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
|
80 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
|
81 else: |
17217
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
16709
diff
changeset
|
82 try: |
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
16709
diff
changeset
|
83 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
|
84 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
|
85 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
|
86 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
|
87 raise |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
88 |
28505
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
89 def _importh(name): |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
90 """import and return the <name> module""" |
30570
c4c51fd0e11d
py3: use pycompat.sysstr() in __import__()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30306
diff
changeset
|
91 mod = __import__(pycompat.sysstr(name)) |
28505
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
92 components = name.split('.') |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
93 for comp in components[1:]: |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
94 mod = getattr(mod, comp) |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
95 return mod |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
96 |
30058
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
97 def _importext(name, path=None, reportfunc=None): |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
98 if path: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
99 # the module will be loaded in sys.modules |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
100 # choose an unique name so that it doesn't |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
101 # conflicts with other modules |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
102 mod = loadpath(path, 'hgext.%s' % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
103 else: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
104 try: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
105 mod = _importh("hgext.%s" % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
106 except ImportError as err: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
107 if reportfunc: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
108 reportfunc(err, "hgext.%s" % name, "hgext3rd.%s" % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
109 try: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
110 mod = _importh("hgext3rd.%s" % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
111 except ImportError as err: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
112 if reportfunc: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
113 reportfunc(err, "hgext3rd.%s" % name, name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
114 mod = _importh(name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
115 return mod |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
116 |
28506
10252652c6e4
extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28505
diff
changeset
|
117 def _reportimporterror(ui, err, failed, next): |
30028
3741a8f86e88
extensions: add a note about debug output during extensions search
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
30027
diff
changeset
|
118 # note: this ui.debug happens before --debug is processed, |
3741a8f86e88
extensions: add a note about debug output during extensions search
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
30027
diff
changeset
|
119 # Use --config ui.debug=1 to see them. |
28506
10252652c6e4
extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28505
diff
changeset
|
120 ui.debug('could not import %s (%s): trying %s\n' |
33682
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33527
diff
changeset
|
121 % (failed, util.forcebytestr(err), next)) |
28506
10252652c6e4
extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28505
diff
changeset
|
122 if ui.debugflag: |
10252652c6e4
extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28505
diff
changeset
|
123 ui.traceback() |
10252652c6e4
extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28505
diff
changeset
|
124 |
32342
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
125 # attributes set by registrar.command |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
126 _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo') |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
127 |
32343
d47d7d3bd07b
extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents:
32342
diff
changeset
|
128 def _validatecmdtable(ui, cmdtable): |
32342
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
129 """Check if extension commands have required attributes""" |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
130 for c, e in cmdtable.iteritems(): |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
131 f = e[0] |
32343
d47d7d3bd07b
extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents:
32342
diff
changeset
|
132 if getattr(f, '_deprecatedregistrar', False): |
d47d7d3bd07b
extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents:
32342
diff
changeset
|
133 ui.deprecwarn("cmdutil.command is deprecated, use " |
d47d7d3bd07b
extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents:
32342
diff
changeset
|
134 "registrar.command to register '%s'" % c, '4.6') |
32342
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
135 missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)] |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
136 if not missing: |
34048
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
137 for option in e[1]: |
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
138 default = option[2] |
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
139 if isinstance(default, type(u'')): |
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
140 raise error.ProgrammingError( |
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
141 "option '%s.%s' has a unicode default value" |
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
142 % (c, option[1]), |
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
143 hint=("change the %s.%s default value to a " |
0e0ac8f09048
extensions: prohibit unicode defaults
Christophe de Vienne <christophe@cdevienne.info>
parents:
34014
diff
changeset
|
144 "non-unicode string" % (c, option[1]))) |
32342
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
145 continue |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
146 raise error.ProgrammingError( |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
147 'missing attributes: %s' % ', '.join(missing), |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
148 hint="use @command decorator to register '%s'" % c) |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32341
diff
changeset
|
149 |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
150 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
|
151 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
|
152 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
|
153 else: |
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
154 shortname = name |
27111
9de814b35808
extensions: rename _ignore to _builtin, add descriptive comment
Bryan O'Sullivan <bos@serpentine.com>
parents:
26781
diff
changeset
|
155 if shortname in _builtin: |
13349
0d3f35394af4
extensions: add an ignore list for old extensions
Matt Mackall <mpm@selenic.com>
parents:
13191
diff
changeset
|
156 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
|
157 if shortname in _extensions: |
12779
891ddf76b73e
extensions.load: return module
Erik Zielke <ez@aragost.com>
parents:
11521
diff
changeset
|
158 return _extensions[shortname] |
5087
b3cc62268a91
Cache extension load failures.
Brendan Cully <brendan@kublai.com>
parents:
4635
diff
changeset
|
159 _extensions[shortname] = None |
30058
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30028
diff
changeset
|
160 mod = _importext(name, path, bind(_reportimporterror, ui)) |
27142
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
161 |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
162 # Before we do anything with the extension, check against minimum stated |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
163 # compatibility. This gives extension authors a mechanism to have their |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
164 # extensions short circuit when loaded with a known incompatible version |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
165 # of Mercurial. |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
166 minver = getattr(mod, 'minimumhgversion', None) |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
167 if minver and util.versiontuple(minver, 2) > util.versiontuple(n=2): |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
168 ui.warn(_('(third party extension %s requires version %s or newer ' |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
169 'of Mercurial; disabling)\n') % (shortname, minver)) |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
170 return |
32343
d47d7d3bd07b
extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents:
32342
diff
changeset
|
171 _validatecmdtable(ui, getattr(mod, 'cmdtable', {})) |
27142
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
172 |
5031
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
173 _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
|
174 _order.append(shortname) |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
175 for fn in _aftercallbacks.get(shortname, []): |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
176 fn(loaded=True) |
12779
891ddf76b73e
extensions.load: return module
Erik Zielke <ez@aragost.com>
parents:
11521
diff
changeset
|
177 return mod |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
178 |
29461
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
179 def _runuisetup(name, ui): |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
180 uisetup = getattr(_extensions[name], 'uisetup', None) |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
181 if uisetup: |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
182 try: |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
183 uisetup(ui) |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
184 except Exception as inst: |
34845
78d9a7b7cdb6
extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents:
34187
diff
changeset
|
185 ui.traceback(force=True) |
33682
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33527
diff
changeset
|
186 msg = util.forcebytestr(inst) |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
187 ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg)) |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
188 return False |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
189 return True |
29461
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
190 |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
191 def _runextsetup(name, ui): |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
192 extsetup = getattr(_extensions[name], 'extsetup', None) |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
193 if extsetup: |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
194 try: |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
195 try: |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
196 extsetup(ui) |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
197 except TypeError: |
33722
62fbe95075d3
extensions: attempt to use non-deprecated inspect method
Augie Fackler <augie@google.com>
parents:
33699
diff
changeset
|
198 # Try to use getfullargspec (Python 3) first, and fall |
62fbe95075d3
extensions: attempt to use non-deprecated inspect method
Augie Fackler <augie@google.com>
parents:
33699
diff
changeset
|
199 # back to getargspec only if it doesn't exist so as to |
62fbe95075d3
extensions: attempt to use non-deprecated inspect method
Augie Fackler <augie@google.com>
parents:
33699
diff
changeset
|
200 # avoid warnings. |
62fbe95075d3
extensions: attempt to use non-deprecated inspect method
Augie Fackler <augie@google.com>
parents:
33699
diff
changeset
|
201 if getattr(inspect, 'getfullargspec', |
62fbe95075d3
extensions: attempt to use non-deprecated inspect method
Augie Fackler <augie@google.com>
parents:
33699
diff
changeset
|
202 getattr(inspect, 'getargspec'))(extsetup).args: |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
203 raise |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
204 extsetup() # old extsetup with no ui argument |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
205 except Exception as inst: |
34845
78d9a7b7cdb6
extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents:
34187
diff
changeset
|
206 ui.traceback(force=True) |
33682
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33527
diff
changeset
|
207 msg = util.forcebytestr(inst) |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
208 ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg)) |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
209 return False |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
210 return True |
29461
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
211 |
32416
9a3e88d4a030
extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents:
32343
diff
changeset
|
212 def loadall(ui, whitelist=None): |
4617
669e76b7df24
extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents:
4582
diff
changeset
|
213 result = ui.configitems("extensions") |
32417
f40dc6f7c12f
profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents:
32416
diff
changeset
|
214 if whitelist is not None: |
32416
9a3e88d4a030
extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents:
32343
diff
changeset
|
215 result = [(k, v) for (k, v) in result if k in whitelist] |
9410
1c83938b6a8e
extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents:
9136
diff
changeset
|
216 newindex = len(_order) |
7876
53c72ba36c2b
cleanup: drop enumerate() when index is not used
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
7644
diff
changeset
|
217 for (name, path) in result: |
4617
669e76b7df24
extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents:
4582
diff
changeset
|
218 if path: |
31264
063d7957fa12
extensions: use [0:1] slice on config path instead of [0]
Augie Fackler <raf@durin42.com>
parents:
31263
diff
changeset
|
219 if path[0:1] == '!': |
29895
b1ebc767563d
help: show content for explicitly disabled extension (issue5228)
liscju <piotr.listkiewicz@gmail.com>
parents:
29841
diff
changeset
|
220 _disabledextensions[name] = path[1:] |
5469
b12432b1c2c7
Allow explicit disabling of extensions
Steve Borho <steve@borho.org>
parents:
5192
diff
changeset
|
221 continue |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
222 try: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
223 load(ui, name, path) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25364
diff
changeset
|
224 except Exception as inst: |
33682
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33527
diff
changeset
|
225 msg = util.forcebytestr(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
|
226 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
|
227 ui.warn(_("*** failed to import extension %s from %s: %s\n") |
32341
b88d879e468a
extensions: optionally print hint on import failure
Yuya Nishihara <yuya@tcha.org>
parents:
32291
diff
changeset
|
228 % (name, path, msg)) |
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
|
229 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
|
230 ui.warn(_("*** failed to import extension %s: %s\n") |
32341
b88d879e468a
extensions: optionally print hint on import failure
Yuya Nishihara <yuya@tcha.org>
parents:
32291
diff
changeset
|
231 % (name, msg)) |
b88d879e468a
extensions: optionally print hint on import failure
Yuya Nishihara <yuya@tcha.org>
parents:
32291
diff
changeset
|
232 if isinstance(inst, error.Hint) and inst.hint: |
b88d879e468a
extensions: optionally print hint on import failure
Yuya Nishihara <yuya@tcha.org>
parents:
32291
diff
changeset
|
233 ui.warn(_("*** (%s)\n") % inst.hint) |
25364
de23a552fc23
extensions: show traceback on load failure if --traceback flag is set
Yuya Nishihara <yuya@tcha.org>
parents:
24950
diff
changeset
|
234 ui.traceback() |
34187
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
235 # list of (objname, loadermod, loadername) tuple: |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
236 # - objname is the name of an object in extension module, |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
237 # from which extra information is loaded |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
238 # - loadermod is the module where loader is placed |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
239 # - loadername is the name of the function, |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
240 # which takes (ui, extensionname, extraobj) arguments |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
241 # |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
242 # This one is for the list of item that must be run before running any setup |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
243 earlyextraloaders = [ |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
244 ('configtable', configitems, 'loadconfigtable'), |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
245 ] |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34186
diff
changeset
|
246 _loadextra(ui, newindex, earlyextraloaders) |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
247 |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
248 broken = set() |
9410
1c83938b6a8e
extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents:
9136
diff
changeset
|
249 for name in _order[newindex:]: |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
250 if not _runuisetup(name, ui): |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
251 broken.add(name) |
9410
1c83938b6a8e
extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents:
9136
diff
changeset
|
252 |
9660
e0eae93e6c67
extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents:
9610
diff
changeset
|
253 for name in _order[newindex:]: |
32724
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
254 if name in broken: |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
255 continue |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
256 if not _runextsetup(name, ui): |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
257 broken.add(name) |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
258 |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
259 for name in broken: |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32722
diff
changeset
|
260 _extensions[name] = None |
9660
e0eae93e6c67
extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents:
9610
diff
changeset
|
261 |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
262 # Call aftercallbacks that were never met. |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
263 for shortname in _aftercallbacks: |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
264 if shortname in _extensions: |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
265 continue |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
266 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
267 for fn in _aftercallbacks[shortname]: |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
268 fn(loaded=False) |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
269 |
24950
e6e7d1cce04d
extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24734
diff
changeset
|
270 # 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
|
271 # 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
|
272 _aftercallbacks.clear() |
e6e7d1cce04d
extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24734
diff
changeset
|
273 |
33052
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
274 # delay importing avoids cyclic dependency (especially commands) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
275 from . import ( |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
276 color, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
277 commands, |
33699
50c44dee741a
filemerge: move decorator definition for internal merge tools to registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33682
diff
changeset
|
278 filemerge, |
33052
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
279 fileset, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
280 revset, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
281 templatefilters, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
282 templatekw, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
283 templater, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
284 ) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
285 |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
286 # list of (objname, loadermod, loadername) tuple: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
287 # - objname is the name of an object in extension module, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
288 # from which extra information is loaded |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
289 # - loadermod is the module where loader is placed |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
290 # - loadername is the name of the function, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
291 # which takes (ui, extensionname, extraobj) arguments |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
292 extraloaders = [ |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
293 ('cmdtable', commands, 'loadcmdtable'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
294 ('colortable', color, 'loadcolortable'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
295 ('filesetpredicate', fileset, 'loadpredicate'), |
33699
50c44dee741a
filemerge: move decorator definition for internal merge tools to registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33682
diff
changeset
|
296 ('internalmerge', filemerge, 'loadinternalmerge'), |
33052
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
297 ('revsetpredicate', revset, 'loadpredicate'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
298 ('templatefilter', templatefilters, 'loadfilter'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
299 ('templatefunc', templater, 'loadfunction'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
300 ('templatekeyword', templatekw, 'loadkeyword'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
301 ] |
34186
f7c9c5d8c7f4
extensions: factor extra data loading out
Boris Feld <boris.feld@octobus.net>
parents:
34128
diff
changeset
|
302 _loadextra(ui, newindex, extraloaders) |
33052
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
303 |
34186
f7c9c5d8c7f4
extensions: factor extra data loading out
Boris Feld <boris.feld@octobus.net>
parents:
34128
diff
changeset
|
304 def _loadextra(ui, newindex, extraloaders): |
33052
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
305 for name in _order[newindex:]: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
306 module = _extensions[name] |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
307 if not module: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
308 continue # loading this module failed |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
309 |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
310 for objname, loadermod, loadername in extraloaders: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
311 extraobj = getattr(module, objname, None) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
312 if extraobj is not None: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
313 getattr(loadermod, loadername)(ui, name, extraobj) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33014
diff
changeset
|
314 |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
315 def afterloaded(extension, callback): |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
316 '''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
|
317 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
318 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
|
319 immediately. |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
320 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
321 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
|
322 all extensions have been loaded. |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
323 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
324 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
|
325 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
|
326 ''' |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
327 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
328 if extension in _extensions: |
33014
80a5d237a4ae
extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents:
32724
diff
changeset
|
329 # Report loaded as False if the extension is disabled |
80a5d237a4ae
extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents:
32724
diff
changeset
|
330 loaded = (_extensions[extension] is not None) |
80a5d237a4ae
extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents:
32724
diff
changeset
|
331 callback(loaded=loaded) |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
332 else: |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
333 _aftercallbacks.setdefault(extension, []).append(callback) |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
334 |
24734
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
335 def bind(func, *args): |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
336 '''Partial function application |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
337 |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
338 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
|
339 to func. For example, |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
340 |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
341 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
|
342 assert callable(func) |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
343 def closure(*a, **kw): |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
344 return func(*(args + a), **kw) |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
345 return closure |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
346 |
29763
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
347 def _updatewrapper(wrap, origfn, unboundwrapper): |
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
348 '''Copy and add some useful attributes to wrapper''' |
34128
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34088
diff
changeset
|
349 try: |
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34088
diff
changeset
|
350 wrap.__name__ = origfn.__name__ |
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34088
diff
changeset
|
351 except AttributeError: |
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34088
diff
changeset
|
352 pass |
28310
01dc11e7191f
extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
28155
diff
changeset
|
353 wrap.__module__ = getattr(origfn, '__module__') |
01dc11e7191f
extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
28155
diff
changeset
|
354 wrap.__doc__ = getattr(origfn, '__doc__') |
28312
24f1d3c70c41
extensions: copy extra __dict__ of original function
Yuya Nishihara <yuya@tcha.org>
parents:
28311
diff
changeset
|
355 wrap.__dict__.update(getattr(origfn, '__dict__', {})) |
29763
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
356 wrap._origfunc = origfn |
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
357 wrap._unboundwrapper = unboundwrapper |
28310
01dc11e7191f
extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
28155
diff
changeset
|
358 |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
359 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
|
360 '''Wrap the command named `command' in table |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
361 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
362 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
|
363 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
|
364 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
365 The wrapper will be called like |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
366 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
367 wrapper(orig, *args, **kwargs) |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
368 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
369 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
|
370 are the arguments passed to it. |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
371 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
372 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
|
373 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
|
374 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
|
375 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
376 synopsis = ' [-a] [--remote]' |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
377 docstring = """ |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
378 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
379 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
|
380 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
|
381 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
|
382 local bookmarks. |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
383 """ |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
384 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
385 extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks, |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
386 synopsis, docstring) |
11519
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
387 ''' |
21795
711498bb4ff5
extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents:
21229
diff
changeset
|
388 assert callable(wrapper) |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
389 aliases, entry = cmdutil.findcmd(command, table) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
390 for alias, e in table.iteritems(): |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
391 if e is entry: |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
392 key = alias |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
393 break |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
394 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
395 origfn = entry[0] |
34088 | 396 wrap = functools.partial(util.checksignature(wrapper), |
397 util.checksignature(origfn)) | |
29763
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
398 _updatewrapper(wrap, origfn, wrapper) |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
399 if docstring is not None: |
28310
01dc11e7191f
extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
28155
diff
changeset
|
400 wrap.__doc__ += docstring |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
401 |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
402 newentry = list(entry) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
403 newentry[0] = wrap |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
404 if synopsis is not None: |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
405 newentry[2] += synopsis |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
406 table[key] = tuple(newentry) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
407 return entry |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
408 |
32722
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
409 def wrapfilecache(cls, propname, wrapper): |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
410 """Wraps a filecache property. |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
411 |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
412 These can't be wrapped using the normal wrapfunction. |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
413 """ |
33836
38a3767975a7
extensions: if on py3 and propname is a bytestr, convert to sysstr
Augie Fackler <augie@google.com>
parents:
33722
diff
changeset
|
414 propname = pycompat.sysstr(propname) |
32722
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
415 assert callable(wrapper) |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
416 for currcls in cls.__mro__: |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
417 if propname in currcls.__dict__: |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
418 origfn = currcls.__dict__[propname].func |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
419 assert callable(origfn) |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
420 def wrap(*args, **kwargs): |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
421 return wrapper(origfn, *args, **kwargs) |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
422 currcls.__dict__[propname].func = wrap |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
423 break |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
424 |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
425 if currcls is object: |
33837
0646608368a9
extensions: don't give AttributeError bytes message on Python 3
Augie Fackler <augie@google.com>
parents:
33836
diff
changeset
|
426 raise AttributeError(r"type '%s' has no property '%s'" % ( |
0646608368a9
extensions: don't give AttributeError bytes message on Python 3
Augie Fackler <augie@google.com>
parents:
33836
diff
changeset
|
427 cls, propname)) |
32722
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32417
diff
changeset
|
428 |
34014
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
429 class wrappedfunction(object): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
430 '''context manager for temporarily wrapping a function''' |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
431 |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
432 def __init__(self, container, funcname, wrapper): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
433 assert callable(wrapper) |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
434 self._container = container |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
435 self._funcname = funcname |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
436 self._wrapper = wrapper |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
437 |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
438 def __enter__(self): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
439 wrapfunction(self._container, self._funcname, self._wrapper) |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
440 |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
441 def __exit__(self, exctype, excvalue, traceback): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
442 unwrapfunction(self._container, self._funcname, self._wrapper) |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33837
diff
changeset
|
443 |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
444 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
|
445 '''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
|
446 |
11520
94b3bbc886cf
extensions: improve language for wrapfunction() docstring.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11519
diff
changeset
|
447 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
|
448 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
|
449 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
450 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
|
451 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
452 wrapper(orig, *args, **kwargs) |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
453 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
454 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
|
455 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
|
456 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
457 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
|
458 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
|
459 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
|
460 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
|
461 reposetup() should look like |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
462 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
463 def reposetup(ui, repo): |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
464 class myrepo(repo.__class__): |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
465 def whatever(self, *args, **kwargs): |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
466 [...extension stuff...] |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
467 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
|
468 [...extension stuff...] |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
469 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
470 repo.__class__ = myrepo |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
471 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
472 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
|
473 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
|
474 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
|
475 subclass trick. |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
476 ''' |
21795
711498bb4ff5
extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents:
21229
diff
changeset
|
477 assert callable(wrapper) |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
478 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
479 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
|
480 assert callable(origfn) |
34087
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
481 if inspect.ismodule(container): |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
482 # origfn is not an instance or class method. "partial" can be used. |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
483 # "partial" won't insert a frame in traceback. |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
484 wrap = functools.partial(wrapper, origfn) |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
485 else: |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
486 # "partial" cannot be safely used. Emulate its effect by using "bind". |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
487 # The downside is one more frame in traceback. |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34048
diff
changeset
|
488 wrap = bind(wrapper, origfn) |
29763
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
489 _updatewrapper(wrap, origfn, wrapper) |
28311
1b0ef07ba783
extensions: copy attributes to wrapper by wrapfunction()
Yuya Nishihara <yuya@tcha.org>
parents:
28310
diff
changeset
|
490 setattr(container, funcname, wrap) |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
491 return origfn |
8871
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
492 |
29765
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
493 def unwrapfunction(container, funcname, wrapper=None): |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
494 '''undo wrapfunction |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
495 |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
496 If wrappers is None, undo the last wrap. Otherwise removes the wrapper |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
497 from the chain of wrappers. |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
498 |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
499 Return the removed wrapper. |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
500 Raise IndexError if wrapper is None and nothing to unwrap; ValueError if |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
501 wrapper is not None but is not found in the wrapper chain. |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
502 ''' |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
503 chain = getwrapperchain(container, funcname) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
504 origfn = chain.pop() |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
505 if wrapper is None: |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
506 wrapper = chain[0] |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
507 chain.remove(wrapper) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
508 setattr(container, funcname, origfn) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
509 for w in reversed(chain): |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
510 wrapfunction(container, funcname, w) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
511 return wrapper |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29764
diff
changeset
|
512 |
29764
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
513 def getwrapperchain(container, funcname): |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
514 '''get a chain of wrappers of a function |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
515 |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
516 Return a list of functions: [newest wrapper, ..., oldest wrapper, origfunc] |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
517 |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
518 The wrapper functions are the ones passed to wrapfunction, whose first |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
519 argument is origfunc. |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
520 ''' |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
521 result = [] |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
522 fn = getattr(container, funcname) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
523 while fn: |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
524 assert callable(fn) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
525 result.append(getattr(fn, '_unboundwrapper', fn)) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
526 fn = getattr(fn, '_origfunc', None) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
527 return result |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29763
diff
changeset
|
528 |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
529 def _disabledpaths(strip_init=False): |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
530 '''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
|
531 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
|
532 import hgext |
31074
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30575
diff
changeset
|
533 extpath = os.path.dirname( |
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30575
diff
changeset
|
534 os.path.abspath(pycompat.fsencode(hgext.__file__))) |
8964
119d1f664eae
extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents:
8896
diff
changeset
|
535 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
|
536 files = os.listdir(extpath) |
119d1f664eae
extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents:
8896
diff
changeset
|
537 except OSError: |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
538 return {} |
8964
119d1f664eae
extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents:
8896
diff
changeset
|
539 |
8871
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
540 exts = {} |
8964
119d1f664eae
extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents:
8896
diff
changeset
|
541 for e in files: |
8872
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
542 if e.endswith('.py'): |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
543 name = e.rsplit('.', 1)[0] |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
544 path = os.path.join(extpath, e) |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
545 else: |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
546 name = e |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
547 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
|
548 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
|
549 continue |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
550 if strip_init: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
551 path = os.path.dirname(path) |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
552 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
|
553 continue |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
554 exts[name] = path |
33327
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33132
diff
changeset
|
555 for name, path in _disabledextensions.iteritems(): |
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33132
diff
changeset
|
556 # If no path was provided for a disabled extension (e.g. "color=!"), |
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33132
diff
changeset
|
557 # don't replace the path we already found by the scan above. |
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33132
diff
changeset
|
558 if path: |
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33132
diff
changeset
|
559 exts[name] = path |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
560 return exts |
8872
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
561 |
14317
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
562 def _moduledoc(file): |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
563 '''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
|
564 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
565 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
|
566 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
|
567 the synopsis''' |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
568 result = [] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
569 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
570 line = file.readline() |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
571 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
|
572 line = file.readline() |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
573 if not line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
574 break |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
575 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
576 start = line[:3] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
577 if start == '"""' or start == "'''": |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
578 line = line[3:] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
579 while line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
580 if line.rstrip().endswith(start): |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
581 line = line.split(start)[0] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
582 if line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
583 result.append(line) |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
584 break |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
585 elif not line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
586 return None # unmatched delimiter |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
587 result.append(line) |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
588 line = file.readline() |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
589 else: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
590 return None |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
591 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
592 return ''.join(result) |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
593 |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
594 def _disabledhelp(path): |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
595 '''retrieve help synopsis of a disabled extension (without importing)''' |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
596 try: |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
597 file = open(path) |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
598 except IOError: |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
599 return |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
600 else: |
14318
1f46be4689ed
help: consolidate topic hooks in help.py
Matt Mackall <mpm@selenic.com>
parents:
14317
diff
changeset
|
601 doc = _moduledoc(file) |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
602 file.close() |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
603 |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
604 if doc: # extracting localized synopsis |
30306
5581b294f3c6
help: show help for disabled extensions (issue5228)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30058
diff
changeset
|
605 return gettext(doc) |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
606 else: |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
607 return _('(no help text available)') |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
608 |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
609 def disabled(): |
14530
cd31a1cc1521
extensions: update doc of enabled() and disabled() according to d5b525697ddb
Yuya Nishihara <yuya@tcha.org>
parents:
14415
diff
changeset
|
610 '''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
|
611 try: |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
612 from hgext import __index__ |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
613 return dict((name, gettext(desc)) |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
614 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
|
615 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
|
616 except (ImportError, AttributeError): |
14539
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
617 pass |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
618 |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
619 paths = _disabledpaths() |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
620 if not paths: |
16709
9eca39a91964
extensions.disabled: return {} instead of None no extensions are disabled
Augie Fackler <raf@durin42.com>
parents:
16667
diff
changeset
|
621 return {} |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
622 |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
623 exts = {} |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
624 for name, path in paths.iteritems(): |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
625 doc = _disabledhelp(path) |
14316
d5b525697ddb
extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents:
14079
diff
changeset
|
626 if doc: |
30306
5581b294f3c6
help: show help for disabled extensions (issue5228)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30058
diff
changeset
|
627 exts[name] = doc.splitlines()[0] |
8871
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
628 |
14316
d5b525697ddb
extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents:
14079
diff
changeset
|
629 return exts |
8871
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
630 |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
631 def disabledext(name): |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
632 '''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
|
633 try: |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
634 from hgext import __index__ |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
635 if name in _order: # enabled |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
636 return |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
637 else: |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
638 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
|
639 except (ImportError, AttributeError): |
14539
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
640 pass |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
641 |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
642 paths = _disabledpaths() |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
643 if name in paths: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
644 return _disabledhelp(paths[name]) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
645 |
13191
1aea66b71f4f
extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents:
12779
diff
changeset
|
646 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
|
647 '''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
|
648 returns (cmdname, extname, module)''' |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
649 |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
650 paths = _disabledpaths(strip_init=True) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
651 if not paths: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
652 raise error.UnknownCommand(cmd) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
653 |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
654 def findcmd(cmd, name, path): |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
655 try: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
656 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
|
657 except Exception: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
658 return |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
659 try: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
660 aliases, entry = cmdutil.findcmd(cmd, |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
661 getattr(mod, 'cmdtable', {}), strict) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
662 except (error.AmbiguousCommand, error.UnknownCommand): |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
663 return |
13191
1aea66b71f4f
extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents:
12779
diff
changeset
|
664 except Exception: |
1aea66b71f4f
extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents:
12779
diff
changeset
|
665 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
|
666 ui.traceback() |
1aea66b71f4f
extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents:
12779
diff
changeset
|
667 return |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
668 for c in aliases: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
669 if c.startswith(cmd): |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
670 cmd = c |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
671 break |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
672 else: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
673 cmd = aliases[0] |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
674 return (cmd, name, mod) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
675 |
16667
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
676 ext = None |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
677 # 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
|
678 path = paths.pop(cmd, None) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
679 if path: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
680 ext = findcmd(cmd, cmd, path) |
16667
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
681 if not ext: |
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
682 # 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
|
683 for name, path in paths.iteritems(): |
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
684 ext = findcmd(cmd, name, path) |
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
685 if ext: |
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
686 break |
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
687 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
|
688 return ext |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
689 |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
690 raise error.UnknownCommand(cmd) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
691 |
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
|
692 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
|
693 '''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
|
694 exts = {} |
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
695 for ename, ext in extensions(): |
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
696 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
|
697 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
|
698 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
|
699 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
|
700 |
14316
d5b525697ddb
extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents:
14079
diff
changeset
|
701 return exts |
21848
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
702 |
28155
7f430b2ac7fd
extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents:
27990
diff
changeset
|
703 def notloaded(): |
7f430b2ac7fd
extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents:
27990
diff
changeset
|
704 '''return short names of extensions that failed to load''' |
7f430b2ac7fd
extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents:
27990
diff
changeset
|
705 return [name for name, mod in _extensions.iteritems() if mod is None] |
7f430b2ac7fd
extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents:
27990
diff
changeset
|
706 |
21848
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
707 def moduleversion(module): |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
708 '''return version information from given module as a string''' |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
709 if (util.safehasattr(module, 'getversion') |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
710 and callable(module.getversion)): |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
711 version = module.getversion() |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
712 elif util.safehasattr(module, '__version__'): |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
713 version = module.__version__ |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
714 else: |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
715 version = '' |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
716 if isinstance(version, (list, tuple)): |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
717 version = '.'.join(str(o) for o in version) |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
718 return version |
27990
96bfd2875213
version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents:
27637
diff
changeset
|
719 |
96bfd2875213
version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents:
27637
diff
changeset
|
720 def ismoduleinternal(module): |
96bfd2875213
version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents:
27637
diff
changeset
|
721 exttestedwith = getattr(module, 'testedwith', None) |
29841
d5883fd055c6
extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents:
29765
diff
changeset
|
722 return exttestedwith == "ships-with-hg-core" |