Allow user-specified programs to override system-installed ones

(manually tested)

  - new rc var: GL_BINDIR2; see doc update in this commit

  - added _which() function to search both $GL_BINDIR and $GL_BINDIR2
  - 'gitolite <command>', non-perl triggers, VREFs, and sugar, use this

  - unshifted $GL_BINDIR2/lib into @INC upfront in Rc.pm
  - perl triggers use this
redis
Sitaram Chamarty 2012-06-09 07:48:56 +05:30
parent cd37fe7c36
commit 3c0f177481
5 changed files with 52 additions and 17 deletions

View File

@ -97,3 +97,25 @@ information.
require the '@' to be escaped:
DEFAULT_ROLE_PERMS => "READERS \@all\nWRITERS \@senior_devs",
* `GL_BINDIR2`, string
This is useful when you install gitolite system-wide, but want to add or
override commands, VREFs, triggers, etc., by putting them somewhere in the
hosting user's home directory (i.e., without requiring root privileges).
Add a new variable `GL_BINDIR2` to the the rc file. Example:
GL_BINDIR2 => "$ENV{HOME}/gitolite/src2",
In that directory, create as much of the following directory structure as
you need to add your programs:
.
|-- commands
|-- lib
| `-- Gitolite
| `-- Triggers
|-- syntactic-sugar
|-- triggers
`-- VREF

View File

@ -73,9 +73,10 @@ if ( $command eq 'setup' ) {
} elsif ( $command eq 'trigger' ) {
trigger(@args);
} elsif ( -x "$rc{GL_BINDIR}/commands/$command" ) {
trace( 2, "attempting gitolite command $command" );
run_command( $command, @args );
} elsif ( my $c = _which("commands/$command", 'x' ) ) {
trace( 2, "attempting gitolite command $c" );
_system( $c, @args );
exit 0;
} elsif ( $command eq 'list-phy-repos' ) {
_chdir( $rc{GL_REPO_BASE} );
@ -99,11 +100,3 @@ sub args {
}
# ----------------------------------------------------------------------
sub run_command {
my $pgm = shift;
my $fullpath = "$ENV{GL_BINDIR}/commands/$pgm";
_die "'$pgm' not found or not executable" if not -x $fullpath;
_system( $fullpath, @_ );
exit 0;
}

View File

@ -52,7 +52,7 @@ sub sugar {
# perl-ism; apart from keeping the full path separate from the
# simple name, this also protects %rc from change by implicit
# aliasing, which would happen if you touched $s itself
my $sfp = "$ENV{GL_BINDIR}/syntactic-sugar/$s";
my $sfp = _which("syntactic-sugar/$s", 'r');
_warn("skipped sugar script '$s'"), next if not -r $sfp;
$lines = SugarBox::run_sugar_script( $sfp, $lines );

View File

@ -61,8 +61,8 @@ sub check_vrefs {
}
} else {
my ( $dummy, $pgm, @args ) = split '/', $vref;
$pgm = "$ENV{GL_BINDIR}/VREF/$pgm";
-x $pgm or _die "'$vref': helper program missing or unexecutable";
$pgm = _which("VREF/$pgm", 'x');
$pgm or _die "'$vref': helper program missing or unexecutable";
open( my $fh, "-|", $pgm, @_, $vref, @args ) or _die "'$vref': can't spawn helper program: $!";
while (<$fh>) {

View File

@ -9,6 +9,7 @@ package Gitolite::Rc;
query_rc
version
trigger
_which
$REMOTE_COMMAND_PATT
$REF_OR_FILENAME_PATT
@ -83,9 +84,11 @@ unshift @{ $rc{ACCESS_1} }, 'Writable::access_1';
# use an env var that is highly unlikely to appear in real life :)
do $ENV{G3T_RC} if exists $ENV{G3T_RC} and -r $ENV{G3T_RC};
# fix some env vars, setup gitolite internal "env" vars (aka rc vars)
# setup some perl/rc/env vars
# ----------------------------------------------------------------------
unshift @INC, "$rc{GL_BINDIR2}/lib" if $rc{GL_BINDIR2};
$ENV{PATH} = "$ENV{GL_BINDIR}:$ENV{PATH}";
{
@ -215,9 +218,9 @@ sub trigger {
Gitolite::Triggers::run( $module, $sub, @args, $rc_section, @_ );
} else {
$pgm = "$ENV{GL_BINDIR}/triggers/$pgm";
$pgm = _which("triggers/$pgm", 'x');
_warn("skipped command '$s'"), next if not -x $pgm;
_warn("skipped command '$s'"), next if not $pgm;
trace( 2, "command: $s" );
_system( $pgm, @args, $rc_section, @_ ); # they better all return with 0 exit codes!
}
@ -228,6 +231,23 @@ sub trigger {
trace( 2, "'$rc_section' not found in rc" );
}
sub _which {
# looks for a file in GL_BINDIR2 or GL_BINDIR. Returns whichever exists
# (GL_BINDIR2 preferred if defined) or 0 if not found.
my $file = shift;
my $mode = shift; # could be 'x' or 'r'
my @files = ("$rc{GL_BINDIR}/$file");
unshift @files, ("$rc{GL_BINDIR2}/$file") if $rc{GL_BINDIR2};
for my $f ( @files ) {
return $f if -x $f;
return $f if -r $f and $mode eq 'r';
}
return 0;
}
# ----------------------------------------------------------------------
=for args