From 850882c1a6d95446e38ff8ceaa7d2513e44b57f5 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Mon, 30 Apr 2012 05:35:26 +0530 Subject: [PATCH] allow VREF code to print to STDOUT... Using a g2-style "chained update hook" as a VREF doesn't *quite* work: - all STDOUT from the hook is lost - worse, all lines get parsed as a ref followed by a message, and if the ref doesn't look like a ref it dies So now we do all this only if the message starts with 'VREF/'. Any other output is just printed out as is. --- doc/vref.mkd | 31 ++++++++++++++++++------------- src/lib/Gitolite/Hooks/Update.pm | 6 ++++++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/doc/vref.mkd b/doc/vref.mkd index a5bfb27..ac6599b 100644 --- a/doc/vref.mkd +++ b/doc/vref.mkd @@ -71,9 +71,9 @@ Briefly, a refex starting with `VREF/FOO` triggers a call to a program called `FOO` in `$GL_BINDIR/VREF`. That program is expected to print zero or more lines to its STDOUT; each line -is taken by gitolite as a new "ref" to be matched against all the refexes for -this user in the config. Including the refex that caused the vref call, of -course. +that starts with `VREF/` is taken by gitolite as a new "ref" to be matched +against all the refexes for this user in the config. Including the refex that +caused the vref call, of course. Normally, you send back the refex itself, if the test determines that the rule should be matched, otherwise nothing. So, in our example, we print @@ -102,16 +102,21 @@ exit. The program is passed **nine arguments** in this case (see next section for details). - * The script can print anything it wants to STDOUT; the first word in each - such line will be treated as a virtual ref to be matched against all the - rules, while the rest, if any, is a message to be added to the standard - "...DENIED..." message that gitolite prints if that refex matches. + * The script can print anything it wants to STDOUT. Lines not starting with + `VREF/` are printed as is (so your VREF can do mostly-normal printing to + STDOUT). + + For lines starting with `VREF/`, the first word in each such line will be + treated as a virtual ref to be matched against all the rules, while the + rest, if any, is a message to be added to the standard "...DENIED..." + message that gitolite prints if that refex matches. Usually it only makes sense to either - * Print nothing -- if you don't want the rule that triggered it to match - (ie., whatever condition being tested was not violated; like if the - count of changed files did not exceed 9, in our earlier example). + * Print nothing that starts with `VREF/` -- if you don't want the rule + that triggered it to match (ie., whatever condition being tested was + not violated; like if the count of changed files did not exceed 9, in + our earlier example). * Print the refex itself (plus an optional message), so that it matches the line which invoked it. @@ -151,9 +156,9 @@ to write vref scripts in any language. See script examples in source. ## what (else) can the vref code pass back -Actually, the vref code can pass anything back; each line in its output will -be matched against all the rules as usual (with the exception that fallthru is -not failure). +Actually, the vref code can pass anything back; each line in its output that +starts with `VREF/` will be matched against all the rules as usual (with the +exception that fallthru is not failure). For example, you could have a ruleset like this: diff --git a/src/lib/Gitolite/Hooks/Update.pm b/src/lib/Gitolite/Hooks/Update.pm index 3bcb8cf..ed4a03f 100644 --- a/src/lib/Gitolite/Hooks/Update.pm +++ b/src/lib/Gitolite/Hooks/Update.pm @@ -66,6 +66,12 @@ sub check_vrefs { open( my $fh, "-|", $pgm, @_, $vref, @args ) or _die "$vref: can't spawn helper program: $!"; while (<$fh>) { + # print non-vref lines and skip processing (for example, + # normal STDOUT by a normal update hook) + unless (m(^VREF/)) { + print; + next; + } my ( $ref, $deny_message ) = split( ' ', $_, 2 ); check_vref( $aa, $ref, $deny_message ); }