]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Config.pm
qspawn: wire up RLIMIT_* handling to limiters
[public-inbox.git] / lib / PublicInbox / Config.pm
index ccfc114f9888a7da1711ab9a582c825470afc913..6f62712f0eb1ea43b645e52a4a7fabe3c0cc1e9c 100644 (file)
@@ -30,9 +30,10 @@ sub new {
        $self->{-no_obfuscate} ||= {};
        $self->{-limiters} ||= {};
        $self->{-code_repos} ||= {}; # nick => PublicInbox::Git object
+       $self->{-cgitrc_unparsed} = $self->{'publicinbox.cgitrc'};
 
        if (my $no = delete $self->{'publicinbox.noobfuscate'}) {
-               $no = [ $no ] if ref($no) ne 'ARRAY';
+               $no = _array($no);
                my @domains;
                foreach my $n (@$no) {
                        my @n = split(/\s+/, $n);
@@ -132,7 +133,9 @@ sub limiter {
        $self->{-limiters}->{$name} ||= do {
                require PublicInbox::Qspawn;
                my $max = $self->{"publicinboxlimiter.$name.max"};
-               PublicInbox::Qspawn::Limiter->new($max);
+               my $limiter = PublicInbox::Qspawn::Limiter->new($max);
+               $limiter->setup_rlimit($name, $self);
+               $limiter;
        };
 }
 
@@ -147,6 +150,7 @@ sub default_file {
 sub git_config_dump {
        my ($file) = @_;
        my (%section_seen, @section_order);
+       return {} unless -e $file;
        my @cmd = (qw/git config/, "--file=$file", '-l');
        my $cmd = join(' ', @cmd);
        my $fh = popen_rd(\@cmd) or die "popen_rd failed for $file: $!\n";
@@ -196,15 +200,59 @@ sub valid_inbox_name ($) {
        1;
 }
 
+sub cgit_repo_merge ($$) {
+       my ($self, $repo) = @_;
+       # $repo = { url => 'foo.git', path => '/path/to/foo.git' }
+       my $nick = $repo->{url};
+       $self->{"coderepo.$nick.dir"} ||= $repo->{path};
+       $self->{"coderepo.$nick.cgiturl"} ||= $nick;
+}
+
+sub parse_cgitrc {
+       my ($self, $cgitrc, $nesting) = @_;
+
+       # same limit as cgit/configfile.c::parse_configfile
+       return if $nesting > 8;
+
+       open my $fh, '<', $cgitrc or do {
+               warn "failed to open cgitrc=$cgitrc: $!\n";
+               return;
+       };
+
+       # FIXME: this doesn't support macro expansion via $VARS, yet
+       my $repo;
+       foreach (<$fh>) {
+               chomp;
+               if (m!\Arepo\.url=(.+?)/*\z!) {
+                       my $nick = $1;
+                       cgit_repo_merge($self, $repo) if $repo;
+                       $repo = { url => $nick };
+               } elsif (m!\Arepo\.path=(.+)\z!) {
+                       if (defined $repo) {
+                               $repo->{path} = $1;
+                       } else {
+                               warn "$_ without repo.url\n";
+                       }
+               } elsif (m!\Ainclude=(.+)\z!) {
+                       parse_cgitrc($self, $1, $nesting + 1);
+               }
+       }
+       cgit_repo_merge($self, $repo) if $repo;
+}
+
 # parse a code repo
 # Only git is supported at the moment, but SVN and Hg are possibilities
 sub _fill_code_repo {
        my ($self, $nick) = @_;
        my $pfx = "coderepo.$nick";
 
+       # TODO: support gitweb and other repository viewers?
+       if (defined(my $cgitrc = delete $self->{-cgitrc_unparsed})) {
+               parse_cgitrc($self, $cgitrc, 0);
+       }
        my $dir = $self->{"$pfx.dir"}; # aka "GIT_DIR"
        unless (defined $dir) {
-               warn "$pfx.repodir unset";
+               warn "$pfx.dir unset";
                return;
        }
 
@@ -225,8 +273,6 @@ sub _fill_code_repo {
                        } @$cgits;
                }
        }
-       # TODO: support gitweb and other repository viewers?
-       # TODO: parse cgitrc
 
        $git;
 }
@@ -291,7 +337,11 @@ sub _fill {
                my $code_repos = $self->{-code_repos};
                my $repo_objs = $rv->{-repo_objs} = [];
                foreach my $nick (@$ibx_code_repos) {
-                       valid_inbox_name($nick) or next;
+                       my @parts = split(m!/!, $nick);
+                       my $valid = 0;
+                       $valid += valid_inbox_name($_) foreach (@parts);
+                       $valid == scalar(@parts) or next;
+
                        my $repo = $code_repos->{$nick} ||=
                                                _fill_code_repo($self, $nick);
                        push @$repo_objs, $repo if $repo;