Patchwork [3,of,4] hook: add support for disabling the shell to native command translation

login
register
mail settings
Submitter Matt Harbison
Date July 9, 2018, 3:27 p.m.
Message ID <6c1736648339979cd495.1531150066@Envy>
Download mbox | patch
Permalink /patch/32713/
State Accepted
Headers show

Comments

Matt Harbison - July 9, 2018, 3:27 p.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1531021086 14400
#      Sat Jul 07 23:38:06 2018 -0400
# Node ID 6c1736648339979cd4950d435cd696f0d4a4a186
# Parent  f32405ce6d8e71c277c15e3a7598e1b406e6f452
hook: add support for disabling the shell to native command translation

I think having it on by default is the right thing to do, but this is an escape
hatch if someone has a command that shouldn't be mangled.  The inspiration is
the priority prefix.  The translation does nothing on non Windows platforms, so
the default value is selected to avoid printing a useless note by default.
Yuya Nishihara - July 10, 2018, 12:36 p.m.
On Mon, 09 Jul 2018 11:27:46 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1531021086 14400
> #      Sat Jul 07 23:38:06 2018 -0400
> # Node ID 6c1736648339979cd4950d435cd696f0d4a4a186
> # Parent  f32405ce6d8e71c277c15e3a7598e1b406e6f452
> hook: add support for disabling the shell to native command translation

Queued this, too.


> +    [hooks]
> +    incoming.autobuild = /my/build/hook
> +    # disable translation to cmd.exe syntax for autobuild hook
> +    tonative.incoming.autobuild = False

It would be nice if we could use the :<sub-opt> syntax, but we can't because
<hookname>:<sub-opt> would be recognised as a hook by older Mercurial.

> -    cmd = procutil.shelltonative(cmd, env)
> +    if ui.configbool('hooks', 'tonative.%s' % name, pycompat.iswindows):
> +        ui.note(_('converting hook "%s" to native\n') % name)
> +        cmd = procutil.shelltonative(cmd, env)

This seems a bit verbose. Maybe it can be enabled only if cmd != orig cmd?

Patch

diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -890,7 +890,14 @@  be ``$HG_HOOKTYPE=incoming`` and ``$HG_H
 
   Some basic Unix syntax is supported for portability, including ``$VAR``
   and ``${VAR}`` style variables.  To use a literal ``$``, it must be
-  escaped with a back slash or inside of a strong quote.
+  escaped with a back slash or inside of a strong quote.  This can be
+  disabled by adding a prefix of ``tonative.`` to the hook name on a new
+  line, and setting it to ``False``.  For example::
+
+    [hooks]
+    incoming.autobuild = /my/build/hook
+    # disable translation to cmd.exe syntax for autobuild hook
+    tonative.incoming.autobuild = False
 
 ``changegroup``
   Run after a changegroup has been added via push, pull or unbundle.  The ID of
diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -139,7 +139,9 @@  def _exthook(ui, repo, htype, name, cmd,
             v = stringutil.pprint(v)
         env['HG_' + k.upper()] = v
 
-    cmd = procutil.shelltonative(cmd, env)
+    if ui.configbool('hooks', 'tonative.%s' % name, pycompat.iswindows):
+        ui.note(_('converting hook "%s" to native\n') % name)
+        cmd = procutil.shelltonative(cmd, env)
 
     ui.note(_("running hook %s: %s\n") % (name, cmd))
 
@@ -181,9 +183,11 @@  def _hookitems(ui, _untrusted=False):
     """return all hooks items ready to be sorted"""
     hooks = {}
     for name, cmd in ui.configitems('hooks', untrusted=_untrusted):
-        if not name.startswith('priority.'):
-            priority = ui.configint('hooks', 'priority.%s' % name, 0)
-            hooks[name] = (-priority, len(hooks), name, cmd)
+        if name.startswith('priority.') or name.startswith('tonative.'):
+            continue
+
+        priority = ui.configint('hooks', 'priority.%s' % name, 0)
+        hooks[name] = (-priority, len(hooks), name, cmd)
     return hooks
 
 _redirect = False
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -194,6 +194,7 @@  delete a remote bookmark
   bundle2-input: part header size: 0
   bundle2-input: end of bundle2 stream
   bundle2-input-bundle: 3 parts total
+  converting hook "txnclose-bookmark.test" to native (windows !)
   running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
   test-hook-bookmark: W:  0000000000000000000000000000000000000000 -> 
   bundle2-output-bundle: "HG20", 1 parts total
@@ -308,6 +309,7 @@  delete a remote bookmark
   bundle2-input: part header size: 0
   bundle2-input: end of bundle2 stream
   bundle2-input-bundle: 3 parts total
+  converting hook "txnclose-bookmark.test" to native (windows !)
   running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
   test-hook-bookmark: W:  0000000000000000000000000000000000000000 -> 
   bundle2-output-bundle: "HG20", 0 parts total
diff --git a/tests/test-commit-amend.t b/tests/test-commit-amend.t
--- a/tests/test-commit-amend.t
+++ b/tests/test-commit-amend.t
@@ -205,6 +205,7 @@  at first, test saving last-message.txt
   a
   committing manifest
   committing changelog
+  converting hook "pretxncommit.test-saving-last-message" to native (windows !)
   running hook pretxncommit.test-saving-last-message: false
   transaction abort!
   rollback completed
@@ -230,6 +231,7 @@  at first, test saving last-message.txt
   a
   committing manifest
   committing changelog
+  converting hook "pretxncommit.test-saving-last-message" to native (windows !)
   running hook pretxncommit.test-saving-last-message: false
   transaction abort!
   rollback completed
diff --git a/tests/test-histedit-fold.t b/tests/test-histedit-fold.t
--- a/tests/test-histedit-fold.t
+++ b/tests/test-histedit-fold.t
@@ -494,6 +494,7 @@  Test unix -> windows style variable subs
   $ cat > $TESTTMP/tmp.hgrc <<'EOF'
   > [hooks]
   > pre-add = echo no variables
+  > tonative.pre-add = False
   > post-add = echo ran $HG_ARGS, literal \$non-var, 'also $non-var', $HG_RESULT
   > EOF
 
@@ -503,6 +504,7 @@  TODO: Windows should output double quote
   running hook pre-add: echo no variables
   no variables
   adding amended.txt
+  converting hook "post-add" to native (windows !)
   running hook post-add: echo ran %HG_ARGS%, literal $non-var, 'also $non-var', %HG_RESULT% (windows !)
   running hook post-add: echo ran $HG_ARGS, literal \$non-var, 'also $non-var', $HG_RESULT (no-windows !)
   ran add -v amended.txt, literal $non-var, 'also $non-var', 0 (windows !)
diff --git a/tests/test-keyword.t b/tests/test-keyword.t
--- a/tests/test-keyword.t
+++ b/tests/test-keyword.t
@@ -183,6 +183,7 @@  Commit with several checks
   overwriting a expanding keywords
   updating the branch cache
   committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
+  converting hook "commit.test" to native (windows !)
   running hook commit.test: cp a hooktest
   $ hg status
   ? hooktest
diff --git a/tests/test-push-http.t b/tests/test-push-http.t
--- a/tests/test-push-http.t
+++ b/tests/test-push-http.t
@@ -90,10 +90,13 @@  expect success
   remote: adding a revisions
   remote: added 1 changesets with 1 changes to 1 files
   remote: updating the branch cache
+  remote: converting hook "txnclose-phase.test" to native (windows !)
   remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh
   remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b:  draft -> public
+  remote: converting hook "txnclose-phase.test" to native (windows !)
   remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
+  remote: converting hook "changegroup" to native (windows !)
   remote: running hook changegroup: sh -c "printenv.py changegroup 0"
   remote: changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP: (glob)
   % serve errors
@@ -110,10 +113,13 @@  expect success
   remote: adding a revisions
   remote: added 1 changesets with 1 changes to 1 files
   remote: updating the branch cache
+  remote: converting hook "txnclose-phase.test" to native (windows !)
   remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh
   remote: phase-move: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b:  draft -> public
+  remote: converting hook "txnclose-phase.test" to native (windows !)
   remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh
   remote: phase-move: ba677d0156c1196c1a699fa53f390dcfc3ce3872:   -> public
+  remote: converting hook "changegroup" to native (windows !)
   remote: running hook changegroup: sh -c "printenv.py changegroup 0"
   remote: changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_NODE_LAST=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:http:$LOCALIP: (glob)
   % serve errors