]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LEI.pm
lei init: split out into separate file
[public-inbox.git] / lib / PublicInbox / LEI.pm
index 99e180f61e9e3e4f2572bc5f98ece05356cc326e..fdb0bbcf2fe1ffb1afb73ebea5abfae4b3a2a0d9 100644 (file)
@@ -120,6 +120,9 @@ sub index_opt {
 }
 
 my @c_opt = qw(c=s@ C=s@ quiet|q);
+my @lxs_opt = (qw(remote! local! external! include|I=s@ exclude=s@ only=s@
+       import-remote!  no-torsocks torsocks=s),
+       PublicInbox::LeiQuery::curl_opt());
 
 # we generate shell completion + help using %CMD and %OPTDESC,
 # see lei__complete() and PublicInbox::LeiHelp
@@ -127,16 +130,15 @@ my @c_opt = qw(c=s@ C=s@ quiet|q);
 our %CMD = ( # sorted in order of importance/use:
 'q' => [ '--stdin|SEARCH_TERMS...', 'search for messages matching terms',
        'stdin|', # /|\z/ must be first for lone dash
+       @lxs_opt,
        qw(save-as=s output|mfolder|o=s format|f=s dedupe|d=s threads|t+
-       sort|s=s reverse|r offset=i remote! local! external! pretty
-       include|I=s@ exclude=s@ only=s@ jobs|j=s globoff|g augment|a
-       import-remote! import-before! lock=s@ rsyncable
-       alert=s@ mua=s no-torsocks torsocks=s verbose|v+), @c_opt,
-       PublicInbox::LeiQuery::curl_opt(), opt_dash('limit|n=i', '[0-9]+') ],
+       sort|s=s reverse|r offset=i pretty jobs|j=s globoff|g augment|a
+       import-before! lock=s@ rsyncable alert=s@ mua=s verbose|v+), @c_opt,
+       opt_dash('limit|n=i', '[0-9]+') ],
 
