]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
repobrowse: show repository index
authorEric Wong <e@80x24.org>
Sat, 16 Jan 2016 22:22:42 +0000 (22:22 +0000)
committerEric Wong <e@80x24.org>
Tue, 5 Apr 2016 18:58:27 +0000 (18:58 +0000)
Sometimes; people like to advertise projects and group them.
Of course, "-hidden" is a valid group for projects which do
not want to be advertised.

lib/PublicInbox/Repobrowse.pm
lib/PublicInbox/RepobrowseConfig.pm
lib/PublicInbox/RepobrowseGitLog.pm
lib/PublicInbox/RepobrowseGitSummary.pm
lib/PublicInbox/RepobrowseGitTag.pm
lib/PublicInbox/RepobrowseRoot.pm [new file with mode: 0644]

index f344e0f882757eded6276e9a798336ef3bfc9051..cc18255dc24306181c3f09842aa7046bbb7ac322 100644 (file)
@@ -61,6 +61,12 @@ sub no_tslash {
          [ "Redirecting to $url\n" ] ]
 }
 
+sub root_index {
+       my ($self) = @_;
+       my $mod = load_once('PublicInbox::RepobrowseRoot');
+       $mod->new->call($self->{rconfig}); # RepobrowseRoot::call
+}
+
 sub run {
        my ($self, $cgi, $method) = @_;
        return r(405, 'Method Not Allowed') if ($method !~ /\AGET|HEAD\z/);
@@ -68,11 +74,12 @@ sub run {
        # URL syntax: / repo [ / cmd [ / path ] ]
        # cmd: log | commit | diff | tree | view | blob | snapshot
        # repo and path (@extra) may both contain '/'
-       my $rconfig = $self->{rconfig};
        my $path_info = uri_unescape($cgi->path_info);
        my (undef, $repo_path, @extra) = split(m{/+}, $path_info, -1);
 
-       return r404() unless $repo_path;
+       return $self->root_index($self) unless length($repo_path);
+
+       my $rconfig = $self->{rconfig}; # RepobrowseConfig
        my $repo_info;
        until ($repo_info = $rconfig->lookup($repo_path)) {
                my $p = shift @extra or last;
@@ -104,12 +111,8 @@ sub run {
                if ($path_info =~ m!/\z!) {
                        $tslash = $path_info =~ tr!/!!;
                } else {
-                       my @repo = split('/', $repo_path);
-                       if (@repo > 1) {
-                               $req->{relcmd} = "./$repo[-1]/";
-                       } else {
-                               $req->{relcmd} = "/$repo[-1]/";
-                       }
+                       my @x = split('/', $repo_path);
+                       $req->{relcmd} = @x > 1 ? "./$x[-1]/" : "/$x[-1]/";
                }
        }
        while (@extra && $extra[-1] eq '') {
@@ -117,9 +120,7 @@ sub run {
                ++$tslash;
        }
 
-       if ($tslash && $path_info ne '/' && $NO_TSLASH{$mod}) {
-               return no_tslash($cgi);
-       }
+       return no_tslash($cgi) if ($tslash && $NO_TSLASH{$mod});
 
        $req->{tslash} = $tslash;
        $mod = load_once("PublicInbox::Repobrowse$vcs$mod");
index 800db05d4b56b645615201b890301cb4951ccb11..5752beedf6029e8c158dc0189bf2e8b7c487c7e3 100644 (file)
@@ -11,6 +11,8 @@ sub new {
        $file = default_file() unless defined($file);
        my $self = bless PublicInbox::Config::git_config_dump($file), $class;
        $self->{-cache} = {};
+       # for root
+       $self->{-groups} = { -hidden => [], -none => [] };
        $self;
 }
 
@@ -36,8 +38,9 @@ sub lookup {
        my $path = $self->{"repo.$repo_path.path"};
        (defined $path && -d $path) or return;
        $rv->{path} = $path;
-       $rv->{path_info} = $repo_path;
+       $rv->{repo} = $repo_path;
 
+       # gitweb compatibility
        foreach my $key (qw(description cloneurl)) {
                $rv->{$key} = try_cat("$path/$key");
        }
@@ -45,10 +48,18 @@ sub lookup {
        $rv->{desc_html} =
                PublicInbox::Hval->new_oneline($rv->{description})->as_html;
 
-       foreach my $key (qw(publicinbox vcs readme)) {
+       foreach my $key (qw(publicinbox vcs readme group)) {
                $rv->{$key} = $self->{"repo.$repo_path.$key"};
        }
 
+       my $g = $rv->{group};
+       defined $g or $g = '-none';
+       if (ref($g) eq 'ARRAY') {
+               push @{$self->{-groups}->{$_} ||= []}, $repo_path foreach @$g;
+       } else {
+               push @{$self->{-groups}->{$g} ||= []}, $repo_path;
+       }
+
        # of course git is the default VCS
        $rv->{vcs} ||= 'git';
        $self->{-cache}->{$repo_path} = $rv;
index 197d2cb1f1335d6e0f3972c5d6b7bacd1f7448d6..0c360e737d80f925d13b96db446844349b3b5059 100644 (file)
@@ -29,7 +29,7 @@ sub call_git_log {
        sub {
                my ($res) = @_; # Plack callback
                my $fh = $res->([200, ['Content-Type'=>'text/html']]);
-               my $title = utf8_html("log: $repo_info->{path_info} ($h)");
+               my $title = "log: $repo_info->{repo} ".utf8_html("($h)");
                $fh->write($self->html_start($req, $title));
                git_log_stream($req, $q, $log, $fh, $git);
                $fh->close;
index 65e32b6a69cd4472b4605c91443263689af21739..db601ad986fb0ed967a617a0c3df4c107245a5b4 100644 (file)
@@ -37,7 +37,7 @@ sub emit_summary {
        $fh = $res->([200, ['Content-Type'=>'text/html; charset=UTF-8']]);
        # ref names are unpredictable in length and requires tables :<
        $fh->write($self->html_start($req,
-                               "$repo_info->{path_info}: overview") .
+                               "$repo_info->{repo}: overview") .
                        '</pre><table>');
 
        my $rel = $req->{relcmd};
index ebda729eb967bd803b24a058f8de7f9005e7751e..229d5ff0968f78392bc07b63179c012ae0054d1b 100644 (file)
@@ -133,7 +133,7 @@ sub git_tag_list {
 
        # tag names are unpredictable in length and requires tables :<
        $fh->write($self->html_start($req,
-                               "$repo_info->{path_info}: tag list") .
+                               "$repo_info->{repo}: tag list") .
                '</pre><table><tr>' .
                join('', map { "<th><tt>$_</tt></th>" } qw(tag subject date)).
                '</tr>');
@@ -166,7 +166,7 @@ sub unknown_tag_type {
        my $obj_link = qq(<a\nhref="$rel$cmd?id=$hex">$label</a>\n);
 
        $fh->write($self->html_start($req,
-                               "$repo_info->{path_info}: ref: $h") .
+                               "$repo_info->{repo}: ref: $h") .
                "\n\n       <b>$h</b> (lightweight tag)\nobject $obj_link\n");
 }
 
diff --git a/lib/PublicInbox/RepobrowseRoot.pm b/lib/PublicInbox/RepobrowseRoot.pm
new file mode 100644 (file)
index 0000000..fda9643
--- /dev/null
@@ -0,0 +1,71 @@
+# Copyright (C) 2016 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# displays the root '/' where all the projects lie
+package PublicInbox::RepobrowseRoot;
+use strict;
+use warnings;
+use base qw(PublicInbox::RepobrowseBase);
+use PublicInbox::Hval qw(utf8_html);
+
+sub call {
+       my ($self, $rconfig) = @_;
+       sub {
+               my ($res) = @_; # PSGI callback
+               my @h = ('Content-Type', 'text/html; charset=UTF-8');
+               my $fh = $res->([200, \@h]);
+               repobrowse_index($fh, $rconfig);
+               $fh->close;
+       }
+}
+
+sub repobrowse_index {
+       my ($fh, $rconfig) = @_;
+       my $title = 'repobrowse index';
+       $fh->write("<html><head><title>$title</title>" .
+                       PublicInbox::Hval::STYLE .
+                       "</head><body><pre><b>$title</b>");
+
+       # preload all groups
+       foreach my $k (sort keys %$rconfig) {
+               $k =~ /\Arepo\.(.+)\.path\z/ or next;
+               my $repo_path = $1;
+               $rconfig->lookup($repo_path); # insert into groups
+       }
+
+       my $groups = $rconfig->{-groups};
+       if (scalar(keys %$groups) > 2) { # default has '-none' + '-hidden'
+               $fh->write("\n\n<b>uncategorized</b></pre>".
+                       "<table\nsummary=repoindex>");
+       } else {
+               $fh->write("</pre><table\nsummary=repoindex>");
+       }
+       foreach my $repo_path (sort @{$groups->{-none}}) {
+               my $r = $rconfig->lookup($repo_path);
+               my $p = PublicInbox::Hval->utf8($r->{repo});
+               my $l = $p->as_html;
+               $p = $p->as_path;
+               $fh->write(qq(<tr><td><tt><a\nhref="$p">$l</a></tt></td>) .
+                       "<td><tt> $r->{desc_html}</tt></td></tr>");
+       }
+
+       foreach my $group (keys %$groups) {
+               next if $group =~ /\A-(?:none|hidden)\z/;
+               my $g = utf8_html($group);
+               $fh->write("<tr><td><pre> </pre></td></tr>".
+                       "<tr><td><pre><b>$g</b></pre></tr>");
+               foreach my $repo_path (sort @{$groups->{$group}}) {
+                       my $r = $rconfig->lookup($repo_path);
+                       my $p = PublicInbox::Hval->utf8($r->{repo});
+                       my $l = $p->as_html;
+                       $p = $p->as_path;
+                       $fh->write('<tr><td><tt> ' .
+                               qq(<a\nhref="$p">$l</a></tt></td>) .
+                               "<td><tt> $r->{desc_html}</tt></td></tr>");
+               }
+       }
+
+       $fh->write('</table></body></html>');
+}
+
+1;