about summary refs log tree commit homepage
path: root/lib/PublicInbox/LeiRediff.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/LeiRediff.pm')
-rw-r--r--lib/PublicInbox/LeiRediff.pm63
1 files changed, 25 insertions, 38 deletions
diff --git a/lib/PublicInbox/LeiRediff.pm b/lib/PublicInbox/LeiRediff.pm
index c312d90f..35728330 100644
--- a/lib/PublicInbox/LeiRediff.pm
+++ b/lib/PublicInbox/LeiRediff.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>
 
 # The "lei rediff" sub-command, regenerates diffs with new options
@@ -7,7 +7,7 @@ use strict;
 use v5.10.1;
 use parent qw(PublicInbox::IPC PublicInbox::LeiInput);
 use File::Temp 0.19 (); # 0.19 for ->newdir
-use PublicInbox::Spawn qw(spawn which);
+use PublicInbox::Spawn qw(run_wait popen_wr which);
 use PublicInbox::MsgIter qw(msg_part_text);
 use PublicInbox::ViewDiff;
 use PublicInbox::LeiBlob;
@@ -82,6 +82,7 @@ sub _lei_diff_prepare ($$) {
                         push @$cmd, $c ? "-$c" : "--$o";
                 }
         }
+        push(@$cmd, "-O$opt->{'order-file'}") if $opt->{'order-file'};
 }
 
 sub diff_ctxq ($$) {
@@ -113,65 +114,51 @@ EOM
         if (!$rw->{-tmp}) {
                 my $d = "$self->{rdtmp}/for_tree.git";
                 -d $d or PublicInbox::Import::init_bare($d);
-                my $f = "$d/objects/info/alternates"; # always overwrite
-                open my $fh, '>', $f or die "open $f: $!";
-                for my $git (@{$self->{gits}}) {
-                        print $fh $git->git_path('objects'),"\n";
-                }
-                close $fh or die "close $f: $!";
+                # always overwrite
+                PublicInbox::IO::write_file '>', "$d/objects/info/alternates",
+                        map { $_->git_path('objects')."\n" } @{$self->{gits}};
                 $rw = PublicInbox::Git->new($d);
         }
-        pipe(my ($r, $w)) or die "pipe: $!";
-        my $pid = spawn(['git', "--git-dir=$rw->{git_dir}",
+        my $w = popen_wr(['git', "--git-dir=$rw->{git_dir}",
                         qw(fast-import --quiet --done --date-format=raw)],
-                        $lei->{env}, { 2 => $lei->{2}, 0 => $r });
-        close $r or die "close r fast-import: $!";
+                        $lei->{env}, { 2 => $lei->{2} });
         print $w $ta, "\n", $tb, "\ndone\n" or die "print fast-import: $!";
-        close $w or die "close w fast-import: $!";
-        waitpid($pid, 0);
-        die "fast-import failed: \$?=$?" if $?;
+        $w->close or die "close w fast-import: \$?=$? \$!=$!";
 
         my $cmd = [ 'diff' ];
         _lei_diff_prepare($lei, $cmd);
         $lei->qerr("# git @$cmd");
         push @$cmd, qw(A B);
         unshift @$cmd, 'git', "--git-dir=$rw->{git_dir}";
-        $pid = spawn($cmd, $lei->{env}, { 2 => $lei->{2}, 1 => $lei->{1} });
-        waitpid($pid, 0);
-        $lei->child_error($?) if $?; # for git diff --exit-code
+        run_wait($cmd, $lei->{env}, { 2 => $lei->{2}, 1 => $lei->{1} }) and
+                $lei->child_error($?); # for git diff --exit-code
         undef;
 }
 
-sub wait_requote ($$$) { # OnDestroy callback
-        my ($lei, $pid, $old_1) = @_;
-        $lei->{1} = $old_1; # closes stdin of `perl -pE 's/^/> /'`
-        waitpid($pid, 0) == $pid or die "BUG(?) waitpid: \$!=$! \$?=$?";
-        $lei->child_error($?) if $?;
-}
+# awaitpid callback
+sub wait_requote { $_[1]->child_error($?) if $? }
 
-sub requote ($$) {
+sub requote ($$) { # '> ' prefix(es) lei->{1}
         my ($lei, $pfx) = @_;
-        pipe(my($r, $w)) or die "pipe: $!";
-        my $rdr = { 0 => $r, 1 => $lei->{1}, 2 => $lei->{2} };
+        my $opt = { 1 => $lei->{1}, 2 => $lei->{2} };
         # $^X (perl) is overkill, but maybe there's a weird system w/o sed
-        my $pid = spawn([$^X, '-pE', "s/^/$pfx/"], $lei->{env}, $rdr);
-        my $old_1 = $lei->{1};
-        $w->autoflush(1);
+        my $w = popen_wr([$^X, '-pe', "s/^/$pfx/"], $lei->{env}, $opt,
+                         \&wait_requote, $lei);
         binmode $w, ':utf8';
-        $lei->{1} = $w;
-        PublicInbox::OnDestroy->new(\&wait_requote, $lei, $pid, $old_1);
+        $w;
 }
 
 sub extract_oids { # Eml each_part callback
         my ($ary, $self) = @_;
+        my $lei = $self->{lei};
         my ($p, undef, $idx) = @$ary;
-        $self->{lei}->out($p->header_obj->as_string, "\n");
+        $lei->out($p->header_obj->as_string, "\n");
         my ($s, undef) = msg_part_text($p, $p->content_type || 'text/plain');
         defined $s or return;
-        my $rq;
-        if ($self->{dqre} && $s =~ s/$self->{dqre}//g) { # '> ' prefix(es)
-                $rq = requote($self->{lei}, $1) if $self->{lei}->{opt}->{drq};
-        }
+
+        $self->{dqre} && $s =~ s/$self->{dqre}//g && $lei->{opt}->{drq} and
+                local $lei->{1} = requote($lei, $1);
+
         my @top = split($PublicInbox::ViewDiff::EXTRACT_DIFFS, $s);
         undef $s;
         my $blobs = $self->{blobs}; # blobs to resolve
@@ -268,7 +255,7 @@ sub lei_rediff {
         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->ale->refresh_externals($lxs, $lei);
         my $self = bless {