-'show' => [ 'MID|OID', 'show a given object (Message-ID or object ID)',
-       qw(type=s solve! format|f=s dedupe|d=s threads|t remote local!
-       verbose|v+), @c_opt, pass_through('git show') ],
+'blob' => [ 'OID', 'display a git blob object, solving if necessary',
+       qw(git-dir=s@ cwd! verbose|v+ oid-a|A=s path-a|a=s path-b|b=s),
+       @lxs_opt, @c_opt ],
 
 'add-external' => [ 'LOCATION',
        'add/set priority of a publicinbox|extindex for extra matches',
@@ -145,6 +147,7 @@ our %CMD = ( # sorted in order of importance/use:
        PublicInbox::LeiQuery::curl_opt() ],
 '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 ],
 'forget-external' => [ 'LOCATION...|--prune',
        'exclude further results from a publicinbox|extindex',
        qw(prune), @c_opt ],
@@ -349,7 +352,7 @@ my %CONFIG_KEYS = (
        'leistore.dir' => 'top-level storage location',
 );
 
-my @WQ_KEYS = qw(lxs l2m imp mrr cnv p2q mark); # internal workers
+my @WQ_KEYS = qw(lxs l2m imp mrr cnv p2q mark sol); # internal workers
 
 # pronounced "exit": x_it(1 << 8) => exit(1); x_it(13) => SIGPIPE
 sub x_it ($$) {
@@ -463,7 +466,6 @@ sub _lei_atfork_child {
                }
        } else { # worker, Net::NNTP (Net::Cmd) uses STDERR directly
                open STDERR, '+>&='.fileno($self->{2}) or warn "open $!";
-               delete $self->{0};
        }
        for (delete @$self{qw(3 old_1 au_done)}) {
                close($_) if defined($_);
@@ -492,11 +494,11 @@ sub _delete_pkt_op { # OnDestroy callback to prevent leaks on die
 }
 
 sub pkt_op_pair {
-       my ($self, $ops) = @_;
+       my ($self) = @_;
        require PublicInbox::OnDestroy;
        require PublicInbox::PktOp;
        my $end = PublicInbox::OnDestroy->new($$, \&_delete_pkt_op, $self);
-       @$self{qw(pkt_op_c pkt_op_p)} = PublicInbox::PktOp->pair($ops);
+       @$self{qw(pkt_op_c pkt_op_p)} = PublicInbox::PktOp->pair;
        $end;
 }
 
@@ -510,14 +512,13 @@ sub workers_start {
                ($ops ? %$ops : ()),
        };
        $ops->{''} //= [ \&dclose, $lei ];
-       my $end = $lei->pkt_op_pair($ops);
+       my $end = $lei->pkt_op_pair;
        $wq->wq_workers_start($ident, $jobs, $lei->oldset, { lei => $lei });
        delete $lei->{pkt_op_p};
-       my $op = delete $lei->{pkt_op_c};
+       my $op_c = delete $lei->{pkt_op_c};
        @$end = ();
        $lei->event_step_init;
-       # oneshot needs $op, daemon-mode uses DS->EventLoop to handle $op
-       $lei->{oneshot} ? $op : undef;
+       ($op_c, $ops);
 }
 
 sub _help {
@@ -726,10 +727,6 @@ sub _lei_store ($;$) {
        };
 }
 
-sub lei_show {
-       my ($self, @argv) = @_;
-}
-
 sub _config {
        my ($self, @argv) = @_;
        my %env = (%{$self->{env}}, GIT_CONFIG => undef);
@@ -747,38 +744,6 @@ sub lei_config {
        x_it($self, $?) if $?;
 }
 
-sub lei_init {
-       my ($self, $dir) = @_;
-       my $cfg = _lei_cfg($self, 1);
-       my $cur = $cfg->{'leistore.dir'};
-       $dir //= store_path($self);
-       $dir = rel2abs($self, $dir);
-       my @cur = stat($cur) if defined($cur);
-       $cur = File::Spec->canonpath($cur // $dir);
-       my @dir = stat($dir);
-       my $exists = "# leistore.dir=$cur already initialized" if @dir;
-       if (@cur) {
-               if ($cur eq $dir) {
-                       _lei_store($self, 1)->done;
-                       return qerr($self, $exists);
-               }
-
-               # some folks like symlinks and bind mounts :P
-               if (@dir && "@cur[1,0]" eq "@dir[1,0]") {
-                       lei_config($self, 'leistore.dir', $dir);
-                       _lei_store($self, 1)->done;
-                       return qerr($self, "$exists (as $cur)");
-               }
-               return fail($self, <<"");
-E: leistore.dir=$cur already initialized and it is not $dir
-
-       }
-       lei_config($self, 'leistore.dir', $dir);
-       _lei_store($self, 1)->done;
-       $exists //= "# leistore.dir=$dir newly initialized";
-       return qerr($self, $exists);
-}
-
 sub lei_daemon_pid { puts shift, $$ }
 
 sub lei_daemon_kill {
@@ -787,8 +752,6 @@ sub lei_daemon_kill {
        kill($sig, $$) or fail($self, "kill($sig, $$): $!");
 }
 
-sub lei_help { _help($_[0]) }
-
 # Shell completion helper.  Used by lei-completion.bash and hopefully
 # other shells.  Try to do as much here as possible to avoid redundancy
 # and improve maintainability.
@@ -928,19 +891,17 @@ sub poke_mua { # forces terminal MUAs to wake up and hopefully notice new mail
 }
 
 my %path_to_fd = ('/dev/stdin' => 0, '/dev/stdout' => 1, '/dev/stderr' => 2);
-$path_to_fd{"/dev/fd/$_"} = $path_to_fd{"/proc/self/fd/$_"} for (0..2);
-sub fopen {
-       my ($self, $mode, $path) = @_;
-       rel2abs($self, $path);
+$path_to_fd{"/dev/fd/$_"} = $_ for (0..2);
+
+# this also normalizes the path
+sub path_to_fd {
+       my ($self, $path) = @_;
+       $path = rel2abs($self, $path);
        $path =~ tr!/!/!s;
-       if (defined(my $fd = $path_to_fd{$path})) {
-               return $self->{$fd};
-       }
-       if ($path =~ m!\A/(?:dev|proc/self)/fd/[0-9]+\z!) {
-               return fail($self, "cannot open $path from daemon");
-       }
-       open my $fh, $mode, $path or return;
-       $fh;
+       $path_to_fd{$path} // (
+               ($path =~ m!\A/(?:dev|proc/self)/fd/[0-9]+\z!) ?
+                       fail($self, "cannot open $path from daemon") : -1
+       );
 }
 
 # caller needs to "-t $self->{1}" to check if tty
@@ -1029,9 +990,6 @@ sub dclose {
                }
        }
        close(delete $self->{1}) if $self->{1}; # may reap_compress
-       if (my $sto = delete $self->{sto}) {
-               $sto->ipc_do('done');
-       }
        $self->close if $self->{-event_init_done}; # PublicInbox::DS::close
 }