##// END OF EJS Templates
dispatch: provide help for disabled extensions and commands...
Brodie Rao -
r10364:de1e7099 default
parent child Browse files
Show More
@@ -1457,7 +1457,7 def heads(ui, repo, *branchrevs, **opts)
1457 1457 displayer.show(ctx)
1458 1458 displayer.close()
1459 1459
1460 def help_(ui, name=None, with_version=False):
1460 def help_(ui, name=None, with_version=False, unknowncmd=False):
1461 1461 """show help for a given topic or a help overview
1462 1462
1463 1463 With no arguments, print a list of commands with short help messages.
@@ -1490,7 +1490,7 def help_(ui, name=None, with_version=Fa
1490 1490 ui.write('\n')
1491 1491
1492 1492 try:
1493 aliases, entry = cmdutil.findcmd(name, table, False)
1493 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1494 1494 except error.AmbiguousCommand, inst:
1495 1495 # py3k fix: except vars can't be used outside the scope of the
1496 1496 # except block, nor can be used inside a lambda. python issue4617
@@ -1501,6 +1501,7 def help_(ui, name=None, with_version=Fa
1501 1501
1502 1502 # check if it's an invalid alias and display its error if it is
1503 1503 if getattr(entry[0], 'badalias', False):
1504 if not unknowncmd:
1504 1505 entry[0](ui)
1505 1506 return
1506 1507
@@ -1592,10 +1593,13 def help_(ui, name=None, with_version=Fa
1592 1593 def helpext(name):
1593 1594 try:
1594 1595 mod = extensions.find(name)
1596 doc = gettext(mod.__doc__) or _('no help text available')
1595 1597 except KeyError:
1598 mod = None
1599 doc = extensions.disabledext(name)
1600 if not doc:
1596 1601 raise error.UnknownCommand(name)
1597 1602
1598 doc = gettext(mod.__doc__) or _('no help text available')
1599 1603 if '\n' not in doc:
1600 1604 head, tail = doc, ""
1601 1605 else:
@@ -1605,17 +1609,36 def help_(ui, name=None, with_version=Fa
1605 1609 ui.write(minirst.format(tail, textwidth))
1606 1610 ui.status('\n\n')
1607 1611
1612 if mod:
1608 1613 try:
1609 1614 ct = mod.cmdtable
1610 1615 except AttributeError:
1611 1616 ct = {}
1612
1613 1617 modcmds = set([c.split('|', 1)[0] for c in ct])
1614 1618 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1619 else:
1620 ui.write(_('use "hg help extensions" for information on enabling '
1621 'extensions\n'))
1622
1623 def helpextcmd(name):
1624 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1625 doc = gettext(mod.__doc__).splitlines()[0]
1626
1627 msg = help.listexts(_("'%s' is provided by the following "
1628 "extension:") % cmd, {ext: doc}, len(ext),
1629 indent=4)
1630 ui.write(minirst.format(msg, textwidth))
1631 ui.write('\n\n')
1632 ui.write(_('use "hg help extensions" for information on enabling '
1633 'extensions\n'))
1615 1634
1616 1635 if name and name != 'shortlist':
1617 1636 i = None
1618 for f in (helptopic, helpcmd, helpext):
1637 if unknowncmd:
1638 queries = (helpextcmd,)
1639 else:
1640 queries = (helptopic, helpcmd, helpext, helpextcmd)
1641 for f in queries:
1619 1642 try:
1620 1643 f(name)
1621 1644 i = None
@@ -93,6 +93,11 def _runcatch(ui, args):
93 93 ui.warn(_("killed!\n"))
94 94 except error.UnknownCommand, inst:
95 95 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
96 try:
97 # check if the command is in a disabled extension
98 # (but don't check for extensions themselves)
99 commands.help_(ui, inst.args[0], unknowncmd=True)
100 except error.UnknownCommand:
96 101 commands.help_(ui, 'shortlist')
97 102 except util.Abort, inst:
98 103 ui.warn(_("abort: %s\n") % inst)
@@ -218,6 +223,11 class cmdalias(object):
218 223 def fn(ui, *args):
219 224 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
220 225 % (self.name, cmd))
226 try:
227 # check if the command is in a disabled extension
228 commands.help_(ui, cmd, unknowncmd=True)
229 except error.UnknownCommand:
230 pass
221 231 return 1
222 232 self.fn = fn
223 233 self.badalias = True
@@ -6,7 +6,7
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 import imp, os
9 import util, cmdutil, help
9 import util, cmdutil, help, error
10 10 from i18n import _, gettext
11 11
12 12 _extensions = {}
@@ -131,8 +131,9 def wrapfunction(container, funcname, wr
131 131 setattr(container, funcname, wrap)
132 132 return origfn
133 133
134 def _disabledpaths():
135 '''find paths of disabled extensions. returns a dict of {name: path}'''
134 def _disabledpaths(strip_init=False):
135 '''find paths of disabled extensions. returns a dict of {name: path}
136 removes /__init__.py from packages if strip_init is True'''
136 137 import hgext
137 138 extpath = os.path.dirname(os.path.abspath(hgext.__file__))
138 139 try: # might not be a filesystem path
@@ -150,6 +151,8 def _disabledpaths():
150 151 path = os.path.join(extpath, e, '__init__.py')
151 152 if not os.path.exists(path):
152 153 continue
154 if strip_init:
155 path = os.path.dirname(path)
153 156 if name in exts or name in _order or name == '__init__':
154 157 continue
155 158 exts[name] = path
@@ -191,6 +194,53 def disabled():
191 194
192 195 return exts, maxlength
193 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)
243
194 244 def enabled():
195 245 '''return a dict of {name: desc} of extensions, and the max name length'''
196 246 exts = {}
@@ -42,13 +42,14 def moduledoc(file):
42 42
43 43 return ''.join(result)
44 44
45 def listexts(header, exts, maxlength):
45 def listexts(header, exts, maxlength, indent=1):
46 46 '''return a text listing of the given extensions'''
47 47 if not exts:
48 48 return ''
49 49 result = '\n%s\n\n' % header
50 50 for name, desc in sorted(exts.iteritems()):
51 result += ' %-*s %s\n' % (maxlength + 2, ':%s:' % name, desc)
51 result += '%s%-*s %s\n' % (' ' * indent, maxlength + 2,
52 ':%s:' % name, desc)
52 53 return result
53 54
54 55 def extshelp():
@@ -153,3 +153,27 echo "hgext/mq=" >> $HGRCPATH
153 153
154 154 echo % show extensions
155 155 hg debugextensions
156
157 echo '% disabled extension commands'
158 HGRCPATH=
159 hg help email
160 hg qdel
161 hg churn
162 echo '% disabled extensions'
163 hg help churn
164 hg help patchbomb
165 echo '% broken disabled extension and command'
166 mkdir hgext
167 echo > hgext/__init__.py
168 cat > hgext/broken.py <<EOF
169 "broken extension'
170 EOF
171 TMPPYTHONPATH="$PYTHONPATH"
172 PYTHONPATH="`pwd`:$PYTHONPATH"
173 export PYTHONPATH
174 hg help broken
175 hg help foo > /dev/null
176 PYTHONPATH="$TMPPYTHONPATH"
177 export PYTHONPATH
178
179 exit 0
@@ -96,3 +96,33 global options:
96 96 % show extensions
97 97 debugissue811
98 98 mq
99 % disabled extension commands
100 'email' is provided by the following extension:
101
102 patchbomb command to send changesets as (a series of) patch emails
103
104 use "hg help extensions" for information on enabling extensions
105 hg: unknown command 'qdel'
106 'qdelete' is provided by the following extension:
107
108 mq manage a stack of patches
109
110 use "hg help extensions" for information on enabling extensions
111 hg: unknown command 'churn'
112 'churn' is provided by the following extension:
113
114 churn command to display statistics about repository history
115
116 use "hg help extensions" for information on enabling extensions
117 % disabled extensions
118 churn extension - command to display statistics about repository history
119
120 use "hg help extensions" for information on enabling extensions
121 patchbomb extension - command to send changesets as (a series of) patch emails
122
123 use "hg help extensions" for information on enabling extensions
124 % broken disabled extension and command
125 broken extension - (no help text available)
126
127 use "hg help extensions" for information on enabling extensions
128 hg: unknown command 'foo'
General Comments 0
You need to be logged in to leave comments. Login now