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.
This commit is contained in:
Sitaram Chamarty 2012-04-30 05:35:26 +05:30
parent 88c8d774d0
commit 850882c1a6
2 changed files with 24 additions and 13 deletions

View file

@ -71,9 +71,9 @@ Briefly, a refex starting with `VREF/FOO` triggers a call to a program called
`FOO` in `$GL_BINDIR/VREF`. `FOO` in `$GL_BINDIR/VREF`.
That program is expected to print zero or more lines to its STDOUT; each line 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 that starts with `VREF/` is taken by gitolite as a new "ref" to be matched
this user in the config. Including the refex that caused the vref call, of against all the refexes for this user in the config. Including the refex that
course. caused the vref call, of course.
Normally, you send back the refex itself, if the test determines that the rule 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 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 The program is passed **nine arguments** in this case (see next section
for details). for details).
* The script can print anything it wants to STDOUT; the first word in each * The script can print anything it wants to STDOUT. Lines not starting with
such line will be treated as a virtual ref to be matched against all the `VREF/` are printed as is (so your VREF can do mostly-normal printing to
rules, while the rest, if any, is a message to be added to the standard STDOUT).
"...DENIED..." message that gitolite prints if that refex matches.
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 Usually it only makes sense to either
* Print nothing -- if you don't want the rule that triggered it to match * Print nothing that starts with `VREF/` -- if you don't want the rule
(ie., whatever condition being tested was not violated; like if the that triggered it to match (ie., whatever condition being tested was
count of changed files did not exceed 9, in our earlier example). 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 * Print the refex itself (plus an optional message), so that it matches
the line which invoked it. 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 ## what (else) can the vref code pass back
Actually, the vref code can pass anything back; each line in its output will Actually, the vref code can pass anything back; each line in its output that
be matched against all the rules as usual (with the exception that fallthru is starts with `VREF/` will be matched against all the rules as usual (with the
not failure). exception that fallthru is not failure).
For example, you could have a ruleset like this: For example, you could have a ruleset like this:

View file

@ -66,6 +66,12 @@ sub check_vrefs {
open( my $fh, "-|", $pgm, @_, $vref, @args ) or _die "$vref: can't spawn helper program: $!"; open( my $fh, "-|", $pgm, @_, $vref, @args ) or _die "$vref: can't spawn helper program: $!";
while (<$fh>) { 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 ); my ( $ref, $deny_message ) = split( ' ', $_, 2 );
check_vref( $aa, $ref, $deny_message ); check_vref( $aa, $ref, $deny_message );
} }