user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
* [PATCH 0/5] lei: more UI/UX tweaks
@ 2021-05-01  6:21 Eric Wong
  2021-05-01  6:21 ` [PATCH 1/5] xt/lei-onion-convert: test for NNTP+IMAP onions Eric Wong
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Eric Wong @ 2021-05-01  6:21 UTC (permalink / raw)
  To: meta

4/5 is an incompatible change of an incomplete feature
2/5 is something I noticed from using "lei up --all=local"

Editing searches is less surprising, as lei.q.output updates
and auto-conversion are now supported (since there's no
"lei mv-search").

Eric Wong (5):
  xt/lei-onion-convert: test for NNTP+IMAP onions
  lei <q|up>: distinguish between mset and l2m counts
  lei_saved_search: fix excess indent for first lei.q entry
  lei: rename ls-sync to ls-mail-sync
  lei edit-search: support relocating lei.q.output

 MANIFEST                                      |  3 +-
 lib/PublicInbox/LEI.pm                        |  2 +-
 lib/PublicInbox/LeiConvert.pm                 |  5 +-
 lib/PublicInbox/LeiEditSearch.pm              | 15 ++++-
 .../{LeiLsSync.pm => LeiLsMailSync.pm}        |  4 +-
 lib/PublicInbox/LeiSavedSearch.pm             | 53 +++++++++++++++-
 lib/PublicInbox/LeiToMail.pm                  | 36 ++++++-----
 lib/PublicInbox/LeiXSearch.pm                 | 18 ++++--
 script/lei                                    |  7 +++
 t/lei-import-imap.t                           |  4 +-
 t/lei-import-maildir.t                        |  4 +-
 xt/lei-onion-convert.t                        | 61 +++++++++++++++++++
 12 files changed, 180 insertions(+), 32 deletions(-)
 rename lib/PublicInbox/{LeiLsSync.pm => LeiLsMailSync.pm} (93%)
 create mode 100644 xt/lei-onion-convert.t


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

* [PATCH 1/5] xt/lei-onion-convert: test for NNTP+IMAP onions
  2021-05-01  6:21 [PATCH 0/5] lei: more UI/UX tweaks Eric Wong
@ 2021-05-01  6:21 ` Eric Wong
  2021-05-01  6:21 ` [PATCH 2/5] lei <q|up>: distinguish between mset and l2m counts Eric Wong
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-05-01  6:21 UTC (permalink / raw)
  To: meta

These tests require a running Tor instance (defaulting to
127.0.0.1:9050) and Internet connectivity, but otherwise
work pretty well.
---
 MANIFEST               |  1 +
 xt/lei-onion-convert.t | 61 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 xt/lei-onion-convert.t

diff --git a/MANIFEST b/MANIFEST
index bc2ad671..82f25735 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -516,6 +516,7 @@ xt/httpd-async-stream.t
 xt/imapd-mbsync-oimap.t
 xt/imapd-validate.t
 xt/lei-auth-fail.t
+xt/lei-onion-convert.t
 xt/mem-imapd-tls.t
 xt/mem-msgview.t
 xt/msgtime_cmp.t
diff --git a/xt/lei-onion-convert.t b/xt/lei-onion-convert.t
new file mode 100644
index 00000000..d38b4b16
--- /dev/null
+++ b/xt/lei-onion-convert.t
@@ -0,0 +1,61 @@
+#!perl -w
+# 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; use PublicInbox::TestCommon;
+use PublicInbox::MboxReader;
+my $test_tor = $ENV{TEST_TOR};
+plan skip_all => "TEST_TOR unset" unless $test_tor;
+unless ($test_tor =~ m!\Asocks5h://!i) {
+	my $default = 'socks5h://127.0.0.1:9050';
+	diag "using $default (set TEST_TOR=socks5h://ADDR:PORT to override)";
+	$test_tor = $default;
+}
+my $onion = $ENV{TEST_ONION_HOST} //'ou63pmih66umazou.onion';
+my $ng = 'inbox.comp.mail.public-inbox.meta';
+my $nntp_url = $ENV{TEST_NNTP_ONION_URL} // "nntp://$onion/$ng";
+my $imap_url = $ENV{TEST_IMAP_ONION_URL} // "imap://$onion/$ng.0";
+my @cnv = qw(lei convert -o mboxrd:/dev/stdout);
+my @proxy_cli = ("--proxy=$test_tor");
+my $proxy_cfg = "proxy=$test_tor";
+test_lei(sub {
+	my $run = {};
+	for my $args ([$nntp_url, @proxy_cli], [$imap_url, @proxy_cli],
+			[ $nntp_url, '-c', "nntp.$proxy_cfg" ],
+			[ $imap_url, '-c', "imap.$proxy_cfg" ]) {
+		pipe(my ($r, $w)) or xbail "pipe: $!";
+		my $cmd = [@cnv, @$args];
+		my $td = start_script($cmd, undef, { 1 => $w, run_mode => 0 });
+		$args->[0] =~ s!\A(.+?://).*!$1...!;
+		my $key = "@$args";
+		ok($td, "$key running");
+		$run->{$key} = { td => $td, r => $r };
+	}
+	while (my ($key, $x) = each %$run) {
+		my ($td, $r) = delete(@$x{qw(td r)});
+		eval {
+			PublicInbox::MboxReader->mboxrd($r, sub {
+				my ($eml) = @_;
+				if ($key =~ m!\Anntps?://!i) {
+					for (qw(Xref Newsgroups Path)) {
+						$eml->header_set($_);
+					}
+				}
+				push @{$x->{eml}}, $eml;
+				close $r;
+				$td->kill('-INT');
+				die "$key done\n";
+			});
+		};
+		chomp(my $done = $@);
+		like($done, qr/\Q$key\E done/, $done);
+		$td->join;
+	}
+	my @keys = keys %$run;
+	my $first_key = shift @keys;
+	for my $key (@keys) {
+		is_deeply($run->{$key}, $run->{$first_key},
+			"`$key' matches `$first_key'");
+	}
+});
+
+done_testing;

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

