aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/gl-compile-conf')
-rwxr-xr-xsrc/gl-compile-conf164
1 files changed, 102 insertions, 62 deletions
diff --git a/src/gl-compile-conf b/src/gl-compile-conf
index e962a9c..f8d35bb 100755
--- a/src/gl-compile-conf
+++ b/src/gl-compile-conf
@@ -92,6 +92,9 @@ our %groups = ();
# in between :)
my %repos = ();
+# repos whose ACLs don't make it into the main compiled config file
+my %split_conf = ();
+
# rule sequence number
my $rule_seq = 0;
@@ -105,8 +108,8 @@ our $current_data_version; # this comes from gitolite.pm
# catch usernames<->pubkeys mismatches; search for "lint" below
my %user_list = ();
-# repo configurations
-our %repo_config = ();
+# repo specific 'git config' stuff
+our %git_configs = ();
# gitweb descriptions and owners; plain text, keyed by "$repo.git"
my %desc = ();
@@ -274,7 +277,7 @@ sub parse_conf_line
}
}
}
- # configuration
+ # repo specific 'git config' stuff
elsif ($line =~ /^config (.+) = ?(.*)/)
{
my ($key, $value) = ($1, $2);
@@ -283,7 +286,7 @@ sub parse_conf_line
die "$ABRT git config $key not allowed\ncheck GL_GITCONFIG_KEYS in the rc file for how to allow it\n" if (@matched < 1);
for my $repo (@{ $repos_p }) # each repo in the current stanza
{
- $repo_config{$repo}{$key} = $value;
+ $git_configs{$repo}{$key} = $value;
# no problem if it's a plain repo (non-pattern, non-groupname)
# OR wild configs are allowed
unless ( ($repo =~ $REPONAME_PATT and $repo !~ /^@/) or $GL_GITCONFIG_WILD) {
@@ -405,26 +408,31 @@ for my $fragment_file (glob("conf/fragments/*.conf"))
parse_conf_file($fragment_file, $fragment);
}
-my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
-my $data_version = $current_data_version;
-print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
-my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
-$dumped_data .= Data::Dumper->Dump([\%repo_config], [qw(*repo_config)]) if %repo_config;
-# the dump uses single quotes, but we convert any strings containing $creator
-# and $gl_user to double quoted strings. A bit sneaky, but not too much...
-$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
-print $compiled_fh $dumped_data;
-if (%groups) {
- $dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
- $dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
+sub write_compiled_conf
+{
+ my $compiled_fh = wrap_open( ">", "$GL_CONF_COMPILED.new" );
+ my $data_version = $current_data_version;
+ print $compiled_fh Data::Dumper->Dump([$data_version], [qw(*data_version)]);
+ my $dumped_data = Data::Dumper->Dump([\%repos], [qw(*repos)]);
+ $dumped_data .= Data::Dumper->Dump([\%git_configs], [qw(*git_configs)]) if %git_configs;
+ # the dump uses single quotes, but we convert any strings containing $creator
+ # and $gl_user to double quoted strings. A bit sneaky, but not too much...
$dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
print $compiled_fh $dumped_data;
+ if (%groups) {
+ $dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
+ $dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
+ $dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
+ print $compiled_fh $dumped_data;
+ }
+ print $compiled_fh Data::Dumper->Dump([\%split_conf], [qw(*split_conf)]) if %split_conf;
+ close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
+ rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
}
-close $compiled_fh or die "$ABRT close compiled-conf failed: $!\n";
-rename "$GL_CONF_COMPILED.new", "$GL_CONF_COMPILED";
# ----------------------------------------------------------------------------
-# (that ends the config file compiler and write)
+# (that ends the config file compiler, though we postpone the writing
+# for now to deal with the latest GL_BIG_CONFIG innovation!)
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
@@ -450,25 +458,31 @@ die "\n\t\t***** AAARGH! *****\n" .
"\tthe newer features, please upgrade.\n"
if $git_version < 10602; # that's 1.6.2 to you
-
-
-# ----------------------------------------------------------------------------
-# the rest of this program can be "switched off"; see doc/big-config.mkd for
-# details.
-# ----------------------------------------------------------------------------
-
# ----------------------------------------------------------------------------
-# any new repos to be created?
+# most of the rest of this program can be "switched off"; see
+# doc/big-config.mkd for details.
# ----------------------------------------------------------------------------
-# repo-base needs to be an absolute path for this loop to work right
+# repo-base needs to be an absolute path due to all the jumping around we do,
# so if it was not already absolute, prefix $HOME.
$ENV{GL_REPO_BASE_ABS} = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$ENV{HOME}/$REPO_BASE" );
-unless ($GL_NO_CREATE_REPOS) {
+# process the normal repos in %repos. This includes creating them if needed
+# (and GL_NO_CREATE_REPOS is not set), checking hooks, and finally, if
+# GL_BIG_CONFIG is set, writing out the one-repo config file for directly
+# specified repos (i.e., "repo foo", not "@grp = foo" + "repo @grp")
+do_normal_repos();
+write_compiled_conf(); # write out the final compiled config
+
+# ----------------------------------------------------------------------------
+# process the normal repos in %repos (create, hook, one_repo config...)
+# ----------------------------------------------------------------------------
+
+sub do_normal_repos
+{
wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
- # autocreate repos. Start with the ones that are normal repos in %repos
+ # start with the ones that are normal repos in %repos
my @repos = grep { $_ =~ $REPONAME_PATT and not /^@/ } sort keys %repos;
# then, for each repogroup, find the members of the group and add them in
map { push @repos, keys %{ $groups{$_} } } grep { /^@/ } keys %repos;
@@ -477,39 +491,67 @@ unless ($GL_NO_CREATE_REPOS) {
@repos = sort keys %seen;
for my $repo (sort @repos) {
- next unless $repo =~ $REPONAME_PATT;
- next if $repo =~ m(^\@|EXTCMD/); # these are not real repos
- unless (-d "$repo.git") {
- print STDERR "creating $repo...\n";
- new_repo($repo, "$GL_ADMINDIR/hooks/common");
- # new_repo would have chdir'd us away; come back
- wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
- }
+ next unless $repo =~ $REPONAME_PATT; # skip repo patterns
+ next if $repo =~ m(^\@|EXTCMD/); # skip groups and fake repos
+
+ unless ($GL_NO_CREATE_REPOS) {
+ unless (-d "$repo.git") {
+ print STDERR "creating $repo...\n";
+ new_repo($repo, "$GL_ADMINDIR/hooks/common");
+ # new_repo would have chdir'd us away; come back
+ wrap_chdir("$ENV{GL_REPO_BASE_ABS}");
+ }
- # when repos are copied over from elsewhere, one had to run easy install
- # once again to make the new (OS-copied) repo contain the proper update
- # hook. Perhaps we can make this easier now, and eliminate the easy
- # install, with a quick check (and a new, empty, "hook" as a sentinel)
- unless (-l "$repo.git/hooks/gitolite-hooked") {
- ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo.git/hooks");
- # in case of package install, GL_ADMINDIR is no longer the top cop;
- # override with the package hooks
- ln_sf("$GL_PACKAGE_HOOKS/common", "*", "$repo.git/hooks") if $GL_PACKAGE_HOOKS;
+ # when repos are copied over from elsewhere, one had to run easy install
+ # once again to make the new (OS-copied) repo contain the proper update
+ # hook. Perhaps we can make this easier now, and eliminate the easy
+ # install, with a quick check (and a new, empty, "hook" as a sentinel)
+ unless (-l "$repo.git/hooks/gitolite-hooked") {
+ ln_sf("$GL_ADMINDIR/hooks/common", "*", "$repo.git/hooks");
+ # in case of package install, GL_ADMINDIR is no longer the top cop;
+ # override with the package hooks
+ ln_sf("$GL_PACKAGE_HOOKS/common", "*", "$repo.git/hooks") if $GL_PACKAGE_HOOKS;
+ }
}
+
+ # write a one_repo config for normal repos declared directly (not just via a group)
+ write_1_compiled_conf($repo) if $GL_BIG_CONFIG and $repos{$repo} and -d "$repo.git";
}
}
-# ----------------------------------------------------------------------------
-# collect repo_patt for each actual repo
-# ----------------------------------------------------------------------------
+sub write_1_compiled_conf
+{
+ # warning: writes and *deletes* it from %repos and %git_configs
+ my ($repo) = shift;
+ my (%one_repo, %one_git_config);
-# go through each actual repo on disk, and match it to either its own name in
-# the config (non-wild) or a wild pattern that matches it. Lots of things
-# later will need this correspondence so we may as well snarf it in one shot
+ open(my $compiled_fh, ">", "$repo.git/gl-conf") or return;
+ $one_repo{$repo} = $repos{$repo};
+ delete $repos{$repo};
+ my $dumped_data = Data::Dumper->Dump([\%one_repo], [qw(*one_repo)]);
-my %repo_patts = ();
-%repo_patts = &collect_repo_patts(\%repos) unless $GL_NO_DAEMON_NO_GITWEB;
+ if ($git_configs{$repo}) {
+ $one_git_config{$repo} = $git_configs{$repo};
+ delete $git_configs{$repo};
+ $dumped_data .= Data::Dumper->Dump([\%one_git_config], [qw(*one_git_config)]);
+ }
+
+ # the dump uses single quotes, but we convert any strings containing $creator
+ # and $gl_user to double quoted strings. A bit sneaky, but not too much...
+ $dumped_data =~ s/'(?=[^']*\$(?:creator|gl_user))~?(.*?)'/"$1"/g;
+ print $compiled_fh $dumped_data;
+ close $compiled_fh;
+
+ $split_conf{$repo} = 1;
+}
+
+# ----------------------------------------------------------------------------
+# get a list of physical repos for later
+# ----------------------------------------------------------------------------
+
+my @phy_repos = ();
+@phy_repos = &list_phy_repos() unless $GL_NO_DAEMON_NO_GITWEB;
# NOTE: we're overloading GL_NO_DAEMON_NO_GITWEB to mean "no git config" also.
# In fact anything that requires trawling through the existing repos doing
@@ -527,8 +569,6 @@ my %repo_patts = ();
# update repo configurations, gitweb description, daemon export-ok, etc
# ----------------------------------------------------------------------------
-# all these require a "chdir" to the repo, so we club them for efficiency
-
my %projlist = ();
# for each real repo (and remember this will be empty, thus skipping all this,
@@ -537,13 +577,13 @@ my %projlist = ();
# note: we do them in 2 separate loops to avoid breaking the optimisation in
# sub parse_acl (look for variable $saved_crwu)
-for my $repo (keys %repo_patts) {
+for my $repo (@phy_repos) {
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
# daemon is easy
&setup_daemon_access($repo);
}
-for my $repo (keys %repo_patts) {
+for my $repo (@phy_repos) {
wrap_chdir("$ENV{GL_REPO_BASE_ABS}/$repo.git");
# gitweb is a little more complicated. Here're some notes:
# - "setup_gitweb_access" also sets "owner", despite the name
@@ -562,9 +602,9 @@ for my $repo (keys %repo_patts) {
# calls (setup daemon or gitweb). The reason is that they call
# "can_read", which eventually calls parse_acl with the right "creator"
# set for the *current* repo, which in turn stores translated values for
- # $creator in the repo_config hash, which, (phew!) is needed for a match
- # that eventually gets you a valid $repo_config{} below
- &setup_repo_configs($repo, \%repo_config) if $repo_config{$repo};
+ # $creator in the git_configs hash, which, (phew!) is needed for a match
+ # that eventually gets you a valid $git_configs{} below
+ &setup_git_configs($repo, \%git_configs) if $git_configs{$repo};
}
# write out the project list