hooks: allow Unix style environment variables on external Windows hooks
authorMatt Harbison <matt_harbison@yahoo.com>
Sun, 02 Jul 2017 00:32:09 -0400
changeset 38484 e9e61fbac787
parent 38483 3efadf2317c7
child 38485 56b2074114b1
hooks: allow Unix style environment variables on external Windows hooks This will help making common hooks between Windows and non-Windows platforms. Having to build the shellenviron dict here and in procutil.system() is a bit unfortunate, but the only other option is to fix up the command inside procutil.system(). It seems more important that the note about the hook being run reflects what is actually run. The patch from last summer added the hooks on the command line, but it looks like HG_ARGS has since learned about --config args, and the output was just confusing. Therefore, it's now loaded from a file in the histedit test for clarity.
mercurial/help/config.txt
mercurial/hook.py
tests/test-histedit-fold.t
tests/test-rebase-interruptions.t
--- a/mercurial/help/config.txt	Sun Jun 24 01:13:09 2018 -0400
+++ b/mercurial/help/config.txt	Sun Jul 02 00:32:09 2017 -0400
@@ -886,6 +886,12 @@
 of the hook in the config, respectively. In the example above, this will
 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
 
+.. container:: windows
+
+  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.
+
 ``changegroup``
   Run after a changegroup has been added via push, pull or unbundle.  The ID of
   the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
--- a/mercurial/hook.py	Sun Jun 24 01:13:09 2018 -0400
+++ b/mercurial/hook.py	Sun Jul 02 00:32:09 2017 -0400
@@ -120,8 +120,6 @@
     return r, False
 
 def _exthook(ui, repo, htype, name, cmd, args, throw):
-    ui.note(_("running hook %s: %s\n") % (name, cmd))
-
     starttime = util.timer()
     env = {}
 
@@ -141,6 +139,12 @@
             v = stringutil.pprint(v)
         env['HG_' + k.upper()] = v
 
+    if pycompat.iswindows:
+        environ = procutil.shellenviron(env)
+        cmd = util.platform.shelltocmdexe(cmd, environ)
+
+    ui.note(_("running hook %s: %s\n") % (name, cmd))
+
     if repo:
         cwd = repo.root
     else:
--- a/tests/test-histedit-fold.t	Sun Jun 24 01:13:09 2018 -0400
+++ b/tests/test-histedit-fold.t	Sun Jul 02 00:32:09 2017 -0400
@@ -478,14 +478,7 @@
   1:199b6bb90248 b
   0:6c795aa153cb a
 
-Setup the proper environment variable symbol for the platform, to be subbed
-into the hook command.
-#if windows
-  $ NODE="%HG_NODE%"
-#else
-  $ NODE="\$HG_NODE"
-#endif
-  $ hg histedit 6c795aa153cb --config hooks.commit="echo commit $NODE" --commands - 2>&1 << EOF | fixbundle
+  $ hg histedit 6c795aa153cb --config hooks.commit='echo commit $HG_NODE' --commands - 2>&1 << EOF | fixbundle
   > pick 199b6bb90248 b
   > fold a1a953ffb4b0 c
   > pick 6c795aa153cb a
@@ -496,8 +489,24 @@
   1:9599899f62c0 a
   0:79b99e9c8e49 b
 
+Test unix -> windows style variable substitution in external hooks.
+
+  $ cat > $TESTTMP/tmp.hgrc <<'EOF'
+  > [hooks]
+  > pre-add = echo no variables
+  > post-add = echo ran $HG_ARGS, literal \$non-var, 'also $non-var', $HG_RESULT
+  > EOF
+
+TODO: Windows should output double quotes around "also $non-var"
   $ echo "foo" > amended.txt
-  $ hg add amended.txt
+  $ HGRCPATH=$TESTTMP/tmp.hgrc hg add -v amended.txt
+  running hook pre-add: echo no variables
+  no variables
+  adding amended.txt
+  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 !)
+  ran add -v amended.txt, literal $non-var, also $non-var, 0 (no-windows !)
   $ hg ci -q --config extensions.largefiles= --amend -I amended.txt
   The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
 
--- a/tests/test-rebase-interruptions.t	Sun Jun 24 01:13:09 2018 -0400
+++ b/tests/test-rebase-interruptions.t	Sun Jul 02 00:32:09 2017 -0400
@@ -333,12 +333,7 @@
 
   $ cp -R a3 hook-pretxncommit
   $ cd hook-pretxncommit
-#if windows
-  $ NODE="%HG_NODE%"
-#else
-  $ NODE="\$HG_NODE"
-#endif
-  $ hg rebase --source 2 --dest 5 --tool internal:other --config "hooks.pretxncommit=hg log -r $NODE | grep \"summary:     C\""
+  $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.pretxncommit=hg log -r $HG_NODE | grep "summary:     C"'
   rebasing 2:965c486023db "C"
   summary:     C
   rebasing 6:a0b2430ebfb8 "F" (tip)