]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LEI.pm
lei: hide *_atfork_child from command-line
[public-inbox.git] / lib / PublicInbox / LEI.pm
index 9e3bb9b760e9cd695f33db82739273da46687a2c..17ca637eb304fd6d2fc246e38976aea4bd60319d 100644 (file)
@@ -157,9 +157,10 @@ our %CMD = ( # sorted in order of importance/use:
 'plonk' => [ '--threads|--from=IDENT',
        'exclude mail matching From: or threads from non-Message-ID searches',
        qw(stdin| threads|t from|f=s mid=s oid=s), @c_opt ],
-'mark' => [ 'MESSAGE_FLAGS...',
-       'set/unset keywords on message(s) from stdin',
-       qw(stdin| oid=s exact by-mid|mid:s), @c_opt ],
+'mark' => [ 'KEYWORDS...',
+       'set/unset keywords on message(s)',
+       qw(stdin| in-format|F=s input|i=s@ oid=s@ mid=s@), @c_opt,
+       pass_through('-kw:foo for delete') ],
 'forget' => [ '[--stdin|--oid=OID|--by-mid=MID]',
        "exclude message(s) on stdin from `q' search results",
        qw(stdin| oid=s exact by-mid|mid:s), @c_opt ],
@@ -348,7 +349,7 @@ my %CONFIG_KEYS = (
        'leistore.dir' => 'top-level storage location',
 );
 
-my @WQ_KEYS = qw(lxs l2m imp mrr cnv p2q); # internal workers
+my @WQ_KEYS = qw(lxs l2m imp mrr cnv p2q mark); # internal workers
 
 # pronounced "exit": x_it(1 << 8) => exit(1); x_it(13) => SIGPIPE
 sub x_it ($$) {
@@ -419,23 +420,6 @@ sub fail ($$;$) {
        undef;
 }
 
-sub check_input_format ($;$) {
-       my ($self, $files) = @_;
-       my $opt_key = 'in-format';
-       my $fmt = $self->{opt}->{$opt_key};
-       if (!$fmt) {
-               my $err = $files ? "regular file(s):\n@$files" : '--stdin';
-               return fail($self, "--$opt_key unset for $err");
-       }
-       require PublicInbox::MboxLock if $files;
-       require PublicInbox::MboxReader;
-       return 1 if $fmt eq 'eml';
-       # XXX: should this handle {gz,bz2,xz}? that's currently in LeiToMail
-       PublicInbox::MboxReader->can($fmt) or
-               return fail($self, "--$opt_key=$fmt unrecognized");
-       1;
-}
-
 sub out ($;@) {
        my $self = shift;
        return if print { $self->{1} // return } @_; # likely
@@ -465,7 +449,7 @@ sub note_sigpipe { # triggers sigpipe_handler
        x_it($self, 13);
 }
 
-sub lei_atfork_child {
+sub _lei_atfork_child {
        my ($self, $persist) = @_;
        # we need to explicitly close things which are on stack
        if ($persist) {
@@ -477,7 +461,7 @@ sub lei_atfork_child {
                open STDERR, '+>&='.fileno($self->{2}) or warn "open $!";
                delete $self->{0};
        }
-       delete @$self{qw(cnv)};
+       delete @$self{qw(cnv mark imp)};
        for (delete @$self{qw(3 old_1 au_done)}) {
                close($_) if defined($_);
        }
@@ -498,12 +482,13 @@ sub lei_atfork_child {
 sub workers_start {
        my ($lei, $wq, $ident, $jobs, $ops) = @_;
        $ops = {
-               '!' => [ $lei->can('fail_handler'), $lei ],
-               '|' => [ $lei->can('sigpipe_handler'), $lei ],
-               'x_it' => [ $lei->can('x_it'), $lei ],
-               'child_error' => [ $lei->can('child_error'), $lei ],
-               %$ops
+               '!' => [ \&fail_handler, $lei ],
+               '|' => [ \&sigpipe_handler, $lei ],
+               'x_it' => [ \&x_it, $lei ],
+               'child_error' => [ \&child_error, $lei ],
+               ($ops ? %$ops : ()),
        };
+       $ops->{''} //= [ \&dclose, $lei ];
        require PublicInbox::PktOp;
        ($lei->{pkt_op_c}, $lei->{pkt_op_p}) = PublicInbox::PktOp->pair($ops);
        $wq->wq_workers_start($ident, $jobs, $lei->oldset, { lei => $lei });
@@ -619,6 +604,19 @@ EOM
        }
 }
 
+sub lazy_cb ($$$) {
+       my ($self, $cmd, $pfx) = @_;
+       my $ucmd = $cmd;
+       $ucmd =~ tr/-/_/;
+       my $cb;
+       $cb = $self->can($pfx.$ucmd) and return $cb;
+       my $base = $ucmd;
+       $base =~ s/_([a-z])/\u$1/g;
+       my $pkg = "PublicInbox::Lei\u$base";
+       ($INC{"PublicInbox/Lei\u$base.pm"} // eval("require $pkg")) ?
+               $pkg->can($pfx.$ucmd) : undef;
+}
+
 sub dispatch {
        my ($self, $cmd, @argv) = @_;
        local $current_lei = $self; # for __WARN__
@@ -631,14 +629,7 @@ sub dispatch {
                push @{$self->{opt}->{substr($cmd, 1, 1)}}, $v;
                $cmd = shift(@argv) // return _help($self, 'no command given');
        }
-       my $func = "lei_$cmd";
-       $func =~ tr/-/_/;
-       my $cb = __PACKAGE__->can($func) // ($CMD{$cmd} ? do {
-               my $mod = "PublicInbox::Lei\u$cmd";
-               ($INC{"PublicInbox/Lei\u$cmd.pm"} //
-                       eval("require $mod")) ? $mod->can($func) : undef;
-       } : undef);
-       if ($cb) {
+       if (my $cb = lazy_cb(__PACKAGE__, $cmd, 'lei_')) {
                optparse($self, $cmd, \@argv) or return;
                $self->{opt}->{c} and (_tmp_cfg($self) // return);
                if (my $chdir = $self->{opt}->{C}) {
@@ -706,10 +697,6 @@ sub lei_show {
        my ($self, @argv) = @_;
 }
 
-sub lei_mark {
-       my ($self, @argv) = @_;
-}
-
 sub _config {
        my ($self, @argv) = @_;
        my %env = (%{$self->{env}}, GIT_CONFIG => undef);
@@ -827,9 +814,8 @@ sub lei__complete {
                        @v;
                } grep(/\A(?:[\w-]+\|)*$opt\b.*?(?:\t$cmd)?\z/, keys %OPTDESC);
        }
-       $cmd =~ tr/-/_/;
-       if (my $sub = $self->can("_complete_$cmd")) {
-               puts $self, $sub->($self, @argv, $cur ? ($cur) : ());
+       if (my $cb = lazy_cb($self, $cmd, '_complete_')) {
+               puts $self, $cb->($self, @argv, $cur ? ($cur) : ());
        }
        # TODO: URLs, pathnames, OIDs, MIDs, etc...  See optparse() for
        # proto parsing.