annotate mercurial/extensions.py @ 52269:8317993a49f1 stable

extensions: allow wrapping a function with a bytes name again This backs out 7b837fabc990 and eda075d7b2ac. The cleanup to transition away from bytes broke JavaHg, which is used by hosting software SCM Manager. I'm not sure who maintains JavaHg these days, so I'm not sure how to get a build out and get everyone to upgrade. Let's revert the change for a quicker fix (and fix an unknown number of other unmaintained extensions), and rely on pytype to flag any potential issues. It's also trivial, so let's not wait until the next feature release (with the added burden for packagers this cycle in dealing with the `setup.py` changes).
author Matt Harbison <matt_harbison@yahoo.com>
date Fri, 07 Feb 2025 19:14:05 -0500
parents f4733654f144
children 42f78c859dd1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Rapha?l Gom?s <rgomes@octobus.net>
parents: 46397
diff changeset
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8206
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9679
diff changeset
6 # GNU General Public License version 2 or any later version.
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
51901
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51762
diff changeset
8 from __future__ import annotations
25946
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
50753
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
13 import importlib
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
50753
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
16 import sys
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
17
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
18 from .i18n import (
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
19 _,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
20 gettext,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
21 )
43087
66f2cc210a29 py3: manually import pycompat.setattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
22 from .pycompat import (
66f2cc210a29 py3: manually import pycompat.setattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
23 open,
66f2cc210a29 py3: manually import pycompat.setattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
24 )
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
25
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
26 from . import (
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
27 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
28 configitems,
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
29 error,
30575
c4c51fd0e11d py3: use pycompat.sysstr() in __import__()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30319
diff changeset
30 pycompat,
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
31 util,
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
32 )
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
33
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
34 from .utils import stringutil
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36928
diff changeset
35
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
36 _extensions = {}
29899
b1ebc767563d help: show content for explicitly disabled extension (issue5228)
liscju <piotr.listkiewicz@gmail.com>
parents: 29852
diff changeset
37 _disabledextensions = {}
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
38 _aftercallbacks = {}
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
39 _order = []
33526
792d121f22ba extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents: 33327
diff changeset
40 _builtin = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
41 b'hbisect',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
42 b'bookmarks',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
43 b'color',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
44 b'parentrevspec',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
45 b'progress',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
46 b'interhg',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
47 b'inotify',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
48 b'hgcia',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
49 b'shelve',
33526
792d121f22ba extensions: expand the builtins extensions declaration
Boris Feld <boris.feld@octobus.net>
parents: 33327
diff changeset
50 }
5192
60acf1432ee0 Move cmdtable and reposetup handling out of extensions.py
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5152
diff changeset
51
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
52
19777
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
53 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
54 if ui:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
55
19777
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
56 def enabled(name):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
57 for format in [b'%s', b'hgext.%s']:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
58 conf = ui.config(b'extensions', format % name)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
59 if conf is not None and not conf.startswith(b'!'):
19777
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
60 return True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
61
19777
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
62 else:
6f72e7d28b35 extensions: list up only enabled extensions, if "ui" is specified
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19769
diff changeset
63 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
64 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
65 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
66 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
67 yield name, module
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
69
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
70 def find(name):
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 '''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
72 mod = None
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73 try:
27637
b502138f5faa cleanup: remove superfluous space after space after equals (python)
timeless <timeless@mozdev.org>
parents: 27142
diff changeset
74 mod = _extensions[name]
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 except KeyError:
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
76 for k, v in _extensions.items():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
77 if k.endswith(b'.' + name) or k.endswith(b'/' + name):
14415
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
78 mod = v
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
79 break
c238b12a1ed4 extensions: raise when trying to find an extension that failed to load
Idan Kamara <idankk86@gmail.com>
parents: 14318
diff changeset
80 if not mod:
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
81 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
82 return mod
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
84
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
85 def loadpath(path, module_name):
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
86 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
87 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
88 path = pycompat.fsdecode(path)
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
89 if os.path.isdir(path):
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
90 # module/__init__.py style
50753
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
91 init_py_path = os.path.join(path, '__init__.py')
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
92 if not os.path.exists(init_py_path):
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
93 raise ImportError("No module named '%s'" % os.path.basename(path))
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
94 path = init_py_path
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
95
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
96 loader = importlib.machinery.SourceFileLoader(module_name, path)
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
97 spec = importlib.util.spec_from_file_location(module_name, loader=loader)
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
98 assert spec is not None # help Pytype
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
99 module = importlib.util.module_from_spec(spec)
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
100 sys.modules[module_name] = module
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
101 spec.loader.exec_module(module)
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50751
diff changeset
102 return module
7916
f779e1996e23 ability to load hooks from arbitrary python module
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7876
diff changeset
103
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
104
28505
d5512a0a8ad6 extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28312
diff changeset
105 def _importh(name):
d5512a0a8ad6 extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28312
diff changeset
106 """import and return the <name> module"""
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
107 mod = __import__(name)
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
108 components = name.split('.')
28505
d5512a0a8ad6 extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28312
diff changeset
109 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
110 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
111 return mod
d5512a0a8ad6 extensions: extract the 'importh' closure as normal function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28312
diff changeset
112
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
113
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
114 def _importext(name, path=None, reportfunc=None):
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
115 name = pycompat.fsdecode(name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
116 if path:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
117 # 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
118 # 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
119 # conflicts with other modules
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
120 mod = loadpath(path, 'hgext.%s' % name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
121 else:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
122 try:
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
123 mod = _importh("hgext.%s" % name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
124 except ImportError as err:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
125 if reportfunc:
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
126 reportfunc(err, "hgext.%s" % name, "hgext3rd.%s" % name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
127 try:
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
128 mod = _importh("hgext3rd.%s" % name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
129 except ImportError as err:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
130 if reportfunc:
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
131 reportfunc(err, "hgext3rd.%s" % name, name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
132 mod = _importh(name)
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
133 return mod
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30030
diff changeset
134
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
135
28506
10252652c6e4 extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28505
diff changeset
136 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
137 # 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
138 # Use --config ui.debug=1 to see them.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
139 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
140 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
141 b' - could not import %s (%s): trying %s\n',
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
142 stringutil.forcebytestr(failed),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
143 stringutil.forcebytestr(err),
50946
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50945
diff changeset
144 stringutil.forcebytestr(next),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
145 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
146 if ui.debugflag and ui.configbool(b'devel', b'debug.extensions'):
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
147 ui.traceback()
28506
10252652c6e4 extensions: factor import error reporting out
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 28505
diff changeset
148
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
149
36302
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
150 def _rejectunicode(name, xs):
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
151 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
152 for x in xs:
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
153 _rejectunicode(name, x)
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
154 elif isinstance(xs, dict):
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
155 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
156 _rejectunicode(name, k)
50944
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
157 k = pycompat.sysstr(k)
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
158 _rejectunicode('%s.%s' % (name, k), v)
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
159 elif isinstance(xs, str):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
160 raise error.ProgrammingError(
50944
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
161 b"unicode %r found in %s" % (xs, stringutil.forcebytestr(name)),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
162 hint=b"use b'' to make it byte string",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
163 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
164
36302
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
165
32381
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32380
diff changeset
166 # attributes set by registrar.command
50945
0e6cea0c3113 extension: check the command attributes using `sysstr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50944
diff changeset
167 _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo')
32381
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32380
diff changeset
168
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
169
32382
d47d7d3bd07b extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents: 32381
diff changeset
170 def _validatecmdtable(ui, cmdtable):
32381
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32380
diff changeset
171 """Check if extension commands have required attributes"""
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
172 for c, e in cmdtable.items():
32381
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32380
diff changeset
173 f = e[0]
50951
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50946
diff changeset
174 missing = [a for a in _cmdfuncattrs if not hasattr(f, a)]
32381
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32380
diff changeset
175 if not missing:
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32380
diff changeset
176 continue
50945
0e6cea0c3113 extension: check the command attributes using `sysstr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50944
diff changeset
177 msg = b'missing attributes: %s'
0e6cea0c3113 extension: check the command attributes using `sysstr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50944
diff changeset
178 msg %= b', '.join([stringutil.forcebytestr(m) for m in missing])
0e6cea0c3113 extension: check the command attributes using `sysstr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50944
diff changeset
179 hint = b"use @command decorator to register '%s'" % c
0e6cea0c3113 extension: check the command attributes using `sysstr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50944
diff changeset
180 raise error.ProgrammingError(msg, hint=hint)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
181
32381
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32380
diff changeset
182
36302
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
183 def _validatetables(ui, mod):
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
184 """Sanity check for loadable tables provided by extension module"""
50944
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
185 for t in ['cmdtable', 'colortable', 'configtable']:
36302
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
186 _rejectunicode(t, getattr(mod, t, {}))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
187 for t in [
50944
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
188 'filesetpredicate',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
189 'internalmerge',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
190 'revsetpredicate',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
191 'templatefilter',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
192 'templatefunc',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
193 'templatekeyword',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
194 ]:
36302
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
195 o = getattr(mod, t, None)
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
196 if o:
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
197 _rejectunicode(t, o._table)
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
198 _validatecmdtable(ui, getattr(mod, 'cmdtable', {}))
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36216
diff changeset
199
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
200
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
201 def load(ui, name, path, loadingtime=None):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
202 if name.startswith(b'hgext.') or name.startswith(b'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
203 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
204 else:
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
205 shortname = name
27111
9de814b35808 extensions: rename _ignore to _builtin, add descriptive comment
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
206 if shortname in _builtin:
13349
0d3f35394af4 extensions: add an ignore list for old extensions
Matt Mackall <mpm@selenic.com>
parents: 13191
diff changeset
207 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
208 if shortname in _extensions:
12779
891ddf76b73e extensions.load: return module
Erik Zielke <ez@aragost.com>
parents: 11521
diff changeset
209 return _extensions[shortname]
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
210 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
211 _extensions[shortname] = None
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
212 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
213 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
214 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
215 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
216 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
217
060f83d219b9 extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27116
diff changeset
218 # 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
219 # 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
220 # 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
221 # of Mercurial.
060f83d219b9 extensions: refuse to load extensions if minimum hg version not met
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27116
diff changeset
222 minver = getattr(mod, 'minimumhgversion', None)
45774
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
223 if minver:
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
224 curver = util.versiontuple(n=2)
48039
5caec48d9a01 extensions: prevent a crash on py3 with a `minimumhgversion` str value
Matt Harbison <matt_harbison@yahoo.com>
parents: 48038
diff changeset
225 extmin = util.versiontuple(stringutil.forcebytestr(minver), 2)
45774
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
226
48038
a9bedc56f025 extensions: prevent a crash on py3 when testing a bad extension minimum
Matt Harbison <matt_harbison@yahoo.com>
parents: 47625
diff changeset
227 if None in extmin:
a9bedc56f025 extensions: prevent a crash on py3 when testing a bad extension minimum
Matt Harbison <matt_harbison@yahoo.com>
parents: 47625
diff changeset
228 extmin = (extmin[0] or 0, extmin[1] or 0)
a9bedc56f025 extensions: prevent a crash on py3 when testing a bad extension minimum
Matt Harbison <matt_harbison@yahoo.com>
parents: 47625
diff changeset
229
a9bedc56f025 extensions: prevent a crash on py3 when testing a bad extension minimum
Matt Harbison <matt_harbison@yahoo.com>
parents: 47625
diff changeset
230 if None in curver or extmin > curver:
45774
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
231 msg = _(
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
232 b'(third party extension %s requires version %s or newer '
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
233 b'of Mercurial (current: %s); disabling)\n'
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
234 )
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
235 ui.warn(msg % (shortname, minver, util.version()))
e402a45261db extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
236 return
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
237 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
238 _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
239
5031
af0995261f02 extensions: don't get confused by aliasing between "foo" and "hgext.foo"
Bryan O'Sullivan <bos@serpentine.com>
parents: 4818
diff changeset
240 _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
241 _order.append(shortname)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
242 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
243 b'extension', b' - invoking registered callbacks: %s\n', shortname
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
244 )
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
245 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
246 for fn in _aftercallbacks.get(shortname, []):
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
247 fn(loaded=True)
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
248 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
249 return mod
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
250
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
251
29461
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
252 def _runuisetup(name, ui):
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
253 uisetup = getattr(_extensions[name], 'uisetup', None)
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
254 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
255 try:
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32742
diff changeset
256 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
257 except Exception as inst:
34845
78d9a7b7cdb6 extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents: 34199
diff changeset
258 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
259 msg = stringutil.forcebytestr(inst)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
260 ui.warn(_(b"*** failed to set up extension %s: %s\n") % (name, msg))
32744
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32742
diff changeset
261 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
262 return True
29461
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
263
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
264
29461
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
265 def _runextsetup(name, ui):
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
266 extsetup = getattr(_extensions[name], 'extsetup', None)
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
267 if extsetup:
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
268 try:
42357
38b7b45627a2 extensions: drop support for extsetup() without `ui` argument (API)
Matt Harbison <matt_harbison@yahoo.com>
parents: 41071
diff changeset
269 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
270 except Exception as inst:
34845
78d9a7b7cdb6 extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents: 34199
diff changeset
271 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
272 msg = stringutil.forcebytestr(inst)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
273 ui.warn(_(b"*** failed to set up extension %s: %s\n") % (name, msg))
32744
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32742
diff changeset
274 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
275 return True
29461
7d88fde2309f extensions: move uisetup and extsetup to standalone functions
Jun Wu <quark@fb.com>
parents: 29162
diff changeset
276
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
277
32454
9a3e88d4a030 extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents: 32382
diff changeset
278 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
279 loadingtime = collections.defaultdict(int)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
280 result = ui.configitems(b"extensions")
32455
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 32454
diff changeset
281 if whitelist is not None:
32454
9a3e88d4a030 extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents: 32382
diff changeset
282 result = [(k, v) for (k, v) in result if k in whitelist]
48406
c6d44457f7e3 extensions: ignore "sub-options" when looking for extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48039
diff changeset
283 result = [(k, v) for (k, v) in result if b':' not in k]
9410
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 9136
diff changeset
284 newindex = len(_order)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
285 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
286 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
287 b'loading %sextensions\n',
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
288 b'additional ' if newindex else b'',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
289 )
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
290 ui.log(b'extension', b'- processing %d entries\n', len(result))
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
291 with util.timedcm('load all extensions') as stats:
48410
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48409
diff changeset
292 default_sub_options = ui.configsuboptions(b"extensions", b"*")[1]
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48409
diff changeset
293
51762
ca7bde5dbafb black: format the codebase with 23.3.0
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51759
diff changeset
294 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
295 if path:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
296 if path[0:1] == b'!':
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
297 if name not in _disabledextensions:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
298 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
299 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
300 b' - skipping disabled extension: %s\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
301 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
302 )
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
303 _disabledextensions[name] = path[1:]
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
304 continue
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
305 try:
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
306 load(ui, name, path, loadingtime)
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
307 except Exception as inst:
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
308 msg = stringutil.forcebytestr(inst)
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
309 if path:
48408
e4acdf5d94a2 extensions: highlight the name of the faulty extensions in the error message
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48407
diff changeset
310 error_msg = _(
e4acdf5d94a2 extensions: highlight the name of the faulty extensions in the error message
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48407
diff changeset
311 b'failed to import extension "%s" from %s: %s'
e4acdf5d94a2 extensions: highlight the name of the faulty extensions in the error message
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48407
diff changeset
312 )
48407
e4e2ce328599 extensions: refactor handling of loading error make it reusable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48406
diff changeset
313 error_msg %= (name, path, msg)
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
314 else:
48408
e4acdf5d94a2 extensions: highlight the name of the faulty extensions in the error message
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48407
diff changeset
315 error_msg = _(b'failed to import extension "%s": %s')
48407
e4e2ce328599 extensions: refactor handling of loading error make it reusable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48406
diff changeset
316 error_msg %= (name, msg)
48409
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
317
48410
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48409
diff changeset
318 options = default_sub_options.copy()
48409
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
319 ext_options = ui.configsuboptions(b"extensions", name)[1]
48410
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48409
diff changeset
320 options.update(ext_options)
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48409
diff changeset
321 if stringutil.parsebool(options.get(b"required", b'no')):
48409
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
322 hint = None
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
323 if isinstance(inst, error.Hint) and inst.hint:
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
324 hint = inst.hint
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
325 if hint is None:
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
326 hint = _(
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
327 b"loading of this extension was required, "
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
328 b"see `hg help config.extensions` for details"
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
329 )
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
330 raise error.Abort(error_msg, hint=hint)
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
331 else:
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
332 ui.warn((b"*** %s\n") % error_msg)
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
333 if isinstance(inst, error.Hint) and inst.hint:
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
334 ui.warn(_(b"*** (%s)\n") % inst.hint)
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48408
diff changeset
335 ui.traceback()
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
336
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
337 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
338 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
339 b'> loaded %d extensions, total time %s\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
340 len(_order) - newindex,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
341 stats,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
342 )
34199
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
343 # list of (objname, loadermod, loadername) tuple:
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
344 # - 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
345 # from which extra information is loaded
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
346 # - loadermod is the module where loader is placed
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
347 # - loadername is the name of the function,
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
348 # which takes (ui, extensionname, extraobj) arguments
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
349 #
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
350 # 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
351 earlyextraloaders = [
50944
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
352 ('configtable', configitems, 'loadconfigtable'),
34199
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34198
diff changeset
353 ]
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
354
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
355 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
356 _loadextra(ui, newindex, earlyextraloaders)
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
357
32744
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32742
diff changeset
358 broken = set()
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
359 ui.log(b'extension', b'- executing uisetup hooks\n')
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
360 with util.timedcm('all uisetup') as alluisetupstats:
39525
1a2bfc4d756a extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39286
diff changeset
361 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
362 ui.log(b'extension', b' - running uisetup for %s\n', name)
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
363 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
364 if not _runuisetup(name, ui):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
365 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
366 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
367 b' - the %s extension uisetup failed\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
368 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
369 )
39525
1a2bfc4d756a extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39286
diff changeset
370 broken.add(name)
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' > 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
372 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
373 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
374
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
375 ui.log(b'extension', b'- executing extsetup hooks\n')
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
376 with util.timedcm('all extsetup') as allextetupstats:
39526
3a86f7eb8b78 extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39525
diff changeset
377 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
378 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
379 continue
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
380 ui.log(b'extension', b' - running extsetup for %s\n', name)
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
381 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
382 if not _runextsetup(name, ui):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
383 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
384 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
385 b' - the %s extension extsetup failed\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
386 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
387 )
39526
3a86f7eb8b78 extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39525
diff changeset
388 broken.add(name)
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
389 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
390 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
391 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
392
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32742
diff changeset
393 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
394 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
395 _extensions[name] = None
9660
e0eae93e6c67 extensions: changed to call extsetup() from extensions.loadall()
Yuya Nishihara <yuya@tcha.org>
parents: 9610
diff changeset
396
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
397 # 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
398 ui.log(b'extension', b'- executing remaining aftercallbacks\n')
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
399 with util.timedcm('aftercallbacks') as stats:
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
400 for shortname in _aftercallbacks:
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
401 if shortname in _extensions:
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
402 continue
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
403
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
404 for fn in _aftercallbacks[shortname]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
405 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
406 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
407 b' - extension %s not loaded, notify callbacks\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
408 shortname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
409 )
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
410 fn(loaded=False)
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
411 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
412
24950
e6e7d1cce04d extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24734
diff changeset
413 # 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
414 # 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
415 _aftercallbacks.clear()
e6e7d1cce04d extensions: clear aftercallbacks after execution (issue4646)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24734
diff changeset
416
33064
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
417 # 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
418 from . import (
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
419 color,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
420 commands,
33725
50c44dee741a filemerge: move decorator definition for internal merge tools to registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33708
diff changeset
421 filemerge,
33064
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
422 fileset,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
423 revset,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
424 templatefilters,
36928
521f6c7e1756 templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36302
diff changeset
425 templatefuncs,
33064
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
426 templatekw,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
427 )
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
428
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
429 # 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
430 # - 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
431 # 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
432 # - 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
433 # - 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
434 # 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
435 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
436 extraloaders = [
50944
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
437 ('cmdtable', commands, 'loadcmdtable'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
438 ('colortable', color, 'loadcolortable'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
439 ('filesetpredicate', fileset, 'loadpredicate'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
440 ('internalmerge', filemerge, 'loadinternalmerge'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
441 ('revsetpredicate', revset, 'loadpredicate'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
442 ('templatefilter', templatefilters, 'loadfilter'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
443 ('templatefunc', templatefuncs, 'loadfunction'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50917
diff changeset
444 ('templatekeyword', templatekw, 'loadkeyword'),
33064
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
445 ]
43238
101ae8bbfa02 cleanup: hgdemandimport.tracing accepts strings, not bytes
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
446 with util.timedcm('load registration objects') as stats:
38838
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
447 _loadextra(ui, newindex, extraloaders)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
448 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
449 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
450 b'> extension registration object loading took %s\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
451 stats,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
452 )
39528
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39526
diff changeset
453
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39526
diff changeset
454 # 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
455 for name in sorted(loadingtime):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
456 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
457 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
458 b'> extension %s take a total of %s to load\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
459 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
460 util.timecount(loadingtime[name]),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
461 )
39528
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39526
diff changeset
462
41006
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40763
diff changeset
463 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
464
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
465
34198
f7c9c5d8c7f4 extensions: factor extra data loading out
Boris Feld <boris.feld@octobus.net>
parents: 34143
diff changeset
466 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
467 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
468 module = _extensions[name]
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
469 if not module:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
470 continue # loading this module failed
33064
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
471
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33030
diff changeset
472 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
473 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
474 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
475 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
476
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
477
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
478 def afterloaded(extension, callback):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
479 """Run the specified function after a named extension is loaded.
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
480
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
481 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
482 immediately.
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
483
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
484 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
485 all extensions have been loaded.
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
486
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
487 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
488 indicating whether the dependent extension actually loaded.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
489 """
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
490
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
491 if extension in _extensions:
33030
80a5d237a4ae extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents: 32744
diff changeset
492 # Report loaded as False if the extension is disabled
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
493 loaded = _extensions[extension] is not None
33030
80a5d237a4ae extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents: 32744
diff changeset
494 callback(loaded=loaded)
24065
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
495 else:
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
496 _aftercallbacks.setdefault(extension, []).append(callback)
d8837ad682dd extensions: support callbacks after another extension loads
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23953
diff changeset
497
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
498
40763
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
499 def populateui(ui):
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
500 """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
501 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
502
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
503 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
504 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
505 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
506 """
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
507 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
508 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
509 if not hook:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
510 continue
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
511 try:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
512 hook(ui)
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
513 except Exception as inst:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
514 ui.traceback(force=True)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
515 ui.warn(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
516 _(b'*** failed to populate ui by extension %s: %s\n')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
517 % (name, stringutil.forcebytestr(inst))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
518 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
519
40763
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40515
diff changeset
520
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
521 def bind(func, *args):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
522 """Partial function application
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
523
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
524 Returns a new function that is the partial application of args and kwargs
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
525 to func. For example,
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
526
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
527 f(1, 2, bar=3) === bind(f, 1)(2, bar=3)"""
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
528 assert callable(func)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
529
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
530 def closure(*a, **kw):
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
531 return func(*(args + a), **kw)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
532
24734
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
533 return closure
fb6cb1b82f4f extensions: extract partial application into a bind() function
Eric Sumner <ericsumner@fb.com>
parents: 24145
diff changeset
534
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
535
29775
ce6317dcb944 extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents: 29461
diff changeset
536 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
537 '''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
538 try:
82bd4c5a81e5 extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents: 34105
diff changeset
539 wrap.__name__ = origfn.__name__
82bd4c5a81e5 extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents: 34105
diff changeset
540 except AttributeError:
82bd4c5a81e5 extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents: 34105
diff changeset
541 pass
28310
01dc11e7191f extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 28155
diff changeset
542 wrap.__module__ = getattr(origfn, '__module__')
01dc11e7191f extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 28155
diff changeset
543 wrap.__doc__ = getattr(origfn, '__doc__')
28312
24f1d3c70c41 extensions: copy extra __dict__ of original function
Yuya Nishihara <yuya@tcha.org>
parents: 28311
diff changeset
544 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
545 wrap._origfunc = origfn
ce6317dcb944 extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents: 29461
diff changeset
546 wrap._unboundwrapper = unboundwrapper
28310
01dc11e7191f extensions: extract function that copies function attributes to wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 28155
diff changeset
547
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
548
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
549 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
550 '''Wrap the command named `command' in table
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
551
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
552 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
553 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
554
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
555 The wrapper will be called like
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
556
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
557 wrapper(orig, *args, **kwargs)
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
558
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
559 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
560 are the arguments passed to it.
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
561
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
562 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
563 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
564 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
565
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
566 synopsis = ' [-a] [--remote]'
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
567 docstring = """
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
568
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
569 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
570 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
571 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
572 local bookmarks.
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
573 """
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
574
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
575 extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
576 synopsis, docstring)
11519
bbdf1fb1d3e3 extensions: add docstring for wrapcommand().
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11402
diff changeset
577 '''
21795
711498bb4ff5 extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21229
diff changeset
578 assert callable(wrapper)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
579 aliases, entry = cmdutil.findcmd(command, table)
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
580 for alias, e in table.items():
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
581 if e is entry:
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
582 key = alias
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
583 break
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
584
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
585 origfn = entry[0]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
586 wrap = functools.partial(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
587 util.checksignature(wrapper), util.checksignature(origfn)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
588 )
29775
ce6317dcb944 extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents: 29461
diff changeset
589 _updatewrapper(wrap, origfn, wrapper)
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
590 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
591 wrap.__doc__ += docstring
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
592
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
593 newentry = list(entry)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
594 newentry[0] = wrap
24124
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
595 if synopsis is not None:
042d95beeee8 extensions: allow extending command synopsis and docstring
Ryan McElroy <rm@fb.com>
parents: 24065
diff changeset
596 newentry[2] += synopsis
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
597 table[key] = tuple(newentry)
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
598 return entry
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
599
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
600
32742
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
601 def wrapfilecache(cls, propname, wrapper):
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
602 """Wraps a filecache property.
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
603
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
604 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
605 """
33857
38a3767975a7 extensions: if on py3 and propname is a bytestr, convert to sysstr
Augie Fackler <augie@google.com>
parents: 33748
diff changeset
606 propname = pycompat.sysstr(propname)
32742
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
607 assert callable(wrapper)
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
608 for currcls in cls.__mro__:
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
609 if propname in currcls.__dict__:
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
610 origfn = currcls.__dict__[propname].func
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
611 assert callable(origfn)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
612
32742
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
613 def wrap(*args, **kwargs):
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
614 return wrapper(origfn, *args, **kwargs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
615
32742
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
616 currcls.__dict__[propname].func = wrap
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
617 break
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
618
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
619 if currcls is object:
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43238
diff changeset
620 raise AttributeError("type '%s' has no property '%s'" % (cls, propname))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
621
32742
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32455
diff changeset
622
49037
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 49004
diff changeset
623 class wrappedfunction:
34032
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
624 '''context manager for temporarily wrapping a function'''
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
625
52269
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
626 def __init__(self, container, funcname: str, wrapper):
34032
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
627 assert callable(wrapper)
50837
94506fc107b7 wrapfunction: deprecates calling `wrappedfunction` with bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49602
diff changeset
628 if not isinstance(funcname, str):
52269
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
629 # Keep this compat shim around for older/unmaintained extensions
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
630 msg = b"pass wrappedfunction target name as `str`, not `bytes`"
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
631 util.nouideprecwarn(msg, b"6.6", stacklevel=2)
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
632 funcname = pycompat.sysstr(funcname)
34032
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
633 self._container = container
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
634 self._funcname = funcname
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
635 self._wrapper = wrapper
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
636
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
637 def __enter__(self):
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
638 wrapfunction(self._container, self._funcname, self._wrapper)
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
639
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
640 def __exit__(self, exctype, excvalue, traceback):
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
641 unwrapfunction(self._container, self._funcname, self._wrapper)
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33858
diff changeset
642
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
643
52269
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
644 def wrapfunction(container, funcname: str, wrapper):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
645 """Wrap the function named funcname in container
11402
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
646
11520
94b3bbc886cf extensions: improve language for wrapfunction() docstring.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11519
diff changeset
647 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
648 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
649
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
650 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
651
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
652 wrapper(orig, *args, **kwargs)
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
653
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
654 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
655 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
656
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
657 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
658 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
659 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
660 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
661 reposetup() should look like
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
662
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
663 def reposetup(ui, repo):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
664 class myrepo(repo.__class__):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
665 def whatever(self, *args, **kwargs):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
666 [...extension stuff...]
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
667 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
668 [...extension stuff...]
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
669
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
670 repo.__class__ = myrepo
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
671
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
672 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
673 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
674 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
675 subclass trick.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
676 """
21795
711498bb4ff5 extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21229
diff changeset
677 assert callable(wrapper)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
678
50838
ee1617c04858 wrapfunction: deprecated calling "wrapfunction" with bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50837
diff changeset
679 if not isinstance(funcname, str):
52269
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
680 # Keep this compat shim around for older/unmaintained extensions
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
681 msg = b"pass wrapfunction target name as `str`, not `bytes`"
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
682 util.nouideprecwarn(msg, b"6.6", stacklevel=2)
8317993a49f1 extensions: allow wrapping a function with a bytes name again
Matt Harbison <matt_harbison@yahoo.com>
parents: 51901
diff changeset
683 funcname = pycompat.sysstr(funcname)
50838
ee1617c04858 wrapfunction: deprecated calling "wrapfunction" with bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50837
diff changeset
684
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
685 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
686 assert callable(origfn)
34104
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34065
diff changeset
687 if inspect.ismodule(container):
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34065
diff changeset
688 # 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
689 # "partial" won't insert a frame in traceback.
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34065
diff changeset
690 wrap = functools.partial(wrapper, origfn)
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34065
diff changeset
691 else:
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34065
diff changeset
692 # "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
693 # The downside is one more frame in traceback.
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34065
diff changeset
694 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
695 _updatewrapper(wrap, origfn, wrapper)
28311
1b0ef07ba783 extensions: copy attributes to wrapper by wrapfunction()
Yuya Nishihara <yuya@tcha.org>
parents: 28310
diff changeset
696 setattr(container, funcname, wrap)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
697 return origfn
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
C?dric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
698
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
699
29777
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
700 def unwrapfunction(container, funcname, wrapper=None):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
701 """undo wrapfunction
29777
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
702
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
703 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
704 from the chain of wrappers.
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
705
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
706 Return the removed wrapper.
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
707 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
708 wrapper is not None but is not found in the wrapper chain.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
709 """
29777
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
710 chain = getwrapperchain(container, funcname)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
711 origfn = chain.pop()
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
712 if wrapper is None:
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
713 wrapper = chain[0]
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
714 chain.remove(wrapper)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
715 setattr(container, funcname, origfn)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
716 for w in reversed(chain):
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
717 wrapfunction(container, funcname, w)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
718 return wrapper
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29776
diff changeset
719
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
720
29776
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
721 def getwrapperchain(container, funcname):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
722 """get a chain of wrappers of a function
29776
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
723
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
724 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
725
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
726 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
727 argument is origfunc.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
728 """
29776
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
729 result = []
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
730 fn = getattr(container, funcname)
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
731 while fn:
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
732 assert callable(fn)
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
733 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
734 fn = getattr(fn, '_origfunc', None)
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
735 return result
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29775
diff changeset
736
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
737
38196
b39958d6b81b extensions: remove strip_init=True from _disabledpaths()
Yuya Nishihara <yuya@tcha.org>
parents: 38195
diff changeset
738 def _disabledpaths():
b39958d6b81b extensions: remove strip_init=True from _disabledpaths()
Yuya Nishihara <yuya@tcha.org>
parents: 38195
diff changeset
739 '''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
740 import hgext
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
741
49601
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
742 exts = {}
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
743
45105
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44659
diff changeset
744 # The hgext might not have a __file__ attribute (e.g. in PyOxidizer) and
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44659
diff changeset
745 # it might not be on a filesystem even if it does.
50951
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50946
diff changeset
746 if hasattr(hgext, '__file__'):
45105
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44659
diff changeset
747 extpath = os.path.dirname(
47625
7bafe40ab78a windows: use abspath in extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47026
diff changeset
748 util.abspath(pycompat.fsencode(hgext.__file__))
45105
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44659
diff changeset
749 )
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44659
diff changeset
750 try:
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44659
diff changeset
751 files = os.listdir(extpath)
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44659
diff changeset
752 except OSError:
49601
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
753 pass
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
754 else:
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
755 for e in files:
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
756 if e.endswith(b'.py'):
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
757 name = e.rsplit(b'.', 1)[0]
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
758 path = os.path.join(extpath, e)
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
759 else:
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
760 name = e
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
761 path = os.path.join(extpath, e, b'__init__.py')
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
762 if not os.path.exists(path):
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
763 continue
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
764 if name in exts or name in _order or name == b'__init__':
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
765 continue
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49091
diff changeset
766 exts[name] = path
8964
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
C?dric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
767
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
768 for name, path in _disabledextensions.items():
33327
68b7ceda99d7 dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents: 33139
diff changeset
769 # 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
770 # 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
771 if path:
68b7ceda99d7 dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents: 33139
diff changeset
772 exts[name] = path
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
773 return exts
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
774
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
775
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
776 def _moduledoc(file):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
777 """return the top-level python documentation for the given file
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
778
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
779 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
780 handle triple quotes and to return the whole text instead of just
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
781 the synopsis"""
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
782 result = []
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
783
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
784 line = file.readline()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
785 while line[:1] == b'#' or not line.strip():
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
786 line = file.readline()
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
787 if not line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
788 break
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
789
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
790 start = line[:3]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
791 if start == b'"""' or start == b"'''":
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
792 line = line[3:]
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
793 while line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
794 if line.rstrip().endswith(start):
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
795 line = line.split(start)[0]
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
796 if line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
797 result.append(line)
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
798 break
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
799 elif not line:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
800 return None # unmatched delimiter
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
801 result.append(line)
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
802 line = file.readline()
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
803 else:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
804 return None
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
805
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
806 return b''.join(result)
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
807
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
808
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
809 def _disabledhelp(path):
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
810 '''retrieve help synopsis of a disabled extension (without importing)'''
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
811 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
812 with open(path, b'rb') as src:
38350
c6f82a18a63d extensions: use context manger for open()
Yuya Nishihara <yuya@tcha.org>
parents: 38349
diff changeset
813 doc = _moduledoc(src)
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
814 except IOError:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
815 return
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
816
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
817 if doc: # extracting localized synopsis
30319
5581b294f3c6 help: show help for disabled extensions (issue5228)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30058
diff changeset
818 return gettext(doc)
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
819 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
820 return _(b'(no help text available)')
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
821
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
822
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
823 def disabled():
14530
cd31a1cc1521 extensions: update doc of enabled() and disabled() according to d5b525697ddb
Yuya Nishihara <yuya@tcha.org>
parents: 14415
diff changeset
824 '''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
825 try:
43745
1ea33dff7841 extensions: hide two confusing import statements from pytype
Augie Fackler <augie@google.com>
parents: 43554
diff changeset
826 from hgext import __index__ # pytype: disable=import-error
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
827
44470
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43747
diff changeset
828 return {
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43747
diff changeset
829 name: gettext(desc)
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
830 for name, desc in __index__.docs.items()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
831 if name not in _order
44470
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43747
diff changeset
832 }
21229
54d7657d7d1e setup.py, make: avoid problems with outdated, existing hgext/__index__.py*
Thomas Arendsen Hein <thomas@intevation.de>
parents: 20645
diff changeset
833 except (ImportError, AttributeError):
14539
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
834 pass
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
835
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
836 paths = _disabledpaths()
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
837 if not paths:
16709
9eca39a91964 extensions.disabled: return {} instead of None no extensions are disabled
Augie Fackler <raf@durin42.com>
parents: 16667
diff changeset
838 return {}
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
839
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
840 exts = {}
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
841 for name, path in paths.items():
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
842 doc = _disabledhelp(path)
46095
1ced08423d59 extensions: avoid including `__index__` in the disabled extension list
Matt Harbison <matt_harbison@yahoo.com>
parents: 46034
diff changeset
843 if doc and name != b'__index__':
49091
2d519511c5c3 extensions: use new function for getting first line of string
Martin von Zweigbergk <martinvonz@google.com>
parents: 49037
diff changeset
844 exts[name] = stringutil.firstline(doc)
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
C?dric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
845
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
846 return exts
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
C?dric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
847
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
848
44659
843418dc0b1b extensions: refactor function for obtaining disabled extension help
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44470
diff changeset
849 def disabled_help(name):
843418dc0b1b extensions: refactor function for obtaining disabled extension help
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44470
diff changeset
850 """Obtain the full help text for a disabled extension, or None."""
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
851 paths = _disabledpaths()
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
852 if name in paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
853 return _disabledhelp(paths[name])
49602
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
854 else:
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
855 try:
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
856 import hgext
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
857 from hgext import __index__ # pytype: disable=import-error
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
858
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
859 # The extensions are filesystem based, so either an error occurred
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
860 # or all are enabled.
50951
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50946
diff changeset
861 if hasattr(hgext, '__file__'):
49602
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
862 return
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
863
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
864 if name in _order: # enabled
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
865 return
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
866 else:
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
867 return gettext(__index__.docs.get(name))
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
868 except (ImportError, AttributeError):
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49601
diff changeset
869 pass
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
870
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
871
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
872 def _walkcommand(node):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
873 """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
874 todo = collections.deque([node])
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
875 while todo:
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
876 node = todo.popleft()
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
877 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
878 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
879 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
880 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
881 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
882 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
883 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
884 continue
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
885 if d.func.id != 'command':
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
886 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
887 yield d
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
888
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
889
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
890 def _disabledcmdtable(path):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
891 """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
892
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
893 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
894 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
895 with open(path, b'rb') as src:
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
896 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
897 cmdtable = {}
50751
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
898
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
899 # Python 3.12 started removing Bytes and Str and deprecate harder
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
900 use_constant = 'Bytes' not in vars(ast)
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
901
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
902 for node in _walkcommand(root):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
903 if not node.args:
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
904 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
905 a = node.args[0]
50751
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
906 if use_constant: # Valid since Python 3.8
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
907 if isinstance(a, ast.Constant):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
908 if isinstance(a.value, str):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
909 name = pycompat.sysbytes(a.value)
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
910 elif isinstance(a.value, bytes):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
911 name = a.value
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
912 else:
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
913 continue
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
914 else:
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
915 continue
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
916 else: # Valid until 3.11
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
917 if isinstance(a, ast.Str):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
918 name = pycompat.sysbytes(a.s)
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
919 elif isinstance(a, ast.Bytes):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
920 name = a.s
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
921 else:
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49602
diff changeset
922 continue
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
923 cmdtable[name] = (None, [], b'')
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
924 return cmdtable
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
925
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
926
38018
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
927 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
928 try:
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
929 cmdtable = _disabledcmdtable(path)
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
930 except (IOError, SyntaxError):
38018
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
931 return
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
932 try:
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
933 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
934 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
935 return
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
936 for c in aliases:
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
937 if c.startswith(cmd):
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
938 cmd = c
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
939 break
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
940 else:
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
941 cmd = aliases[0]
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
942 doc = _disabledhelp(path)
38019
6e526b0961a8 help: load module doc of disabled extension in extensions.disabledcmd()
Yuya Nishihara <yuya@tcha.org>
parents: 38018
diff changeset
943 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
944
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
945
13191
1aea66b71f4f extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents: 12779
diff changeset
946 def disabledcmd(ui, cmd, strict=False):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
947 """find cmd from disabled extensions without importing.
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45774
diff changeset
948 returns (cmdname, extname, doc)"""
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
949
38195
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38062
diff changeset
950 paths = _disabledpaths()
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
951 if not paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
952 raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
953
16667
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
954 ext = None
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
955 # 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
956 path = paths.pop(cmd, None)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
957 if path:
38018
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
958 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
959 if not ext:
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
960 # otherwise, interrogate each extension until there's a match
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
961 for name, path in paths.items():
38018
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 38017
diff changeset
962 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
963 if ext:
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
964 break
38017
5b60f7d652f2 extensions: drop dead code trying to exclude deprecated disabled commands
Yuya Nishihara <yuya@tcha.org>
parents: 38001
diff changeset
965 if ext:
16667
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
966 return ext
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
967
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
968 raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
969
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
970
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
971 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
972 '''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
973 exts = {}
20a25042fadc extensions: move extensions listing functions from mercurial.help
C?dric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
974 for ename, ext in extensions():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
975 doc = gettext(ext.__doc__) or _(b'(no help text available)')
46397
90a92f041fc6 typing: add an assertion instead of blacklisting mercurial/extensions.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46095
diff changeset
976 assert doc is not None # help pytype
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
977 if shortname:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
978 ename = ename.split(b'.')[-1]
49091
2d519511c5c3 extensions: use new function for getting first line of string
Martin von Zweigbergk <martinvonz@google.com>
parents: 49037
diff changeset
979 exts[ename] = stringutil.firstline(doc).strip()
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
C?dric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
980
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
981 return exts
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
982
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
983
28155
7f430b2ac7fd extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents: 27990
diff changeset
984 def notloaded():
7f430b2ac7fd extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents: 27990
diff changeset
985 '''return short names of extensions that failed to load'''
49004
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48985
diff changeset
986 return [name for name, mod in _extensions.items() if mod is None]
28155
7f430b2ac7fd extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents: 27990
diff changeset
987
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
988
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
989 def moduleversion(module):
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
990 '''return version information from given module as a string'''
50951
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50946
diff changeset
991 if hasattr(module, 'getversion') and callable(module.getversion):
47026
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
992 try:
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
993 version = module.getversion()
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
994 except Exception:
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
995 version = b'unknown'
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
996
50951
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50946
diff changeset
997 elif hasattr(module, '__version__'):
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
998 version = module.__version__
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
999 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1000 version = b''
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
1001 if isinstance(version, (list, tuple)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1002 version = b'.'.join(pycompat.bytestr(o) for o in version)
45778
27c23c8f14da extensions: avoid a crash when the version isn't properly byteified on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 45774
diff changeset
1003 else:
27c23c8f14da extensions: avoid a crash when the version isn't properly byteified on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 45774
diff changeset
1004 # version data should be bytes, but not all extensions are ported
27c23c8f14da extensions: avoid a crash when the version isn't properly byteified on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 45774
diff changeset
1005 # to py3.
27c23c8f14da extensions: avoid a crash when the version isn't properly byteified on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 45774
diff changeset
1006 version = stringutil.forcebytestr(version)
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
1007 return version
27990
96bfd2875213 version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents: 27637
diff changeset
1008
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42553
diff changeset
1009
27990
96bfd2875213 version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents: 27637
diff changeset
1010 def ismoduleinternal(module):
96bfd2875213 version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents: 27637
diff changeset
1011 exttestedwith = getattr(module, 'testedwith', None)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1012 return exttestedwith == b"ships-with-hg-core"