Subject: Re: What about allowing multiple hooks?

From: Anders Waldenborg <[email-masked]>
Date: Wed, 21 Jan 2009 21:35:58 +0100

Junio C Hamano wrote:
> I deliberately omitted support for multiple scripts in core git Porcelains
> to avoid this exact issue.  It is a huge can of worms and it is dubious if
> you can have a coherent and generic enough semantics.
> 
> In the meantime, you can have a single .git/hooks/pre-commit script that
> defines your own convention.  Maybe it uses .git/hooks/pre-commit.d/
> directory, full of scripts, and implements the semantics you want,
> including:
> 
>  (1) the execution order and the naming convention of the scripts (e.g.
>      they all live in pre-commit.d/ directory, and executed in ASCII byte
>      value order of their names);
 >
 >  (2) how their exit status combine together.

I need multiple hooks, so I've done some thinking about this, so I 
thought it may be a good idea to share this here.

I currently use configvalues to specify which hooks to run. For example 
this is how my post-receive looks:

data=$(cat)
git config --get-all hooks.post-receive.hook | while read hook; do
         $hook <<__EOF__
"$data"
__EOF__
done

Now none of my hooks wants to prevent update, so I don't care about 
return status. But it could easily be extended, for example by having 
some indicator per hook that can have the values (are these enough?):

  ignore - pretent that no failure was returned no matter what
  sufficient - if this hook suceeds end result is always sucess
  required - if this hook fails we fail, no more hooks are run

That could be done with the simple configvalue thing as follows:

git config -add hooks.post-receive.hook \
    "sufficient allow-repo-owner-to-do-anything.sh"
git config -add hooks.post-receive.hook \
    "required finegrained-access-control.sh"
git config -add hooks.post-receive.hook \
    "required allow-repo-owner-to-do-anything.sh"
git config -add hooks.post-receive.hook \
    "ignore send-mail.sh"
git config -add hooks.post-receive.hook \
    "ignore send-irc-notification.py"

One problem is that to change order one has to resort to manually 
editing config. So maybe something richer could be used:

[hooks "allow-repo-owner-to-do-anything"]
  cmd = /usr/share/git-hooks/allow-repo-owner-to-do-anything.sh
  enabled = 1
  type = post-receive
  mode = sufficient
  priority = 10

[hooks "mail"]
  cmd = /usr/share/git-hooks/allow-repo-owner-to-do-anything.sh
  enabled = 1
  type = post-receive
  mode = ignore
  priority = 1000

(this would even allow running hooks at same priority simultaneously)

Also then the hook's own config variables fits nicely in same section. 
(note that then each [hooks "x"] will be an instance that could use the 
same script, but different configvars)

  anders