Mercurial > hg-stable
annotate mercurial/extensions.py @ 42357:38b7b45627a2
extensions: drop support for extsetup() without `ui` argument (API)
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sat, 18 May 2019 19:33:48 -0400 |
parents | 28a4fb793ba1 |
children | 6a3872e34503 |
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 |
38195
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
10 import ast |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
11 import collections |
34104
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
12 import functools |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
13 import imp |
31273
d79761fe697f
extensions: use inspect module instead of func_code.co_argcount
Augie Fackler <raf@durin42.com>
parents:
31091
diff
changeset
|
14 import inspect |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
15 import os |
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 from .i18n import ( |
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 gettext, |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
20 ) |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 from . import ( |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
23 cmdutil, |
33139
c467d13334ee
configitems: add an official API for extensions to register config item
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
33064
diff
changeset
|
24 configitems, |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
25 error, |
30575
c4c51fd0e11d
py3: use pycompat.sysstr() in __import__()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30319
diff
changeset
|
26 pycompat, |
25946
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
27 util, |
5e0d80195a0f
extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
28 ) |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
29 |
37087
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36928
diff
changeset
|
30 from .utils import ( |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36928
diff
changeset
|
31 stringutil, |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36928
diff
changeset
|
32 ) |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36928
diff
changeset
|
33 |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
34 _extensions = {} |
29899
b1ebc767563d
help: show content for explicitly disabled extension (issue5228)
liscju <piotr.listkiewicz@gmail.com>
parents:
29852
diff
changeset
|
35 _disabledextensions = {} |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
36 _aftercallbacks = {} |
5192
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
37 _order = [] |
33526
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
38 _builtin = { |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
39 'hbisect', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
40 'bookmarks', |
33527
6a3e83781c6e
color: drop the now useless color extension
Boris Feld <boris.feld@octobus.net>
parents:
33526
diff
changeset
|
41 'color', |
33526
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
42 'parentrevspec', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
43 'progress', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
44 'interhg', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
45 'inotify', |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
46 'hgcia' |
792d121f22ba
extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents:
33327
diff
changeset
|
47 } |
5192
60acf1432ee0
Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5152
diff
changeset
|
48 |
19777
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
49 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
|
50 if ui: |
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
51 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
|
52 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
|
53 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
|
54 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
|
55 return True |
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
56 else: |
6f72e7d28b35
extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19769
diff
changeset
|
57 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
|
58 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
|
59 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
|
60 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
|
61 yield name, module |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
62 |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
63 def find(name): |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
64 '''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
|
65 mod = None |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
66 try: |
27637
b502138f5faa
cleanup: remove superfluous space after space after equals (python)
timeless <timeless@mozdev.org>
parents:
27142
diff
changeset
|
67 mod = _extensions[name] |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
68 except KeyError: |
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
69 for k, v in _extensions.iteritems(): |
4560
3daed3680554
extensions: fix lookup of hgext.foo modules
Matt Mackall <mpm@selenic.com>
parents:
4558
diff
changeset
|
70 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
|
71 mod = v |
c238b12a1ed4
extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents:
14318
diff
changeset
|
72 break |
c238b12a1ed4
extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents:
14318
diff
changeset
|
73 if not mod: |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
74 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
|
75 return mod |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
76 |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
77 def loadpath(path, module_name): |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
78 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
|
79 path = util.normpath(util.expandpath(path)) |
30580
5ffbaba9acac
py3: use pycompat.fsdecode() to pass to imp.* functions
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30575
diff
changeset
|
80 module_name = pycompat.fsdecode(module_name) |
5ffbaba9acac
py3: use pycompat.fsdecode() to pass to imp.* functions
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30575
diff
changeset
|
81 path = pycompat.fsdecode(path) |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
82 if os.path.isdir(path): |
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
83 # module/__init__.py style |
20645
7d83c3b6e8d9
extensions: use normpath to allow trailing '\' on Windows (issue4187)
Ed Morley <emorley@mozilla.com>
parents:
20622
diff
changeset
|
84 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
|
85 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
|
86 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
|
87 else: |
17217
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
16709
diff
changeset
|
88 try: |
1b2b727a885f
hooks: print out more information when loading a python hook fails
Simon Heimberg <simohe@besonet.ch>
parents:
16709
diff
changeset
|
89 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
|
90 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
|
91 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
|
92 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
|
93 raise |
7916
f779e1996e23
ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7876
diff
changeset
|
94 |
28505
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
95 def _importh(name): |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
96 """import and return the <name> module""" |
30575
c4c51fd0e11d
py3: use pycompat.sysstr() in __import__()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30319
diff
changeset
|
97 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
|
98 components = name.split('.') |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
99 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
|
100 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
|
101 return mod |
d5512a0a8ad6
extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28312
diff
changeset
|
102 |
30058
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
103 def _importext(name, path=None, reportfunc=None): |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
104 if path: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
105 # the module will be loaded in sys.modules |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
106 # choose an unique name so that it doesn't |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
107 # conflicts with other modules |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
108 mod = loadpath(path, 'hgext.%s' % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
109 else: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
110 try: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
111 mod = _importh("hgext.%s" % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
112 except ImportError as err: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
113 if reportfunc: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
114 reportfunc(err, "hgext.%s" % name, "hgext3rd.%s" % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
115 try: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
116 mod = _importh("hgext3rd.%s" % name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
117 except ImportError as err: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
118 if reportfunc: |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
119 reportfunc(err, "hgext3rd.%s" % name, name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
120 mod = _importh(name) |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
121 return mod |
8f54f9b8010d
extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents:
30030
diff
changeset
|
122 |
28506
10252652c6e4
extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28505
diff
changeset
|
123 def _reportimporterror(ui, err, failed, next): |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
124 # note: this ui.log happens before --debug is processed, |
30030
3741a8f86e88
extensions: add a note about debug output during extensions search
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
30029
diff
changeset
|
125 # Use --config ui.debug=1 to see them. |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
126 ui.log(b'extension', b' - could not import %s (%s): trying %s\n', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
127 failed, stringutil.forcebytestr(err), next) |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
128 if ui.debugflag and ui.configbool('devel', 'debug.extensions'): |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
129 ui.traceback() |
28506
10252652c6e4
extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
28505
diff
changeset
|
130 |
36302
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
131 def _rejectunicode(name, xs): |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
132 if isinstance(xs, (list, set, tuple)): |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
133 for x in xs: |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
134 _rejectunicode(name, x) |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
135 elif isinstance(xs, dict): |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
136 for k, v in xs.items(): |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
137 _rejectunicode(name, k) |
37087
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36928
diff
changeset
|
138 _rejectunicode(b'%s.%s' % (name, stringutil.forcebytestr(k)), v) |
36302
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
139 elif isinstance(xs, type(u'')): |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
140 raise error.ProgrammingError(b"unicode %r found in %s" % (xs, name), |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
141 hint="use b'' to make it byte string") |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
142 |
32381
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
143 # attributes set by registrar.command |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
144 _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo') |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
145 |
32382
d47d7d3bd07b
extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents:
32381
diff
changeset
|
146 def _validatecmdtable(ui, cmdtable): |
32381
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
147 """Check if extension commands have required attributes""" |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
148 for c, e in cmdtable.iteritems(): |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
149 f = e[0] |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
150 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:
32380
diff
changeset
|
151 if not missing: |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
152 continue |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
153 raise error.ProgrammingError( |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
154 'missing attributes: %s' % ', '.join(missing), |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
155 hint="use @command decorator to register '%s'" % c) |
e5fbf9687600
extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents:
32380
diff
changeset
|
156 |
36302
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
157 def _validatetables(ui, mod): |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
158 """Sanity check for loadable tables provided by extension module""" |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
159 for t in ['cmdtable', 'colortable', 'configtable']: |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
160 _rejectunicode(t, getattr(mod, t, {})) |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
161 for t in ['filesetpredicate', 'internalmerge', 'revsetpredicate', |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
162 'templatefilter', 'templatefunc', 'templatekeyword']: |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
163 o = getattr(mod, t, None) |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
164 if o: |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
165 _rejectunicode(t, o._table) |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
166 _validatecmdtable(ui, getattr(mod, 'cmdtable', {})) |
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
167 |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
168 def load(ui, name, path, loadingtime=None): |
7011
7da76778dbd7
Do not try to load extensions twice (issue811)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
6212
diff
changeset
|
169 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
|
170 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
|
171 else: |
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
172 shortname = name |
27111
9de814b35808
extensions: rename _ignore to _builtin, add descriptive comment
Bryan O'Sullivan <bos@serpentine.com>
parents:
26781
diff
changeset
|
173 if shortname in _builtin: |
13349
0d3f35394af4
extensions: add an ignore list for old extensions
Matt Mackall <mpm@selenic.com>
parents:
13191
diff
changeset
|
174 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
|
175 if shortname in _extensions: |
12779
891ddf76b73e
extensions.load: return module
Erik Zielke <ez@aragost.com>
parents:
11521
diff
changeset
|
176 return _extensions[shortname] |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
177 ui.log(b'extension', b' - loading extension: %s\n', shortname) |
5087
b3cc62268a91
Cache extension load failures.
Brendan Cully <brendan@kublai.com>
parents:
4635
diff
changeset
|
178 _extensions[shortname] = None |
40505
09a37a5d8f5d
extensions: fix up many many debug logs that use %r
Augie Fackler <augie@google.com>
parents:
39528
diff
changeset
|
179 with util.timedcm('load extension %s', shortname) as stats: |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
180 mod = _importext(name, path, bind(_reportimporterror, ui)) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
181 ui.log(b'extension', b' > %s extension loaded in %s\n', shortname, stats) |
39528
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
182 if loadingtime is not None: |
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
183 loadingtime[shortname] += stats.elapsed |
27142
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
184 |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
185 # 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
|
186 # 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
|
187 # 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
|
188 # of Mercurial. |
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
189 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
|
190 if minver and util.versiontuple(minver, 2) > util.versiontuple(n=2): |
40515
cfa564037789
extensions: include current version in "invalid version" message
Boris Feld <boris.feld@octobus.net>
parents:
40505
diff
changeset
|
191 msg = _('(third party extension %s requires version %s or newer ' |
cfa564037789
extensions: include current version in "invalid version" message
Boris Feld <boris.feld@octobus.net>
parents:
40505
diff
changeset
|
192 'of Mercurial (current: %s); disabling)\n') |
cfa564037789
extensions: include current version in "invalid version" message
Boris Feld <boris.feld@octobus.net>
parents:
40505
diff
changeset
|
193 ui.warn(msg % (shortname, minver, util.version())) |
27142
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
194 return |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
195 ui.log(b'extension', b' - validating extension tables: %s\n', shortname) |
36302
4088e568a411
extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents:
36216
diff
changeset
|
196 _validatetables(ui, mod) |
27142
060f83d219b9
extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27116
diff
changeset
|
197 |
5031
af0995261f02
extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents:
4818
diff
changeset
|
198 _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
|
199 _order.append(shortname) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
200 ui.log(b'extension', b' - invoking registered callbacks: %s\n', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
201 shortname) |
40505
09a37a5d8f5d
extensions: fix up many many debug logs that use %r
Augie Fackler <augie@google.com>
parents:
39528
diff
changeset
|
202 with util.timedcm('callbacks extension %s', shortname) as stats: |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
203 for fn in _aftercallbacks.get(shortname, []): |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
204 fn(loaded=True) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
205 ui.log(b'extension', b' > callbacks completed in %s\n', stats) |
12779
891ddf76b73e
extensions.load: return module
Erik Zielke <ez@aragost.com>
parents:
11521
diff
changeset
|
206 return mod |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
207 |
29461
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
208 def _runuisetup(name, ui): |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
209 uisetup = getattr(_extensions[name], 'uisetup', None) |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
210 if uisetup: |
32744
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
211 try: |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
212 uisetup(ui) |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
213 except Exception as inst: |
34845
78d9a7b7cdb6
extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents:
34199
diff
changeset
|
214 ui.traceback(force=True) |
37087
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36928
diff
changeset
|
215 msg = stringutil.forcebytestr(inst) |
32744
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
216 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:
32742
diff
changeset
|
217 return False |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
218 return True |
29461
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
219 |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
220 def _runextsetup(name, ui): |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
221 extsetup = getattr(_extensions[name], 'extsetup', None) |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
222 if extsetup: |
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
223 try: |
42357
38b7b45627a2
extensions: drop support for extsetup() without `ui` argument (API)
Matt Harbison <matt_harbison@yahoo.com>
parents:
41071
diff
changeset
|
224 extsetup(ui) |
32744
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
225 except Exception as inst: |
34845
78d9a7b7cdb6
extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents:
34199
diff
changeset
|
226 ui.traceback(force=True) |
37087
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36928
diff
changeset
|
227 msg = stringutil.forcebytestr(inst) |
32744
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
228 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:
32742
diff
changeset
|
229 return False |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
230 return True |
29461
7d88fde2309f
extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents:
29162
diff
changeset
|
231 |
32454
9a3e88d4a030
extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents:
32382
diff
changeset
|
232 def loadall(ui, whitelist=None): |
39528
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
233 loadingtime = collections.defaultdict(int) |
4617
669e76b7df24
extensions: pull extension-aware bits out of ui
Matt Mackall <mpm@selenic.com>
parents:
4582
diff
changeset
|
234 result = ui.configitems("extensions") |
32455
f40dc6f7c12f
profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents:
32454
diff
changeset
|
235 if whitelist is not None: |
32454
9a3e88d4a030
extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents:
32382
diff
changeset
|
236 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
|
237 newindex = len(_order) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
238 ui.log(b'extension', b'loading %sextensions\n', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
239 'additional ' if newindex else '') |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
240 ui.log(b'extension', b'- processing %d entries\n', len(result)) |
39286
331ab85e910b
cleanup: make all uses of timedcm specify what they're timing
Augie Fackler <augie@google.com>
parents:
38838
diff
changeset
|
241 with util.timedcm('load all extensions') as stats: |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
242 for (name, path) in result: |
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
|
243 if path: |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
244 if path[0:1] == '!': |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
245 if name not in _disabledextensions: |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
246 ui.log(b'extension', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
247 b' - skipping disabled extension: %s\n', name) |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
248 _disabledextensions[name] = path[1:] |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
249 continue |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
250 try: |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
251 load(ui, name, path, loadingtime) |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
252 except Exception as inst: |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
253 msg = stringutil.forcebytestr(inst) |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
254 if path: |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
255 ui.warn(_("*** failed to import extension %s from %s: %s\n") |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
256 % (name, path, msg)) |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
257 else: |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
258 ui.warn(_("*** failed to import extension %s: %s\n") |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
259 % (name, msg)) |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
260 if isinstance(inst, error.Hint) and inst.hint: |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
261 ui.warn(_("*** (%s)\n") % inst.hint) |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
262 ui.traceback() |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
263 |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
264 ui.log(b'extension', b'> loaded %d extensions, total time %s\n', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
265 len(_order) - newindex, stats) |
34199
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
266 # list of (objname, loadermod, loadername) tuple: |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
267 # - objname is the name of an object in extension module, |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
268 # from which extra information is loaded |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
269 # - loadermod is the module where loader is placed |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
270 # - loadername is the name of the function, |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
271 # which takes (ui, extensionname, extraobj) arguments |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
272 # |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
273 # 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:
34198
diff
changeset
|
274 earlyextraloaders = [ |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
275 ('configtable', configitems, 'loadconfigtable'), |
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
276 ] |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
277 |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
278 ui.log(b'extension', b'- loading configtable attributes\n') |
34199
4c5730c21523
extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents:
34198
diff
changeset
|
279 _loadextra(ui, newindex, earlyextraloaders) |
4544
930ed513c864
Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
280 |
32744
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
281 broken = set() |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
282 ui.log(b'extension', b'- executing uisetup hooks\n') |
39525
1a2bfc4d756a
extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39286
diff
changeset
|
283 with util.timedcm('all uisetup') as alluisetupstats: |
1a2bfc4d756a
extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39286
diff
changeset
|
284 for name in _order[newindex:]: |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
285 ui.log(b'extension', b' - running uisetup for %s\n', name) |
40505
09a37a5d8f5d
extensions: fix up many many debug logs that use %r
Augie Fackler <augie@google.com>
parents:
39528
diff
changeset
|
286 with util.timedcm('uisetup %s', name) as stats: |
39525
1a2bfc4d756a
extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39286
diff
changeset
|
287 if not _runuisetup(name, ui): |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
288 ui.log(b'extension', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
289 b' - the %s extension uisetup failed\n', name) |
39525
1a2bfc4d756a
extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39286
diff
changeset
|
290 broken.add(name) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
291 ui.log(b'extension', b' > uisetup for %s took %s\n', name, stats) |
39528
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
292 loadingtime[name] += stats.elapsed |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
293 ui.log(b'extension', b'> all uisetup took %s\n', alluisetupstats) |
9410
1c83938b6a8e
extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents:
9136
diff
changeset
|
294 |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
295 ui.log(b'extension', b'- executing extsetup hooks\n') |
39526
3a86f7eb8b78
extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39525
diff
changeset
|
296 with util.timedcm('all extsetup') as allextetupstats: |
3a86f7eb8b78
extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39525
diff
changeset
|
297 for name in _order[newindex:]: |
3a86f7eb8b78
extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39525
diff
changeset
|
298 if name in broken: |
3a86f7eb8b78
extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39525
diff
changeset
|
299 continue |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
300 ui.log(b'extension', b' - running extsetup for %s\n', name) |
40505
09a37a5d8f5d
extensions: fix up many many debug logs that use %r
Augie Fackler <augie@google.com>
parents:
39528
diff
changeset
|
301 with util.timedcm('extsetup %s', name) as stats: |
39526
3a86f7eb8b78
extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39525
diff
changeset
|
302 if not _runextsetup(name, ui): |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
303 ui.log(b'extension', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
304 b' - the %s extension extsetup failed\n', name) |
39526
3a86f7eb8b78
extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents:
39525
diff
changeset
|
305 broken.add(name) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
306 ui.log(b'extension', b' > extsetup for %s took %s\n', name, stats) |
39528
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
307 loadingtime[name] += stats.elapsed |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
308 ui.log(b'extension', b'> all extsetup took %s\n', allextetupstats) |
32744
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
309 |
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
310 for name in broken: |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
311 ui.log(b'extension', b' - disabling broken %s extension\n', name) |
32744
ea1c2eb7abd3
extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents:
32742
diff
changeset
|
312 _extensions[name] = None |
9660
e0eae93e6c67
extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents:
9610
diff
changeset
|
313 |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
314 # Call aftercallbacks that were never met. |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
315 ui.log(b'extension', b'- executing remaining aftercallbacks\n') |
39286
331ab85e910b
cleanup: make all uses of timedcm specify what they're timing
Augie Fackler <augie@google.com>
parents:
38838
diff
changeset
|
316 with util.timedcm('aftercallbacks') as stats: |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
317 for shortname in _aftercallbacks: |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
318 if shortname in _extensions: |
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
319 continue |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
320 |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
321 for fn in _aftercallbacks[shortname]: |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
322 ui.log(b'extension', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
323 b' - extension %s not loaded, notify callbacks\n', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
324 shortname) |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
325 fn(loaded=False) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
326 ui.log(b'extension', b'> remaining aftercallbacks completed in %s\n', stats) |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
327 |
24950
e6e7d1cce04d
extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24734
diff
changeset
|
328 # 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
|
329 # 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
|
330 _aftercallbacks.clear() |
e6e7d1cce04d
extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24734
diff
changeset
|
331 |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
332 # delay importing avoids cyclic dependency (especially commands) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
333 from . import ( |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
334 color, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
335 commands, |
33725
50c44dee741a
filemerge: move decorator definition for internal merge tools to registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33708
diff
changeset
|
336 filemerge, |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
337 fileset, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
338 revset, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
339 templatefilters, |
36928
521f6c7e1756
templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36302
diff
changeset
|
340 templatefuncs, |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
341 templatekw, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
342 ) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
343 |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
344 # list of (objname, loadermod, loadername) tuple: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
345 # - 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:
33030
diff
changeset
|
346 # from which extra information is loaded |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
347 # - 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:
33030
diff
changeset
|
348 # - loadername is the name of the function, |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
349 # which takes (ui, extensionname, extraobj) arguments |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
350 ui.log(b'extension', b'- loading extension registration objects\n') |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
351 extraloaders = [ |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
352 ('cmdtable', commands, 'loadcmdtable'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
353 ('colortable', color, 'loadcolortable'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
354 ('filesetpredicate', fileset, 'loadpredicate'), |
33725
50c44dee741a
filemerge: move decorator definition for internal merge tools to registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33708
diff
changeset
|
355 ('internalmerge', filemerge, 'loadinternalmerge'), |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
356 ('revsetpredicate', revset, 'loadpredicate'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
357 ('templatefilter', templatefilters, 'loadfilter'), |
36928
521f6c7e1756
templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36302
diff
changeset
|
358 ('templatefunc', templatefuncs, 'loadfunction'), |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
359 ('templatekeyword', templatekw, 'loadkeyword'), |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
360 ] |
39286
331ab85e910b
cleanup: make all uses of timedcm specify what they're timing
Augie Fackler <augie@google.com>
parents:
38838
diff
changeset
|
361 with util.timedcm('load registration objects') as stats: |
38838
d58958676b3c
extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents:
38727
diff
changeset
|
362 _loadextra(ui, newindex, extraloaders) |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
363 ui.log(b'extension', b'> extension registration object loading took %s\n', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
364 stats) |
39528
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
365 |
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
366 # Report per extension loading time (except reposetup) |
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
367 for name in sorted(loadingtime): |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
368 ui.log(b'extension', b'> extension %s take a total of %s to load\n', |
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
369 name, util.timecount(loadingtime[name])) |
39528
1ab185c78cc3
extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents:
39526
diff
changeset
|
370 |
41006
6f2510b581a0
extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents:
40763
diff
changeset
|
371 ui.log(b'extension', b'extension loading complete\n') |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
372 |
34198
f7c9c5d8c7f4
extensions: factor extra data loading out
Boris Feld <boris.feld@octobus.net>
parents:
34143
diff
changeset
|
373 def _loadextra(ui, newindex, extraloaders): |
33064
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
374 for name in _order[newindex:]: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
375 module = _extensions[name] |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
376 if not module: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
377 continue # loading this module failed |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
378 |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
379 for objname, loadermod, loadername in extraloaders: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
380 extraobj = getattr(module, objname, None) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
381 if extraobj is not None: |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
382 getattr(loadermod, loadername)(ui, name, extraobj) |
45b0e9d05ee9
extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33030
diff
changeset
|
383 |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
384 def afterloaded(extension, callback): |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
385 '''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
|
386 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
387 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
|
388 immediately. |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
389 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
390 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
|
391 all extensions have been loaded. |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
392 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
393 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
|
394 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
|
395 ''' |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
396 |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
397 if extension in _extensions: |
33030
80a5d237a4ae
extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents:
32744
diff
changeset
|
398 # 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:
32744
diff
changeset
|
399 loaded = (_extensions[extension] is not None) |
80a5d237a4ae
extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents:
32744
diff
changeset
|
400 callback(loaded=loaded) |
24065
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
401 else: |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
402 _aftercallbacks.setdefault(extension, []).append(callback) |
d8837ad682dd
extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23953
diff
changeset
|
403 |
40763
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
404 def populateui(ui): |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
405 """Run extension hooks on the given ui to populate additional members, |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
406 extend the class dynamically, etc. |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
407 |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
408 This will be called after the configuration is loaded, and/or extensions |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
409 are loaded. In general, it's once per ui instance, but in command-server |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
410 and hgweb, this may be called more than once with the same ui. |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
411 """ |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
412 for name, mod in extensions(ui): |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
413 hook = getattr(mod, 'uipopulate', None) |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
414 if not hook: |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
415 continue |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
416 try: |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
417 hook(ui) |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
418 except Exception as inst: |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
419 ui.traceback(force=True) |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
420 ui.warn(_('*** failed to populate ui by extension %s: %s\n') |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
421 % (name, stringutil.forcebytestr(inst))) |
c93d046d4300
extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents:
40515
diff
changeset
|
422 |
24734
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
423 def bind(func, *args): |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
424 '''Partial function application |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
425 |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
426 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
|
427 to func. For example, |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
428 |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
429 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
|
430 assert callable(func) |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
431 def closure(*a, **kw): |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
432 return func(*(args + a), **kw) |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
433 return closure |
fb6cb1b82f4f
extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents:
24145
diff
changeset
|
434 |
29775
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
435 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
|
436 '''Copy and add some useful attributes to wrapper''' |
34143
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34105
diff
changeset
|
437 try: |
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34105
diff
changeset
|
438 wrap.__name__ = origfn.__name__ |
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34105
diff
changeset
|
439 except AttributeError: |
82bd4c5a81e5
extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents:
34105
diff
changeset
|
440 pass |
28310
01dc11e7191f
extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
28155
diff
changeset
|
441 wrap.__module__ = getattr(origfn, '__module__') |
01dc11e7191f
extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
28155
diff
changeset
|
442 wrap.__doc__ = getattr(origfn, '__doc__') |
28312
24f1d3c70c41
extensions: copy extra __dict__ of original function
Yuya Nishihara <yuya@tcha.org>
parents:
28311
diff
changeset
|
443 wrap.__dict__.update(getattr(origfn, '__dict__', {})) |
29775
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
444 wrap._origfunc = origfn |
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
445 wrap._unboundwrapper = unboundwrapper |
28310
01dc11e7191f
extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
28155
diff
changeset
|
446 |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
447 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
|
448 '''Wrap the command named `command' in table |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
449 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
450 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
|
451 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
|
452 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
453 The wrapper will be called like |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
454 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
455 wrapper(orig, *args, **kwargs) |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
456 |
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
457 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
|
458 are the arguments passed to it. |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
459 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
460 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
|
461 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
|
462 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
|
463 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
464 synopsis = ' [-a] [--remote]' |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
465 docstring = """ |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
466 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
467 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
|
468 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
|
469 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
|
470 local bookmarks. |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
471 """ |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
472 |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
473 extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks, |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
474 synopsis, docstring) |
11519
bbdf1fb1d3e3
extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11402
diff
changeset
|
475 ''' |
21795
711498bb4ff5
extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents:
21229
diff
changeset
|
476 assert callable(wrapper) |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
477 aliases, entry = cmdutil.findcmd(command, table) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
478 for alias, e in table.iteritems(): |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
479 if e is entry: |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
480 key = alias |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
481 break |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
482 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
483 origfn = entry[0] |
34105 | 484 wrap = functools.partial(util.checksignature(wrapper), |
485 util.checksignature(origfn)) | |
29775
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
486 _updatewrapper(wrap, origfn, wrapper) |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
487 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
|
488 wrap.__doc__ += docstring |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
489 |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
490 newentry = list(entry) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
491 newentry[0] = wrap |
24124
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
492 if synopsis is not None: |
042d95beeee8
extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents:
24065
diff
changeset
|
493 newentry[2] += synopsis |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
494 table[key] = tuple(newentry) |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
495 return entry |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
496 |
32742
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
497 def wrapfilecache(cls, propname, wrapper): |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
498 """Wraps a filecache property. |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
499 |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
500 These can't be wrapped using the normal wrapfunction. |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
501 """ |
33857
38a3767975a7
extensions: if on py3 and propname is a bytestr, convert to sysstr
Augie Fackler <augie@google.com>
parents:
33748
diff
changeset
|
502 propname = pycompat.sysstr(propname) |
32742
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
503 assert callable(wrapper) |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
504 for currcls in cls.__mro__: |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
505 if propname in currcls.__dict__: |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
506 origfn = currcls.__dict__[propname].func |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
507 assert callable(origfn) |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
508 def wrap(*args, **kwargs): |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
509 return wrapper(origfn, *args, **kwargs) |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
510 currcls.__dict__[propname].func = wrap |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
511 break |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
512 |
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
513 if currcls is object: |
33858
0646608368a9
extensions: don't give AttributeError bytes message on Python 3
Augie Fackler <augie@google.com>
parents:
33857
diff
changeset
|
514 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:
33857
diff
changeset
|
515 cls, propname)) |
32742
de09138bf0f5
extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents:
32455
diff
changeset
|
516 |
34032
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
517 class wrappedfunction(object): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
518 '''context manager for temporarily wrapping a function''' |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
519 |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
520 def __init__(self, container, funcname, wrapper): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
521 assert callable(wrapper) |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
522 self._container = container |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
523 self._funcname = funcname |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
524 self._wrapper = wrapper |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
525 |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
526 def __enter__(self): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
527 wrapfunction(self._container, self._funcname, self._wrapper) |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
528 |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
529 def __exit__(self, exctype, excvalue, traceback): |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
530 unwrapfunction(self._container, self._funcname, self._wrapper) |
47e52f079a57
extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents:
33858
diff
changeset
|
531 |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
532 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
|
533 '''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
|
534 |
11520
94b3bbc886cf
extensions: improve language for wrapfunction() docstring.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11519
diff
changeset
|
535 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
|
536 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
|
537 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
538 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
|
539 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
540 wrapper(orig, *args, **kwargs) |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
541 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
542 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
|
543 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
|
544 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
545 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
|
546 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
|
547 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
|
548 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
|
549 reposetup() should look like |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
550 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
551 def reposetup(ui, repo): |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
552 class myrepo(repo.__class__): |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
553 def whatever(self, *args, **kwargs): |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
554 [...extension stuff...] |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
555 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
|
556 [...extension stuff...] |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
557 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
558 repo.__class__ = myrepo |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
559 |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
560 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
|
561 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
|
562 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
|
563 subclass trick. |
367ce8514da0
extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents:
10364
diff
changeset
|
564 ''' |
21795
711498bb4ff5
extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents:
21229
diff
changeset
|
565 assert callable(wrapper) |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
566 |
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
567 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
|
568 assert callable(origfn) |
34104
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
569 if inspect.ismodule(container): |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
570 # 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:
34065
diff
changeset
|
571 # "partial" won't insert a frame in traceback. |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
572 wrap = functools.partial(wrapper, origfn) |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
573 else: |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
574 # "partial" cannot be safely used. Emulate its effect by using "bind". |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
575 # The downside is one more frame in traceback. |
5361771f9714
wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents:
34065
diff
changeset
|
576 wrap = bind(wrapper, origfn) |
29775
ce6317dcb944
extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents:
29461
diff
changeset
|
577 _updatewrapper(wrap, origfn, wrapper) |
28311
1b0ef07ba783
extensions: copy attributes to wrapper by wrapfunction()
Yuya Nishihara <yuya@tcha.org>
parents:
28310
diff
changeset
|
578 setattr(container, funcname, wrap) |
7215
0ab5f21c390b
extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents:
7011
diff
changeset
|
579 return origfn |
8871
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
580 |
29777
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
581 def unwrapfunction(container, funcname, wrapper=None): |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
582 '''undo wrapfunction |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
583 |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
584 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:
29776
diff
changeset
|
585 from the chain of wrappers. |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
586 |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
587 Return the removed wrapper. |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
588 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:
29776
diff
changeset
|
589 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:
29776
diff
changeset
|
590 ''' |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
591 chain = getwrapperchain(container, funcname) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
592 origfn = chain.pop() |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
593 if wrapper is None: |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
594 wrapper = chain[0] |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
595 chain.remove(wrapper) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
596 setattr(container, funcname, origfn) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
597 for w in reversed(chain): |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
598 wrapfunction(container, funcname, w) |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
599 return wrapper |
19578bb84731
extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents:
29776
diff
changeset
|
600 |
29776
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
601 def getwrapperchain(container, funcname): |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
602 '''get a chain of wrappers of a function |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
603 |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
604 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:
29775
diff
changeset
|
605 |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
606 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:
29775
diff
changeset
|
607 argument is origfunc. |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
608 ''' |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
609 result = [] |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
610 fn = getattr(container, funcname) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
611 while fn: |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
612 assert callable(fn) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
613 result.append(getattr(fn, '_unboundwrapper', fn)) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
614 fn = getattr(fn, '_origfunc', None) |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
615 return result |
8bf97c4c6c2a
extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents:
29775
diff
changeset
|
616 |
38196
b39958d6b81b
extensions: remove strip_init=True from _disabledpaths()
Yuya Nishihara <yuya@tcha.org>
parents:
38195
diff
changeset
|
617 def _disabledpaths(): |
b39958d6b81b
extensions: remove strip_init=True from _disabledpaths()
Yuya Nishihara <yuya@tcha.org>
parents:
38195
diff
changeset
|
618 '''find paths of disabled extensions. returns a dict of {name: path}''' |
8872
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
619 import hgext |
31091
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30580
diff
changeset
|
620 extpath = os.path.dirname( |
2912b06905dc
py3: use pycompat.fsencode() to convert __file__ to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30580
diff
changeset
|
621 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
|
622 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
|
623 files = os.listdir(extpath) |
119d1f664eae
extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents:
8896
diff
changeset
|
624 except OSError: |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
625 return {} |
8964
119d1f664eae
extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents:
8896
diff
changeset
|
626 |
8871
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
627 exts = {} |
8964
119d1f664eae
extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents:
8896
diff
changeset
|
628 for e in files: |
8872
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
629 if e.endswith('.py'): |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
630 name = e.rsplit('.', 1)[0] |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
631 path = os.path.join(extpath, e) |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
632 else: |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
633 name = e |
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
634 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
|
635 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
|
636 continue |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
637 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
|
638 continue |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
639 exts[name] = path |
33327
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33139
diff
changeset
|
640 for name, path in _disabledextensions.iteritems(): |
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33139
diff
changeset
|
641 # 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:
33139
diff
changeset
|
642 # 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:
33139
diff
changeset
|
643 if path: |
68b7ceda99d7
dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents:
33139
diff
changeset
|
644 exts[name] = path |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
645 return exts |
8872
d0c0013f8713
extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8871
diff
changeset
|
646 |
14317
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
647 def _moduledoc(file): |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
648 '''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
|
649 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
650 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
|
651 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
|
652 the synopsis''' |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
653 result = [] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
654 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
655 line = file.readline() |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
656 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
|
657 line = file.readline() |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
658 if not line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
659 break |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
660 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
661 start = line[:3] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
662 if start == '"""' or start == "'''": |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
663 line = line[3:] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
664 while line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
665 if line.rstrip().endswith(start): |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
666 line = line.split(start)[0] |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
667 if line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
668 result.append(line) |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
669 break |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
670 elif not line: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
671 return None # unmatched delimiter |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
672 result.append(line) |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
673 line = file.readline() |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
674 else: |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
675 return None |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
676 |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
677 return ''.join(result) |
660b0c1b6196
extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents:
14316
diff
changeset
|
678 |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
679 def _disabledhelp(path): |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
680 '''retrieve help synopsis of a disabled extension (without importing)''' |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
681 try: |
38350
c6f82a18a63d
extensions: use context manger for open()
Yuya Nishihara <yuya@tcha.org>
parents:
38349
diff
changeset
|
682 with open(path, 'rb') as src: |
c6f82a18a63d
extensions: use context manger for open()
Yuya Nishihara <yuya@tcha.org>
parents:
38349
diff
changeset
|
683 doc = _moduledoc(src) |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
684 except IOError: |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
685 return |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
686 |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
687 if doc: # extracting localized synopsis |
30319
5581b294f3c6
help: show help for disabled extensions (issue5228)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30058
diff
changeset
|
688 return gettext(doc) |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
689 else: |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
690 return _('(no help text available)') |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
691 |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
692 def disabled(): |
14530
cd31a1cc1521
extensions: update doc of enabled() and disabled() according to d5b525697ddb
Yuya Nishihara <yuya@tcha.org>
parents:
14415
diff
changeset
|
693 '''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
|
694 try: |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
695 from hgext import __index__ |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
696 return dict((name, gettext(desc)) |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
697 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
|
698 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
|
699 except (ImportError, AttributeError): |
14539
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
700 pass |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
701 |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
702 paths = _disabledpaths() |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
703 if not paths: |
16709
9eca39a91964
extensions.disabled: return {} instead of None no extensions are disabled
Augie Fackler <raf@durin42.com>
parents:
16667
diff
changeset
|
704 return {} |
10363
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
705 |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
706 exts = {} |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
707 for name, path in paths.iteritems(): |
c07974215b3d
extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
708 doc = _disabledhelp(path) |
14316
d5b525697ddb
extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents:
14079
diff
changeset
|
709 if doc: |
30319
5581b294f3c6
help: show help for disabled extensions (issue5228)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30058
diff
changeset
|
710 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
|
711 |
14316
d5b525697ddb
extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents:
14079
diff
changeset
|
712 return exts |
8871
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
713 |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
714 def disabledext(name): |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
715 '''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
|
716 try: |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
717 from hgext import __index__ |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
718 if name in _order: # enabled |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
719 return |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
720 else: |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
721 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
|
722 except (ImportError, AttributeError): |
14539
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
723 pass |
558ec14ba6be
extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents:
14530
diff
changeset
|
724 |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
725 paths = _disabledpaths() |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
726 if name in paths: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
727 return _disabledhelp(paths[name]) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
728 |
38195
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
729 def _walkcommand(node): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
730 """Scan @command() decorators in the tree starting at node""" |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
731 todo = collections.deque([node]) |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
732 while todo: |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
733 node = todo.popleft() |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
734 if not isinstance(node, ast.FunctionDef): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
735 todo.extend(ast.iter_child_nodes(node)) |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
736 continue |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
737 for d in node.decorator_list: |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
738 if not isinstance(d, ast.Call): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
739 continue |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
740 if not isinstance(d.func, ast.Name): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
741 continue |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
742 if d.func.id != r'command': |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
743 continue |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
744 yield d |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
745 |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
746 def _disabledcmdtable(path): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
747 """Construct a dummy command table without loading the extension module |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
748 |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
749 This may raise IOError or SyntaxError. |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
750 """ |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
751 with open(path, 'rb') as src: |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
752 root = ast.parse(src.read(), path) |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
753 cmdtable = {} |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
754 for node in _walkcommand(root): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
755 if not node.args: |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
756 continue |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
757 a = node.args[0] |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
758 if isinstance(a, ast.Str): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
759 name = pycompat.sysbytes(a.s) |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
760 elif pycompat.ispy3 and isinstance(a, ast.Bytes): |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
761 name = a.s |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
762 else: |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
763 continue |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
764 cmdtable[name] = (None, [], b'') |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
765 return cmdtable |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
766 |
38018
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
767 def _finddisabledcmd(ui, cmd, name, path, strict): |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
768 try: |
38195
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
769 cmdtable = _disabledcmdtable(path) |
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
770 except (IOError, SyntaxError): |
38018
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
771 return |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
772 try: |
38195
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
773 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict) |
38018
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
774 except (error.AmbiguousCommand, error.UnknownCommand): |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
775 return |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
776 for c in aliases: |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
777 if c.startswith(cmd): |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
778 cmd = c |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
779 break |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
780 else: |
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
781 cmd = aliases[0] |
38195
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
782 doc = _disabledhelp(path) |
38019
6e526b0961a8
help: load module doc of disabled extension in extensions.disabledcmd()
Yuya Nishihara <yuya@tcha.org>
parents:
38018
diff
changeset
|
783 return (cmd, name, doc) |
38018
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
784 |
13191
1aea66b71f4f
extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents:
12779
diff
changeset
|
785 def disabledcmd(ui, cmd, strict=False): |
38195
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
786 '''find cmd from disabled extensions without importing. |
38019
6e526b0961a8
help: load module doc of disabled extension in extensions.disabledcmd()
Yuya Nishihara <yuya@tcha.org>
parents:
38018
diff
changeset
|
787 returns (cmdname, extname, doc)''' |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
788 |
38195
bdf344aea0ee
extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents:
38062
diff
changeset
|
789 paths = _disabledpaths() |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
790 if not paths: |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
791 raise error.UnknownCommand(cmd) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
792 |
16667
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
793 ext = None |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
794 # 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
|
795 path = paths.pop(cmd, None) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
796 if path: |
38018
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
797 ext = _finddisabledcmd(ui, cmd, cmd, path, strict=strict) |
16667
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
798 if not ext: |
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
799 # 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
|
800 for name, path in paths.iteritems(): |
38018
b45f4c1532c0
extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents:
38017
diff
changeset
|
801 ext = _finddisabledcmd(ui, cmd, name, path, strict=strict) |
16667
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
802 if ext: |
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
803 break |
38017
5b60f7d652f2
extensions: drop dead code trying to exclude deprecated disabled commands
Yuya Nishihara <yuya@tcha.org>
parents:
38001
diff
changeset
|
804 if ext: |
16667
bdb7ae65c27c
extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents:
16666
diff
changeset
|
805 return ext |
10364
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
806 |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
807 raise error.UnknownCommand(cmd) |
de1e7099d100
dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents:
10363
diff
changeset
|
808 |
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
|
809 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
|
810 '''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
|
811 exts = {} |
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
812 for ename, ext in extensions(): |
20a25042fadc
extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents:
8225
diff
changeset
|
813 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
|
814 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
|
815 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
|
816 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
|
817 |
14316
d5b525697ddb
extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents:
14079
diff
changeset
|
818 return exts |
21848
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
819 |
28155
7f430b2ac7fd
extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents:
27990
diff
changeset
|
820 def notloaded(): |
7f430b2ac7fd
extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents:
27990
diff
changeset
|
821 '''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
|
822 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
|
823 |
21848
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
824 def moduleversion(module): |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
825 '''return version information from given module as a string''' |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
826 if (util.safehasattr(module, 'getversion') |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
827 and callable(module.getversion)): |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
828 version = module.getversion() |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
829 elif util.safehasattr(module, '__version__'): |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
830 version = module.__version__ |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
831 else: |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
832 version = '' |
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
833 if isinstance(version, (list, tuple)): |
38062
9d44c71bd892
py3: use pycompat.bytestr() instead of str() in extensions.py
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38019
diff
changeset
|
834 version = '.'.join(pycompat.bytestr(o) for o in version) |
21848
ecdbbb6e5d06
version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents:
21795
diff
changeset
|
835 return version |
27990
96bfd2875213
version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents:
27637
diff
changeset
|
836 |
96bfd2875213
version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents:
27637
diff
changeset
|
837 def ismoduleinternal(module): |
96bfd2875213
version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents:
27637
diff
changeset
|
838 exttestedwith = getattr(module, 'testedwith', None) |
29852
d5883fd055c6
extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents:
29777
diff
changeset
|
839 return exttestedwith == "ships-with-hg-core" |