[PATCH] dispatch: add fail-* family of hooks

Jordi Gutiérrez Hermoso jordigh at octave.org
Thu Apr 28 14:39:48 UTC 2016


# HG changeset patch
# User Jordi Gutiérrez Hermoso <jordigh at octave.org>
# Date 1461854267 14400
#      Thu Apr 28 10:37:47 2016 -0400
# Node ID fe6711339ce840a3c08a8c129fdc614ac8f9a8a1
# Parent  c5565fc8848dd084d104ca40c33d1acdfcff8bc6
dispatch: add fail-* family of hooks

The post-* family of hooks will not run in case a command fails (i.e.
raises an exception). This makes it inconvenient to hook into events
such as doing something in case of a failed push.

We catch all exceptions to run the failure hook. I am not sure if this
is too aggressive, but tests apparently pass.

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -627,10 +627,16 @@ def runcommand(lui, repo, cmd, fullargs,
     # run pre-hook, and abort if it fails
     hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs),
               pats=cmdpats, opts=cmdoptions)
-    ret = _runcommand(ui, options, cmd, d)
-    # run post-hook, passing command result
-    hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
-              result=ret, pats=cmdpats, opts=cmdoptions)
+    try:
+        ret = _runcommand(ui, options, cmd, d)
+        # run post-hook, passing command result
+        hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
+                  result=ret, pats=cmdpats, opts=cmdoptions)
+    except Exception:
+        # run failure hook and re-raise
+        hook.hook(lui, repo, "fail-%s" % cmd, False, args=" ".join(fullargs),
+                  pats=cmdpats, opts=cmdoptions)
+        raise
     return ret
 
 def _getlocal(ui, rpath, wd=None):
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -811,6 +811,15 @@ variables it is passed are listed with n
   dictionary of options (with unspecified options set to their defaults).
   ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
 
+``fail-<command>``
+  Run after a failed invocation of an associated command. The contents
+  of the command line are passed as ``$HG_ARGS``. Parsed command line
+  arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
+  string representations of the python data internally passed to
+  <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
+  options set to their defaults). ``$HG_PATS`` is a list of arguments.
+  Hook failure is ignored.
+
 ``pre-<command>``
   Run before executing the associated command. The contents of the
   command line are passed as ``$HG_ARGS``. Parsed command line arguments
diff --git a/tests/test-push-warn.t b/tests/test-push-warn.t
--- a/tests/test-push-warn.t
+++ b/tests/test-push-warn.t
@@ -785,4 +785,14 @@ outgoing:
   no changes found
   [1]
 
+Test fail hook
+
+  $ hg push inner --config hooks.fail-push="echo running fail-push hook"
+  pushing to inner
+  searching for changes
+  running fail-push hook
+  abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
+  (merge or see "hg help push" for details about pushing new heads)
+  [255]
+
   $ cd ..


More information about the Mercurial-devel mailing list