about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2017-02-04 02:21:06 +0000
committerEric Wong <e@80x24.org>2017-02-05 03:58:15 +0000
commit19fb59f389e988e880d378fdb79a53eb16f292a3 (patch)
tree3051ec216938234e4216b5aeba83e974adfaafad /lib/PublicInbox
parent19e629115004d67c42a7c40285b30b71611ce63c (diff)
downloadpublic-inbox-19fb59f389e988e880d378fdb79a53eb16f292a3.tar.gz
I'm unsure if this is even a good idea to support,
but we have it, for now.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/RepobrowseGitTag.pm100
1 files changed, 63 insertions, 37 deletions
diff --git a/lib/PublicInbox/RepobrowseGitTag.pm b/lib/PublicInbox/RepobrowseGitTag.pm
index cf835aed..1d26eab0 100644
--- a/lib/PublicInbox/RepobrowseGitTag.pm
+++ b/lib/PublicInbox/RepobrowseGitTag.pm
@@ -8,6 +8,7 @@ use warnings;
 use base qw(PublicInbox::RepobrowseBase);
 use POSIX qw(strftime);
 use PublicInbox::Hval qw(utf8_html);
+use PublicInbox::Qspawn;
 
 my %cmd_map = ( # type => action
         commit => 'commit',
@@ -20,10 +21,7 @@ sub call_git_tag {
 
         my $q = PublicInbox::RepobrowseGitQuery->new($req->{env});
         my $h = $q->{h};
-        $h eq '' and return sub {
-                my ($res) = @_;
-                git_tag_list($self, $req, $res);
-        };
+        $h eq '' and return git_tag_list($self, $req);
         sub {
                 my ($res) = @_;
                 git_tag_show($self, $req, $h, $res);
@@ -115,45 +113,73 @@ sub invalid_tag_start {
                 qq(see <a\nhref="${rel}tag">tag list</a> for valid tags.);
 }
 
-sub git_tag_list {
-        my ($self, $req, $res) = @_;
+sub git_each_tag_sed ($$) {
+        my ($self, $req) = @_;
         my $repo_info = $req->{repo_info};
-        my $git = $repo_info->{git};
-        my $desc = $repo_info->{desc_html};
+        my $buf = '';
+        my $nr = 0;
+        $req->{thtml} = $self->html_start($req, "$repo_info->{repo}: tag list") .
+                '</pre><table><tr>' .
+                join('', map { "<th><tt>$_</tt></th>" } qw(tag date subject)).
+                '</tr>';
+        sub {
+                my $dst = delete $req->{thtml} || '';
+                my $end = '';
+                my @lines;
+                if (defined $_[0]) {
+                        @lines = split(/\n/, $buf .= $_[0]);
+                        $buf = pop @lines if @lines;
+                } else { # for-each-ref EOF
+                        @lines = split(/\n/, $buf);
+                        $buf = undef;
+                        if ($nr == $req->{-tag_count}) {
+                                $end = "<pre>Showing the latest $nr tags</pre>";
+                        } elsif ($nr == 0) {
+                                $end = '<pre>no tags to show</pre>';
+                        }
+                        $end = "</table>$end</body></html>";
+                }
+                for (@lines) {
+                        my ($ref, $date, $s) = split(' ', $_, 3);
+                        ++$nr;
+                        $ref =~ s!\Arefs/tags/!!;
+                        $ref = PublicInbox::Hval->utf8($ref);
+                        my $h = $ref->as_html;
+                        $ref = $ref->as_href;
+                        $dst .= qq(<tr><td><tt>) .
+                                qq(<a\nhref="?h=$ref"><b>$h</b></a>) .
+                                qq(</tt></td><td><tt>$date</tt></td><td><tt>) .
+                                utf8_html($s) . '</tt></td></tr>';
+                }
+                $dst .= $end;
+        }
+}
+
+sub git_tag_list {
+        my ($self, $req) = @_;
+        my $git = $req->{repo_info}->{git};
 
         # TODO: use Xapian so we can more easily handle offsets/limits
         # for pagination instead of limiting
-        my $nr = 0;
-        my $count = 50;
-        my @cmd = (qw(for-each-ref --sort=-creatordate),
+        my $count = $req->{-tag_count} = 50;
+        my $cmd = $git->cmd(qw(for-each-ref --sort=-creatordate),
                 '--format=%(refname) %(creatordate:short) %(subject)',
                 "--count=$count", 'refs/tags/');
-        my $refs = $git->popen(@cmd);
-        my $fh = $res->([200, ['Content-Type', 'text/html; charset=UTF-8']]);
-
-        # tag names are unpredictable in length and requires tables :<
-        $fh->write($self->html_start($req,
-                                "$repo_info->{repo}: tag list") .
-                '</pre><table><tr>' .
-                join('', map { "<th><tt>$_</tt></th>" } qw(tag subject date)).
-                '</tr>');
-
-        foreach (<$refs>) {
-                my ($ref, $date, $s) = split(' ', $_, 3);
-                ++$nr;
-                $ref =~ s!\Arefs/tags/!!;
-                $ref = PublicInbox::Hval->utf8($ref);
-                my $h = $ref->as_html;
-                $ref = $ref->as_href;
-                $fh->write(qq(<tr><td><a\nhref="?h=$ref">$h</a></td><td>) .
-                        utf8_html($s) . "</td><td>$date</td></tr>");
-        }
-        my $end = '';
-        if ($nr == $count) {
-                $end = "<pre>Showing the latest $nr tags</pre>";
-        }
-        $fh->write("</table>$end</body></html>");
-        $fh->close;
+        my $rdr = { 2 => $git->err_begin };
+        my $qsp = PublicInbox::Qspawn->new($cmd, undef, $rdr);
+        my $env = $req->{env};
+        $env->{'qspawn.quiet'} = 1;
+        $qsp->psgi_return($env, undef, sub { # parse output
+                my ($r) = @_;
+                if (!defined $r) {
+                        my $errmsg = $git->err;
+                        [ 500, [ 'Content-Type', 'text/html; charset=UTF-8'],
+                                [ $errmsg ] ];
+                } else {
+                        $env->{'qspawn.filter'} = git_each_tag_sed($self, $req);
+                        [ 200, [ 'Content-Type', 'text/html; charset=UTF-8' ]];
+                }
+        });
 }
 
 sub unknown_tag_type {