summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSitaram Chamarty <sitaram@atc.tcs.com>2013-08-29 16:46:54 +0530
committerSitaram Chamarty <sitaram@atc.tcs.com>2013-08-29 21:46:54 +0530
commit62fb31755abb7ad93e17a6fe8880b74eb17086fa (patch)
tree18da607b7123b7cb80b6fd3fd149511a05cd9451
parent2515992d8836b2fe333860ad0ed3267efd1cf698 (diff)
repo-specific hooks
-rw-r--r--src/lib/Gitolite/Rc.pm18
-rwxr-xr-xsrc/triggers/repo-specific-hooks54
2 files changed, 72 insertions, 0 deletions
diff --git a/src/lib/Gitolite/Rc.pm b/src/lib/Gitolite/Rc.pm
index 5e1f21e..1d62e89 100644
--- a/src/lib/Gitolite/Rc.pm
+++ b/src/lib/Gitolite/Rc.pm
@@ -423,6 +423,9 @@ BEGIN { $non_core = "
daemon POST_CREATE post-compile/update-git-daemon-access-list
daemon POST_COMPILE post-compile/update-git-daemon-access-list
+
+ repo-specific-hooks POST_COMPILE .
+ repo-specific-hooks POST_CREATE .
";
}
@@ -491,6 +494,18 @@ __DATA__
# ------------------------------------------------------------------
+ # suggested locations for site-local gitolite code (see cust.html)
+
+ # this one is managed directly on the server
+ # LOCAL_CODE => "$ENV{HOME}/local",
+
+ # or you can use this, which lets you put everything in a subdirectory
+ # called "local" in your gitolite-admin repo. For a SECURITY WARNING
+ # on this, see http://gitolite.com/gitolite/cust.html#pushcode
+ # LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local",
+
+ # ------------------------------------------------------------------
+
# List of commands and features to enable
ENABLE => [
@@ -561,6 +576,9 @@ __DATA__
# updates 'description' file instead of 'gitweb.description' config item
# 'cgit',
+ # allow repo-specific hooks to be added
+ # 'repo-specific-hooks',
+
# performance, logging, monitoring...
# be nice
diff --git a/src/triggers/repo-specific-hooks b/src/triggers/repo-specific-hooks
new file mode 100755
index 0000000..6baa508
--- /dev/null
+++ b/src/triggers/repo-specific-hooks
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# setup repo-specific hooks
+
+# code is too long, but if you take out all the error/safety/sanity checks,
+# it's basically just creating a symlink in <repo.git>/hooks pointing to some
+# file inside $rc{LOCAL_CODE}/hooks/repo-specific
+
+use lib $ENV{GL_LIBDIR};
+use Gitolite::Rc;
+use Gitolite::Common;
+
+_die "repo-specific-hooks: LOCAL_CODE not defined in rc" unless $rc{LOCAL_CODE};
+_die "repo-specific-hooks: '$rc{LOCAL_CODE}' does not exist or is not a directory" unless -d $rc{LOCAL_CODE};
+
+_chdir($ENV{GL_REPO_BASE});
+
+@ARGV = ("gitolite list-phy-repos | gitolite git-config -r % gitolite-options\\.hook\\. |");
+
+while (<>) {
+ chomp;
+ my ($repo, $hook, $code) = split /\t/, $_;
+
+ # we don't allow fiddling with the admin repo
+ if ($repo eq 'gitolite-admin') {
+ _warn "repo-specific-hooks: ignoring attempts to set hooks for the admin repo";
+ next;
+ }
+
+ # get the hook name
+ $hook =~ s/^gitolite-options\.hook\.//;
+
+ unless ($hook =~ /^(pre-receive|post-receive|post-update)$/) {
+ _warn "repo-specific-hooks: '$hook' is not one of the 3 hooks allowed, ignoring";
+ next;
+ }
+
+ if ($code =~ m(^/|\.\.)) {
+ _warn "repo-specific-hooks: double dot or leading slash not allowed in '$code'";
+ next;
+ }
+
+ my $src = $rc{LOCAL_CODE} . "/hooks/repo-specific/$code";
+ my $dst = "$repo.git/hooks/$hook";
+ unless (-x $src) {
+ _warn "repo-specific-hooks: '$src' doesn't exist or is not executable";
+ next;
+ }
+ unlink $dst;
+ symlink $src, $dst or _warn "could not symlink '$src' to '$dst'";
+ # no sanity checks for multiple overwrites of the same hook
+}