]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/LeiEditSearch.pm
47166ce724837013d3b13286326fae75a2c863e2
[public-inbox.git] / lib / PublicInbox / LeiEditSearch.pm
1 # Copyright (C) 2021 all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3
4 # "lei edit-search" edit a saved search following "lei q --save"
5 package PublicInbox::LeiEditSearch;
6 use strict;
7 use v5.10.1;
8 use PublicInbox::LeiSavedSearch;
9 use PublicInbox::LeiUp;
10
11 sub edit_begin {
12         my ($lss, $lei) = @_;
13         if (ref($lss->{-cfg}->{'lei.q.output'})) {
14                 delete $lss->{-cfg}->{'lei.q.output'}; # invalid
15                 $lei->pgr_err(<<EOM);
16 $lss->{-f} has multiple values of lei.q.output
17 please remove redundant ones
18 EOM
19         }
20         $lei->{-lss_for_edit} = $lss;
21 }
22
23 sub do_edit ($$;$) {
24         my ($lss, $lei, $reason) = @_;
25         $lei->pgr_err($reason) if defined $reason;
26         my @cmd = (qw(git config --edit -f), $lss->{'-f'});
27         $lei->qerr("# spawning @cmd");
28         edit_begin($lss, $lei);
29         # run in script/lei foreground
30         require PublicInbox::PktOp;
31         my ($op_c, $op_p) = PublicInbox::PktOp->pair;
32         # $op_p will EOF when $EDITOR is done
33         $op_c->{ops} = { '' => [\&op_edit_done, $lss, $lei] };
34         $lei->send_exec_cmd([ @$lei{qw(0 1 2)}, $op_p->{op_p} ], \@cmd, {});
35 }
36
37 sub _edit_done {
38         my ($lss, $lei) = @_;
39         my $cfg = $lss->can('cfg_dump')->($lei, $lss->{'-f'}) //
40                 return do_edit($lss, $lei, <<EOM);
41 $lss->{-f} is unparseable
42 EOM
43         my $new_out = $cfg->{'lei.q.output'} // '';
44         return do_edit($lss, $lei, <<EOM) if ref $new_out;
45 $lss->{-f} has multiple values of lei.q.output
46 EOM
47         return do_edit($lss, $lei, <<EOM) if $new_out eq '';
48 $lss->{-f} needs lei.q.output
49 EOM
50         my $old_out = $lss->{-cfg}->{'lei.q.output'} // return;
51         return if $old_out eq $new_out;
52         my $old_path = $old_out;
53         my $new_path = $new_out;
54         s!$PublicInbox::LeiSavedSearch::LOCAL_PFX!! for ($old_path, $new_path);
55         my $dir_old = $lss->can('lss_dir_for')->($lei, \$old_path, 1);
56         my $dir_new = $lss->can('lss_dir_for')->($lei, \$new_path);
57         return if $dir_new eq $dir_old;
58
59         ($old_out =~ m!\Av2:!i || $new_out =~ m!\Av2:!) and
60                 return do_edit($lss, $lei, <<EOM);
61 conversions from/to v2 inboxes not supported at this time
62 EOM
63         return do_edit($lss, $lei, <<EOM) if -e $dir_new;
64 lei.q.output changed from `$old_out' to `$new_out'
65 However, $dir_new exists
66 EOM
67         # start the conversion asynchronously
68         my $old_sq = PublicInbox::Config::squote_maybe($old_out);
69         my $new_sq = PublicInbox::Config::squote_maybe($new_out);
70         $lei->puts("lei.q.output changed from $old_sq to $new_sq");
71         $lei->qerr("# lei convert $old_sq -o $new_sq");
72         my $v = !$lei->{opt}->{quiet};
73         $lei->{opt} = { output => $new_out, verbose => $v };
74         require PublicInbox::LeiConvert;
75         PublicInbox::LeiConvert::lei_convert($lei, $old_out);
76
77         $lei->fail(<<EOM) if -e $dir_old && !rename($dir_old, $dir_new);
78 E: rename($dir_old, $dir_new) error: $!
79 EOM
80 }
81
82 sub op_edit_done { # PktOp
83         my ($lss, $lei) = @_;
84         eval { _edit_done($lss, $lei) };
85         $lei->fail($@) if $@;
86 }
87
88 sub lei_edit_search {
89         my ($lei, $out) = @_;
90         my $lss = PublicInbox::LeiSavedSearch->up($lei, $out) or return;
91         do_edit($lss, $lei);
92 }
93
94 *_complete_edit_search = \&PublicInbox::LeiUp::_complete_up;
95
96 1;