* [PATCH 2/5] lei <q|up>: distinguish between mset and l2m counts
  2021-05-01  6:21 [PATCH 0/5] lei: more UI/UX tweaks Eric Wong
  2021-05-01  6:21 ` [PATCH 1/5] xt/lei-onion-convert: test for NNTP+IMAP onions Eric Wong
@ 2021-05-01  6:21 ` Eric Wong
  2021-05-01  6:21 ` [PATCH 3/5] lei_saved_search: fix excess indent for first lei.q entry Eric Wong
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-05-01  6:21 UTC (permalink / raw)
  To: meta

The number of messages we write to --output is usually different
than the mset count due to deduplication from combining multiple
sources.

This change makes the stderr output of "lei up --all=local" way
more useful IMHO.
---
 lib/PublicInbox/LeiToMail.pm  | 36 ++++++++++++++++++++---------------
 lib/PublicInbox/LeiXSearch.pm | 18 ++++++++++++++----
 2 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/lib/PublicInbox/LeiToMail.pm b/lib/PublicInbox/LeiToMail.pm
index eda4701c..a546ab42 100644
--- a/lib/PublicInbox/LeiToMail.pm
+++ b/lib/PublicInbox/LeiToMail.pm
@@ -196,9 +196,13 @@ sub _mbox_write_cb ($$) {
 		return if $dedupe->is_dup($eml, $smsg);
 		$lse->xsmsg_vmd($smsg) if $lse;
 		$buf = $eml2mbox->($eml, $smsg);
-		return atomic_append($lei, $buf) if $atomic_append;
-		my $lk = $ovv->lock_for_scope;
-		$lei->out($$buf);
+		if ($atomic_append) {
+			atomic_append($lei, $buf);
+		} else {
+			my $lk = $ovv->lock_for_scope;
+			$lei->out($$buf);
+		}
+		++$lei->{-nr_write};
 	}
 }
 
@@ -273,15 +277,13 @@ sub _maildir_write_cb ($$) {
 	my $dst = $lei->{ovv}->{dst};
 	my $lse = $lei->{lse}; # may be undef
 	sub { # for git_to_mail
-		my ($buf, $smsg, $eml) = @_;
+		my ($bref, $smsg, $eml) = @_;
 		$dst // return $lei->fail; # dst may be undef-ed in last run
-		$buf //= \($eml->as_string);
+		return if $dedupe && $dedupe->is_dup($eml //
+						PublicInbox::Eml->new($$bref));
 		$lse->xsmsg_vmd($smsg) if $lse;
-		return _buf2maildir($dst, $buf, $smsg) if !$dedupe;
-		$eml //= PublicInbox::Eml->new($$buf); # copy buf
-		return if $dedupe->is_dup($eml, $smsg);
-		undef $eml;
-		_buf2maildir($dst, $buf, $smsg);
+		_buf2maildir($dst, $bref // \($eml->as_string), $smsg);
+		++$lei->{-nr_write};
 	}
 }
 
@@ -296,16 +298,15 @@ sub _imap_write_cb ($$) {
 	sub { # for git_to_mail
 		my ($bref, $smsg, $eml) = @_;
 		$mic // return $lei->fail; # mic may be undef-ed in last run
-		if ($dedupe) {
-			$eml //= PublicInbox::Eml->new($$bref); # copy bref
-			return if $dedupe->is_dup($eml, $smsg);
-		}
+		return if $dedupe && $dedupe->is_dup($eml //
+						PublicInbox::Eml->new($$bref));
 		$lse->xsmsg_vmd($smsg) if $lse;
 		eval { $imap_append->($mic, $folder, $bref, $smsg, $eml) };
 		if (my $err = $@) {
 			undef $mic;
 			die $err;
 		}
+		++$lei->{-nr_write};
 	}
 }
 
@@ -659,7 +660,12 @@ sub write_mail { # via ->wq_io_do
 sub wq_atexit_child {
 	my ($self) = @_;
 	delete $self->{wcb};
-	$self->{lei}->{ale}->git->async_wait_all;
+	my $lei = $self->{lei};
+	$lei->{ale}->git->async_wait_all;
+	my $nr = delete($lei->{-nr_write}) or return;
+	return if $lei->{early_mua} || !$lei->{-progress} || !$lei->{pkt_op_p};
+	require PublicInbox::PktOp;
+	PublicInbox::PktOp::pkt_do($lei->{pkt_op_p}, 'l2m_progress', $nr);
 }
 
 # called in top-level lei-daemon when LeiAuth is done
diff --git a/lib/PublicInbox/LeiXSearch.pm b/lib/PublicInbox/LeiXSearch.pm
index b3fd79d0..e04af0dc 100644
--- a/lib/PublicInbox/LeiXSearch.pm
+++ b/lib/PublicInbox/LeiXSearch.pm
@@ -144,6 +144,11 @@ sub mset_progress {
 	}
 }
 
+sub l2m_progress {
+	my ($lei, $nr) = @_;
+	$lei->{-nr_write} += $nr;
+}
+
 sub query_one_mset { # for --threads and l2m w/o sort
 	my ($self, $ibxish) = @_;
 	local $0 = "$0 query_one_mset";
@@ -354,7 +359,7 @@ sub query_done { # EOF callback for main daemon
 	}
 	my $wait = $lei->{sto} ? $lei->{sto}->ipc_do('done') : undef;
 	$lei->{ovv}->ovv_end($lei);
-	my @out;
+	my (@out, $start_mua);
 	if ($l2m) { # close() calls LeiToMail reap_compress
 		@out = (" in $lei->{ovv}->{dst}");
 		if (my $out = delete $lei->{old_1}) {
@@ -370,11 +375,15 @@ Error closing $lei->{ovv}->{dst}: $!
 			$lei->poke_mua;
 		} else { # mbox users
 			delete $l2m->{mbl}; # drop dotlock
-			$lei->start_mua;
+			$start_mua = 1;
 		}
 	}
-	$lei->{-progress} and
-		$lei->err('# ', $lei->{-mset_total} // 0, " matches", @out);
+	if ($lei->{-progress}) {
+		$lei->qerr('# ', $lei->{-mset_total} // 0, " matches", @out);
+		my $nr = $lei->{-nr_write} // 0;
+		$lei->qerr("# $nr written to $lei->{ovv}->{dst}") if $l2m;
+	}
+	$lei->start_mua if $start_mua;
 	$lei->dclose;
 }
 
@@ -456,6 +465,7 @@ sub do_query {
 		'+' => [ \&incr_post_augment, $lei ],
 		'' => [ \&query_done, $lei ],
 		'mset_progress' => [ \&mset_progress, $lei ],
+		'l2m_progress' => [ \&l2m_progress, $lei ],
 		'x_it' => [ $lei->can('x_it'), $lei ],
 		'child_error' => [ $lei->can('child_error'), $lei ],
 		'incr_start_query' => [ \&incr_start_query, $self, $l2m ],

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

* [PATCH 3/5] lei_saved_search: fix excess indent for first lei.q entry
  2021-05-01  6:21 [PATCH 0/5] lei: more UI/UX tweaks Eric Wong
  2021-05-01  6:21 ` [PATCH 1/5] xt/lei-onion-convert: test for NNTP+IMAP onions Eric Wong
  2021-05-01  6:21 ` [PATCH 2/5] lei <q|up>: distinguish between mset and l2m counts Eric Wong
@ 2021-05-01  6:21 ` Eric Wong
  2021-05-01  6:21 ` [PATCH 4/5] lei: rename ls-sync to ls-mail-sync Eric Wong
  2021-05-01  6:21 ` [PATCH 5/5] lei edit-search: support relocating lei.q.output Eric Wong
  4 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-05-01  6:21 UTC (permalink / raw)
  To: meta

