From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id A32962032D for ; Fri, 5 Apr 2019 20:04:30 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 3/5] config: support more cgit directives for project lists Date: Fri, 5 Apr 2019 20:04:27 +0000 Message-Id: <20190405200429.16973-4-e@80x24.org> In-Reply-To: <20190405200429.16973-1-e@80x24.org> References: <20190405200429.16973-1-e@80x24.org> List-Id: Hopefully this gets us closer to matching cgit upstream behavior (which also lacks tests). We'll still need to support macro expansion at some point for compatibility... --- lib/PublicInbox/Config.pm | 95 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm index 2c1c511..2e6f493 100644 --- a/lib/PublicInbox/Config.pm +++ b/lib/PublicInbox/Config.pm @@ -200,12 +200,33 @@ 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; +# XXX needs testing for cgit compatibility +# cf. cgit/scan-tree.c::add_repo +sub cgit_repo_merge ($$$) { + my ($self, $base, $repo) = @_; + my $path = $repo->{dir}; + if (defined(my $se = $self->{-cgit_strict_export})) { + return unless -e "$path/$se"; + } + return if -e "$path/noweb"; + # $repo = { url => 'foo.git', dir => '/path/to/foo.git' } + my $rel = $repo->{url}; + unless (defined $rel) { + my $off = index($path, $base, 0); + if ($off != 0) { + $rel = $path; + } else { + $rel = substr($path, length($base) + 1); + } + + $rel =~ s!/\.git\z!! or + $rel =~ s!/+\z!!; + + $self->{-cgit_remove_suffix} and + $rel =~ s!/?\.git\z!!; + } + $self->{"coderepo.$rel.dir"} ||= $path; + $self->{"coderepo.$rel.cgiturl"} ||= $rel; } sub is_git_dir ($) { @@ -213,22 +234,43 @@ sub is_git_dir ($) { -d "$git_dir/objects" && -f "$git_dir/HEAD"; } +# XXX needs testing for cgit compatibility sub scan_path_coderepo { my ($self, $base, $path) = @_; - opendir my $dh, $path or return; + opendir(my $dh, $path) or do { + warn "error opening directory: $path\n"; + return + }; + my $git_dir = $path; + if (is_git_dir($git_dir) || is_git_dir($git_dir .= '/.git')) { + my $repo = { dir => $git_dir }; + cgit_repo_merge($self, $base, $repo); + return; + } while (defined(my $dn = readdir $dh)) { next if $dn eq '.' || $dn eq '..'; if (index($dn, '.') == 0 && !$self->{-cgit_scan_hidden_path}) { next; } - my $nick = $base eq '' ? $dn : "$base/$dn"; - my $git_dir = "$path/$dn"; - if (is_git_dir($git_dir)) { - my $repo = { url => $nick, path => $git_dir }; - cgit_repo_merge($self, $repo); - } elsif (-d $git_dir) { - scan_path_coderepo($self, $nick, $git_dir); - } + my $dir = "$path/$dn"; + scan_path_coderepo($self, $base, $dir) if -d $dir; + } +} + +sub scan_tree_coderepo ($$) { + my ($self, $path) = @_; + scan_path_coderepo($self, $path, $path); +} + +sub scan_projects_coderepo ($$$) { + my ($self, $list, $path) = @_; + open my $fh, '<', $list or do { + warn "failed to open cgit projectlist=$list: $!\n"; + return; + }; + foreach (<$fh>) { + chomp; + scan_path_coderepo($self, $path, "$path/$_"); } } @@ -255,7 +297,7 @@ sub parse_cgitrc { chomp; if (m!\Arepo\.url=(.+?)/*\z!) { my $nick = $1; - cgit_repo_merge($self, $repo) if $repo; + cgit_repo_merge($self, $repo->{path}, $repo) if $repo; $repo = { url => $nick }; } elsif (m!\Arepo\.path=(.+)\z!) { if (defined $repo) { @@ -265,17 +307,26 @@ sub parse_cgitrc { } } elsif (m!\Ainclude=(.+)\z!) { parse_cgitrc($self, $1, $nesting + 1); - } elsif (m!\Ascan-hidden-path=(\d+)\z!) { - $self->{-cgit_scan_hidden_path} = $1; + } elsif (m!\A(scan-hidden-path|remove-suffix)=(\d+)\z!) { + my ($k, $v) = ($1, $2); + $k =~ tr/-/_/; + $self->{"-cgit_$k"} = $v; + } elsif (m!\A(project-list|strict-export)=(.+)\z!) { + my ($k, $v) = ($1, $2); + $k =~ tr/-/_/; + $self->{"-cgit_$k"} = $v; } elsif (m!\Ascan-path=(.+)\z!) { - scan_path_coderepo($self, '', $1); - + if (defined(my $list = $self->{-cgit_project_list})) { + scan_projects_coderepo($self, $list, $1); + } else { + scan_tree_coderepo($self, $1); + } } elsif (m!\A(?:css|favicon|logo|repo\.logo)=(/.+)\z!) { # absolute paths for static files via PublicInbox::Cgit $self->{-cgit_static}->{$1} = 1; } } - cgit_repo_merge($self, $repo) if $repo; + cgit_repo_merge($self, $repo->{path}, $repo) if $repo; } # parse a code repo @@ -290,7 +341,7 @@ sub _fill_code_repo { } my $dir = $self->{"$pfx.dir"}; # aka "GIT_DIR" unless (defined $dir) { - warn "$pfx.dir unset"; + warn "$pfx.dir unset\n"; return; } -- EW