(lotsa files affected) rc file format changed; see below

The rc file used to be a bunch of variables, each one requiring to be
declared before being used.  While this was nice and all, it was a
little cumbersome to add a new flag or option.

If you disregard the "catch typos" aspect of having to predeclare
variables, it's a lot more useful to have all of rc be in a hash and use
any hash keys you want.

There could be other uses; for instance it could hold arbitrary data
that you would currently put in %ENV, without having to pollute %ENV if
you don't need child tasks to inherit it.

----

NOTE: I also ran perltidy, which I don't always remember to :)
This commit is contained in:
Sitaram Chamarty 2012-03-16 09:59:45 +05:30
parent 1a1be8b222
commit 8ffc5307d6
10 changed files with 309 additions and 94 deletions

View file

@ -40,7 +40,7 @@ my $all = 0;
# ----------------------------------------------------------------------
sub query_rc {
trace( 1, "rc file not found; default should be " . glrc_default_filename() ) if not glrc_filename();
trace( 1, "rc file not found; default should be " . glrc('default-filename') ) if not glrc('filename');
my @vars = args();

View file

@ -56,7 +56,7 @@ sub setup {
sub first_run {
# if the rc file could not be found, it's *definitely* a first run!
return not glrc_filename();
return not glrc('filename');
}
sub args {
@ -91,7 +91,7 @@ sub args {
sub setup_glrc {
trace(1);
_print( glrc_default_filename(), glrc_default_text() );
_print( glrc('default-filename'), glrc('default-text') );
}
sub setup_gladmin {
@ -99,7 +99,7 @@ sub setup_gladmin {
trace( 1, $admin );
# reminder: 'admin files' are in ~/.gitolite, 'admin repo' is
# $GL_REPO_BASE/gitolite-admin.git
# $rc{GL_REPO_BASE}/gitolite-admin.git
# grab the pubkey content before we chdir() away
@ -111,8 +111,8 @@ sub setup_gladmin {
# set up the admin files in admin-base
_mkdir($GL_ADMIN_BASE);
_chdir($GL_ADMIN_BASE);
_mkdir( $rc{GL_ADMIN_BASE} );
_chdir( $rc{GL_ADMIN_BASE} );
_mkdir("conf");
my $conf;
@ -132,15 +132,15 @@ sub setup_gladmin {
# set up the admin repo in repo-base
_chdir();
_mkdir($GL_REPO_BASE);
_chdir($GL_REPO_BASE);
_mkdir( $rc{GL_REPO_BASE} );
_chdir( $rc{GL_REPO_BASE} );
new_repo("gitolite-admin");
# commit the admin files to the admin repo
$ENV{GIT_WORK_TREE} = $GL_ADMIN_BASE;
_chdir("$GL_REPO_BASE/gitolite-admin.git");
$ENV{GIT_WORK_TREE} = $rc{GL_ADMIN_BASE};
_chdir("$rc{GL_REPO_BASE}/gitolite-admin.git");
system("git add conf/gitolite.conf");
system("git add keydir") if $pubkey;
tsh_try("git config --get user.email") or tsh_run( "git config user.email $ENV{USER}\@" . `hostname` );

View file

@ -34,7 +34,7 @@ sub compile {
trace(3);
# XXX assume we're in admin-base/conf
_chdir($GL_ADMIN_BASE);
_chdir( $rc{GL_ADMIN_BASE} );
_chdir("conf");
explode( 'gitolite.conf', 'master', \&parse );
@ -99,7 +99,7 @@ sub parse {
}
} elsif ( $line =~ /^config (.+) = ?(.*)/ ) {
my ( $key, $value ) = ( $1, $2 );
my @validkeys = split( ' ', ( $GL_GITCONFIG_KEYS || '' ) );
my @validkeys = split( ' ', ( $rc{GL_GITCONFIG_KEYS} || '' ) );
push @validkeys, "gitolite-options\\..*";
my @matched = grep { $key =~ /^$_$/ } @validkeys;
# XXX move this also to add_config: _die "git config $key not allowed\ncheck GL_GITCONFIG_KEYS in the rc file for how to allow it" if (@matched < 1);
@ -123,8 +123,8 @@ sub incsub {
# XXX move this to Macros... substitute HOSTNAME word if GL_HOSTNAME defined, otherwise leave as is
# $include_glob =~ s/\bHOSTNAME\b/$GL_HOSTNAME/ if $GL_HOSTNAME;
# XXX g2 diff: include glob is *implicitly* from $GL_ADMIN_BASE/conf, not *explicitly*
# for my $file (glob($include_glob =~ m(^/) ? $include_glob : "$GL_ADMIN_BASE/conf/$include_glob")) {
# XXX g2 diff: include glob is *implicitly* from $rc{GL_ADMIN_BASE}/conf, not *explicitly*
# for my $file (glob($include_glob =~ m(^/) ? $include_glob : "$rc{GL_ADMIN_BASE}/conf/$include_glob")) {
trace( 3, $is_subconf, $include_glob );

View file

@ -92,7 +92,7 @@ sub access {
sub load_common {
_chdir("$GL_ADMIN_BASE");
_chdir( $rc{GL_ADMIN_BASE} );
# we take an unusual approach to caching this function!
# (requires that first call to load_common is before first call to load_1)
@ -118,7 +118,7 @@ sub load_1 {
my $repo = shift;
trace( 4, $repo );
_chdir("$GL_REPO_BASE");
_chdir( $rc{GL_REPO_BASE} );
if ( $repo eq $last_repo ) {
$repos{$repo} = $one_repo{$repo};
@ -172,7 +172,7 @@ sub memberships {
}
sub data_version_mismatch {
return $data_version ne $current_data_version;
return $data_version ne glrc('current-data-version');
}
# ----------------------------------------------------------------------
@ -192,10 +192,10 @@ Usage: gitolite list-groups
load_common();
my @g = ();
while (my ($k, $v) = each ( %groups )) {
push @g, @{ $v };
while ( my ( $k, $v ) = each(%groups) ) {
push @g, @{$v};
}
return (sort_u(\@g));
return ( sort_u( \@g ) );
}
sub list_users {
@ -213,19 +213,18 @@ Usage: gitolite list-users
load_common();
my @u = map { keys %{ $_ } } values %repos;
$total = scalar(keys %split_conf);
my @u = map { keys %{$_} } values %repos;
$total = scalar( keys %split_conf );
warn "WARNING: you have $total repos to check; this could take some time!\n" if $total > 100;
for my $one ( keys %split_conf ) {
load_1($one);
$count++; print STDERR "$count / $total\r" if not ( $count % 100 ) and timer(5);
push @u, map { keys %{ $_ } } values %one_repo;
$count++; print STDERR "$count / $total\r" if not( $count % 100 ) and timer(5);
push @u, map { keys %{$_} } values %one_repo;
}
print STDERR "\n";
return (sort_u(\@u));
return ( sort_u( \@u ) );
}
sub list_repos {
die "
@ -241,7 +240,7 @@ Usage: gitolite list-repos
my @r = keys %repos;
push @r, keys %split_conf;
return (sort_u(\@r));
return ( sort_u( \@r ) );
}
sub list_memberships {
@ -258,7 +257,7 @@ Usage: gitolite list-memberships <name>
load_common();
my @m = memberships($name);
return (sort_u(\@m));
return ( sort_u( \@m ) );
}
sub list_members {
@ -276,13 +275,13 @@ Usage: gitolite list-members <group name>
load_common();
my @m = ();
while (my ($k, $v) = each ( %groups )) {
for my $g ( @{ $v } ) {
while ( my ( $k, $v ) = each(%groups) ) {
for my $g ( @{$v} ) {
push @m, $k if $g eq $name;
}
}
return (sort_u(\@m));
return ( sort_u( \@m ) );
}
# ----------------------------------------------------------------------

View file

@ -145,14 +145,14 @@ sub set_subconf {
sub new_repos {
trace(3);
_chdir($GL_REPO_BASE);
_chdir( $rc{GL_REPO_BASE} );
# normal repos
my @repos = grep { $_ =~ $REPONAME_PATT and not /^@/ } sort keys %repos;
# add in members of repo groups
map { push @repos, keys %{ $groups{$_} } } grep { /^@/ } keys %repos;
for my $repo ( @{ sort_u(\@repos) } ) {
for my $repo ( @{ sort_u( \@repos ) } ) {
next unless $repo =~ $REPONAME_PATT; # skip repo patterns
next if $repo =~ m(^\@|EXTCMD/); # skip groups and fake repos
@ -170,7 +170,7 @@ sub new_repo {
_mkdir("$repo.git");
_chdir("$repo.git");
system("git init --bare >&2");
_chdir($GL_REPO_BASE);
_chdir( $rc{GL_REPO_BASE} );
hook_1($repo);
# XXX ignoring creator for now
@ -180,7 +180,7 @@ sub new_repo {
sub hook_repos {
trace(3);
# all repos, all hooks
_chdir($GL_REPO_BASE);
_chdir( $rc{GL_REPO_BASE} );
# XXX g2 diff: we now don't care if it's a symlink -- it's upto the admin
# on the server to make sure things are kosher
@ -195,14 +195,14 @@ sub store {
trace(3);
# first write out the ones for the physical repos
_chdir($GL_REPO_BASE);
_chdir( $rc{GL_REPO_BASE} );
my $phy_repos = list_phy_repos(1);
for my $repo (@{ $phy_repos }) {
for my $repo ( @{$phy_repos} ) {
store_1($repo);
}
_chdir($GL_ADMIN_BASE);
_chdir( $rc{GL_ADMIN_BASE} );
store_common();
}
@ -261,7 +261,7 @@ sub store_common {
my $cc = "conf/gitolite.conf-compiled.pm";
my $compiled_fh = _open( ">", "$cc.new" );
my $data_version = $current_data_version;
my $data_version = glrc('current-data-version');
trace( 1, "data_version = $data_version" );
print $compiled_fh Data::Dumper->Dump( [$data_version], [qw(*data_version)] );
@ -296,20 +296,20 @@ sub store_common {
# reset the gitolite supplied hooks, in case someone fiddled with
# them, but only once per run
if ( not $hook_reset ) {
_mkdir("$GL_ADMIN_BASE/hooks/common");
_mkdir("$GL_ADMIN_BASE/hooks/gitolite-admin");
_print( "$GL_ADMIN_BASE/hooks/common/update", update_hook() );
_print( "$GL_ADMIN_BASE/hooks/gitolite-admin/post-update", post_update_hook() );
chmod 0755, "$GL_ADMIN_BASE/hooks/common/update";
chmod 0755, "$GL_ADMIN_BASE/hooks/gitolite-admin/post-update";
_mkdir("$rc{GL_ADMIN_BASE}/hooks/common");
_mkdir("$rc{GL_ADMIN_BASE}/hooks/gitolite-admin");
_print( "$rc{GL_ADMIN_BASE}/hooks/common/update", update_hook() );
_print( "$rc{GL_ADMIN_BASE}/hooks/gitolite-admin/post-update", post_update_hook() );
chmod 0755, "$rc{GL_ADMIN_BASE}/hooks/common/update";
chmod 0755, "$rc{GL_ADMIN_BASE}/hooks/gitolite-admin/post-update";
$hook_reset++;
}
# propagate user hooks
ln_sf( "$GL_ADMIN_BASE/hooks/common", "*", "$repo.git/hooks" );
ln_sf( "$rc{GL_ADMIN_BASE}/hooks/common", "*", "$repo.git/hooks" );
# propagate admin hook
ln_sf( "$GL_ADMIN_BASE/hooks/gitolite-admin", "*", "$repo.git/hooks" ) if $repo eq 'gitolite-admin';
ln_sf( "$rc{GL_ADMIN_BASE}/hooks/gitolite-admin", "*", "$repo.git/hooks" ) if $repo eq 'gitolite-admin';
# g2 diff: no "site-wide" hooks (the stuff in between gitolite hooks
# and user hooks) anymore. I don't think anyone used them anyway...

View file

@ -27,7 +27,7 @@ sub post_update {
_die "no files/dirs called 'hooks' or 'logs' are allowed" if tsh_text() =~ /^(hooks|logs)$/;
{
local $ENV{GIT_WORK_TREE} = $GL_ADMIN_BASE;
local $ENV{GIT_WORK_TREE} = $rc{GL_ADMIN_BASE};
tsh_try("git checkout -f --quiet master");
}
system("$ENV{GL_BINDIR}/gitolite compile");

View file

@ -4,24 +4,14 @@ package Gitolite::Rc;
# ----------------------------------------------------------------------
@EXPORT = qw(
$GL_ADMIN_BASE
$GL_REPO_BASE
$GL_UMASK
$GL_GITCONFIG_KEYS
glrc_default_text
glrc_default_filename
glrc_filename
%rc
glrc
$ADC_CMD_ARGS_PATT
$REF_OR_FILENAME_PATT
$REPONAME_PATT
$REPOPATT_PATT
$USERNAME_PATT
$current_data_version
);
use Exporter 'import';
@ -32,14 +22,12 @@ use Gitolite::Common;
# variables that are/could be/should be in the rc file
# ----------------------------------------------------------------------
$GL_ADMIN_BASE = "$ENV{HOME}/.gitolite";
$GL_REPO_BASE = "$ENV{HOME}/repositories";
$rc{GL_ADMIN_BASE} = "$ENV{HOME}/.gitolite";
$rc{GL_REPO_BASE} = "$ENV{HOME}/repositories";
# variables that should probably never be changed
# ----------------------------------------------------------------------
$current_data_version = "3.0";
$ADC_CMD_ARGS_PATT = qr(^[0-9a-zA-Z._\@/+:-]*$);
$REF_OR_FILENAME_PATT = qr(^[0-9a-zA-Z][0-9a-zA-Z._\@/+ :,-]*$);
$REPONAME_PATT = qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@/+-]*$);
@ -48,44 +36,56 @@ $USERNAME_PATT = qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$);
# ----------------------------------------------------------------------
my $current_data_version = "3.0";
my $rc = glrc('filename');
do $rc if -r $rc;
# let values specified in rc file override our internal ones
@rc{ keys %RC } = values %RC;
# ----------------------------------------------------------------------
use strict;
use warnings;
# ----------------------------------------------------------------------
my $rc = glrc_filename();
do $rc if -r $rc;
my $glrc_default_text = '';
{
my $glrc_default_text = '';
local $/ = undef;
$glrc_default_text = <DATA>;
}
sub glrc_default_text {
sub glrc {
my $cmd = shift;
if ( $cmd eq 'default-filename' ) {
trace( 1, "..should happen only on first run" );
return "$ENV{HOME}/.gitolite.rc";
} elsif ( $cmd eq 'default-text' ) {
trace( 1, "..should happen only on first run" );
return $glrc_default_text if $glrc_default_text;
local $/ = undef;
$glrc_default_text = <DATA>;
_die "rc file default text not set; this should not happen!";
} elsif ( $cmd eq 'filename' ) {
# where is the rc file?
trace(4);
# search $HOME first
return "$ENV{HOME}/.gitolite.rc" if -f "$ENV{HOME}/.gitolite.rc";
trace( 2, "$ENV{HOME}/.gitolite.rc not found" );
# XXX for fedora, we can add the following line, but I would really prefer
# if ~/.gitolite.rc on each $HOME was just a symlink to /etc/gitolite.rc
# XXX return "/etc/gitolite.rc" if -f "/etc/gitolite.rc";
return '';
} elsif ( $cmd eq 'current-data-version' ) {
return $current_data_version;
} else {
_die "unknown argument to glrc: $cmd";
}
}
sub glrc_default_filename {
trace( 1, "..should happen only on first run" );
return "$ENV{HOME}/.gitolite.rc";
}
# where is the rc file?
sub glrc_filename {
trace(4);
# search $HOME first
return "$ENV{HOME}/.gitolite.rc" if -f "$ENV{HOME}/.gitolite.rc";
trace( 2, "$ENV{HOME}/.gitolite.rc not found" );
# XXX for fedora, we can add the following line, but I would really prefer
# if ~/.gitolite.rc on each $HOME was just a symlink to /etc/gitolite.rc
# XXX return "/etc/gitolite.rc" if -f "/etc/gitolite.rc";
return '';
}
# ----------------------------------------------------------------------
1;
@ -99,8 +99,10 @@ __DATA__
# this file is in perl syntax. However, you do NOT need to know perl to edit
# it; it should be fairly self-explanatory and easy to maintain
$GL_UMASK = 0077;
$GL_GITCONFIG_KEYS = "";
%RC = (
GL_UMASK => 0077,
GL_GITCONFIG_KEYS => "",
);
# ------------------------------------------------------------------------------
# per perl rules, this should be the last line in such a file:

View file

@ -79,7 +79,7 @@ sub args {
print "$_\n" for ( @{ list_repos() } );
} elsif ( $command eq 'list-phy-repos' ) {
shift @ARGV;
_chdir($GL_REPO_BASE);
_chdir( $rc{GL_REPO_BASE} );
print "$_\n" for ( @{ list_phy_repos() } );
} elsif ( $command eq 'list-memberships' ) {
shift @ARGV;

View file

@ -38,7 +38,7 @@ my $ret = access( $repo, $user, $aa, 'unknown' );
trace( 1, "access($repo, $user, $aa, 'unknown') -> $ret" );
_die $ret if $ret =~ /DENIED/;
$repo = "'$GL_REPO_BASE/$repo.git'";
$repo = "'$rc{GL_REPO_BASE}/$repo.git'";
exec( "git", "shell", "-c", "$verb $repo" );
# ----------------------------------------------------------------------

214
src/Gitolite/Rc.pm Normal file
View file

@ -0,0 +1,214 @@
package Gitolite::Rc;
# everything to do with 'rc'. Also defines some 'constants'
# ----------------------------------------------------------------------
@EXPORT = qw(
%rc
glrc
query_rc
version
$REMOTE_COMMAND_PATT
$REF_OR_FILENAME_PATT
$REPONAME_PATT
$REPOPATT_PATT
$USERNAME_PATT
);
use Exporter 'import';
use Getopt::Long;
use Gitolite::Common;
# ----------------------------------------------------------------------
our %rc;
# ----------------------------------------------------------------------
# variables that are/could be/should be in the rc file
# ----------------------------------------------------------------------
$rc{GL_BINDIR} = $ENV{GL_BINDIR};
$rc{GL_ADMIN_BASE} = "$ENV{HOME}/.gitolite";
$rc{GL_REPO_BASE} = "$ENV{HOME}/repositories";
# variables that should probably never be changed
# ----------------------------------------------------------------------
$REMOTE_COMMAND_PATT = qr(^[- 0-9a-zA-Z\@\%_=+:,./]*$);
$REF_OR_FILENAME_PATT = qr(^[0-9a-zA-Z][0-9a-zA-Z._\@/+ :,-]*$);
$REPONAME_PATT = qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@/+-]*$);
$REPOPATT_PATT = qr(^\@?[0-9a-zA-Z[][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/,-]*$);
$USERNAME_PATT = qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$);
# ----------------------------------------------------------------------
my $current_data_version = "3.0";
my $rc = glrc('filename');
do $rc if -r $rc;
_die "$rc seems to be for older gitolite" if defined($GL_ADMINDIR);
# let values specified in rc file override our internal ones
@rc{ keys %RC } = values %RC;
# testing sometimes requires all of it to be overridden silently; 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 PATH (TODO: do it only if 'gitolite' isn't in PATH)
$ENV{PATH} = "$ENV{GL_BINDIR}:$ENV{PATH}";
# ----------------------------------------------------------------------
use strict;
use warnings;
# ----------------------------------------------------------------------
my $glrc_default_text = '';
{
local $/ = undef;
$glrc_default_text = <DATA>;
}
sub glrc {
my $cmd = shift;
if ( $cmd eq 'default-filename' ) {
return "$ENV{HOME}/.gitolite.rc";
} elsif ( $cmd eq 'default-text' ) {
return $glrc_default_text if $glrc_default_text;
_die "rc file default text not set; this should not happen!";
} elsif ( $cmd eq 'filename' ) {
# where is the rc file?
# search $HOME first
return "$ENV{HOME}/.gitolite.rc" if -f "$ENV{HOME}/.gitolite.rc";
# XXX for fedora, we can add the following line, but I would really prefer
# if ~/.gitolite.rc on each $HOME was just a symlink to /etc/gitolite.rc
# XXX return "/etc/gitolite.rc" if -f "/etc/gitolite.rc";
return '';
} elsif ( $cmd eq 'current-data-version' ) {
return $current_data_version;
} else {
_die "unknown argument to glrc: $cmd";
}
}
# ----------------------------------------------------------------------
# implements 'gitolite query-rc' and 'version'
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
my $all = 0;
my $nonl = 0;
sub query_rc {
my @vars = args();
no strict 'refs';
if ($all) {
for my $e ( sort keys %rc ) {
print "$e=" . ( defined( $rc{$e} ) ? $rc{$e} : 'undef' ) . "\n";
}
return;
}
print join( "\t", map { $rc{$_} || '' } @vars ) . ( $nonl ? '' : "\n" ) if @vars;
}
sub version {
my $version = '';
$version = '(unknown)';
for ("$rc{GL_ADMIN_BASE}/VERSION") {
$version = slurp($_) if -r $_;
}
chomp($version);
return $version;
}
# ----------------------------------------------------------------------
=for args
Usage: gitolite query-rc -a
gitolite query-rc [-n] <list of rc variables>
-a print all variables and values
-n do not append a newline
Example:
gitolite query-rc GL_ADMIN_BASE UMASK
# prints "/home/git/.gitolite<tab>0077" or similar
gitolite query-rc -a
# prints all known variables and values, one per line
=cut
sub args {
my $help = 0;
GetOptions(
'all|a' => \$all,
'nonl|n' => \$nonl,
'help|h' => \$help,
) or usage();
usage("'-a' cannot be combined with other arguments") if $all and @ARGV;
usage() if not $all and not @ARGV or $help;
return @ARGV;
}
1;
# ----------------------------------------------------------------------
__DATA__
# configuration variables for gitolite
# This file is in perl syntax. But you do NOT need to know perl to edit it --
# just mind the commas and make sure the brackets and braces stay matched up!
# (Tip: perl allows a comma after the last item in a list also!)
%RC = (
UMASK => 0077,
GL_GITCONFIG_KEYS => "",
# comment out or uncomment as needed
# these will run in sequence during the conf file parse
SYNTACTIC_SUGAR =>
[
# 'continuation-lines',
],
# comment out or uncomment as needed
# these will run in sequence after post-update
POST_COMPILE =>
[
'post-compile/ssh-authkeys',
],
# comment out or uncomment as needed
# these are available to remote users
COMMANDS =>
{
'help' => 1,
'info' => 1,
},
);
# ------------------------------------------------------------------------------
# per perl rules, this should be the last line in such a file:
1;
# Local variables:
# mode: perl
# End:
# vim: set syn=perl: