Submitter | liscju |
---|---|
Date | Oct. 8, 2016, 3:22 p.m. |
Message ID | <5497a92be82db414f691.1475940146@liscju-VirtualBox> |
Download | mbox | patch |
Permalink | /patch/16936/ |
State | Changes Requested |
Headers | show |
Comments
On Sat, 08 Oct 2016 17:22:26 +0200, liscju wrote: > # HG changeset patch > # User liscju <piotr.listkiewicz@gmail.com> > # Date 1475926049 -7200 > # Sat Oct 08 13:27:29 2016 +0200 > # Node ID 5497a92be82db414f6913f869d5acd18b205cb2b > # Parent 91a3c58ecf938ed675f5364b88f0d663f12b0047 > help: show help content for disabled extension > > So far for disabled extension help showed only extension > summary. This commit makes help read content of the help > comments in extension module without actually loading > the module. > > diff --git a/mercurial/help.py b/mercurial/help.py > --- a/mercurial/help.py > +++ b/mercurial/help.py > @@ -7,6 +7,7 @@ > > from __future__ import absolute_import > > +import ast > import itertools > import os > import textwrap > @@ -300,6 +301,38 @@ addtopicsymbols('templates', '.. functio > addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands, > dedent=True) > > +def parsedisabledext(modname): Have you tried the simpler way you pointed out? I said we could use ast since I didn't know that. https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-September/087972.html > + # return list of (command_name, command_module, command_doc) > + def finddisabledext(name): > + paths = extensions._disabledpaths() > + if name in paths: > + return paths[name] > + return None > + > + def iscmd(funast): > + for decorator in funast.decorator_list: > + if isinstance(decorator, ast.Call) and decorator.func.id == 'command': > + return True > + return False > + > + def extractcmds(extast): > + return [funast.name for funast in extast.body if isinstance(funast, ast.FunctionDef) and iscmd(funast)] > + > + def extractcmddoc(extast, cmd): > + funasts = [funast for funast in extast.body > + if isinstance(funast, ast.FunctionDef) and iscmd(funast) and funast.name == cmd] > + if len(funasts) > 0: > + return ast.get_docstring(funasts[0]) > + else: > + return None > + > + extfile = open(finddisabledext(modname), 'r') > + try: > + extast = ast.parse(extfile.read()) > + return [(cmdname, modname, extractcmddoc(extast, cmdname)) for cmdname in extractcmds(extast)] > + except SyntaxError: > + return [] Though we could provide the list of commands possibly defined by the disabled extension, I don't think that's necessary because that would complicate things.
Have we considered supporting `hg help churn.churn` where the first churn is a (possibly) disabled extension name, and the second is the name of a command within that extension? I'm not saying we should do this right away, but I can see some advantages to being able to support it later...
On Fri, 21 Oct 2016 09:13:11 -0400, timeless wrote: > Have we considered supporting `hg help churn.churn` where the first > churn is a (possibly) disabled extension name, and the second is the > name of a command within that extension? Not yet? > I'm not saying we should do this right away, but I can see some > advantages to being able to support it later... Perhaps that would be somewhat useful, but would be much complicated compared to just parsing a module doc. That's why I think we should simply fix the issue5228 first. https://bz.mercurial-scm.org/show_bug.cgi?id=5228
On Sat, Oct 22, 2016 at 1:38 PM, Yuya Nishihara <yuya@tcha.org> wrote: > On Fri, 21 Oct 2016 09:13:11 -0400, timeless wrote: >> Have we considered supporting `hg help churn.churn` where the first >> churn is a (possibly) disabled extension name, and the second is the >> name of a command within that extension? > > Not yet? Well working on issue5228, I found that we support something like `hg help qrecord` and if record extension is not enabled it will say, 'qrecord' is provided by the following extension: record commands to interactively select changes for commit/qrefresh (DEPRECATED) (use 'hg help extensions' for information on enabling extensions) We support saying that this command is provided by the following extension, if the extension is disabled. >> I'm not saying we should do this right away, but I can see some >> advantages to being able to support it later... > > Perhaps that would be somewhat useful, but would be much complicated compared > to just parsing a module doc. That's why I think we should simply fix the > issue5228 first. > > https://bz.mercurial-scm.org/show_bug.cgi?id=5228 > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
On Mon, 31 Oct 2016 23:44:27 +0530, Pulkit Goyal wrote: > On Sat, Oct 22, 2016 at 1:38 PM, Yuya Nishihara <yuya@tcha.org> wrote: > > On Fri, 21 Oct 2016 09:13:11 -0400, timeless wrote: > >> Have we considered supporting `hg help churn.churn` where the first > >> churn is a (possibly) disabled extension name, and the second is the > >> name of a command within that extension? > > > > Not yet? > > Well working on issue5228, I found that we support something like `hg > help qrecord` and > if record extension is not enabled it will say, > > 'qrecord' is provided by the following extension: > > record commands to interactively select changes for commit/qrefresh > (DEPRECATED) > (use 'hg help extensions' for information on enabling extensions) > > We support saying that this command is provided by the following > extension, if the > extension is disabled. Yep, we try importing all extension modules to provide this message. That's why "hg unknown-command" is slow. I don't think we should reuse this hack to provide the help of disabled extensions since that would mean disabled modules could be loaded into long-running hgweb processes.
Patch
diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -7,6 +7,7 @@ from __future__ import absolute_import +import ast import itertools import os import textwrap @@ -300,6 +301,38 @@ addtopicsymbols('templates', '.. functio addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands, dedent=True) +def parsedisabledext(modname): + # return list of (command_name, command_module, command_doc) + def finddisabledext(name): + paths = extensions._disabledpaths() + if name in paths: + return paths[name] + return None + + def iscmd(funast): + for decorator in funast.decorator_list: + if isinstance(decorator, ast.Call) and decorator.func.id == 'command': + return True + return False + + def extractcmds(extast): + return [funast.name for funast in extast.body if isinstance(funast, ast.FunctionDef) and iscmd(funast)] + + def extractcmddoc(extast, cmd): + funasts = [funast for funast in extast.body + if isinstance(funast, ast.FunctionDef) and iscmd(funast) and funast.name == cmd] + if len(funasts) > 0: + return ast.get_docstring(funasts[0]) + else: + return None + + extfile = open(finddisabledext(modname), 'r') + try: + extast = ast.parse(extfile.read()) + return [(cmdname, modname, extractcmddoc(extast, cmdname)) for cmdname in extractcmds(extast)] + except SyntaxError: + return [] + def help_(ui, name, unknowncmd=False, full=True, subtopic=None, **opts): ''' Generate the help for 'name' as unformatted restructured text. If @@ -395,7 +428,7 @@ def help_(ui, name, unknowncmd=False, fu return rst - def helplist(select=None, **opts): + def helplist(select=None, disabledext=None, **opts): # list of commands if name == "shortlist": header = _('basic commands:\n\n') @@ -406,17 +439,24 @@ def help_(ui, name, unknowncmd=False, fu h = {} cmds = {} - for c, e in commands.table.iteritems(): + + if not disabledext: + commandinfos = [(c, e[0].__module__, e[0].__doc__) for c, e in commands.table.iteritems()] + else: + commandinfos = parsedisabledext(disabledext) + + for cmdname, cmdmod, cmddoc in commandinfos: + c = cmdname f = c.partition("|")[0] if select and not select(f): continue if (not select and name != 'shortlist' and - e[0].__module__ != commands.__name__): + cmdmod != commands.__name__): continue if name == "shortlist" and not f.startswith("^"): continue f = f.lstrip("^") - doc = e[0].__doc__ + doc = cmddoc if filtercmd(ui, f, name, doc): continue doc = gettext(doc) @@ -548,7 +588,8 @@ def help_(ui, name, unknowncmd=False, fu modcmds = set([c.partition('|')[0] for c in ct]) rst.extend(helplist(modcmds.__contains__)) else: - rst.append(_("(use 'hg help extensions' for information on enabling" + rst.extend(helplist(lambda w: True, disabledext=name)) + rst.append(_("\n(use 'hg help extensions' for information on enabling" " extensions)\n")) return rst diff --git a/tests/test-extension.t b/tests/test-extension.t --- a/tests/test-extension.t +++ b/tests/test-extension.t @@ -1040,11 +1040,23 @@ Disabled extensions: $ hg help churn churn extension - command to display statistics about repository history + list of commands: + + churn histogram of changes to the repository + + (use 'hg help -v -e churn' to show built-in aliases and global options) + (use 'hg help extensions' for information on enabling extensions) $ hg help patchbomb patchbomb extension - command to send changesets as (a series of) patch emails + list of commands: + + email send changesets by email + + (use 'hg help -v patchbomb' to show built-in aliases and global options) + (use 'hg help extensions' for information on enabling extensions) @@ -1065,6 +1077,8 @@ Broken disabled extension and command: $ hg --config extensions.path=./path.py help broken broken extension - (no help text available) + no commands defined + (use 'hg help extensions' for information on enabling extensions) diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -1636,6 +1636,8 @@ Show help content of disabled extensions $ hg help -e ambiguous ambiguous extension - (no help text available) + no commands defined + (use 'hg help extensions' for information on enabling extensions) Test dynamic list of merge tools only shows up once diff --git a/tests/test-qrecord.t b/tests/test-qrecord.t --- a/tests/test-qrecord.t +++ b/tests/test-qrecord.t @@ -9,6 +9,13 @@ help record (no record) record extension - commands to interactively select changes for commit/qrefresh (DEPRECATED) + list of commands: + + qrecord interactively record a new patch + record interactively select changes to commit + + (use 'hg help -v -e record' to show built-in aliases and global options) + (use 'hg help extensions' for information on enabling extensions) help qrecord (no record)