This was harmless, but ugly and possibly confusing to
users who run "lei edit-search".
---
 lib/PublicInbox/LeiSavedSearch.pm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/PublicInbox/LeiSavedSearch.pm b/lib/PublicInbox/LeiSavedSearch.pm
index 682a43e8..79125214 100644
--- a/lib/PublicInbox/LeiSavedSearch.pm
+++ b/lib/PublicInbox/LeiSavedSearch.pm
@@ -137,7 +137,7 @@ sub new { # new saved search "lei q --save"
 	print $fh <<EOM;
 ; to refresh with new results, run: lei up $sq_dst
 [lei]
-	$q
+$q
 [lei "q"]
 	output = $dst
 EOM

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

* [PATCH 4/5] lei: rename ls-sync to ls-mail-sync
  2021-05-01  6:21 [PATCH 0/5] lei: more UI/UX tweaks Eric Wong
                   ` (2 preceding siblings ...)
  2021-05-01  6:21 ` [PATCH 3/5] lei_saved_search: fix excess indent for first lei.q entry Eric Wong
@ 2021-05-01  6:21 ` Eric Wong
  2021-05-01 19:29   ` [PATCH 6/5] lei import: fix --mail-sync handling in LeiInput Eric Wong
  2021-05-01  6:21 ` [PATCH 5/5] lei edit-search: support relocating lei.q.output Eric Wong
  4 siblings, 1 reply; 7+ messages in thread
From: Eric Wong @ 2021-05-01  6:21 UTC (permalink / raw)
  To: meta

This allows tab-completion for "ls-search" to work with fewer
characters ("ls-s<TAB>" instead of "ls-se<TAB>"), and I expect
"ls-search" to be used more frequently than "ls-mail-sync".

This also matches the --mail-sync switch of "lei import"
---
 MANIFEST                                           | 2 +-
 lib/PublicInbox/LEI.pm                             | 2 +-
 lib/PublicInbox/{LeiLsSync.pm => LeiLsMailSync.pm} | 4 ++--
 t/lei-import-imap.t                                | 4 ++--
 t/lei-import-maildir.t                             | 4 ++--
 5 files changed, 8 insertions(+), 8 deletions(-)
 rename lib/PublicInbox/{LeiLsSync.pm => LeiLsMailSync.pm} (93%)

diff --git a/MANIFEST b/MANIFEST
index 82f25735..b7e55793 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -202,8 +202,8 @@ lib/PublicInbox/LeiInput.pm
 lib/PublicInbox/LeiInspect.pm
 lib/PublicInbox/LeiLcat.pm
 lib/PublicInbox/LeiLsLabel.pm
+lib/PublicInbox/LeiLsMailSync.pm
 lib/PublicInbox/LeiLsSearch.pm
-lib/PublicInbox/LeiLsSync.pm
 lib/PublicInbox/LeiMailSync.pm
 lib/PublicInbox/LeiMirror.pm
 lib/PublicInbox/LeiOverview.pm
diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm
index bb67fc0b..5d701d5e 100644
--- a/lib/PublicInbox/LEI.pm
+++ b/lib/PublicInbox/LEI.pm
@@ -170,7 +170,7 @@ our %CMD = ( # sorted in order of importance/use:
 'ls-external' => [ '[FILTER]', 'list publicinbox|extindex locations',
 	qw(format|f=s z|0 globoff|g invert-match|v local remote), @c_opt ],
 'ls-label' => [ '', 'list labels', qw(z|0 stats:s), @c_opt ],
-'ls-sync' => [ '', 'list sync folders',
+'ls-mail-sync' => [ '', 'list mail sync folders',
 		qw(z|0 z|0 globoff|g invert-match|v local remote), @c_opt ],
 'forget-external' => [ 'LOCATION...|--prune',
 	'exclude further results from a publicinbox|extindex',
diff --git a/lib/PublicInbox/LeiLsSync.pm b/lib/PublicInbox/LeiLsMailSync.pm
similarity index 93%
rename from lib/PublicInbox/LeiLsSync.pm
rename to lib/PublicInbox/LeiLsMailSync.pm
index 71f111a9..2b3d326d 100644
--- a/lib/PublicInbox/LeiLsSync.pm
+++ b/lib/PublicInbox/LeiLsMailSync.pm
@@ -2,12 +2,12 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 
 # front-end for the "lei ls-sync" sub-command
-package PublicInbox::LeiLsSync;
+package PublicInbox::LeiLsMailSync;
 use strict;
 use v5.10.1;
 use PublicInbox::LeiMailSync;
 
-sub lei_ls_sync {
+sub lei_ls_mail_sync {
 	my ($lei, $filter) = @_;
 	my $sto = $lei->_lei_store or return;
 	my $lms = $sto->search->lms or return;
diff --git a/t/lei-import-imap.t b/t/lei-import-imap.t
index c977c68e..3a1fff4c 100644
--- a/t/lei-import-imap.t
+++ b/t/lei-import-imap.t
@@ -22,8 +22,8 @@ test_lei({ tmpdir => $tmpdir }, sub {
 	is_deeply(json_utf8->decode($lei_out), {}, 'no inspect stats, yet');
 
 	lei_ok('import', $url);
-	lei_ok 'ls-sync';
-	like($lei_out, qr!\A\Q$url\E;UIDVALIDITY=\d+\n\z!, 'ls-sync');
+	lei_ok 'ls-mail-sync';
+	like($lei_out, qr!\A\Q$url\E;UIDVALIDITY=\d+\n\z!, 'ls-mail-sync');
 	chomp(my $u = $lei_out);
 	lei_ok('import', $u, \'UIDVALIDITY match in URL');
 	$u =~ s/;UIDVALIDITY=(\d+)\s*/;UIDVALIDITY=9$1/s;
diff --git a/t/lei-import-maildir.t b/t/lei-import-maildir.t
index 808e1a73..02fe43e1 100644
--- a/t/lei-import-maildir.t
+++ b/t/lei-import-maildir.t
@@ -40,8 +40,8 @@ test_lei(sub {
 	is_deeply($inspect, { sync => { "maildir:$md" => [ 'x:2,S' ] } },
 		'maildir sync info as expected');
 
-	lei_ok qw(ls-sync);
-	is($lei_out, "maildir:$md\n", 'ls-sync as expected');
+	lei_ok qw(ls-mail-sync);
+	is($lei_out, "maildir:$md\n", 'ls-mail-sync as expected');
 
 	lei_ok(qw(import), $md, \'import Maildir again');
 	$imp_err = $lei_err;

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

* [PATCH 5/5] lei edit-search: support relocating lei.q.output
  2021-05-01  6:21 [PATCH 0/5] lei: more UI/UX tweaks Eric Wong
                   ` (3 preceding siblings ...)
  2021-05-01  6:21 ` [PATCH 4/5] lei: rename ls-sync to ls-mail-sync Eric Wong
@ 2021-05-01  6:21 ` Eric Wong
  4 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-05-01  6:21 UTC (permalink / raw)
  To: meta

The contents of the old lei.q.output will not be removed,
but will be converted into the new one.
---
 lib/PublicInbox/LeiConvert.pm     |  5 ++-
 lib/PublicInbox/LeiEditSearch.pm  | 15 +++++++--
 lib/PublicInbox/LeiSavedSearch.pm | 51 +++++++++++++++++++++++++++++++
 script/lei                        |  7 +++++
 4 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/lib/PublicInbox/LeiConvert.pm b/lib/PublicInbox/LeiConvert.pm
index cefcaf65..5b27ec2d 100644
--- a/lib/PublicInbox/LeiConvert.pm
+++ b/lib/PublicInbox/LeiConvert.pm
@@ -37,8 +37,11 @@ sub process_inputs { # via wq_do
 	my ($self) = @_;
 	local $PublicInbox::DS::in_loop = 0; # force synchronous dwaitpid
 	$self->SUPER::process_inputs;
-	delete $self->{lei}->{1};
+	my $lei = $self->{lei};
+	delete $lei->{1};
 	delete $self->{wcb}; # commit
+	my $nr = delete($lei->{-nr_write}) // 0;
+	$lei->err("# converted $nr messages") if $lei->{opt}->{verbose};
 }
 
 sub lei_convert { # the main "lei convert" method
diff --git a/lib/PublicInbox/LeiEditSearch.pm b/lib/PublicInbox/LeiEditSearch.pm
index fb36fdcd..30ac65bd 100644
--- a/lib/PublicInbox/LeiEditSearch.pm
+++ b/lib/PublicInbox/LeiEditSearch.pm
@@ -13,10 +13,19 @@ sub lei_edit_search {
 	my $lss = PublicInbox::LeiSavedSearch->up($lei, $out) or return;
 	my @cmd = (qw(git config --edit -f), $lss->{'-f'});
 	$lei->qerr("# spawning @cmd");
+	$lss->edit_begin($lei);
 	if ($lei->{oneshot}) {
-		exec(@cmd) or die "exec @cmd: $!\n";
-	} else {
-		$lei->send_exec_cmd([], \@cmd, {});
+		require PublicInbox::Spawn;
+		waitpid(PublicInbox::Spawn::spawn(\@cmd), 0);
+		# non-fatal, editor could fail after successful write
+		$lei->child_error($?) if $?;
+		$lss->edit_done($lei);
+	} else { # run in script/lei foreground
+		require PublicInbox::PktOp;
+		my ($op_c, $op_p) = PublicInbox::PktOp->pair;
+		# $op_p will EOF when $EDITOR is done
+		$op_c->{ops} = { '' => [$lss->can('edit_done'), $lss, $lei] };
+		$lei->send_exec_cmd([ @$lei{qw(0 1 2)}, $op_p ], \@cmd, {});
 	}
 }
 
diff --git a/lib/PublicInbox/LeiSavedSearch.pm b/lib/PublicInbox/LeiSavedSearch.pm
index 79125214..8177c98e 100644
--- a/lib/PublicInbox/LeiSavedSearch.pm
+++ b/lib/PublicInbox/LeiSavedSearch.pm
@@ -259,6 +259,57 @@ sub output2lssdir {
 	undef;
 }
 
+sub edit_begin {
+	my ($self, $lei) = @_;
+	if (ref($self->{-cfg}->{'lei.q.output'})) {
+		delete $self->{-cfg}->{'lei.q.output'}; # invalid
+		$lei->err(<<EOM);
+$self->{-f} has multiple values of lei.q.output
+please remove redundant ones
+EOM
+	}
+	$lei->{-lss_for_edit} = $self;
+}
+
+sub edit_done {
+	my ($self, $lei) = @_;
+	my $cfg = PublicInbox::Config->git_config_dump($self->{'-f'});
+	my $new_out = $cfg->{'lei.q.output'} // '';
+	return $lei->fail(<<EOM) if ref $new_out;
+$self->{-f} has multiple values of lei.q.output
+please edit again
+EOM
+	return $lei->fail(<<EOM) if $new_out eq '';
+$self->{-f} needs lei.q.output
+please edit again
+EOM
+	my $old_out = $self->{-cfg}->{'lei.q.output'} // '';
+	return if $old_out eq $new_out;
+	my $old_path = $old_out;
+	my $new_path = $new_out;
+	s!$LOCAL_PFX!! for ($old_path, $new_path);
+	my $dir_old = lss_dir_for($lei, \$old_path, 1);
+	my $dir_new = lss_dir_for($lei, \$new_path);
+	return if $dir_new eq $dir_old; # no change, likely
+	return $lei->fail(<<EOM) if -e $dir_new;
+lei.q.output changed from `$old_out' to `$new_out'
+However, $dir_new exists
+EOM
+	# start the conversion asynchronously
+	my $old_sq = PublicInbox::Config::squote_maybe($old_out);
+	my $new_sq = PublicInbox::Config::squote_maybe($new_out);
+	$lei->puts("lei.q.output changed from $old_sq to $new_sq");
+	$lei->qerr("# lei convert $old_sq -o $new_sq");
+	my $v = !$lei->{opt}->{quiet};
+	$lei->{opt} = { output => $new_out, verbose => $v };
+	require PublicInbox::LeiConvert;
+	PublicInbox::LeiConvert::lei_convert($lei, $old_out);
+
+	$lei->fail(<<EOM) if -e $dir_old && !rename($dir_old, $dir_new);
+E: rename($dir_old, $dir_new) error: $!
+EOM
+}
+
 no warnings 'once';
 *nntp_url = \&cloneurl;
 *base_url = \&PublicInbox::Inbox::base_url;
diff --git a/script/lei b/script/lei
index 90a93839..bec6b001 100755
--- a/script/lei
+++ b/script/lei
@@ -33,8 +33,15 @@ my $exec_cmd = sub {
 		push @rdr, shift(@old), $newfh;
 	}
 	my $do_exec = sub {
+		my @non_std; # ex. $op_p from lei_edit_search
 		while (my ($io, $newfh) = splice(@rdr, 0, 2)) {
+			my $old_io = !!$io;
 			open $io, '+<&', $newfh or die "open +<&=: $!";
+			push @non_std, $io unless $old_io;
+		}
+		if (@non_std) {
+			require Fcntl;
+			fcntl($_, Fcntl::F_SETFD(), 0) for @non_std;
 		}
 		my %env = map { split(/=/, $_, 2) } splice(@argv, $argc);
 		@ENV{keys %env} = values %env;

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

* [PATCH 6/5] lei import: fix --mail-sync handling in LeiInput
  2021-05-01  6:21 ` [PATCH 4/5] lei: rename ls-sync to ls-mail-sync Eric Wong
@ 2021-05-01 19:29   ` Eric Wong
  0 siblings, 0 replies; 7+ messages in thread
From: Eric Wong @ 2021-05-01 19:29 UTC (permalink / raw)
  To: meta

"lei inspect" also shows "mail-sync" as a field name
---
 lib/PublicInbox/LeiInput.pm   | 8 ++++----
 lib/PublicInbox/LeiInspect.pm | 2 +-
 t/lei-import-imap.t           | 4 ++--
 t/lei-import-maildir.t        | 2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/PublicInbox/LeiInput.pm b/lib/PublicInbox/LeiInput.pm
index 86f300c3..9bcc86e1 100644
--- a/lib/PublicInbox/LeiInput.pm
+++ b/lib/PublicInbox/LeiInput.pm
@@ -204,7 +204,7 @@ sub prepare_http_input ($$$) {
 sub prepare_inputs { # returns undef on error
 	my ($self, $lei, $inputs) = @_;
 	my $in_fmt = $lei->{opt}->{'in-format'};
-	my $sync = $lei->{opt}->{sync} ? {} : undef; # using LeiMailSync
+	my $sync = $lei->{opt}->{'mail-sync'} ? {} : undef; # using LeiMailSync
 	if ($lei->{opt}->{stdin}) {
 		@$inputs and return
 			$lei->fail("--stdin and @$inputs do not mix");
@@ -286,11 +286,11 @@ $input is `eml', not --in-format=$in_fmt
 	}
 	if ($sync && $sync->{no}) {
 		return $lei->fail(<<"") if !$sync->{ok};
---sync specified but no inputs support it
+--mail-sync specified but no inputs support it
 
 		# non-fatal if some inputs support support sync
-		$lei->err("# --sync will only be used for @{$sync->{ok}}");
-		$lei->err("# --sync is not supported for: @{$sync->{no}}");
+		$lei->err("# --mail-sync will only be used for @{$sync->{ok}}");
+		$lei->err("# --mail-sync is not supported for: @{$sync->{no}}");
 	}
 	if ($net) {
 		$net->{-can_die} = 1;
diff --git a/lib/PublicInbox/LeiInspect.pm b/lib/PublicInbox/LeiInspect.pm
index 6cfc8083..714d2526 100644
--- a/lib/PublicInbox/LeiInspect.pm
+++ b/lib/PublicInbox/LeiInspect.pm
@@ -18,7 +18,7 @@ sub inspect_blob ($$) {
 		$ent->{'lei/store'} = \@docids if @docids;
 		my $lms = $lse->lms;
 		if (my $loc = $lms ? $lms->locations_for($oidhex) : undef) {
-			$ent->{sync} = $loc;
+			$ent->{'mail-sync'} = $loc;
 		}
 	}
 	$ent;
diff --git a/t/lei-import-imap.t b/t/lei-import-imap.t
index 3a1fff4c..fd15ef4f 100644
--- a/t/lei-import-imap.t
+++ b/t/lei-import-imap.t
@@ -54,8 +54,8 @@ test_lei({ tmpdir => $tmpdir }, sub {
 	lei_ok('inspect', "blob:$out->[5]->{blob}");
 	my $x = json_utf8->decode($lei_out);
 	is(ref($x->{'lei/store'}), 'ARRAY', 'lei/store in inspect');
-	is(ref($x->{sync}), 'HASH', 'sync in inspect');
-	is(ref($x->{sync}->{$k[0]}), 'ARRAY', 'UID arrays in inspect');
+	is(ref($x->{'mail-sync'}), 'HASH', 'sync in inspect');
+	is(ref($x->{'mail-sync'}->{$k[0]}), 'ARRAY', 'UID arrays in inspect');
 
 	my $psgi_attach = 'cfa3622cbeffc9bd6b0fc66c4d60d420ba74f60d';
 	lei_ok('blob', $psgi_attach);
diff --git a/t/lei-import-maildir.t b/t/lei-import-maildir.t
index 02fe43e1..b85d3026 100644
--- a/t/lei-import-maildir.t
+++ b/t/lei-import-maildir.t
@@ -37,7 +37,7 @@ test_lei(sub {
 	lei_ok('inspect', "blob:$res->[0]->{blob}");
 	$inspect = json_utf8->decode($lei_out);
 	is(ref(delete $inspect->{"lei/store"}), 'ARRAY', 'lei/store IDs');
-	is_deeply($inspect, { sync => { "maildir:$md" => [ 'x:2,S' ] } },
+	is_deeply($inspect, { 'mail-sync' => { "maildir:$md" => [ 'x:2,S' ] } },
 		'maildir sync info as expected');
 
 	lei_ok qw(ls-mail-sync);

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

end of thread, other threads:[~2021-05-01 19:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-01  6:21 [PATCH 0/5] lei: more UI/UX tweaks Eric Wong
2021-05-01  6:21 ` [PATCH 1/5] xt/lei-onion-convert: test for NNTP+IMAP onions Eric Wong
2021-05-01  6:21 ` [PATCH 2/5] lei <q|up>: distinguish between mset and l2m counts Eric Wong
2021-05-01  6:21 ` [PATCH 3/5] lei_saved_search: fix excess indent for first lei.q entry Eric Wong
2021-05-01  6:21 ` [PATCH 4/5] lei: rename ls-sync to ls-mail-sync Eric Wong
2021-05-01 19:29   ` [PATCH 6/5] lei import: fix --mail-sync handling in LeiInput Eric Wong
2021-05-01  6:21 ` [PATCH 5/5] lei edit-search: support relocating lei.q.output Eric Wong

user/dev discussion of public-inbox itself

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://public-inbox.org/meta
	git clone --mirror http://czquwvybam4bgbro.onion/meta
	git clone --mirror http://hjrcffqmbrq6wope.onion/meta
	git clone --mirror http://ou63pmih66umazou.onion/meta

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 meta meta/ https://public-inbox.org/meta \
		meta@public-inbox.org
	public-inbox-index meta

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.mail.public-inbox.meta
	nntp://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.mail.public-inbox.meta
	nntp://ie5yzdi7fg72h7s4sdcztq5evakq23rdt33mfyfcddc5u3ndnw24ogqd.onion/inbox.comp.mail.public-inbox.meta
	nntp://4uok3hntl7oi7b4uf4rtfwefqeexfzil2w6kgk2jn5z2f764irre7byd.onion/inbox.comp.mail.public-inbox.meta
	nntp://news.gmane.io/gmane.mail.public-inbox.general
 note: .onion URLs require Tor: https://www.torproject.org/

code repositories for project(s) associated with this inbox:

	https://80x24.org/public-inbox.git

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git