repo specific hooks:
[gitolite.git] / src / triggers / repo-specific-hooks
blobf8d26906eba638cda19251fe2375b7ab4091201a
1 #!/usr/bin/perl
2 use strict;
3 use warnings;
5 # setup repo-specific hooks
7 use lib $ENV{GL_LIBDIR};
8 use Gitolite::Rc;
9 use Gitolite::Common;
11 _die "repo-specific-hooks: LOCAL_CODE not defined in rc" unless $rc{LOCAL_CODE};
12 _die "repo-specific-hooks: '$rc{LOCAL_CODE}/hooks/repo-specific' does not exist or is not a directory" unless -d "$rc{LOCAL_CODE}/hooks/repo-specific";
14 _chdir( $ENV{GL_REPO_BASE} );
16 @ARGV = ("gitolite list-phy-repos | gitolite git-config -ev -r % gitolite-options\\.hook\\. |");
18 my $driver = "$rc{LOCAL_CODE}/hooks/multi-hook-driver";
19 # Hook Driver
21 local $/ = undef;
22 my $hook_text = <DATA>;
23 _print( $driver, $hook_text );
24 chmod 0755, $driver;
27 my %repo_hooks;
28 while (<>) {
29 chomp;
30 my ( $repo, $hook, $codes ) = split /\t/, $_;
31 $codes ||= '';
33 # get the hook name
34 $hook =~ s/^gitolite-options\.hook\.//;
35 $hook =~ s/\..*//;
37 # this is a special case
38 if ( $repo eq 'gitolite-admin' and $hook eq 'post-update' ) {
39 _warn "repo-specific-hooks: ignoring attempts to set post-update hook for the admin repo";
40 next;
43 unless ( $hook =~ /^(pre-receive|post-receive|post-update)$/ ) {
44 _warn "repo-specific-hooks: '$hook' is not allowed, ignoring";
45 _warn " (only pre-receive, post-receive, and post-update are allowed)";
46 next;
49 my @codes = split /\s+/, $codes;
50 push @{ $repo_hooks{$repo}{$hook} }, @codes if @codes;
53 for my $repo (keys %repo_hooks) {
54 for my $hook (keys %{ $repo_hooks{$repo} }) {
55 my @codes = @{ $repo_hooks{$repo}{$hook} };
57 my $dst = "$repo.git/hooks/$hook";
58 unlink( glob("$dst.*") );
60 my $counter = "h00";
61 foreach my $code (@codes) {
62 if ( $code =~ m(^/|\.\.) ) {
63 _warn "repo-specific-hooks: double dot or leading slash not allowed in '$code'";
64 next;
67 my $src = $rc{LOCAL_CODE} . "/hooks/repo-specific/$code";
68 my $dst = "$repo.git/hooks/$hook.$counter-$code";
69 unless ( -x $src ) {
70 _warn "repo-specific-hooks: '$src' doesn't exist or is not executable";
71 next;
73 unlink $dst;
74 symlink $src, $dst or _warn "could not symlink '$src' to '$dst'";
75 $counter++;
77 # no sanity checks for multiple overwrites of the same hook
80 unlink $dst;
81 symlink $driver, $dst or die "could not symlink '$driver' to '$dst'";
85 __DATA__
86 #/bin/sh
88 # Determine what input the hook needs
89 # post-update takes args, pre/post-receive take stdin
90 type=args
91 stdin=''
92 [ $0 != hooks/post-update ] && {
93 type=stdin
94 stdin=`cat`
97 for h in $0.*; do
98 [ -x $h ] || continue
99 if [ $type = args ]
100 then
101 $h $@
102 else
103 echo "$stdin" | $h
105 done