about summary refs log tree commit homepage
path: root/lib/PublicInbox/LeiBlob.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/LeiBlob.pm')
-rw-r--r--lib/PublicInbox/LeiBlob.pm57
1 files changed, 29 insertions, 28 deletions
diff --git a/lib/PublicInbox/LeiBlob.pm b/lib/PublicInbox/LeiBlob.pm
index 004b156c..00697097 100644
--- a/lib/PublicInbox/LeiBlob.pm
+++ b/lib/PublicInbox/LeiBlob.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 
 # "lei blob $OID" command
@@ -7,8 +7,11 @@ package PublicInbox::LeiBlob;
 use strict;
 use v5.10.1;
 use parent qw(PublicInbox::IPC);
-use PublicInbox::Spawn qw(spawn popen_rd which);
+use PublicInbox::Spawn qw(run_wait run_qx which);
 use PublicInbox::DS;
+use PublicInbox::Eml;
+use PublicInbox::Git;
+use PublicInbox::IO qw(read_all);
 
 sub get_git_dir ($$) {
         my ($lei, $d) = @_;
@@ -21,10 +24,8 @@ sub get_git_dir ($$) {
         } else { # implicit --cwd, quiet errors
                 open $opt->{2}, '>', '/dev/null' or die "open /dev/null: $!";
         }
-        my ($r, $pid) = popen_rd($cmd, {GIT_DIR => undef}, $opt);
-        chomp(my $gd = do { local $/; <$r> });
-        waitpid($pid, 0) == $pid or die "BUG: waitpid @$cmd ($!)";
-        $? == 0 ? $gd : undef;
+        chomp(my $git_dir = run_qx($cmd, {GIT_DIR => undef}, $opt));
+        $? ? undef : $git_dir;
 }
 
 sub solver_user_cb { # called by solver when done
@@ -44,8 +45,7 @@ sub solver_user_cb { # called by solver when done
 
         my $cmd = [ 'git', "--git-dir=$gd", 'show', $oid ];
         my $rdr = { 1 => $lei->{1}, 2 => $lei->{2} };
-        waitpid(spawn($cmd, $lei->{env}, $rdr), 0);
-        $lei->child_error($?) if $?;
+        run_wait($cmd, $lei->{env}, $rdr) and $lei->child_error($?);
 }
 
 sub do_solve_blob { # via wq_do
@@ -70,7 +70,7 @@ sub do_solve_blob { # via wq_do
                         } @$git_dirs ],
                 user_cb => \&solver_user_cb,
                 uarg => $self,
-                # -cur_di, -qsp, -msg => temporary fields for Qspawn callbacks
+                # -cur_di, -msg => temporary fields for Qspawn callbacks
                 inboxes => [ $self->{lxs}->locals, @rmt ],
         }, 'PublicInbox::SolverGit';
         local $PublicInbox::DS::in_loop = 0; # waitpid synchronously
@@ -119,28 +119,29 @@ sub lei_blob {
                 } else {
                         open $rdr->{2}, '>', '/dev/null' or die "open: $!";
                 }
-                my $cmd = [ 'git', '--git-dir='.$lei->ale->git->{git_dir},
-                                'cat-file', 'blob', $blob ];
+                my $cmd = $lei->ale->git->cmd('cat-file', 'blob', $blob);
+                my $cerr;
                 if (defined $lei->{-attach_idx}) {
-                        my $fh = popen_rd($cmd, $lei->{env}, $rdr);
-                        require PublicInbox::Eml;
-                        my $buf = do { local $/; <$fh> };
-                        return extract_attach($lei, $blob, \$buf) if close($fh);
+                        my $buf = run_qx($cmd, $lei->{env}, $rdr);
+                        return extract_attach($lei, $blob, \$buf) unless $?;
+                        $cerr = $?;
                 } else {
-                        $rdr->{1} = $lei->{1};
-                        waitpid(spawn($cmd, $lei->{env}, $rdr), 0);
+                        $rdr->{1} = $lei->{1}; # write directly to client
+                        $cerr = run_wait($cmd, $lei->{env}, $rdr) or return;
                 }
-                my $ce = $?;
-                return if $ce == 0;
+                # fall back to unimported ('lei index') and inflight blobs
                 my $lms = $lei->lms;
-                if (my $bref = $lms ? $lms->local_blob($blob, 1) : undef) {
-                        defined($lei->{-attach_idx}) and
-                                return extract_attach($lei, $blob, $bref);
-                        return $lei->out($$bref);
-                } elsif ($opt->{mail}) {
-                        my $eh = $rdr->{2};
-                        seek($eh, 0, 0);
-                        return $lei->child_error($ce, do { local $/; <$eh> });
+                my $bref = ($lms ? $lms->local_blob($blob, 1) : undef) // do {
+                        my $sto = $lei->{sto} // $lei->_lei_store;
+                        $sto && $sto->{-wq_s1} ? $sto->wq_do('cat_blob', $blob)
+                                                : undef;
+                };
+                $bref and return $lei->{-attach_idx} ?
+                                        extract_attach($lei, $blob, $bref) :
+                                        $lei->out($$bref);
+                if ($opt->{mail}) {
+                        seek($rdr->{2}, 0, 0);
+                        return $lei->child_error($cerr, read_all($rdr->{2}));
                 } # else: fall through to solver below
         }
 
@@ -158,7 +159,7 @@ sub lei_blob {
         if ($lxs->remotes) {
                 require PublicInbox::LeiRemote;
                 $lei->{curl} //= which('curl') or return
-                        $lei->fail('curl needed for', $lxs->remotes);
+                        $lei->fail('curl needed for '.join(', ',$lxs->remotes));
                 $lei->_lei_store(1)->write_prepare($lei);
         }
         require PublicInbox::SolverGit;