annotate mercurial/extensions.py @ 52178:bcd4962e0df9

rust-revlog: don't create an in-memory nodemap for filelogs from Python Explanations inline. Benchmarks from this change affect positively the only repo that showed this being a problem: ``` ### data-env-vars.name = mozilla-try-2024-03-26-ds2-pnm # benchmark.name = hg.command.cat # bin-env-vars.hg.flavor = rust # bin-env-vars.hg.py-re2-module = default # benchmark.variants.files = all-root # benchmark.variants.output = plain # benchmark.variants.rev = tip default: 62.848869 ~~~~~ before-this-patch: 58.113051 (-7.54%, -4.74) this-patch: 57.407533 (-8.66%, -5.44) ### data-env-vars.name = mozilla-try-2024-03-26-ds2-pnm # benchmark.name = hg.command.log # bin-env-vars.hg.flavor = rust # bin-env-vars.hg.py-re2-module = default # benchmark.variants.limit-rev = 10 # benchmark.variants.patch = yes # benchmark.variants.rev = none default: 3.173532 ~~~~~ before-this-patch: 3.543591 (+11.66%, +0.37) this-patch: 3.297235 (+3.90%, +0.12) ```
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 31 Jul 2024 13:35:54 +0200
parents f4733654f144
children
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: 46690
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
51863
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
8 from __future__ import annotations
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
9
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
10 import ast
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
11 import collections
34087
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
12 import functools
50757
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50755
diff changeset
13 import importlib
31263
d79761fe697f extensions: use inspect module instead of func_code.co_argcount
Augie Fackler <raf@durin42.com>
parents: 31074
diff changeset
14 import inspect
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
15 import os
50757
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50755
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,
33132
c467d13334ee configitems: add an official API for extensions to register config item
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33052
diff changeset
28 configitems,
25946
5e0d80195a0f extensions: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
29 error,
30570
c4c51fd0e11d py3: use pycompat.sysstr() in __import__()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30306
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: 42547
diff changeset
34 from .utils import stringutil
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36922
diff changeset
35
4544
930ed513c864 Create a separate module for managing extensions
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
36 _extensions = {}
29895
b1ebc767563d help: show content for explicitly disabled extension (issue5228)
liscju <piotr.listkiewicz@gmail.com>
parents: 29841
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: 42547
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: 42547
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: 42547
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: 42547
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:
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
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: 42547
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):
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
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))
30575
5ffbaba9acac py3: use pycompat.fsdecode() to pass to imp.* functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30570
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
50757
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50755
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: 50755
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: 50755
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: 50755
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: 50755
diff changeset
95
19108906abaf extensions: imp module is removed in Python 3.12 - use importlib to load files
Mads Kiilerich <mads@kiilerich.com>
parents: 50755
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: 50755
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: 50755
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: 50755
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: 50755
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: 50755
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: 50755
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: 42547
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"""
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
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: 50922
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: 42547
diff changeset
113
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
114 def _importext(name, path=None, reportfunc=None):
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
diff changeset
115 name = pycompat.fsdecode(name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
116 if path:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
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: 30028
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: 30028
diff changeset
119 # conflicts with other modules
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
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: 30028
diff changeset
121 else:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
122 try:
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
diff changeset
123 mod = _importh("hgext.%s" % name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
124 except ImportError as err:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
125 if reportfunc:
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
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: 30028
diff changeset
127 try:
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
diff changeset
128 mod = _importh("hgext3rd.%s" % name)
30058
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
129 except ImportError as err:
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
130 if reportfunc:
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
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: 30028
diff changeset
132 mod = _importh(name)
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
133 return mod
8f54f9b8010d extensions: move the "import" logic out from "load"
Jun Wu <quark@fb.com>
parents: 30028
diff changeset
134
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
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):
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
137 # note: this ui.log happens before --debug is processed,
30028
3741a8f86e88 extensions: add a note about debug output during extensions search
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30027
diff changeset
138 # Use --config ui.debug=1 to see them.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
139 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
140 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
141 b' - could not import %s (%s): trying %s\n',
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
diff changeset
142 stringutil.forcebytestr(failed),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
143 stringutil.forcebytestr(err),
50923
c642c03969ff dynamic-import: use sysstr for importing extension and others
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50922
diff changeset
144 stringutil.forcebytestr(next),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
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'):
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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: 42547
diff changeset
149
36269
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
150 def _rejectunicode(name, xs):
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
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: 36178
diff changeset
152 for x in xs:
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
153 _rejectunicode(name, x)
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
154 elif isinstance(xs, dict):
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
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: 36178
diff changeset
156 _rejectunicode(name, k)
50921
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
157 k = pycompat.sysstr(k)
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
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: 50894
diff changeset
159 elif isinstance(xs, str):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
160 raise error.ProgrammingError(
50921
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
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: 42547
diff changeset
163 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
164
36269
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
165
32342
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32341
diff changeset
166 # attributes set by registrar.command
50922
0e6cea0c3113 extension: check the command attributes using `sysstr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50921
diff changeset
167 _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo')
32342
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32341
diff changeset
168
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
169
32343
d47d7d3bd07b extensions: show deprecation warning for the use of cmdutil.command
Yuya Nishihara <yuya@tcha.org>
parents: 32342
diff changeset
170 def _validatecmdtable(ui, cmdtable):
32342
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32341
diff changeset
171 """Check if extension commands have required attributes"""
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
diff changeset
172 for c, e in cmdtable.items():
32342
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32341
diff changeset
173 f = e[0]
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50923
diff changeset
174 missing = [a for a in _cmdfuncattrs if not hasattr(f, a)]
32342
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32341
diff changeset
175 if not missing:
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32341
diff changeset
176 continue
50922
0e6cea0c3113 extension: check the command attributes using `sysstr`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50921
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: 50921
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: 50921
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: 50921
diff changeset
180 raise error.ProgrammingError(msg, hint=hint)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
181
32342
e5fbf9687600 extensions: prohibit registration of command without using @command (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32341
diff changeset
182
36269
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
183 def _validatetables(ui, mod):
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
184 """Sanity check for loadable tables provided by extension module"""
50921
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
185 for t in ['cmdtable', 'colortable', 'configtable']:
36269
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
186 _rejectunicode(t, getattr(mod, t, {}))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
187 for t in [
50921
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
188 'filesetpredicate',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
189 'internalmerge',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
190 'revsetpredicate',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
191 'templatefilter',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
192 'templatefunc',
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
193 'templatekeyword',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
194 ]:
36269
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
195 o = getattr(mod, t, None)
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
196 if o:
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
197 _rejectunicode(t, o._table)
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
198 _validatecmdtable(ui, getattr(mod, 'cmdtable', {}))
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
diff changeset
199
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
200
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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]
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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:
38798
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
213 mod = _importext(name, path, bind(_reportimporterror, ui))
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
214 ui.log(b'extension', b' > %s extension loaded in %s\n', shortname, stats)
39511
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39509
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: 39509
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)
45899
f96059fa519c 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:
f96059fa519c 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)
48016
5caec48d9a01 extensions: prevent a crash on py3 with a `minimumhgversion` str value
Matt Harbison <matt_harbison@yahoo.com>
parents: 48015
diff changeset
225 extmin = util.versiontuple(stringutil.forcebytestr(minver), 2)
45899
f96059fa519c extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
226
48015
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:
45899
f96059fa519c extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
231 msg = _(
f96059fa519c 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 '
f96059fa519c 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'
f96059fa519c extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
234 )
f96059fa519c 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()))
f96059fa519c extensions: gracefully warn when doing min version check with no local version
Matt Harbison <matt_harbison@yahoo.com>
parents: 45105
diff changeset
236 return
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
237 ui.log(b'extension', b' - validating extension tables: %s\n', shortname)
36269
4088e568a411 extensions: reject any unicode strings in tables before loading
Yuya Nishihara <yuya@tcha.org>
parents: 36178
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: 42547
diff changeset
242 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
243 b'extension', b' - invoking registered callbacks: %s\n', shortname
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
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:
38798
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)
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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: 42547
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:
32724
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
diff changeset
255 try:
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
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: 32722
diff changeset
257 except Exception as inst:
34845
78d9a7b7cdb6 extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents: 34187
diff changeset
258 ui.traceback(force=True)
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36922
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))
32724
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
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: 32722
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: 42547
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:
42335
38b7b45627a2 extensions: drop support for extsetup() without `ui` argument (API)
Matt Harbison <matt_harbison@yahoo.com>
parents: 41068
diff changeset
269 extsetup(ui)
32724
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
diff changeset
270 except Exception as inst:
34845
78d9a7b7cdb6 extensions: always include traceback when extension setup fails
Martin von Zweigbergk <martinvonz@google.com>
parents: 34187
diff changeset
271 ui.traceback(force=True)
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36922
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))
32724
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
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: 32722
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: 42547
diff changeset
277
32416
9a3e88d4a030 extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents: 32343
diff changeset
278 def loadall(ui, whitelist=None):
39511
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39509
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")
32417
f40dc6f7c12f profiling: allow loading profiling extension before everything else
Jun Wu <quark@fb.com>
parents: 32416
diff changeset
281 if whitelist is not None:
32416
9a3e88d4a030 extensions: allow loading a whitelisted subset of extensions
Jun Wu <quark@fb.com>
parents: 32343
diff changeset
282 result = [(k, v) for (k, v) in result if k in whitelist]
48358
c6d44457f7e3 extensions: ignore "sub-options" when looking for extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48016
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: 42547
diff changeset
285 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
286 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
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: 42547
diff changeset
289 )
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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:
48362
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48361
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: 48361
diff changeset
293
51703
ca7bde5dbafb black: format the codebase with 23.3.0
Raphaël Gomès <rgomes@octobus.net>
parents: 51700
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'!':
38798
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: 42547
diff changeset
298 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
299 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
300 b' - skipping disabled extension: %s\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
301 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
302 )
38798
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:
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
306 load(ui, name, path, loadingtime)
38798
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:
48360
e4acdf5d94a2 extensions: highlight the name of the faulty extensions in the error message
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48359
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: 48359
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: 48359
diff changeset
312 )
48359
e4e2ce328599 extensions: refactor handling of loading error make it reusable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48358
diff changeset
313 error_msg %= (name, path, msg)
38798
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
314 else:
48360
e4acdf5d94a2 extensions: highlight the name of the faulty extensions in the error message
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48359
diff changeset
315 error_msg = _(b'failed to import extension "%s": %s')
48359
e4e2ce328599 extensions: refactor handling of loading error make it reusable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48358
diff changeset
316 error_msg %= (name, msg)
48361
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48360
diff changeset
317
48362
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48361
diff changeset
318 options = default_sub_options.copy()
48361
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48360
diff changeset
319 ext_options = ui.configsuboptions(b"extensions", name)[1]
48362
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48361
diff changeset
320 options.update(ext_options)
7e6488aa1261 extensions: add a default "*" suboptions prefix
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48361
diff changeset
321 if stringutil.parsebool(options.get(b"required", b'no')):
48361
0d0ce2529540 extension: add a `required` suboption to enforce the use of an extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
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: 48360
diff changeset
335 ui.traceback()
38798
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: 42547
diff changeset
337 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
338 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
339 b'> loaded %d extensions, total time %s\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
340 len(_order) - newindex,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
341 stats,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
342 )
34187
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
diff changeset
343 # list of (objname, loadermod, loadername) tuple:
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
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: 34186
diff changeset
345 # from which extra information is loaded
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
diff changeset
346 # - loadermod is the module where loader is placed
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
diff changeset
347 # - loadername is the name of the function,
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
diff changeset
348 # which takes (ui, extensionname, extraobj) arguments
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
diff changeset
349 #
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
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: 34186
diff changeset
351 earlyextraloaders = [
50921
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
352 ('configtable', configitems, 'loadconfigtable'),
34187
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
diff changeset
353 ]
38798
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
354
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
355 ui.log(b'extension', b'- loading configtable attributes\n')
34187
4c5730c21523 extensions: register config item early
Boris Feld <boris.feld@octobus.net>
parents: 34186
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
32724
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
diff changeset
358 broken = set()
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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:
39508
1a2bfc4d756a extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39258
diff changeset
361 for name in _order[newindex:]:
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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:
39508
1a2bfc4d756a extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39258
diff changeset
364 if not _runuisetup(name, ui):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
365 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
366 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
367 b' - the %s extension uisetup failed\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
368 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
369 )
39508
1a2bfc4d756a extensions: trace the total time of running all uisetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39258
diff changeset
370 broken.add(name)
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
371 ui.log(b'extension', b' > uisetup for %s took %s\n', name, stats)
39511
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39509
diff changeset
372 loadingtime[name] += stats.elapsed
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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:
39509
3a86f7eb8b78 extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39508
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: 39508
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: 39508
diff changeset
379 continue
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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:
39509
3a86f7eb8b78 extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39508
diff changeset
382 if not _runextsetup(name, ui):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
383 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
384 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
385 b' - the %s extension extsetup failed\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
386 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
387 )
39509
3a86f7eb8b78 extensions: trace the total time of running all extsetup callbacks
Boris Feld <boris.feld@octobus.net>
parents: 39508
diff changeset
388 broken.add(name)
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
389 ui.log(b'extension', b' > extsetup for %s took %s\n', name, stats)
39511
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39509
diff changeset
390 loadingtime[name] += stats.elapsed
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
391 ui.log(b'extension', b'> all extsetup took %s\n', allextetupstats)
32724
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
diff changeset
392
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
diff changeset
393 for name in broken:
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
394 ui.log(b'extension', b' - disabling broken %s extension\n', name)
32724
ea1c2eb7abd3 extensions: catch uisetup and extsetup failures and don't let them break hg
Augie Fackler <augie@google.com>
parents: 32722
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.
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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:
38798
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
38798
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: 42547
diff changeset
405 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
406 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
407 b' - extension %s not loaded, notify callbacks\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
408 shortname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
409 )
38798
d58958676b3c extensions: add detailed loading information
Martijn Pieters <mj@zopatista.com>
parents: 38727
diff changeset
410 fn(loaded=False)
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
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
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
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: 33014
diff changeset
418 from . import (
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
419 color,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
420 commands,
33699
50c44dee741a filemerge: move decorator definition for internal merge tools to registrar
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33682
diff changeset
421 filemerge,
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
422 fileset,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
423 revset,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
424 templatefilters,
36922
521f6c7e1756 templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36269
diff changeset
425 templatefuncs,
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
426 templatekw,
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
427 )
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
428
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
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: 33014
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: 33014
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: 33014
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: 33014
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: 33014
diff changeset
434 # which takes (ui, extensionname, extraobj) arguments
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
435 ui.log(b'extension', b'- loading extension registration objects\n')
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
436 extraloaders = [
50921
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
437 ('cmdtable', commands, 'loadcmdtable'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
438 ('colortable', color, 'loadcolortable'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
439 ('filesetpredicate', fileset, 'loadpredicate'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
440 ('internalmerge', filemerge, 'loadinternalmerge'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
441 ('revsetpredicate', revset, 'loadpredicate'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
442 ('templatefilter', templatefilters, 'loadfilter'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
443 ('templatefunc', templatefuncs, 'loadfunction'),
538c5a48e8f4 extension: access special module members using sysstr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50894
diff changeset
444 ('templatekeyword', templatekw, 'loadkeyword'),
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
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:
38798
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: 42547
diff changeset
448 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
449 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
450 b'> extension registration object loading took %s\n',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
451 stats,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
452 )
39511
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39509
diff changeset
453
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39509
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: 39509
diff changeset
455 for name in sorted(loadingtime):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
456 ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
457 b'extension',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
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: 42547
diff changeset
459 name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
460 util.timecount(loadingtime[name]),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
461 )
39511
1ab185c78cc3 extension: add a summary of total loading time per extension
Boris Feld <boris.feld@octobus.net>
parents: 39509
diff changeset
462
40996
6f2510b581a0 extensions: use ui.log() interface to provide detailed loading information
Yuya Nishihara <yuya@tcha.org>
parents: 40729
diff changeset
463 ui.log(b'extension', b'extension loading complete\n')
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
464
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
465
34186
f7c9c5d8c7f4 extensions: factor extra data loading out
Boris Feld <boris.feld@octobus.net>
parents: 34128
diff changeset
466 def _loadextra(ui, newindex, extraloaders):
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
467 for name in _order[newindex:]:
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
468 module = _extensions[name]
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
469 if not module:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
470 continue # loading this module failed
33052
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
diff changeset
471
45b0e9d05ee9 extensions: register functions always at loading extension (issue5601)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33014
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: 33014
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: 33014
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: 33014
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: 33014
diff changeset
476
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
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):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
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.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
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:
33014
80a5d237a4ae extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents: 32724
diff changeset
492 # Report loaded as False if the extension is disabled
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
493 loaded = _extensions[extension] is not None
33014
80a5d237a4ae extensions: call afterloaded() with loaded=False for disabled extensions
Adam Simpkins <simpkins@fb.com>
parents: 32724
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: 42547
diff changeset
498
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
diff changeset
499 def populateui(ui):
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
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: 40463
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: 40463
diff changeset
502
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
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: 40463
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: 40463
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: 40463
diff changeset
506 """
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
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: 40463
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: 40463
diff changeset
509 if not hook:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
diff changeset
510 continue
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
diff changeset
511 try:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
diff changeset
512 hook(ui)
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
diff changeset
513 except Exception as inst:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
diff changeset
514 ui.traceback(force=True)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
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: 42547
diff changeset
517 % (name, stringutil.forcebytestr(inst))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
518 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
519
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40463
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):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
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
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
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: 45899
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
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
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: 42547
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: 42547
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: 42547
diff changeset
535
29763
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'''
34128
82bd4c5a81e5 extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
538 try:
82bd4c5a81e5 extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
539 wrap.__name__ = origfn.__name__
82bd4c5a81e5 extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
540 except AttributeError:
82bd4c5a81e5 extensions: fix wrapcommand/function of class instance
Yuya Nishihara <yuya@tcha.org>
parents: 34088
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__', {}))
29763
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: 42547
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)
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
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: 42547
diff changeset
586 wrap = functools.partial(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
587 util.checksignature(wrapper), util.checksignature(origfn)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
588 )
29763
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: 42547
diff changeset
600
32722
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
601 def wrapfilecache(cls, propname, wrapper):
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
602 """Wraps a filecache property.
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
603
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
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: 32417
diff changeset
605 """
33836
38a3767975a7 extensions: if on py3 and propname is a bytestr, convert to sysstr
Augie Fackler <augie@google.com>
parents: 33722
diff changeset
606 propname = pycompat.sysstr(propname)
32722
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
607 assert callable(wrapper)
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
608 for currcls in cls.__mro__:
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
609 if propname in currcls.__dict__:
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
610 origfn = currcls.__dict__[propname].func
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
611 assert callable(origfn)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
612
32722
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
613 def wrap(*args, **kwargs):
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
614 return wrapper(origfn, *args, **kwargs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
615
32722
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
616 currcls.__dict__[propname].func = wrap
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
617 break
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
618
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
619 if currcls is object:
43503
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: 42547
diff changeset
621
32722
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32417
diff changeset
622
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
623 class wrappedfunction:
34014
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
624 '''context manager for temporarily wrapping a function'''
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
625
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
626 def __init__(self, container, funcname, wrapper):
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
627 assert callable(wrapper)
50800
94506fc107b7 wrapfunction: deprecates calling `wrappedfunction` with bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49781
diff changeset
628 if not isinstance(funcname, str):
51139
7b837fabc990 cleanup: turn `wrappedfunction` deprecation warning into an error
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
629 msg = b"wrappedfunction target name should be `str`, not `bytes`"
7b837fabc990 cleanup: turn `wrappedfunction` deprecation warning into an error
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
630 raise TypeError(msg)
34014
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
631 self._container = container
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
632 self._funcname = funcname
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
633 self._wrapper = wrapper
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
634
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
635 def __enter__(self):
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
636 wrapfunction(self._container, self._funcname, self._wrapper)
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
637
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
638 def __exit__(self, exctype, excvalue, traceback):
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
639 unwrapfunction(self._container, self._funcname, self._wrapper)
47e52f079a57 extensions: add wrappedfunction() context manager
Martin von Zweigbergk <martinvonz@google.com>
parents: 33837
diff changeset
640
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
641
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
642 def wrapfunction(container, funcname, wrapper):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
643 """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
644
11520
94b3bbc886cf extensions: improve language for wrapfunction() docstring.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11519
diff changeset
645 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
646 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
647
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
648 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
649
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
650 wrapper(orig, *args, **kwargs)
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 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
653 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
654
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
655 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
656 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
657 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
658 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
659 reposetup() should look like
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
660
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
661 def reposetup(ui, repo):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
662 class myrepo(repo.__class__):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
663 def whatever(self, *args, **kwargs):
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
664 [...extension stuff...]
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
665 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
666 [...extension stuff...]
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
667
367ce8514da0 extensions: recommend against using wrapfunction for repo methods
Greg Ward <greg-hg@gerg.ca>
parents: 10364
diff changeset
668 repo.__class__ = myrepo
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 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
671 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
672 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
673 subclass trick.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
674 """
21795
711498bb4ff5 extensions: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21229
diff changeset
675 assert callable(wrapper)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
676
50801
ee1617c04858 wrapfunction: deprecated calling "wrapfunction" with bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50800
diff changeset
677 if not isinstance(funcname, str):
51140
eda075d7b2ac cleanup: turn `wrapfunction` deprecation warning into an error
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51139
diff changeset
678 msg = b"wrapfunction target name should be `str`, not `bytes`"
eda075d7b2ac cleanup: turn `wrapfunction` deprecation warning into an error
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51139
diff changeset
679 raise TypeError(msg)
50801
ee1617c04858 wrapfunction: deprecated calling "wrapfunction" with bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50800
diff changeset
680
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
681 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
682 assert callable(origfn)
34087
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
683 if inspect.ismodule(container):
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
684 # origfn is not an instance or class method. "partial" can be used.
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
685 # "partial" won't insert a frame in traceback.
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
686 wrap = functools.partial(wrapper, origfn)
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
687 else:
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
688 # "partial" cannot be safely used. Emulate its effect by using "bind".
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
689 # The downside is one more frame in traceback.
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34048
diff changeset
690 wrap = bind(wrapper, origfn)
29763
ce6317dcb944 extensions: set attributes to wrappers so we can trace them back
Jun Wu <quark@fb.com>
parents: 29461
diff changeset
691 _updatewrapper(wrap, origfn, wrapper)
28311
1b0ef07ba783 extensions: copy attributes to wrapper by wrapfunction()
Yuya Nishihara <yuya@tcha.org>
parents: 28310
diff changeset
692 setattr(container, funcname, wrap)
7215
0ab5f21c390b extensions: add wrapping functions
Matt Mackall <mpm@selenic.com>
parents: 7011
diff changeset
693 return origfn
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
694
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
695
29765
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
696 def unwrapfunction(container, funcname, wrapper=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
697 """undo wrapfunction
29765
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
698
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
699 If wrappers is None, undo the last wrap. Otherwise removes the wrapper
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
700 from the chain of wrappers.
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
701
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
702 Return the removed wrapper.
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
703 Raise IndexError if wrapper is None and nothing to unwrap; ValueError if
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
704 wrapper is not None but is not found in the wrapper chain.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
705 """
29765
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
706 chain = getwrapperchain(container, funcname)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
707 origfn = chain.pop()
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
708 if wrapper is None:
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
709 wrapper = chain[0]
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
710 chain.remove(wrapper)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
711 setattr(container, funcname, origfn)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
712 for w in reversed(chain):
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
713 wrapfunction(container, funcname, w)
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
714 return wrapper
19578bb84731 extensions: add unwrapfunction to undo wrapfunction
Jun Wu <quark@fb.com>
parents: 29764
diff changeset
715
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
716
29764
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
717 def getwrapperchain(container, funcname):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
718 """get a chain of wrappers of a function
29764
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
719
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
720 Return a list of functions: [newest wrapper, ..., oldest wrapper, origfunc]
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
721
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
722 The wrapper functions are the ones passed to wrapfunction, whose first
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
723 argument is origfunc.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
724 """
29764
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
725 result = []
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
726 fn = getattr(container, funcname)
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
727 while fn:
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
728 assert callable(fn)
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
729 result.append(getattr(fn, '_unboundwrapper', fn))
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
730 fn = getattr(fn, '_origfunc', None)
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
731 return result
8bf97c4c6c2a extensions: add getwrapperchain to get a list of wrappers
Jun Wu <quark@fb.com>
parents: 29763
diff changeset
732
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
733
38163
b39958d6b81b extensions: remove strip_init=True from _disabledpaths()
Yuya Nishihara <yuya@tcha.org>
parents: 38162
diff changeset
734 def _disabledpaths():
b39958d6b81b extensions: remove strip_init=True from _disabledpaths()
Yuya Nishihara <yuya@tcha.org>
parents: 38162
diff changeset
735 '''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
736 import hgext
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
737
49780
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
738 exts = {}
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
739
45105
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44657
diff changeset
740 # 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: 44657
diff changeset
741 # it might not be on a filesystem even if it does.
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50923
diff changeset
742 if hasattr(hgext, '__file__'):
45105
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44657
diff changeset
743 extpath = os.path.dirname(
47625
7bafe40ab78a windows: use abspath in extensions
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47055
diff changeset
744 util.abspath(pycompat.fsencode(hgext.__file__))
45105
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44657
diff changeset
745 )
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44657
diff changeset
746 try:
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44657
diff changeset
747 files = os.listdir(extpath)
5d09a120b4be extensions: make `hg nonexistent` not crash with PyOxidizer
Martin von Zweigbergk <martinvonz@google.com>
parents: 44657
diff changeset
748 except OSError:
49780
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
749 pass
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
750 else:
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
751 for e in files:
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
752 if e.endswith(b'.py'):
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
753 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: 49026
diff changeset
754 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: 49026
diff changeset
755 else:
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
756 name = e
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
757 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: 49026
diff changeset
758 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: 49026
diff changeset
759 continue
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
760 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: 49026
diff changeset
761 continue
9d8757ddd0ab extensions: process disabled external paths when `hgext` package is in-memory
Matt Harbison <matt_harbison@yahoo.com>
parents: 49026
diff changeset
762 exts[name] = path
8964
119d1f664eae extensions: catch OSError when hgext is not accessible (issue1708)
Cédric Duval <cedricduval@free.fr>
parents: 8896
diff changeset
763
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
diff changeset
764 for name, path in _disabledextensions.items():
33327
68b7ceda99d7 dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents: 33132
diff changeset
765 # If no path was provided for a disabled extension (e.g. "color=!"),
68b7ceda99d7 dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents: 33132
diff changeset
766 # don't replace the path we already found by the scan above.
68b7ceda99d7 dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents: 33132
diff changeset
767 if path:
68b7ceda99d7 dispatch: fix typo suggestion for disabled extension
Martin von Zweigbergk <martinvonz@google.com>
parents: 33132
diff changeset
768 exts[name] = path
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
769 return exts
8872
d0c0013f8713 extensions: simplify by selecting primary hgext
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8871
diff changeset
770
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
771
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
772 def _moduledoc(file):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
773 """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
774
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
775 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
776 handle triple quotes and to return the whole text instead of just
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
777 the synopsis"""
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
778 result = []
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
779
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
780 line = file.readline()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
781 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
782 line = file.readline()
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
783 if not line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
784 break
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
785
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
786 start = line[:3]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
787 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
788 line = line[3:]
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
789 while line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
790 if line.rstrip().endswith(start):
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
791 line = line.split(start)[0]
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
792 if line:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
793 result.append(line)
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
794 break
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
795 elif not line:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
796 return None # unmatched delimiter
14317
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 line = file.readline()
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
799 else:
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
800 return None
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
801
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
802 return b''.join(result)
14317
660b0c1b6196 extensions: move moduledoc to break import loop with help
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
803
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
804
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
805 def _disabledhelp(path):
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
806 '''retrieve help synopsis of a disabled extension (without importing)'''
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
807 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
808 with open(path, b'rb') as src:
38344
c6f82a18a63d extensions: use context manger for open()
Yuya Nishihara <yuya@tcha.org>
parents: 38343
diff changeset
809 doc = _moduledoc(src)
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
810 except IOError:
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
811 return
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
812
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
813 if doc: # extracting localized synopsis
30306
5581b294f3c6 help: show help for disabled extensions (issue5228)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30058
diff changeset
814 return gettext(doc)
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
815 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
816 return _(b'(no help text available)')
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
817
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
818
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
819 def disabled():
14530
cd31a1cc1521 extensions: update doc of enabled() and disabled() according to d5b525697ddb
Yuya Nishihara <yuya@tcha.org>
parents: 14415
diff changeset
820 '''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
821 try:
43705
1ea33dff7841 extensions: hide two confusing import statements from pytype
Augie Fackler <augie@google.com>
parents: 43506
diff changeset
822 from hgext import __index__ # pytype: disable=import-error
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
823
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43707
diff changeset
824 return {
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43707
diff changeset
825 name: gettext(desc)
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
diff changeset
826 for name, desc in __index__.docs.items()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
827 if name not in _order
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43707
diff changeset
828 }
21229
54d7657d7d1e setup.py, make: avoid problems with outdated, existing hgext/__index__.py*
Thomas Arendsen Hein <thomas@intevation.de>
parents: 20645
diff changeset
829 except (ImportError, AttributeError):
14539
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
830 pass
558ec14ba6be extensions: make disabled()/disabledext() load prebuilt index if available
Yuya Nishihara <yuya@tcha.org>
parents: 14530
diff changeset
831
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
832 paths = _disabledpaths()
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
833 if not paths:
16709
9eca39a91964 extensions.disabled: return {} instead of None no extensions are disabled
Augie Fackler <raf@durin42.com>
parents: 16667
diff changeset
834 return {}
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
835
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
836 exts = {}
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
diff changeset
837 for name, path in paths.items():
10363
c07974215b3d extensions: refactor disabled()
Brodie Rao <me+hg@dackz.net>
parents: 10263
diff changeset
838 doc = _disabledhelp(path)
46094
1ced08423d59 extensions: avoid including `__index__` in the disabled extension list
Matt Harbison <matt_harbison@yahoo.com>
parents: 46030
diff changeset
839 if doc and name != b'__index__':
49026
2d519511c5c3 extensions: use new function for getting first line of string
Martin von Zweigbergk <martinvonz@google.com>
parents: 48946
diff changeset
840 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
841
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
842 return exts
8871
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
843
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
844
44657
843418dc0b1b extensions: refactor function for obtaining disabled extension help
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44452
diff changeset
845 def disabled_help(name):
843418dc0b1b extensions: refactor function for obtaining disabled extension help
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44452
diff changeset
846 """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
847 paths = _disabledpaths()
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
848 if name in paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
849 return _disabledhelp(paths[name])
49781
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
850 else:
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
851 try:
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
852 import hgext
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
853 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: 49780
diff changeset
854
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
855 # 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: 49780
diff changeset
856 # or all are enabled.
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50923
diff changeset
857 if hasattr(hgext, '__file__'):
49781
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
858 return
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
859
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
860 if name in _order: # enabled
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
861 return
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
862 else:
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
863 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: 49780
diff changeset
864 except (ImportError, AttributeError):
f4a363b25859 extensions: load help from hgext.__index__ as a fallback this time
Matt Harbison <matt_harbison@yahoo.com>
parents: 49780
diff changeset
865 pass
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
866
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
867
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
868 def _walkcommand(node):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
869 """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: 38020
diff changeset
870 todo = collections.deque([node])
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
871 while todo:
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
872 node = todo.popleft()
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
873 if not isinstance(node, ast.FunctionDef):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
874 todo.extend(ast.iter_child_nodes(node))
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
875 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
876 for d in node.decorator_list:
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
877 if not isinstance(d, ast.Call):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
878 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
879 if not isinstance(d.func, ast.Name):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
880 continue
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43503
diff changeset
881 if d.func.id != 'command':
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
882 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
883 yield d
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
884
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
885
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
886 def _disabledcmdtable(path):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
887 """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: 38020
diff changeset
888
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
889 This may raise IOError or SyntaxError.
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
890 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
891 with open(path, b'rb') as src:
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
892 root = ast.parse(src.read(), path)
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
893 cmdtable = {}
50755
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
894
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
895 # 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: 49781
diff changeset
896 use_constant = 'Bytes' not in vars(ast)
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
897
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
898 for node in _walkcommand(root):
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
899 if not node.args:
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
900 continue
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
901 a = node.args[0]
50755
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
902 if use_constant: # Valid since Python 3.8
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
903 if isinstance(a, ast.Constant):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
904 if isinstance(a.value, str):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
905 name = pycompat.sysbytes(a.value)
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
906 elif isinstance(a.value, bytes):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
907 name = a.value
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
908 else:
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
909 continue
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
910 else:
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
911 continue
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
912 else: # Valid until 3.11
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
913 if isinstance(a, ast.Str):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
914 name = pycompat.sysbytes(a.s)
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
915 elif isinstance(a, ast.Bytes):
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
916 name = a.s
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
917 else:
b9eb65a1ec14 extensions: address ast deprecations introduced in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents: 49781
diff changeset
918 continue
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
919 cmdtable[name] = (None, [], b'')
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
920 return cmdtable
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
921
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
922
37974
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
923 def _finddisabledcmd(ui, cmd, name, path, strict):
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
924 try:
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
925 cmdtable = _disabledcmdtable(path)
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
926 except (IOError, SyntaxError):
37974
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
927 return
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
928 try:
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
929 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
37974
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
930 except (error.AmbiguousCommand, error.UnknownCommand):
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
931 return
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
932 for c in aliases:
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
933 if c.startswith(cmd):
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
934 cmd = c
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
935 break
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
936 else:
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
937 cmd = aliases[0]
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
938 doc = _disabledhelp(path)
37975
6e526b0961a8 help: load module doc of disabled extension in extensions.disabledcmd()
Yuya Nishihara <yuya@tcha.org>
parents: 37974
diff changeset
939 return (cmd, name, doc)
37974
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
940
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
941
13191
1aea66b71f4f extensions: warn about invalid extensions when listing disabled commands
Mads Kiilerich <mads@kiilerich.com>
parents: 12779
diff changeset
942 def disabledcmd(ui, cmd, strict=False):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
943 """find cmd from disabled extensions without importing.
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45899
diff changeset
944 returns (cmdname, extname, doc)"""
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
945
38162
bdf344aea0ee extensions: peek command table of disabled extensions without importing
Yuya Nishihara <yuya@tcha.org>
parents: 38020
diff changeset
946 paths = _disabledpaths()
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
947 if not paths:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
948 raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
949
16667
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
950 ext = None
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
951 # 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
952 path = paths.pop(cmd, None)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
953 if path:
37974
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
954 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
955 if not ext:
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
956 # otherwise, interrogate each extension until there's a match
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
diff changeset
957 for name, path in paths.items():
37974
b45f4c1532c0 extensions: extract closure that looks for commands from disabled module
Yuya Nishihara <yuya@tcha.org>
parents: 37973
diff changeset
958 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
959 if ext:
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
960 break
37973
5b60f7d652f2 extensions: drop dead code trying to exclude deprecated disabled commands
Yuya Nishihara <yuya@tcha.org>
parents: 37957
diff changeset
961 if ext:
16667
bdb7ae65c27c extensions: don't suggest commands from deprecated extensions
Martin Geisler <mg@lazybytes.net>
parents: 16666
diff changeset
962 return ext
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
963
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
964 raise error.UnknownCommand(cmd)
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10363
diff changeset
965
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
966
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
967 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
968 '''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
969 exts = {}
20a25042fadc extensions: move extensions listing functions from mercurial.help
Cédric Duval <cedricduval@free.fr>
parents: 8225
diff changeset
970 for ename, ext in extensions():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
971 doc = gettext(ext.__doc__) or _(b'(no help text available)')
46690
90a92f041fc6 typing: add an assertion instead of blacklisting mercurial/extensions.py
Matt Harbison <matt_harbison@yahoo.com>
parents: 46094
diff changeset
972 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
973 if shortname:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
974 ename = ename.split(b'.')[-1]
49026
2d519511c5c3 extensions: use new function for getting first line of string
Martin von Zweigbergk <martinvonz@google.com>
parents: 48946
diff changeset
975 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
976
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14079
diff changeset
977 return exts
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
978
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
979
28155
7f430b2ac7fd extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents: 27990
diff changeset
980 def notloaded():
7f430b2ac7fd extensions: add notloaded method to return extensions failed to load
Jun Wu <quark@fb.com>
parents: 27990
diff changeset
981 '''return short names of extensions that failed to load'''
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48894
diff changeset
982 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
983
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
984
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
985 def moduleversion(module):
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
986 '''return version information from given module as a string'''
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50923
diff changeset
987 if hasattr(module, 'getversion') and callable(module.getversion):
47055
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
988 try:
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
989 version = module.getversion()
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
990 except Exception:
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
991 version = b'unknown'
553451522113 extensions: ignore exceptions from an extension's `getversion()` method
Matt Harbison <matt_harbison@yahoo.com>
parents: 46819
diff changeset
992
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50923
diff changeset
993 elif hasattr(module, '__version__'):
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
994 version = module.__version__
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
995 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
996 version = b''
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
997 if isinstance(version, (list, tuple)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
998 version = b'.'.join(pycompat.bytestr(o) for o in version)
46025
27c23c8f14da extensions: avoid a crash when the version isn't properly byteified on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 45899
diff changeset
999 else:
27c23c8f14da extensions: avoid a crash when the version isn't properly byteified on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 45899
diff changeset
1000 # 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: 45899
diff changeset
1001 # to py3.
27c23c8f14da extensions: avoid a crash when the version isn't properly byteified on py3
Matt Harbison <matt_harbison@yahoo.com>
parents: 45899
diff changeset
1002 version = stringutil.forcebytestr(version)
21848
ecdbbb6e5d06 version: show enabled extensions (issue4209)
anatoly techtonik <techtonik@gmail.com>
parents: 21795
diff changeset
1003 return version
27990
96bfd2875213 version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents: 27637
diff changeset
1004
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42547
diff changeset
1005
27990
96bfd2875213 version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents: 27637
diff changeset
1006 def ismoduleinternal(module):
96bfd2875213 version: verbose list internal and external extension source (issue4731)
liscju <piotr.listkiewicz@gmail.com>
parents: 27637
diff changeset
1007 exttestedwith = getattr(module, 'testedwith', None)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1008 return exttestedwith == b"ships-with-hg-core"