help: supporting both help and doc for aliases
ClosedPublic

Authored by rdamazio on Mar 4 2018, 5:15 PM.

Details

Summary

This allows an alias to be definted like:

[alias]
lj = log -Tjson
lj:help = [-r REV]
lj:doc = Shows the revision log in JSON format.

Diff Detail

Repository
rHG Mercurial
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
rdamazio created this revision.Mar 4 2018, 5:15 PM
pulkit added a subscriber: pulkit.Mar 4 2018, 5:18 PM

I am very very much excited about this. But, this patch lacks test. :(

rdamazio updated this revision to Diff 6634.Mar 4 2018, 5:40 PM
In D2678#43196, @pulkit wrote:

I am very very much excited about this. But, this patch lacks test. :(

Sorry, added now (and re-running tests in parallel)

(I'll have more test updates in a min, sorry, please hold :) )

rdamazio updated this revision to Diff 6635.Mar 4 2018, 6:09 PM

Ok, should be good to go now :)

I really like this feature too. Any plans to extend it to {fileset,revset,template}alias?

I don't think this should prevent it from being accepted, but is there a way to get the help text rendered as-is, without reflowing? For example, to simulate the usual 1 line summary + extended detail, I tried:

[alias]
phabimport:doc = Import a stack of revisions from phabricator.
  .
  This is extended help.

That got me:

$ ../hg help phabimport
hg phabimport

shell alias for: "%HG%" phabread $1 | "%HG%" import --bypass -

Import a stack of revisions from phabricator. . This is extended help.

defined by: c:\Users\Matt\projects\hg\.hg\hgrc:28

(some details hidden, use --verbose to show complete help)

(The middle '.' line is necessary, because the config parser throws away empty lines, complains about unexpected leading whitespace in the next line, and then exits without the usual 'abort: ' prefix. That bad format even kills hg version, but the output does indicate exactly where the problem is.)

(I'm stepping in and responding while rdamazio is out for a few days)

I really like this feature too. Any plans to extend it to {fileset,revset,template}alias?

We don't have any concrete plans to do so, but would not be opposed.

I don't think this should prevent it from being accepted, but is there a way to get the help text rendered as-is, without reflowing? For example, to simulate the usual 1 line summary + extended detail, I tried:

[alias]
phabimport:doc = Import a stack of revisions from phabricator.
  .
  This is extended help.

That got me:

$ ../hg help phabimport
hg phabimport

shell alias for: "%HG%" phabread $1 | "%HG%" import --bypass -

Import a stack of revisions from phabricator. . This is extended help.

defined by: c:\Users\Matt\projects\hg\.hg\hgrc:28

(some details hidden, use --verbose to show complete help)

(The middle '.' line is necessary, because the config parser throws away empty lines, complains about unexpected leading whitespace in the next line, and then exits without the usual 'abort: ' prefix. That bad format even kills hg version, but the output does indicate exactly where the problem is.)

I don't think that it'll be easy to make it avoid reflowing, I believe that's a pretty low-level aspect of the help command. It would be better to fix the command parser to allow interstitial blank lines, but I don't have an estimate on how hard that would be. Looks like our internal use of the feature from this patch is avoiding multi-line messages, I don't know if this is because they don't work, or because rdamazio didn't try it. I agree it should hopefully not block the review in the meantime, especially if the desired+expected end-goal is that the config parser lets us have the blank lines (because then we won't need to change the text in a BC way; if we can't get the config parser to work, we may need to have this parse the text looking for things like \n, which could possibly be BC [though so mild I suspect it'll not be a problem])

(I'm stepping in and responding while rdamazio is out for a few days)

I really like this feature too. Any plans to extend it to {fileset,revset,template}alias?

We don't have any concrete plans to do so, but would not be opposed.

I don't think this should prevent it from being accepted, but is there a way to get the help text rendered as-is, without reflowing? For example, to simulate the usual 1 line summary + extended detail, I tried:

[alias]
phabimport:doc = Import a stack of revisions from phabricator.
  .
  This is extended help.

That got me:

$ ../hg help phabimport
hg phabimport

shell alias for: "%HG%" phabread $1 | "%HG%" import --bypass -

Import a stack of revisions from phabricator. . This is extended help.

defined by: c:\Users\Matt\projects\hg\.hg\hgrc:28

(some details hidden, use --verbose to show complete help)

(The middle '.' line is necessary, because the config parser throws away empty lines, complains about unexpected leading whitespace in the next line, and then exits without the usual 'abort: ' prefix. That bad format even kills hg version, but the output does indicate exactly where the problem is.)

I don't think that it'll be easy to make it avoid reflowing, I believe that's a pretty low-level aspect of the help command.

Yeah, avoiding reflow in general is too broad. It is useful, until trying to make paragraphs or the table of options at the bottom of a help command.

It would be better to fix the command parser to allow interstitial blank lines, but I don't have an estimate on how hard that would be.

That's probably not enough for things beyond paragraph breaks, like the options table. FWIW, hg help config.syntax does say such lines are skipped. IDK what changing that would break if extra blank lines happen to be after a random option.

Looks like our internal use of the feature from this patch is avoiding multi-line messages, I don't know if this is because they don't work, or because rdamazio didn't try it. I agree it should hopefully not block the review in the meantime, especially if the desired+expected end-goal is that the config parser lets us have the blank lines (because then we won't need to change the text in a BC way; if we can't get the config parser to work, we may need to have this parse the text looking for things like \n, which could possibly be BC [though so mild I suspect it'll not be a problem])

