# HG changeset patch # User Jordi GutiƩrrez Hermoso # Date 1461854267 14400 # Node ID e6dfb0e4eeef20c14c86ae2573832bf480f32e07 # Parent e521cb13d3545735cf78e7e002bda4c2f4314124 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 -r e521cb13d354 -r e6dfb0e4eeef mercurial/dispatch.py --- a/mercurial/dispatch.py Fri May 06 22:21:32 2016 +0530 +++ b/mercurial/dispatch.py Thu Apr 28 10:37:47 2016 -0400 @@ -633,10 +633,16 @@ # 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 -r e521cb13d354 -r e6dfb0e4eeef mercurial/help/config.txt --- a/mercurial/help/config.txt Fri May 06 22:21:32 2016 +0530 +++ b/mercurial/help/config.txt Thu Apr 28 10:37:47 2016 -0400 @@ -811,6 +811,15 @@ dictionary of options (with unspecified options set to their defaults). ``$HG_PATS`` is a list of arguments. Hook failure is ignored. +``fail-`` + 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 + . ``$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-`` Run before executing the associated command. The contents of the command line are passed as ``$HG_ARGS``. Parsed command line arguments diff -r e521cb13d354 -r e6dfb0e4eeef tests/test-push-warn.t --- a/tests/test-push-warn.t Fri May 06 22:21:32 2016 +0530 +++ b/tests/test-push-warn.t Thu Apr 28 10:37:47 2016 -0400 @@ -785,4 +785,14 @@ 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 ..