'plonk' => [ '--thread|--from=IDENT',
'exclude mail matching From: or thread from non-Message-ID searches',
- qw(thread|t stdin| from|f=s mid=s oid=s) ],
+ qw(stdin| thread|t from|f=s mid=s oid=s) ],
'mark' => [ 'MESSAGE_FLAGS...',
'set/unset flags on message(s) from stdin',
qw(stdin| oid=s exact by-mid|mid:s) ],
qw(quiet|q) ],
'daemon-stop' => [ '', 'stop the lei-daemon' ],
'daemon-pid' => [ '', 'show the PID of the lei-daemon' ],
+'daemon-env' => [ '[NAME=VALUE...]', 'set, unset, or show daemon environment',
+ qw(clear| unset|u=s@ z|0) ],
'help' => [ '[SUBCOMMAND]', 'show help' ],
# XXX do we need this?
'by-mid|mid:s' => [ 'MID', 'match only by Message-ID, ignoring contents' ],
'jobs:i' => 'set parallelism level',
+
+# xargs, env, use "-0", git(1) uses "-z". Should we support z|0 everywhere?
+'z' => 'use NUL \\0 instead of newline (CR) to delimit lines',
+'z|0' => 'use NUL \\0 instead of newline (CR) to delimit lines',
+
+# note: no "--ignore-environment" / "-i" support like env(1) since that
+# is one-shot and this is for a persistent daemon:
+'clear|' => 'clear the daemon environment',
+'unset|u=s@' => ['NAME',
+ 'unset matching NAME, may be specified multiple times'],
); # %OPTDESC
sub x_it ($$) { # pronounced "exit"
join(', ', @allow) . " or $last";
}
my $lhs = join(', ', @s, @l) . join('', @vals);
- $lhs =~ s/\A--/ --/; # pad if no short options
+ if ($x =~ /\|\z/) { # "stdin|" or "clear|"
+ $lhs =~ s/\A--/- , --/;
+ } else {
+ $lhs =~ s/\A--/ --/; # pad if no short options
+ }
$lpad = length($lhs) if length($lhs) > $lpad;
push @opt_desc, $lhs, $desc;
}
my $opt = $client->{opt} = {};
my $info = $CMD{$cmd} // [ '[...]', '(undocumented command)' ];
my ($proto, $desc, @spec) = @$info;
- $glp->getoptionsfromarray($argv, $opt, @spec, qw(help|h)) or
+ push @spec, qw(help|h);
+ my $lone_dash;
+ if ($spec[0] =~ s/\|\z//s) { # "stdin|" or "clear|" allows "-" alias
+ $lone_dash = $spec[0];
+ $opt->{$spec[0]} = \(my $var);
+ push @spec, '' => \$var;
+ }
+ $glp->getoptionsfromarray($argv, $opt, @spec) or
return _help($client, "bad arguments or options for $cmd");
return _help($client) if $opt->{help};
+
+ # "-" aliases "stdin" or "clear"
+ $opt->{$lone_dash} = ${$opt->{$lone_dash}} if defined $lone_dash;
+
my $i = 0;
my $POS_ARG = '[A-Z][A-Z0-9_]+';
my ($err, $inf);
return qerr($client, $exists);
}
-sub lei_daemon_pid {
- emit($_[0], 1, "$$\n");
-}
+sub lei_daemon_pid { emit($_[0], 1, "$$\n") }
sub lei_daemon_stop { $quit->(0) }
+sub lei_daemon_env {
+ my ($client, @argv) = @_;
+ my $opt = $client->{opt};
+ if (defined $opt->{clear}) {
+ %ENV = ();
+ } elsif (my $u = $opt->{unset}) {
+ delete @ENV{@$u};
+ }
+ if (@argv) {
+ %ENV = (%ENV, map { split(/=/, $_, 2) } @argv);
+ } elsif (!defined($opt->{clear}) && !$opt->{unset}) {
+ my $eor = $opt->{z} ? "\0" : "\n";
+ my $buf = '';
+ while (my ($k, $v) = each %ENV) { $buf .= "$k=$v$eor" }
+ emit($client, 1, $buf)
+ }
+}
+
sub lei_help { _help($_[0]) }
sub reap_exec { # dwaitpid callback
delete local $ENV{XDG_CONFIG_HOME};
local $ENV{XDG_RUNTIME_DIR} = "$home/xdg_run";
local $ENV{HOME} = $home;
+local $ENV{FOO} = 'BAR';
mkdir "$home/xdg_run", 0700 or BAIL_OUT "mkdir: $!";
my $test_lei_common = sub {
chomp(my $pid_again = $out);
is($pid, $pid_again, 'daemon-pid idempotent');
+ $out = '';
+ ok(run_script([qw(lei daemon-env -0)], undef, $opt), 'show env');
+ is($err, '', 'no errors in env dump');
+ my @env = split(/\0/, $out);
+ is(scalar grep(/\AHOME=\Q$home\E\z/, @env), 1, 'env has HOME');
+ is(scalar grep(/\AFOO=BAR\z/, @env), 1, 'env has FOO=BAR');
+ is(scalar grep(/\AXDG_RUNTIME_DIR=/, @env), 1, 'has XDG_RUNTIME_DIR');
+
+ $out = '';
+ ok(run_script([qw(lei daemon-env -u FOO)], undef, $opt), 'unset');
+ is($out.$err, '', 'no output for unset');
+ ok(run_script([qw(lei daemon-env -0)], undef, $opt), 'show again');
+ is($err, '', 'no errors in env dump');
+ @env = split(/\0/, $out);
+ is(scalar grep(/\AFOO=BAR\z/, @env), 0, 'env unset FOO');
+
+ $out = '';
+ ok(run_script([qw(lei daemon-env -u FOO -u HOME -u XDG_RUNTIME_DIR)],
+ undef, $opt), 'unset multiple');
+ is($out.$err, '', 'no errors output for unset');
+ ok(run_script([qw(lei daemon-env -0)], undef, $opt), 'show again');
+ is($err, '', 'no errors in env dump');
+ @env = split(/\0/, $out);
+ is(scalar grep(/\A(?:HOME|XDG_RUNTIME_DIR)=\z/, @env), 0, 'env unset@');
+ $out = '';
+ ok(run_script([qw(lei daemon-env -)], undef, $opt), 'clear env');
+ is($out.$err, '', 'no output');
+ ok(run_script([qw(lei daemon-env)], undef, $opt), 'env is empty');
+ is($out, '', 'env cleared');
+
ok(run_script([qw(lei daemon-stop)], undef, $opt), 'daemon-stop');
is($out, '', 'no output from daemon-stop');
is($err, '', 'no error from daemon-stop');