Maybe breaking after an explicit '\n' (string) which doesn't have an escaping '\' is the way to go. I think templates support similar in that the lines for the item are all joined, and then the visible '\n' become hard breaks. Assuming the code that injects it into the help system is what makes the substitution, I'm not sure where the BC comes in (unless you mean FB might have '\n' which should be rendered literally). I don't know much about the help rendering though, so I have no idea how easy this is.

durin42 accepted this revision.Mar 12 2018, 5:46 PM
This revision is now accepted and ready to land.Mar 12 2018, 5:46 PM

Ugh:

--- /home/augie/hg/tests/test-alias.t
+++ /home/augie/hg/tests/test-alias.t.err
@@ -357,15 +357,8 @@
 properly recursive

   $ hg dln
-  changeset:   -1:0000000000000000000000000000000000000000
-  phase:       public
-  parent:      -1:0000000000000000000000000000000000000000
-  parent:      -1:0000000000000000000000000000000000000000
-  manifest:    -1:0000000000000000000000000000000000000000
-  user:
-  date:        Thu Jan 01 00:00:00 1970 +0000
-  extra:       branch=default
-
+  abort: alias 'dln' resolves to unknown command 'lognull'
+  [255]


 path expanding

ERROR: test-alias.t output changed
--- /home/augie/hg/tests/test-show.t
+++ /home/augie/hg/tests/test-show.t.err
@@ -135,19 +135,37 @@
 commands.show.aliasprefix aliases values to `show <view>`

   $ hg --config commands.show.aliasprefix=s sbookmarks
+  devel-warn: config item requires an explicit default value: 'alias.sstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.swork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.sbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
   (no bookmarks set)

   $ hg --config commands.show.aliasprefix=sh shwork
+  devel-warn: config item requires an explicit default value: 'alias.shstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shwork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
   @  7b57 commit for book2
   o  b757 commit for book1
   o  ba59 initial

   $ hg --config commands.show.aliasprefix='s sh' swork
+  devel-warn: config item requires an explicit default value: 'alias.sstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.swork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.sbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shwork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
   @  7b57 commit for book2
   o  b757 commit for book1
   o  ba59 initial

   $ hg --config commands.show.aliasprefix='s sh' shwork
+  devel-warn: config item requires an explicit default value: 'alias.sstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.swork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.sbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shwork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.shbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
   @  7b57 commit for book2
   o  b757 commit for book1
   o  ba59 initial
@@ -155,11 +173,17 @@
 The aliases don't appear in `hg config`

   $ hg --config commands.show.aliasprefix=s config alias
+  devel-warn: config item requires an explicit default value: 'alias.sstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.swork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.sbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
   [1]

 Doesn't overwrite existing alias

   $ hg --config alias.swork='log -r .' --config commands.show.aliasprefix=s swork
+  devel-warn: config item requires an explicit default value: 'alias.sstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.swork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.sbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
   changeset:   2:7b5709ab64cb
   tag:         tip
   user:        test
@@ -168,6 +192,9 @@


   $ hg --config alias.swork='log -r .' --config commands.show.aliasprefix=s config alias
+  devel-warn: config item requires an explicit default value: 'alias.sstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.swork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
+  devel-warn: config item requires an explicit default value: 'alias.sbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup)
   alias.swork=log -r .

   $ cd ..

ERROR: test-show.t output changed

Discarding for now.

spectral updated this revision to Diff 6980.Mar 12 2018, 9:21 PM

Ugh:

--- /home/augie/hg/tests/test-alias.t
+++ /home/augie/hg/tests/test-alias.t.err
@@ -357,15 +357,8 @@
 properly recursive

   $ hg dln
-  changeset:   -1:0000000000000000000000000000000000000000
-  phase:       public
-  parent:      -1:0000000000000000000000000000000000000000
-  parent:      -1:0000000000000000000000000000000000000000
-  manifest:    -1:0000000000000000000000000000000000000000
-  user:
-  date:        Thu Jan 01 00:00:00 1970 +0000
-  extra:       branch=default
-
+  abort: alias 'dln' resolves to unknown command 'lognull'
+  [255]

I wasn't able to reproduce this error when based off of 31581528

path expanding

ERROR: test-alias.t output changed

  • /home/augie/hg/tests/test-show.t +++ /home/augie/hg/tests/test-show.t.err @@ -135,19 +135,37 @@ commands.show.aliasprefix aliases values to show <view>

    $ hg --config commands.show.aliasprefix=s sbookmarks + devel-warn: config item requires an explicit default value: 'alias.sstack' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup) + devel-warn: config item requires an explicit default value: 'alias.swork' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup) + devel-warn: config item requires an explicit default value: 'alias.sbookmarks' at: /tmp/hgtests.iyj57T/install/lib/python/hgext/show.py:430 (extsetup) (no bookmarks set)

