unofficial mirror of meta@public-inbox.org
 help / color / mirror / Atom feed
* [PATCH 0/6] a batch of misc fixes
@ 2021-09-13 20:53 Eric Wong
  2021-09-13 20:53 ` [PATCH 1/6] tests: add require_cmd, require curl when needed Eric Wong
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Eric Wong @ 2021-09-13 20:53 UTC (permalink / raw)
  To: meta

Eric Wong (6):
  tests: add require_cmd, require curl when needed
  lei: stop_pager: restore stdout when done
  use POSIX::PIPE_BUF (instead of _POSIX_PIPE_BUF)
  lei up: localize %ENV in redispatch
  lei_xsearch: sensible errors for missing/broken externals
  lei up: fix --mua with single output

 lib/PublicInbox/Git.pm        |  4 +---
 lib/PublicInbox/LEI.pm        | 12 +++++-------
 lib/PublicInbox/LeiUp.pm      | 26 ++++++++++++++++----------
 lib/PublicInbox/LeiXSearch.pm |  5 ++++-
 lib/PublicInbox/TestCommon.pm | 20 +++++++++++++-------
 t/ds-leak.t                   |  9 +++------
 t/hl_mod.t                    |  9 ++-------
 t/httpd-corner.t              | 11 ++++-------
 t/imapd.t                     |  1 -
 t/lei-daemon.t                |  1 -
 t/lei-externals.t             |  8 ++++----
 t/lei-import-http.t           |  3 +--
 t/lei-mirror.t                |  1 +
 t/lei-q-remote-import.t       |  1 +
 t/lei-up.t                    |  4 ++++
 t/lei.t                       |  4 +---
 t/nntpd.t                     |  7 ++-----
 t/nodatacow.t                 | 10 ++++------
 t/run.perl                    |  4 ++--
 t/solver_git.t                |  4 ++--
 t/v2mirror.t                  |  6 ++----
 t/v2reindex.t                 |  8 ++------
 t/www_altid.t                 |  8 +++-----
 t/www_listing.t               |  8 ++------
 24 files changed, 79 insertions(+), 95 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] tests: add require_cmd, require curl when needed
  2021-09-13 20:53 [PATCH 0/6] a batch of misc fixes Eric Wong
@ 2021-09-13 20:53 ` Eric Wong
  2021-09-13 20:53 ` [PATCH 2/6] lei: stop_pager: restore stdout when done Eric Wong
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-09-13 20:53 UTC (permalink / raw)
  To: meta

t/v2mirror.t and t/lei-mirror.t are now skipped when curl
is missing (instead of failing in appropriate places).
A bunch of which() checks are updated to use require_cmd
to avoid explicitly loading Spawn.
---
 lib/PublicInbox/TestCommon.pm | 20 +++++++++++++-------
 t/ds-leak.t                   |  9 +++------
 t/hl_mod.t                    |  9 ++-------
 t/httpd-corner.t              | 11 ++++-------
 t/imapd.t                     |  1 -
 t/lei-daemon.t                |  1 -
 t/lei-externals.t             |  8 ++++----
 t/lei-import-http.t           |  3 +--
 t/lei-mirror.t                |  1 +
 t/lei-q-remote-import.t       |  1 +
 t/lei.t                       |  4 +---
 t/nntpd.t                     |  7 ++-----
 t/nodatacow.t                 | 10 ++++------
 t/solver_git.t                |  4 ++--
 t/v2mirror.t                  |  6 ++----
 t/v2reindex.t                 |  8 ++------
 t/www_altid.t                 |  8 +++-----
 t/www_listing.t               |  8 ++------
 18 files changed, 47 insertions(+), 72 deletions(-)

diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm
index 628beaf1..d8346673 100644
--- a/lib/PublicInbox/TestCommon.pm
+++ b/lib/PublicInbox/TestCommon.pm
@@ -18,7 +18,7 @@ BEGIN {
 		run_script start_script key2sub xsys xsys_e xqx eml_load tick
 		have_xapian_compact json_utf8 setup_public_inboxes create_inbox
 		tcp_host_port test_lei lei lei_ok $lei_out $lei_err $lei_opt
-		test_httpd xbail);
+		test_httpd xbail require_cmd);
 	require Test::More;
 	my @methods = grep(!/\W/, @Test::More::EXPORT);
 	eval(join('', map { "*$_=\\&Test::More::$_;" } @methods));
@@ -87,6 +87,18 @@ sub tcp_connect {
 	$s;
 }
 
+sub require_cmd ($;$) {
+	my ($cmd, $maybe) = @_;
+	require PublicInbox::Spawn;
+	my $bin = PublicInbox::Spawn::which($cmd);
+	return $bin if $bin;
+	$maybe ? 0 : plan(skip_all => "$cmd missing from PATH for $0");
+}
+
+sub have_xapian_compact () {
+	require_cmd($ENV{XAPIAN_COMPACT} || 'xapian-compact', 1);
+}
+
 sub require_git ($;$) {
 	my ($req, $maybe) = @_;
 	my ($req_maj, $req_min, $req_sub) = split(/\./, $req);
@@ -467,12 +479,6 @@ sub start_script {
 	PublicInboxTestProcess->new($pid, $tail_pid);
 }
 
-sub have_xapian_compact () {
-	require PublicInbox::Spawn;
-	# $ENV{XAPIAN_COMPACT} is used by PublicInbox/Xapcmd.pm, too
-	PublicInbox::Spawn::which($ENV{XAPIAN_COMPACT} || 'xapian-compact');
-}
-
 # favor lei() or lei_ok() over $lei for new code
 sub lei (@) {
 	my ($cmd, $env, $xopt) = @_;
diff --git a/t/ds-leak.t b/t/ds-leak.t
index 57d9cd72..4c211639 100644
--- a/t/ds-leak.t
+++ b/t/ds-leak.t
@@ -3,14 +3,11 @@
 # License: GPL-1.0+ or Artistic-1.0-Perl
 #  <https://www.gnu.org/licenses/gpl-1.0.txt>
 #  <https://dev.perl.org/licenses/artistic.html>
-use strict;
-use warnings;
-use Test::More;
-use PublicInbox::TestCommon;
+use strict; use v5.10.1; use PublicInbox::TestCommon;
 use_ok 'PublicInbox::DS';
 
 if ('close-on-exec for epoll and kqueue') {
-	use PublicInbox::Spawn qw(spawn which);
+	use PublicInbox::Spawn qw(spawn);
 	my $pid;
 	my $evfd_re = qr/(?:kqueue|eventpoll)/i;
 
@@ -32,7 +29,7 @@ if ('close-on-exec for epoll and kqueue') {
 	is($l, undef, 'cloexec works and sleep(1) is running');
 
 	SKIP: {
-		my $lsof = which('lsof') or skip 'lsof missing', 1;
+		my $lsof = require_cmd('lsof', 1) or skip 'lsof missing', 1;
 		my $rdr = { 2 => \(my $null) };
 		my @of = grep(/$evfd_re/, xqx([$lsof, '-p', $pid], {}, $rdr));
 		my $err = $?;
diff --git a/t/hl_mod.t b/t/hl_mod.t
index ffe9e784..96878d51 100644
--- a/t/hl_mod.t
+++ b/t/hl_mod.t
@@ -1,12 +1,7 @@
 #!/usr/bin/perl -w
 # Copyright (C) 2019-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
-use strict;
-use warnings;
-use Test::More;
-use PublicInbox::Spawn qw(which);
-use PublicInbox::TestCommon;
-use IO::Handle; # ->autoflush
+use strict; use v5.10.1; use PublicInbox::TestCommon; use IO::Handle; # ->autoflush
 use Fcntl qw(:seek);
 eval { require highlight } or
 	plan skip_all => "failed to load highlight.pm for $0";
@@ -30,7 +25,7 @@ my $orig = $str;
 	is($$ref, $$lref, 'do_hl_lang matches do_hl');
 
 	SKIP: {
-		my $w3m = which('w3m') or
+		my $w3m = require_cmd('w3m', 1) or
 			skip('w3m(1) missing to check output', 1);
 		my $cmd = [ $w3m, qw(-T text/html -dump -config /dev/null) ];
 		my $in = '<pre>' . $$ref . '</pre>';
diff --git a/t/httpd-corner.t b/t/httpd-corner.t
index 296e1dc1..5dc5734e 100644
--- a/t/httpd-corner.t
+++ b/t/httpd-corner.t
@@ -2,12 +2,9 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 # note: our HTTP server should be standalone and capable of running
 # generic PSGI/Plack apps.
-use strict;
-use warnings;
-use Test::More;
+use strict; use v5.10.1; use PublicInbox::TestCommon;
 use Time::HiRes qw(gettimeofday tv_interval);
-use PublicInbox::Spawn qw(which spawn popen_rd);
-use PublicInbox::TestCommon;
+use PublicInbox::Spawn qw(spawn popen_rd);
 require_mods(qw(Plack::Util Plack::Builder HTTP::Date HTTP::Status));
 use Digest::SHA qw(sha1_hex);
 use IO::Handle ();
@@ -303,7 +300,7 @@ my $check_self = sub {
 };
 
 SKIP: {
-	my $curl = which('curl') or skip('curl(1) missing', 4);
+	my $curl = require_cmd('curl', 1) or skip('curl(1) missing', 4);
 	my $base = 'http://'.tcp_host_port($sock);
 	my $url = "$base/sha1";
 	my ($r, $w);
@@ -606,7 +603,7 @@ SKIP: {
 
 SKIP: {
 	skip 'only testing lsof(8) output on Linux', 1 if $^O ne 'linux';
-	my $lsof = which('lsof') or skip 'no lsof in PATH', 1;
+	my $lsof = require_cmd('lsof', 1) or skip 'no lsof in PATH', 1;
 	my $null_in = '';
 	my $rdr = { 2 => \(my $null_err), 0 => \$null_in };
 	my @lsof = xqx([$lsof, '-p', $td->{pid}], undef, $rdr);
diff --git a/t/imapd.t b/t/imapd.t
index 906b6926..bd8ad7e5 100644
--- a/t/imapd.t
+++ b/t/imapd.t
@@ -7,7 +7,6 @@ use Test::More;
 use Time::HiRes ();
 use PublicInbox::TestCommon;
 use PublicInbox::Config;
-use PublicInbox::Spawn qw(which);
 require_mods(qw(-imapd Mail::IMAPClient));
 my $imap_client = 'Mail::IMAPClient';
 my $can_compress = $imap_client->can('compress');
diff --git a/t/lei-daemon.t b/t/lei-daemon.t
index b0c94a87..b60c7ce6 100644
--- a/t/lei-daemon.t
+++ b/t/lei-daemon.t
@@ -3,7 +3,6 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
 use Socket qw(AF_UNIX SOCK_SEQPACKET MSG_EOR pack_sockaddr_un);
-use PublicInbox::Spawn qw(which);
 
 test_lei({ daemon_only => 1 }, sub {
 	my $send_cmd = PublicInbox::Spawn->can('send_cmd4') // do {
diff --git a/t/lei-externals.t b/t/lei-externals.t
index 5e3c67bc..fed57789 100644
--- a/t/lei-externals.t
+++ b/t/lei-externals.t
@@ -3,7 +3,6 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
 use Fcntl qw(SEEK_SET);
-use PublicInbox::Spawn qw(which);
 require_git 2.6;
 require_mods(qw(json DBD::SQLite Search::Xapian));
 use POSIX qw(WTERMSIG WIFSIGNALED SIGPIPE);
@@ -17,9 +16,10 @@ my $test_external_remote = sub {
 	my ($url, $k) = @_;
 SKIP: {
 	skip "$k unset", 1 if !$url;
-	state $curl = which('curl');
-	$curl or skip 'no curl', 1;
-	which('torsocks') or skip 'no torsocks', 1 if $url =~ m!\.onion/!;
+	require_cmd 'curl', 1 or skip 'curl missing', 1;
+	if ($url =~ m!\.onion/!) {
+		require_cmd 'torsocks', 1 or skip 'no torsocks', 1;
+	}
 	my $mid = '20140421094015.GA8962@dcvr.yhbt.net';
 	my @cmd = ('q', '--only', $url, '-q', "m:$mid");
 	lei_ok(@cmd, \"query $url");
diff --git a/t/lei-import-http.t b/t/lei-import-http.t
index e9eec1f7..d113d479 100644
--- a/t/lei-import-http.t
+++ b/t/lei-import-http.t
@@ -2,9 +2,8 @@
 # Copyright (C) 2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
-use PublicInbox::Spawn qw(which);
 require_mods(qw(lei -httpd));
-which('curl') or plan skip_all => "curl required for $0";
+require_cmd('curl');
 my ($ro_home, $cfg_path) = setup_public_inboxes;
 my ($tmpdir, $for_destroy) = tmpdir;
 my $sock = tcp_server;
diff --git a/t/lei-mirror.t b/t/lei-mirror.t
index 4f4c49c1..44acbe95 100644
--- a/t/lei-mirror.t
+++ b/t/lei-mirror.t
@@ -4,6 +4,7 @@
 use strict; use v5.10.1; use PublicInbox::TestCommon;
 use PublicInbox::Inbox;
 require_mods(qw(-httpd lei));
+require_cmd('curl');
 my $sock = tcp_server();
 my ($tmpdir, $for_destroy) = tmpdir();
 my $http = 'http://'.tcp_host_port($sock);
diff --git a/t/lei-q-remote-import.t b/t/lei-q-remote-import.t
index aaf56e27..9131c01b 100644
--- a/t/lei-q-remote-import.t
+++ b/t/lei-q-remote-import.t
@@ -3,6 +3,7 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
 require_mods(qw(lei -httpd));
+require_cmd 'curl';
 use PublicInbox::MboxReader;
 my ($ro_home, $cfg_path) = setup_public_inboxes;
 my $sock = tcp_server;
diff --git a/t/lei.t b/t/lei.t
index d1f1cbc0..c8f47576 100644
--- a/t/lei.t
+++ b/t/lei.t
@@ -3,11 +3,9 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
 use File::Path qw(rmtree);
-use PublicInbox::Spawn qw(which);
 
 # this only tests the basic help/config/init/completion bits of lei;
 # actual functionality is tested in other t/lei-*.t tests
-my $curl = which('curl');
 my $home;
 my $home_trash = [];
 my $cleanup = sub { rmtree([@$home_trash, @_]) };
@@ -156,7 +154,7 @@ my $test_fail = sub {
 	lei_ok('sucks', \'yes, but hopefully less every day');
 	like($lei_out, qr/loaded features/, 'loaded features shown');
 SKIP: {
-	skip 'no curl', 3 unless which('curl');
+	skip 'no curl', 3 unless require_cmd('curl', 1);
 	lei(qw(q --only http://127.0.0.1:99999/bogus/ t:m));
 	is($? >> 8, 3, 'got curl exit for bogus URL');
 	lei(qw(q --only http://127.0.0.1:99999/bogus/ t:m -o), "$home/junk");
diff --git a/t/nntpd.t b/t/nntpd.t
index 67205fe5..3c171a3b 100644
--- a/t/nntpd.t
+++ b/t/nntpd.t
@@ -1,10 +1,7 @@
 #!perl -w
 # Copyright (C) 2015-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
-use strict;
-use v5.10.1;
-use PublicInbox::TestCommon;
-use PublicInbox::Spawn qw(which);
+use strict; use v5.10.1; use PublicInbox::TestCommon;
 require_mods(qw(DBD::SQLite));
 use PublicInbox::Eml;
 use Socket qw(IPPROTO_TCP TCP_NODELAY);
@@ -17,7 +14,7 @@ use Digest::SHA;
 my $version = $ENV{PI_TEST_VERSION} || 1;
 require_git('2.6') if $version == 2;
 use_ok 'PublicInbox::Msgmap';
-my $lsof = which('lsof');
+my $lsof = require_cmd('lsof', 1);
 my $fast_idle = eval { require Linux::Inotify2; 1 } //
 		eval { require IO::KQueue; 1 };
 
diff --git a/t/nodatacow.t b/t/nodatacow.t
index 9b67c521..19247c10 100644
--- a/t/nodatacow.t
+++ b/t/nodatacow.t
@@ -1,11 +1,8 @@
 #!perl -w
 # Copyright (C) 2020-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
-use strict;
-use Test::More;
+use strict; use v5.10.1; use PublicInbox::TestCommon;
 use File::Temp 0.19;
-use PublicInbox::TestCommon;
-use PublicInbox::Spawn qw(which);
 use_ok 'PublicInbox::NDC_PP';
 
 SKIP: {
@@ -13,8 +10,9 @@ SKIP: {
 	skip 'test is Linux-only', $nr if $^O ne 'linux';
 	my $dir = $ENV{BTRFS_TESTDIR};
 	skip 'BTRFS_TESTDIR not defined', $nr unless defined $dir;
-	skip 'chattr(1) not installed', $nr unless which('chattr');
-	my $lsattr = which('lsattr') or skip 'lsattr(1) not installed', $nr;
+	require_cmd('chattr', 1) or skip 'chattr(1) not installed', $nr;
+	my $lsattr = require_cmd('lsattr', 1) or
+		skip 'lsattr(1) not installed', $nr;
 	my $tmp = File::Temp->newdir('nodatacow-XXXX', DIR => $dir);
 	my $dn = $tmp->dirname;
 
diff --git a/t/solver_git.t b/t/solver_git.t
index f5cc592c..d5f4c4a0 100644
--- a/t/solver_git.t
+++ b/t/solver_git.t
@@ -7,7 +7,7 @@ use PublicInbox::TestCommon;
 use Cwd qw(abs_path);
 require_git(2.6);
 use PublicInbox::ContentHash qw(git_sha);
-use PublicInbox::Spawn qw(popen_rd which);
+use PublicInbox::Spawn qw(popen_rd);
 require_mods(qw(DBD::SQLite Search::Xapian Plack::Util));
 my $git_dir = xqx([qw(git rev-parse --git-dir)], undef, {2 => \(my $null)});
 $? == 0 or plan skip_all => "$0 must be run from a git working tree";
@@ -270,7 +270,7 @@ EOF
 		my $url = "http://$h:$p";
 		local $ENV{PLACK_TEST_EXTERNALSERVER_URI} = $url;
 		Plack::Test::ExternalServer::test_psgi(client => $client);
-		skip 'no curl', 1 unless which('curl');
+		require_cmd('curl', 1) or skip 'no curl', 1;
 
 		mkdir "$tmpdir/ext" // xbail "mkdir $!";
 		test_lei({tmpdir => "$tmpdir/ext"}, sub {
diff --git a/t/v2mirror.t b/t/v2mirror.t
index 2bb3238b..8bcffc29 100644
--- a/t/v2mirror.t
+++ b/t/v2mirror.t
@@ -1,19 +1,17 @@
 # Copyright (C) 2018-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict;
-use warnings;
-use Test::More;
+use v5.10.1;
 use PublicInbox::TestCommon;
 use File::Path qw(remove_tree);
 use Cwd qw(abs_path);
 require_git(2.6);
+require_cmd('curl');
 local $ENV{HOME} = abs_path('t');
 
 # Integration tests for HTTP cloning + mirroring
 require_mods(qw(Plack::Util Plack::Builder
 		HTTP::Date HTTP::Status Search::Xapian DBD::SQLite));
-use IO::Socket;
-use POSIX qw(dup2);
 use_ok 'PublicInbox::V2Writable';
 use PublicInbox::InboxWritable;
 use PublicInbox::Eml;
diff --git a/t/v2reindex.t b/t/v2reindex.t
index e9f2b73b..cafe8648 100644
--- a/t/v2reindex.t
+++ b/t/v2reindex.t
@@ -1,12 +1,9 @@
 # Copyright (C) 2018-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
-use strict;
-use warnings;
-use Test::More;
+use strict; use v5.10.1; use PublicInbox::TestCommon;
 use PublicInbox::Eml;
 use PublicInbox::ContentHash qw(content_digest);
 use File::Path qw(remove_tree);
-use PublicInbox::TestCommon;
 require_git(2.6);
 require_mods(qw(DBD::SQLite Search::Xapian));
 use_ok 'PublicInbox::V2Writable';
@@ -551,9 +548,8 @@ ok(run_script([qw(-index --reindex --xapian-only), $inboxdir], $env, $rdr),
 is($err, '', 'no errors from --xapian-only');
 undef $for_destroy;
 SKIP: {
-	use PublicInbox::Spawn qw(which);
 	skip 'only testing lsof(8) output on Linux', 1 if $^O ne 'linux';
-	my $lsof = which('lsof') or skip 'no lsof in PATH', 1;
+	my $lsof = require_cmd('lsof', 1) or skip 'no lsof in PATH', 1;
 	my $rdr = { 2 => \(my $null_err) };
 	my @d = grep(m!/xap[0-9]+/!, xqx([$lsof, '-p', $$], undef, $rdr));
 	is_deeply(\@d, [], 'no deleted index files') or diag explain(\@d);
diff --git a/t/www_altid.t b/t/www_altid.t
index 7c2b6b21..94a2e807 100644
--- a/t/www_altid.t
+++ b/t/www_altid.t
@@ -1,12 +1,10 @@
 #!perl -w
 # Copyright (C) 2020-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
-use strict;
-use v5.10.1;
-use PublicInbox::TestCommon;
+use strict; use v5.10.1; use PublicInbox::TestCommon;
 use PublicInbox::Config;
-use PublicInbox::Spawn qw(which spawn);
-which('sqlite3') or plan skip_all => 'sqlite3 binary missing';
+use PublicInbox::Spawn qw(spawn);
+require_cmd('sqlite3');
 require_mods(qw(DBD::SQLite HTTP::Request::Common Plack::Test URI::Escape
 	Plack::Builder IO::Uncompress::Gunzip));
 use_ok($_) for qw(Plack::Test HTTP::Request::Common);
diff --git a/t/www_listing.t b/t/www_listing.t
index 5f90139a..eb77969b 100644
--- a/t/www_listing.t
+++ b/t/www_listing.t
@@ -2,11 +2,7 @@
 # Copyright (C) 2019-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 # manifest.js.gz generation and grok-pull integration test
-use strict;
-use v5.10.1;
-use Test::More;
-use PublicInbox::Spawn qw(which);
-use PublicInbox::TestCommon;
+use strict; use v5.10.1; use PublicInbox::TestCommon;
 use PublicInbox::Import;
 use IO::Uncompress::Gunzip qw(gunzip);
 require_mods(qw(json URI::Escape Plack::Builder Digest::SHA HTTP::Tiny));
@@ -134,7 +130,7 @@ SKIP: {
 	tiny_test($json, $host, $port, 1);
 	undef $sock;
 
-	my $grok_pull = which('grok-pull') or
+	my $grok_pull = require_cmd('grok-pull', 1) or
 		skip('grok-pull not available', 12);
 	my ($grok_version) = (xqx([$grok_pull, "--version"])
 			=~ /(\d+)\.(?:\d+)(?:\.(\d+))?/);

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] lei: stop_pager: restore stdout when done
  2021-09-13 20:53 [PATCH 0/6] a batch of misc fixes Eric Wong
  2021-09-13 20:53 ` [PATCH 1/6] tests: add require_cmd, require curl when needed Eric Wong
