diff options
author | Eric Wong <e@80x24.org> | 2016-02-28 03:35:07 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-04-05 18:58:27 +0000 |
commit | 5940f0cab7017aeefeb5df272b0a73897ce175c2 (patch) | |
tree | 0b0cfaeb4cdcdccd8a835a9436ae6f75208f9841 /lib/PublicInbox/RepobrowseGitCommit.pm | |
parent | 64d131a6b4435289f8876b20510a6d80d4dde418 (diff) | |
download | public-inbox-5940f0cab7017aeefeb5df272b0a73897ce175c2.tar.gz |
We'll be moving to Danga::Socket for giant diff generation in future commits. So this is a step towards being more callback-driven...
Diffstat (limited to 'lib/PublicInbox/RepobrowseGitCommit.pm')
-rw-r--r-- | lib/PublicInbox/RepobrowseGitCommit.pm | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/lib/PublicInbox/RepobrowseGitCommit.pm b/lib/PublicInbox/RepobrowseGitCommit.pm index edc27717..156e3e22 100644 --- a/lib/PublicInbox/RepobrowseGitCommit.pm +++ b/lib/PublicInbox/RepobrowseGitCommit.pm @@ -23,7 +23,12 @@ use constant GIT_FMT => '--pretty=format:'.join('%n', '%t', '%p', '%D', '%b%x00'); sub git_commit_stream { - my ($self, $req, $q, $H, $log, $fh) = @_; + my ($self, $req) = @_; + my $log = $req->{log}; + my $H = <$log>; + defined $H or return git_commit_404($req); + my $fh = delete($req->{res})->([200, ['Content-Type'=>'text/html']]); + $req->{fh} = $fh; chomp(my $h = <$log>); # abbreviated commit my $l; chomp(my $s = utf8_html($l = <$log>)); # subject @@ -38,6 +43,7 @@ sub git_commit_stream { my $git = $req->{repo_info}->{git}; my $rel = $req->{relcmd}; + my $q = $req->{'q'}; my $qs = $q->qs(id => $h); chomp $H; my $x = $self->html_start($req, $s) . "\n" . @@ -146,34 +152,47 @@ sub call_git_commit { } my $git = $req->{repo_info}->{git}; - my @cmd = (qw(show -z --numstat -p --encoding=UTF-8 - --no-notes --no-color -c), $git->abbrev); - - my $log = $git->popen(@cmd, GIT_FMT, $id, '--'); - my $H = <$log>; - - # maybe the path didn't exist, yet, zip them back up - return git_commit_404($req, $q) unless defined $H; + my $cmd = [ qw(show -z --numstat -p --encoding=UTF-8 + --no-notes --no-color -c), + $git->abbrev, GIT_FMT, $id, '--' ]; + $req->{log} = $git->popen($cmd, undef, { 2 => $git->err_begin }); + $req->{end} = sub { + $req->{cb} = $req->{end} = undef; + if (my $fh = delete $req->{fh}) { + $fh->close; + } elsif (my $res = delete $req->{res}) { + $res->(r(500)); + } + if (my $log = delete $req->{log}) { + $log->close; # _may_ be Danga::Socket::close + } + # zero the error file for now, be careful about printing + # $id to psgi.errors w/o sanitizing... + $git->err; + }; + $req->{'q'} = $q; + $req->{cb} = sub { # read git-show output and stream to client + git_commit_stream($self, $req); + $req->{end}->(); + }; sub { - my ($res) = @_; # Plack callback - my $fh = $res->([200, ['Content-Type'=>'text/html']]); - git_commit_stream($self, $req, $q, $H, $log, $fh); - $fh->close; + $req->{res} = $_[0]; + $req->{cb}->(); } } sub git_commit_404 { - my ($req, $q) = @_; + my ($req) = @_; my $x = 'Missing commit or path'; my $pfx = "$req->{relcmd}commit"; my $try = 'try'; $x = "<html><head><title>$x</title></head><body><pre><b>$x</b>\n\n"; - my $qs = $q->qs(id => ''); + my $qs = $req->{'q'}->qs(id => ''); $x .= "<a\nhref=\"$pfx$qs\">$try the latest commit in HEAD</a>\n"; $x .= '</pre></body>'; - [ 404, ['Content-Type'=>'text/html'], [ $x ] ]; + delete($req->{res})->([404, ['Content-Type'=>'text/html'], [ $x ]]); } sub git_show_diffstat { |