##// END OF EJS Templates
extensions: check for path existence only when necessary
Cédric Duval -
r8877:08636e18 default
parent child Browse files
Show More
@@ -1,182 +1,184
1 # extensions.py - extension handling for mercurial
1 # extensions.py - extension handling for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 import imp, os, sys
8 import imp, os, sys
9 import util, cmdutil, help
9 import util, cmdutil, help
10 from i18n import _, gettext
10 from i18n import _, gettext
11
11
12 _extensions = {}
12 _extensions = {}
13 _order = []
13 _order = []
14
14
15 def extensions():
15 def extensions():
16 for name in _order:
16 for name in _order:
17 module = _extensions[name]
17 module = _extensions[name]
18 if module:
18 if module:
19 yield name, module
19 yield name, module
20
20
21 def find(name):
21 def find(name):
22 '''return module with given extension name'''
22 '''return module with given extension name'''
23 try:
23 try:
24 return _extensions[name]
24 return _extensions[name]
25 except KeyError:
25 except KeyError:
26 for k, v in _extensions.iteritems():
26 for k, v in _extensions.iteritems():
27 if k.endswith('.' + name) or k.endswith('/' + name):
27 if k.endswith('.' + name) or k.endswith('/' + name):
28 return v
28 return v
29 raise KeyError(name)
29 raise KeyError(name)
30
30
31 def loadpath(path, module_name):
31 def loadpath(path, module_name):
32 module_name = module_name.replace('.', '_')
32 module_name = module_name.replace('.', '_')
33 path = os.path.expanduser(path)
33 path = os.path.expanduser(path)
34 if os.path.isdir(path):
34 if os.path.isdir(path):
35 # module/__init__.py style
35 # module/__init__.py style
36 d, f = os.path.split(path.rstrip('/'))
36 d, f = os.path.split(path.rstrip('/'))
37 fd, fpath, desc = imp.find_module(f, [d])
37 fd, fpath, desc = imp.find_module(f, [d])
38 return imp.load_module(module_name, fd, fpath, desc)
38 return imp.load_module(module_name, fd, fpath, desc)
39 else:
39 else:
40 return imp.load_source(module_name, path)
40 return imp.load_source(module_name, path)
41
41
42 def load(ui, name, path):
42 def load(ui, name, path):
43 if name.startswith('hgext.') or name.startswith('hgext/'):
43 if name.startswith('hgext.') or name.startswith('hgext/'):
44 shortname = name[6:]
44 shortname = name[6:]
45 else:
45 else:
46 shortname = name
46 shortname = name
47 if shortname in _extensions:
47 if shortname in _extensions:
48 return
48 return
49 _extensions[shortname] = None
49 _extensions[shortname] = None
50 if path:
50 if path:
51 # the module will be loaded in sys.modules
51 # the module will be loaded in sys.modules
52 # choose an unique name so that it doesn't
52 # choose an unique name so that it doesn't
53 # conflicts with other modules
53 # conflicts with other modules
54 mod = loadpath(path, 'hgext.%s' % name)
54 mod = loadpath(path, 'hgext.%s' % name)
55 else:
55 else:
56 def importh(name):
56 def importh(name):
57 mod = __import__(name)
57 mod = __import__(name)
58 components = name.split('.')
58 components = name.split('.')
59 for comp in components[1:]:
59 for comp in components[1:]:
60 mod = getattr(mod, comp)
60 mod = getattr(mod, comp)
61 return mod
61 return mod
62 try:
62 try:
63 mod = importh("hgext.%s" % name)
63 mod = importh("hgext.%s" % name)
64 except ImportError:
64 except ImportError:
65 mod = importh(name)
65 mod = importh(name)
66 _extensions[shortname] = mod
66 _extensions[shortname] = mod
67 _order.append(shortname)
67 _order.append(shortname)
68
68
69 uisetup = getattr(mod, 'uisetup', None)
69 uisetup = getattr(mod, 'uisetup', None)
70 if uisetup:
70 if uisetup:
71 uisetup(ui)
71 uisetup(ui)
72
72
73 def loadall(ui):
73 def loadall(ui):
74 result = ui.configitems("extensions")
74 result = ui.configitems("extensions")
75 for (name, path) in result:
75 for (name, path) in result:
76 if path:
76 if path:
77 if path[0] == '!':
77 if path[0] == '!':
78 continue
78 continue
79 try:
79 try:
80 load(ui, name, path)
80 load(ui, name, path)
81 except KeyboardInterrupt:
81 except KeyboardInterrupt:
82 raise
82 raise
83 except Exception, inst:
83 except Exception, inst:
84 if path:
84 if path:
85 ui.warn(_("*** failed to import extension %s from %s: %s\n")
85 ui.warn(_("*** failed to import extension %s from %s: %s\n")
86 % (name, path, inst))
86 % (name, path, inst))
87 else:
87 else:
88 ui.warn(_("*** failed to import extension %s: %s\n")
88 ui.warn(_("*** failed to import extension %s: %s\n")
89 % (name, inst))
89 % (name, inst))
90 if ui.traceback():
90 if ui.traceback():
91 return 1
91 return 1
92
92
93 def wrapcommand(table, command, wrapper):
93 def wrapcommand(table, command, wrapper):
94 aliases, entry = cmdutil.findcmd(command, table)
94 aliases, entry = cmdutil.findcmd(command, table)
95 for alias, e in table.iteritems():
95 for alias, e in table.iteritems():
96 if e is entry:
96 if e is entry:
97 key = alias
97 key = alias
98 break
98 break
99
99
100 origfn = entry[0]
100 origfn = entry[0]
101 def wrap(*args, **kwargs):
101 def wrap(*args, **kwargs):
102 return util.checksignature(wrapper)(
102 return util.checksignature(wrapper)(
103 util.checksignature(origfn), *args, **kwargs)
103 util.checksignature(origfn), *args, **kwargs)
104
104
105 wrap.__doc__ = getattr(origfn, '__doc__')
105 wrap.__doc__ = getattr(origfn, '__doc__')
106 wrap.__module__ = getattr(origfn, '__module__')
106 wrap.__module__ = getattr(origfn, '__module__')
107
107
108 newentry = list(entry)
108 newentry = list(entry)
109 newentry[0] = wrap
109 newentry[0] = wrap
110 table[key] = tuple(newentry)
110 table[key] = tuple(newentry)
111 return entry
111 return entry
112
112
113 def wrapfunction(container, funcname, wrapper):
113 def wrapfunction(container, funcname, wrapper):
114 def wrap(*args, **kwargs):
114 def wrap(*args, **kwargs):
115 return wrapper(origfn, *args, **kwargs)
115 return wrapper(origfn, *args, **kwargs)
116
116
117 origfn = getattr(container, funcname)
117 origfn = getattr(container, funcname)
118 setattr(container, funcname, wrap)
118 setattr(container, funcname, wrap)
119 return origfn
119 return origfn
120
120
121 def disabled():
121 def disabled():
122 '''find disabled extensions from hgext
122 '''find disabled extensions from hgext
123 returns a dict of {name: desc}, and the max name length'''
123 returns a dict of {name: desc}, and the max name length'''
124
124
125 import hgext
125 import hgext
126 extpath = os.path.dirname(os.path.abspath(hgext.__file__))
126 extpath = os.path.dirname(os.path.abspath(hgext.__file__))
127
127
128 exts = {}
128 exts = {}
129 maxlength = 0
129 maxlength = 0
130 for e in os.listdir(extpath):
130 for e in os.listdir(extpath):
131
131
132 if e.endswith('.py'):
132 if e.endswith('.py'):
133 name = e.rsplit('.', 1)[0]
133 name = e.rsplit('.', 1)[0]
134 path = os.path.join(extpath, e)
134 path = os.path.join(extpath, e)
135 else:
135 else:
136 name = e
136 name = e
137 path = os.path.join(extpath, e, '__init__.py')
137 path = os.path.join(extpath, e, '__init__.py')
138 if not os.path.exists(path):
139 continue
138
140
139 if name in exts or name == '__init__' or not os.path.exists(path):
141 if name in exts or name == '__init__':
140 continue
142 continue
141
143
142 try:
144 try:
143 find(name)
145 find(name)
144 except KeyError:
146 except KeyError:
145 pass
147 pass
146 else:
148 else:
147 continue # enabled extension
149 continue # enabled extension
148
150
149 try:
151 try:
150 file = open(path)
152 file = open(path)
151 except IOError:
153 except IOError:
152 continue
154 continue
153 else:
155 else:
154 doc = help.moduledoc(file)
156 doc = help.moduledoc(file)
155 file.close()
157 file.close()
156
158
157 if doc: # extracting localized synopsis
159 if doc: # extracting localized synopsis
158 exts[name] = gettext(doc).splitlines()[0]
160 exts[name] = gettext(doc).splitlines()[0]
159 else:
161 else:
160 exts[name] = _('(no help text available)')
162 exts[name] = _('(no help text available)')
161
163
162 if len(name) > maxlength:
164 if len(name) > maxlength:
163 maxlength = len(name)
165 maxlength = len(name)
164
166
165 return exts, maxlength
167 return exts, maxlength
166
168
167 def enabled():
169 def enabled():
168 '''return a dict of {name: desc} of extensions, and the max name length'''
170 '''return a dict of {name: desc} of extensions, and the max name length'''
169
171
170 if not enabled:
172 if not enabled:
171 return {}, 0
173 return {}, 0
172
174
173 exts = {}
175 exts = {}
174 maxlength = 0
176 maxlength = 0
175 exthelps = []
177 exthelps = []
176 for ename, ext in extensions():
178 for ename, ext in extensions():
177 doc = (gettext(ext.__doc__) or _('(no help text available)'))
179 doc = (gettext(ext.__doc__) or _('(no help text available)'))
178 ename = ename.split('.')[-1]
180 ename = ename.split('.')[-1]
179 maxlength = max(len(ename), maxlength)
181 maxlength = max(len(ename), maxlength)
180 exts[ename] = doc.splitlines(0)[0].strip()
182 exts[ename] = doc.splitlines(0)[0].strip()
181
183
182 return exts, maxlength
184 return exts, maxlength
General Comments 0
You need to be logged in to leave comments. Login now