@ 2021-09-13 20:53 ` Eric Wong
  2021-09-13 20:53 ` [PATCH 3/6] use POSIX::PIPE_BUF (instead of _POSIX_PIPE_BUF) Eric Wong
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-09-13 20:53 UTC (permalink / raw)
  To: meta

The reason(s) we had for not restoring stdout haven't been valid
since script/lei (and not lei-daemon) spawns the pager, nowadays.
---
 lib/PublicInbox/LEI.pm | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm
index 6d5d3c03..784e679d 100644
--- a/lib/PublicInbox/LEI.pm
+++ b/lib/PublicInbox/LEI.pm
@@ -464,11 +464,11 @@ sub x_it ($$) {
 	# make sure client sees stdout before exit
 	$self->{1}->autoflush(1) if $self->{1};
 	stop_pager($self);
-	if ($self->{pkt_op_p}) { # to top lei-daemon
+	if ($self->{pkt_op_p}) { # worker => lei-daemon
 		$self->{pkt_op_p}->pkt_do('x_it', $code);
-	} elsif ($self->{sock}) { # to lei(1) client
+	} elsif ($self->{sock}) { # lei->daemon => lei(1) client
 		send($self->{sock}, "x_it $code", MSG_EOR);
-	} elsif ($quit == \&CORE::exit) { # an admin command
+	} elsif ($quit == \&CORE::exit) { # an admin (one-shot) command
 		exit($code >> 8);
 	} # else ignore if client disconnected
 }
@@ -1065,9 +1065,7 @@ sub pgr_err {
 	start_pager($self, { LESS => 'RX' }); # no 'F' so we prompt
 	print { $self->{2} } @msg;
 	$self->{2}->autoflush(1);
-	my $pgr = delete($self->{pgr}) or return;
-	$self->{2} = $pgr->[2];
-	$self->{1} = $pgr->[1];
+	stop_pager($self);
 	send($self->{sock}, 'wait', MSG_EOR); # wait for user to quit pager
 }
 
@@ -1075,8 +1073,8 @@ sub stop_pager {
 	my ($self) = @_;
 	my $pgr = delete($self->{pgr}) or return;
 	$self->{2} = $pgr->[2];
-	# do not restore original stdout, just close it so we error out
 	close(delete($self->{1})) if $self->{1};
+	$self->{1} = $pgr->[1];
 }
 
 sub accept_dispatch { # Listener {post_accept} callback

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/6] use POSIX::PIPE_BUF (instead of _POSIX_PIPE_BUF)
  2021-09-13 20:53 [PATCH 0/6] a batch of misc fixes Eric Wong
  2021-09-13 20:53 ` [PATCH 1/6] tests: add require_cmd, require curl when needed Eric Wong
  2021-09-13 20:53 ` [PATCH 2/6] lei: stop_pager: restore stdout when done Eric Wong
@ 2021-09-13 20:53 ` Eric Wong
  2021-09-13 20:53 ` [PATCH 4/6] lei up: localize %ENV in redispatch Eric Wong
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-09-13 20:53 UTC (permalink / raw)
  To: meta

PIPE_BUF accounts for Linux being 4096 (and presumably other
OSes differing), while _POSIX_PIPE_BUF is the minimum 512
value.
---
 lib/PublicInbox/Git.pm | 4 +---
 t/run.perl             | 4 ++--
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm
index 219a1732..5ef1db2f 100644
--- a/lib/PublicInbox/Git.pm
+++ b/lib/PublicInbox/Git.pm
@@ -27,9 +27,7 @@ our $PIPE_BUFSIZ = 65536; # Linux default
 our $in_cleanup;
 our $RDTIMEO = 60_000; # milliseconds
 
-use constant MAX_INFLIGHT =>
-	(($^O eq 'linux' ? 4096 : POSIX::_POSIX_PIPE_BUF()) * 3)
-	/
+use constant MAX_INFLIGHT => (POSIX::PIPE_BUF * 3) /
 	65; # SHA-256 hex size + "\n" in preparation for git using non-SHA1
 
 my %GIT_ESC = (
diff --git a/t/run.perl b/t/run.perl
index 5082125b..b0ee611a 100755
--- a/t/run.perl
+++ b/t/run.perl
@@ -18,7 +18,7 @@ use PublicInbox::Spawn;
 use Getopt::Long qw(:config gnu_getopt no_ignore_case auto_abbrev);
 use Errno qw(EINTR);
 use Fcntl qw(:seek);
-use POSIX qw(_POSIX_PIPE_BUF WNOHANG);
+use POSIX qw(WNOHANG);
 use File::Temp ();
 my $jobs = 1;
 my $repeat = 1;
@@ -199,7 +199,7 @@ for (my $i = $repeat; $i != 0; $i--) {
 	pipe(my ($rd, $wr)) or DIE "pipe: $!";
 
 	# fill the queue before forking so children can start earlier
-	my $n = (_POSIX_PIPE_BUF / UINT_SIZE);
+	my $n = (POSIX::PIPE_BUF / UINT_SIZE);
 	if ($n >= $#todo) {
 		print $wr join('', map { pack('I', $_) } (0..$#todo)) or DIE;
 		undef $wr;

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/6] lei up: localize %ENV in redispatch
  2021-09-13 20:53 [PATCH 0/6] a batch of misc fixes Eric Wong
                   ` (2 preceding siblings ...)
  2021-09-13 20:53 ` [PATCH 3/6] use POSIX::PIPE_BUF (instead of _POSIX_PIPE_BUF) Eric Wong
@ 2021-09-13 20:53 ` Eric Wong
  2021-09-13 20:53 ` [PATCH 5/6] lei_xsearch: sensible errors for missing/broken externals Eric Wong
  2021-09-13 20:53 ` [PATCH 6/6] lei up: fix --mua with single output Eric Wong
  5 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-09-13 20:53 UTC (permalink / raw)
  To: meta

We need to restore %ENV of script/lei in case another
lei client has a different %ENV than what daemon has.
---
 lib/PublicInbox/LeiUp.pm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/PublicInbox/LeiUp.pm b/lib/PublicInbox/LeiUp.pm
index be476427..a16117c9 100644
--- a/lib/PublicInbox/LeiUp.pm
+++ b/lib/PublicInbox/LeiUp.pm
@@ -55,13 +55,14 @@ sub up1 ($$) {
 sub up1_redispatch {
 	my ($lei, $out, $op_p) = @_;
 	my $l = bless { %$lei }, ref($lei);
-	$l->{opt} = { %{$l->{opt}} };
+	$l->{opt} = { %{$l->{opt}} }; # deep copy
 	delete $l->{sock}; # do not close
 	$l->{''} = $op_p; # daemon only ($l => $lei => script/lei)
 
 	# make close($l->{1}) happy in lei->dclose
 	open my $fh, '>&', $l->{1} or return $l->child_error(0, "dup: $!");
 	local $PublicInbox::LEI::current_lei = $l;
+	local %ENV = %{$l->{env}};
 	$l->{1} = $fh;
 	eval {
 		$l->qerr("# updating $out");

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/6] lei_xsearch: sensible errors for missing/broken externals
  2021-09-13 20:53 [PATCH 0/6] a batch of misc fixes Eric Wong
                   ` (3 preceding siblings ...)
  2021-09-13 20:53 ` [PATCH 4/6] lei up: localize %ENV in redispatch Eric Wong
@ 2021-09-13 20:53 ` Eric Wong
  2021-09-13 20:53 ` [PATCH 6/6] lei up: fix --mua with single output Eric Wong
  5 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-09-13 20:53 UTC (permalink / raw)
  To: meta

I've been creating and destroying lots of externals, lately...
---
 lib/PublicInbox/LeiXSearch.pm | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/PublicInbox/LeiXSearch.pm b/lib/PublicInbox/LeiXSearch.pm
index 9f7f3885..556ffd58 100644
--- a/lib/PublicInbox/LeiXSearch.pm
+++ b/lib/PublicInbox/LeiXSearch.pm
@@ -572,8 +572,11 @@ sub prepare_external {
 		die "`\\n' not allowed in `$loc'\n" if index($loc, "\n") >= 0;
 		require PublicInbox::Inbox; # v2, v1
 		$loc = bless { inboxdir => $loc }, 'PublicInbox::Inbox';
+	} elsif (!-e $loc) {
+		warn "W: $loc gone, perhaps run: lei forget-external $loc\n";
+		return;
 	} else {
-		warn "W: ignoring $loc, unable to determine type\n";
+		warn "W: $loc ignored, unable to determine external type\n";
 		return;
 	}
 	push @{$self->{locals}}, $loc;

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/6] lei up: fix --mua with single output
  2021-09-13 20:53 [PATCH 0/6] a batch of misc fixes Eric Wong
                   ` (4 preceding siblings ...)
  2021-09-13 20:53 ` [PATCH 5/6] lei_xsearch: sensible errors for missing/broken externals Eric Wong
@ 2021-09-13 20:53 ` Eric Wong
  5 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-09-13 20:53 UTC (permalink / raw)
  To: meta

Oops :x

Fixes: b584a53f053a7629 ("lei up: support --all for IMAP folders")
---
 lib/PublicInbox/LeiUp.pm | 25 +++++++++++++++----------
 t/lei-up.t               |  4 ++++
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/lib/PublicInbox/LeiUp.pm b/lib/PublicInbox/LeiUp.pm
index a16117c9..53f06dbc 100644
--- a/lib/PublicInbox/LeiUp.pm
+++ b/lib/PublicInbox/LeiUp.pm
@@ -54,16 +54,21 @@ sub up1 ($$) {
 
 sub up1_redispatch {
 	my ($lei, $out, $op_p) = @_;
-	my $l = bless { %$lei }, ref($lei);
-	$l->{opt} = { %{$l->{opt}} }; # deep copy
-	delete $l->{sock}; # do not close
-	$l->{''} = $op_p; # daemon only ($l => $lei => script/lei)
-
-	# make close($l->{1}) happy in lei->dclose
-	open my $fh, '>&', $l->{1} or return $l->child_error(0, "dup: $!");
+	my $l;
+	if (defined($lei->{opt}->{mua})) { # single output
+		$l = $lei;
+	} else { # multiple outputs
+		$l = bless { %$lei }, ref($lei);
+		$l->{opt} = { %{$l->{opt}} }; # deep copy
+		delete $l->{sock}; # do not close
+		# make close($l->{1}) happy in lei->dclose
+		open my $fh, '>&', $l->{1} or
+			return $l->child_error(0, "dup: $!");
+		$l->{1} = $fh;
+	}
 	local $PublicInbox::LEI::current_lei = $l;
 	local %ENV = %{$l->{env}};
-	$l->{1} = $fh;
+	$l->{''} = $op_p; # daemon only ($l => $lei => script/lei)
 	eval {
 		$l->qerr("# updating $out");
 		up1($l, $out);
@@ -92,7 +97,7 @@ sub lei_up {
 	$lei->{lse} = $lei->_lei_store(1)->write_prepare($lei)->search;
 	if (defined(my $all = $opt->{all})) {
 		return $lei->fail("--all and @outs incompatible") if @outs;
-		length($opt->{mua}//'') and return
+		defined($opt->{mua}) and return
 			$lei->fail('--all and --mua= are incompatible');
 		@outs = PublicInbox::LeiSavedSearch::list($lei);
 		if ($all eq 'local') {
@@ -110,7 +115,7 @@ sub lei_up {
 		$self->{local} = [ grep(!/$REMOTE_RE/, @outs) ];
 	}
 	((@{$self->{local} // []} + @{$self->{remote} // []}) > 1 &&
-		length($opt->{mua} // '')) and return $lei->fail(<<EOM);
+		defined($opt->{mua})) and return $lei->fail(<<EOM);
 multiple outputs and --mua= are incompatible
 EOM
 	if ($self->{remote}) { # setup lei->{auth}
diff --git a/t/lei-up.t b/t/lei-up.t
index 6b34774d..8937cfb1 100644
--- a/t/lei-up.t
+++ b/t/lei-up.t
@@ -34,6 +34,10 @@ test_lei(sub {
 	open $fh, "$ENV{HOME}/b" or xbail "open: $!";
 	$uc = do { local $/; <$fh> };
 	is($uc, $exp, 'uncompressed both match');
+
+	lei_ok [ 'up', "$ENV{HOME}/b", "--mua=touch $ENV{HOME}/c" ],
+		undef, { run_mode => 0 };
+	ok(-f "$ENV{HOME}/c", '--mua works with single output');
 });
 
 done_testing;

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-09-13 20:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-13 20:53 [PATCH 0/6] a batch of misc fixes Eric Wong
2021-09-13 20:53 ` [PATCH 1/6] tests: add require_cmd, require curl when needed Eric Wong
2021-09-13 20:53 ` [PATCH 2/6] lei: stop_pager: restore stdout when done Eric Wong
2021-09-13 20:53 ` [PATCH 3/6] use POSIX::PIPE_BUF (instead of _POSIX_PIPE_BUF) Eric Wong
2021-09-13 20:53 ` [PATCH 4/6] lei up: localize %ENV in redispatch Eric Wong
2021-09-13 20:53 ` [PATCH 5/6] lei_xsearch: sensible errors for missing/broken externals Eric Wong
2021-09-13 20:53 ` [PATCH 6/6] lei up: fix --mua with single output Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).