diff options
Diffstat (limited to 'src/commands/compile-template-data')
-rwxr-xr-x | src/commands/compile-template-data | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/commands/compile-template-data b/src/commands/compile-template-data new file mode 100755 index 0000000..e4ef86e --- /dev/null +++ b/src/commands/compile-template-data @@ -0,0 +1,101 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# read template data to produce gl-perms and gl-repo-groups files in each +# $repo dir. Create the repo if needed, using the wild repos create logic +# (with a "creator" of "gitolite-admin"!), though they're not really wild +# repos. + +# see rule-templates.html in the gitolite documentation site. + +# pure text manipulation (and very little of that!), no git or gitolite +# functions, no access checks, no possibility of a performance drama (or at +# least not a *complex* performance drama) + +use lib $ENV{GL_LIBDIR}; +use Gitolite::Rc; +use Gitolite::Common; +use Gitolite::Conf::Load; +use Gitolite::Conf::Store; + +my $rb = $rc{GL_REPO_BASE}; + +@ARGV = `find $rc{GL_ADMIN_BASE}/conf -type f -name "*.conf" | sort`; chomp(@ARGV); +# we don't see the files in the exact same order that gitolite compile sees +# them, but we don't need to, for the data we are interested in (as long as +# you don't break up one repo's data across multiple files!) + +# XXX We also potentially see more; a conf file may be in the directory, but +# not pulled in via an 'include' or 'subconf', so it doesn't exist as far as +# 'gitolite compile' is concerned, but here we *do* pull it in. + +my $repos = ''; +my $perms = ''; +my $list = ''; # list of templates to apply +my $lip = ''; # line in progress +while (<>) { + chomp; + next unless /^=begin template-data$/ .. /^=end$/ and not /^=(begin|end)/; + + next unless /\S/; + next if /^\s*#/; + + s/\t/ /g; # all the same to us + + # handle continuation lines (backslash as last character) + if (/\\$/) { + s/\\$//; + $lip .= $_; + next; + } + $_ = $lip . $_; + $lip = ''; + + _warn("bad line: $_"), next if m([^ \w.\@/=-]); # silently ignore lines that have characters we don't need + if (/^\s*repo\s+(\S.*)=\s*(\S.*)$/) { + flush($repos, $list, $perms); + $repos = $1; + $perms = ''; + $list = $2; + + } elsif (/^\s*(\S+)\s*=\s*(\S.*)$/) { + $perms .= "$1 = $2\n"; + } else { + # probably a blank line or a comment line. If not, well *shrug* + } +} +flush($repos, $list, $perms); + +sub flush { + my ($r, $l, $p) = @_; + return unless $r and $l and $p; + $l =~ s/\s+/ /g; + + my @r = split ' ', $r; + while (@r) { + my $r1 = shift @r; + if ($r1 =~ m(^@)) { + my @g = @{ Gitolite::Conf::Load::list_members($r1) }; + _warn "undefined group '$r1'" unless @g; + unshift @r, @g; + next; + } + + flush_1($r1, $l, $p); + } +} +sub flush_1 { + my ($repo, $list, $perms) = @_; + + # beware of wild characters! + return unless $repo =~ $REPONAME_PATT; + + if (not -d "$rb/$repo.git") { + new_wild_repo( $repo, 'gitolite-admin', 'template-data' ); + } + + _print("$rb/$repo.git/gl-repo-groups", $list); + + _print("$rb/$repo.git/gl-perms", $perms); +} |