about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-04-05 20:04:27 +0000
committerEric Wong <e@80x24.org>2019-04-15 06:20:38 +0000
commit5af89c247ef7e9c0f205edb3c30f25356895ce2c (patch)
treebdcbe16723246bfe7e9e50b216ad5da85dcd10c0 /lib/PublicInbox
parent19151f1b6a04532a1bc3f86fa945a10be6849b8d (diff)
downloadpublic-inbox-5af89c247ef7e9c0f205edb3c30f25356895ce2c.tar.gz
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...
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/Config.pm95
1 files changed, 73 insertions, 22 deletions
diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm
index 2c1c5111..2e6f4931 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;
         }