[PATCH] hooks: hook ordering via sort variable in [hooks]
Matt Mackall
mpm at selenic.com
Sun Jan 15 13:09:00 CST 2012
On Sun, 2012-01-15 at 11:29 -0700, Matt Zuba wrote:
> How about something like this...
>
> # HG changeset patch
> # User Matt Zuba <matt.zuba at goodwillaz.org>
> # Date 1326651917 25200
> # Node ID 88be2efad116b71479e204c5b2c17c33e081c7c2
> # Parent e5feebc1f3bb50f0180c76d31e8456a390a86c78
> hooks: prioritize run order of hooks
>
> As of Mercurial 1.3, hooks are sorted in the order they are read into
> Mercurial. There are many instances when someone may want the hooks
> sorted in a specific order; this patch allows prioritizing hooks, while
> maintaining the existing enumeration for hooks without a priority.
>
> diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
> --- a/mercurial/help/config.txt
> +++ b/mercurial/help/config.txt
> @@ -655,7 +655,10 @@
> various actions such as starting or finishing a commit. Multiple
> hooks can be run for the same action by appending a suffix to the
> action. Overriding a site-wide hook can be done by changing its
> -value or setting it to an empty string.
> +value or setting it to an empty string. Hooks can be prioritized
> +by adding a prefix of ``priority`` to the hook name on a new line
> +and setting the priority. The default priority is 0 if
> +not specified.
Your emailer is mangling your patches.
> Example ``.hg/hgrc``::
>
> @@ -666,6 +669,8 @@
> incoming =
> incoming.email = /my/email/hook
> incoming.autobuild = /my/build/hook
> + # force autobuild hook to run before other incoming hooks
> + priority.incoming.autobuild = 1
>
> Most hooks are run with environment variables set that give useful
> additional information. For each hook below, the environment
> diff --git a/mercurial/hook.py b/mercurial/hook.py
> --- a/mercurial/hook.py
> +++ b/mercurial/hook.py
> @@ -6,7 +6,7 @@
> # GNU General Public License version 2 or any later version.
>
> from i18n import _
> -import os, sys
> +import os, sys, heapq
> import extensions, util
>
> def _pythonhook(ui, repo, name, hname, funcname, args, throw):
> @@ -124,6 +124,14 @@
> ui.warn(_('warning: %s hook %s\n') % (name, desc))
> return r
>
> +def _allhooks(ui):
> + hooks = []
> + for hname, cmd in ui.configitems('hooks'):
> + if hname.split('.')[0] != 'priority':
> + priority = ui.configint('hooks', 'priority.%s' % hname, 0)
> + heapq.heappush(hooks, (-priority, len(hooks), hname, cmd))
> + return [(k, v) for priority, count, k, v in hooks]
> +
Using a heap here is overkill. I would do something like:
hooks = []
for name, cmd in ui.configitems('hooks'):
if not name.startswith('priority.'):
priority = ui.configint('hooks', 'priority.%s' % name, 0)
hooks.append((-priority, len(hooks), name, cmd))
return [(n, c) for p, o, n, c in sorted(hooks)]
> _redirect = False
> def redirect(state):
> global _redirect
> @@ -147,7 +155,7 @@
> pass
>
> try:
> - for hname, cmd in ui.configitems('hooks'):
> + for hname, cmd in _allhooks(ui):
> if hname.split('.')[0] != name or not cmd:
> continue
> if util.safehasattr(cmd, '__call__'):
> diff --git a/tests/test-hook.t b/tests/test-hook.t
> --- a/tests/test-hook.t
> +++ b/tests/test-hook.t
> @@ -553,3 +553,19 @@
> calling hook pre-identify: hooktests.verbosehook
> verbose output from hook
> cb9a9f314b8b
> +
> +Ensure hooks can be prioritized
> +
> + $ echo '[hooks]' > .hg/hgrc
> + $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
> + $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
> + $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
> + $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
> + $ hg id --verbose
> + calling hook pre-identify.b: hooktests.verbosehook
> + verbose output from hook
> + calling hook pre-identify.a: hooktests.verbosehook
> + verbose output from hook
> + calling hook pre-identify.c: hooktests.verbosehook
> + verbose output from hook
> + cb9a9f314b8b
>
>
> On 01/14/2012 03:43 PM, Matt Mackall wrote:
> > A better approach would be a way of adding hook priorities. Something
> > like:
> >
> > [hooks]
> > precommit.mine = blah
> > priority.precommit.mine = 1
> >
> > This lets people insert their hook in arbitrary places in the list.
> >
> > Note the trick with implementing this is using the existing enumeration
> > order as a secondary sort key.
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list