... etc ....

I fixed this one. PTAL (added third argument of None to call in hgext/show.py).

pulkit accepted this revision.Mar 26 2018, 4:17 AM

Ugh:

--- /home/augie/hg/tests/test-alias.t
+++ /home/augie/hg/tests/test-alias.t.err
@@ -357,15 +357,8 @@
 properly recursive

   $ hg dln
-  changeset:   -1:0000000000000000000000000000000000000000
-  phase:       public
-  parent:      -1:0000000000000000000000000000000000000000
-  parent:      -1:0000000000000000000000000000000000000000
-  manifest:    -1:0000000000000000000000000000000000000000
-  user:
-  date:        Thu Jan 01 00:00:00 1970 +0000
-  extra:       branch=default
-
+  abort: alias 'dln' resolves to unknown command 'lognull'
+  [255]

I wasn't able to reproduce this error when based off of 31581528

I was queuing this patch, but I see this test failure. It's flaky, sometimes it passes, sometimes it fails. So dropping for now.

rdamazio updated this revision to Diff 7330.Mar 26 2018, 11:30 PM

The flakiness was just due to Python map order randomization in tests (a fixed PYTHONHASHSEED=3170796678 or similar reproduces it consistently by getting dln before lognull).
The real issue was the added "ignoresub=True" argument which broke strict ordering guarantees in the return value, combined with the fact that each lazy alias entry makes a copy of the cmdtable *at the state when it's created*.

I've fixed this in ui.configitems so it preserves ordering - PTAL. Should also be a tiny bit faster now.
I've also added tests for the recursive alias case.

rdamazio updated this revision to Diff 7331.Mar 26 2018, 11:33 PM
pulkit accepted this revision.Mar 27 2018, 3:07 AM

:(

--- /home/foobar/repo/pushaccess/tests/test-paths.t
+++ /home/foobar/repo/pushaccess/tests/test-paths.t.err
@@ -132,10 +132,52 @@
 zeroconf wraps ui.configitems(), which shouldn't crash at least:
 
   $ hg paths --config extensions.zeroconf=
-  dupe = $TESTTMP/b#tip
-  dupe:pushurl = https://example.com/dupe
-  expand = $TESTTMP/a/$SOMETHING/bar
-  insecure = http://foo:***@example.com/
+  ** unknown exception encountered, please report by visiting
+  ** https://mercurial-scm.org/wiki/BugTracker
+  ** Python 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
+  ** Mercurial Distributed SCM (version 4.5.2+1280-deb4b1721fe0)
+  ** Extensions loaded: zeroconf
+  Traceback (most recent call last):
+    File "/tmp/hgtests.p14OA8/install/bin/hg", line 41, in <module>
+      dispatch.run()
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 93, in run
+      status = (dispatch(req) or 0)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 213, in dispatch
+      ret = _runcatch(req)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 354, in _runcatch
+      return _callcatch(ui, _runcatchfunc)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 362, in _callcatch
+      return scmutil.callcatch(ui, func)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/scmutil.py", line 159, in callcatch
+      return func()
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 344, in _runcatchfunc
+      return _dispatch(req)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 958, in _dispatch
+      cmdpats, cmdoptions)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 715, in runcommand
+      ret = _runcommand(ui, options, cmd, d)
+    File "/tmp/hgtests.p14OA8/install/lib/python/hgext/zeroconf/__init__.py", line 205, in cleanupafterdispatch
+      return orig(ui, options, cmd, cmdfunc)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 966, in _runcommand
+      return cmdfunc()
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/dispatch.py", line 955, in <lambda>
+      d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/util.py", line 1537, in check
+      return func(*args, **kwargs)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/commands.py", line 3789, in paths
+      pathitems = sorted(ui.paths.iteritems())
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/util.py", line 1421, in __get__
+      result = self.func(obj)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/ui.py", line 848, in paths
+      return paths(self)
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/ui.py", line 1699, in __init__
+      for name, loc in ui.configitems('paths', ignoresub=True):
+    File "/tmp/hgtests.p14OA8/install/lib/python/mercurial/extensions.py", line 359, in closure
+      return func(*(args + a), **kw)
+    File "/tmp/hgtests.p14OA8/install/lib/python/hgext/zeroconf/__init__.py", line 184, in configitems
+      repos += getzcpaths()
+  TypeError: unsupported operand type(s) for +=: 'generator' and 'generator'
+  [1]
 
   $ cd ..
 

ERROR: test-paths.t output changed
rdamazio updated this revision to Diff 7346.Mar 27 2018, 3:55 PM

Sorry about that, I had fixed this one and forgot to re-upload. Try now.

pulkit accepted this revision.Mar 28 2018, 6:05 AM
This revision was automatically updated to reflect the committed changes.

Is there anything that needs to be done to mark this experimental? I toyed with replacing '\n' substrings with LF, but wasn't happy enough with it to submit, and ran out of time. Last time I played with this, I also saw that '.. container:: verbose' is stripped out, but the following text wasn't, so there may be other useful things to tweak here.