comparison mercurial/extensions.py @ 10364:de1e7099d100

dispatch: provide help for disabled extensions and commands Before a command is declared unknown, each extension in hgext is searched, starting with hgext.<cmdname>. If there's a matching command, a help message suggests the appropriate extension and how to enable it. Every extension could potentially be imported, but for cases like rebase, relink, etc. only one extension is imported. For the case of "hg help disabledext", if the extension is in hgext, the extension description is read and a similar help suggestion is printed. No extension import occurs.
author Brodie Rao <me+hg@dackz.net>
date Sun, 07 Feb 2010 14:01:43 +0100
parents c07974215b3d
children 367ce8514da0
comparison
equal deleted inserted replaced
10363:c07974215b3d 10364:de1e7099d100
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 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 import imp, os 8 import imp, os
9 import util, cmdutil, help 9 import util, cmdutil, help, error
10 from i18n import _, gettext 10 from i18n import _, gettext
11 11
12 _extensions = {} 12 _extensions = {}
13 _order = [] 13 _order = []
14 14
129 129
130 origfn = getattr(container, funcname) 130 origfn = getattr(container, funcname)
131 setattr(container, funcname, wrap) 131 setattr(container, funcname, wrap)
132 return origfn 132 return origfn
133 133
134 def _disabledpaths(): 134 def _disabledpaths(strip_init=False):
135 '''find paths of disabled extensions. returns a dict of {name: path}''' 135 '''find paths of disabled extensions. returns a dict of {name: path}
136 removes /__init__.py from packages if strip_init is True'''
136 import hgext 137 import hgext
137 extpath = os.path.dirname(os.path.abspath(hgext.__file__)) 138 extpath = os.path.dirname(os.path.abspath(hgext.__file__))
138 try: # might not be a filesystem path 139 try: # might not be a filesystem path
139 files = os.listdir(extpath) 140 files = os.listdir(extpath)
140 except OSError: 141 except OSError:
148 else: 149 else:
149 name = e 150 name = e
150 path = os.path.join(extpath, e, '__init__.py') 151 path = os.path.join(extpath, e, '__init__.py')
151 if not os.path.exists(path): 152 if not os.path.exists(path):
152 continue 153 continue
154 if strip_init:
155 path = os.path.dirname(path)
153 if name in exts or name in _order or name == '__init__': 156 if name in exts or name in _order or name == '__init__':
154 continue 157 continue
155 exts[name] = path 158 exts[name] = path
156 return exts 159 return exts
157 160
188 exts[name] = doc 191 exts[name] = doc
189 if len(name) > maxlength: 192 if len(name) > maxlength:
190 maxlength = len(name) 193 maxlength = len(name)
191 194
192 return exts, maxlength 195 return exts, maxlength
196
197 def disabledext(name):
198 '''find a specific disabled extension from hgext. returns desc'''
199 paths = _disabledpaths()
200 if name in paths:
201 return _disabledhelp(paths[name])
202
203 def disabledcmd(cmd, strict=False):
204 '''import disabled extensions until cmd is found.
205 returns (cmdname, extname, doc)'''
206
207 paths = _disabledpaths(strip_init=True)
208 if not paths:
209 raise error.UnknownCommand(cmd)
210
211 def findcmd(cmd, name, path):
212 try:
213 mod = loadpath(path, 'hgext.%s' % name)
214 except Exception:
215 return
216 try:
217 aliases, entry = cmdutil.findcmd(cmd,
218 getattr(mod, 'cmdtable', {}), strict)
219 except (error.AmbiguousCommand, error.UnknownCommand):
220 return
221 for c in aliases:
222 if c.startswith(cmd):
223 cmd = c
224 break
225 else:
226 cmd = aliases[0]
227 return (cmd, name, mod)
228
229 # first, search for an extension with the same name as the command
230 path = paths.pop(cmd, None)
231 if path:
232 ext = findcmd(cmd, cmd, path)
233 if ext:
234 return ext
235
236 # otherwise, interrogate each extension until there's a match
237 for name, path in paths.iteritems():
238 ext = findcmd(cmd, name, path)
239 if ext:
240 return ext
241
242 raise error.UnknownCommand(cmd)
193 243
194 def enabled(): 244 def enabled():
195 '''return a dict of {name: desc} of extensions, and the max name length''' 245 '''return a dict of {name: desc} of extensions, and the max name length'''
196 exts = {} 246 exts = {}
197 maxlength = 0 247 maxlength = 0