From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 0BBC21FF9D for ; Fri, 18 Dec 2020 12:09:52 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 13/26] lei: support pass-through for `lei config' Date: Fri, 18 Dec 2020 12:09:37 +0000 Message-Id: <20201218120950.23272-14-e@80x24.org> In-Reply-To: <20201218120950.23272-1-e@80x24.org> References: <20201218120950.23272-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: This will be a handy wrapper for "git config" for manipulating ~/.config/lei/config. Since we'll have many commands, start breaking up t/lei.t into more distinct sections for ease-of-testing. --- lib/PublicInbox/LEI.pm | 32 ++++++++++++------------- t/lei.t | 54 +++++++++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index b5ba1f71..dbd2875d 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -24,13 +24,16 @@ use Text::Wrap qw(wrap); use File::Path qw(mkpath); use File::Spec; our $quit = \&CORE::exit; -my $glp = Getopt::Long::Parser->new; -$glp->configure(qw(gnu_getopt no_ignore_case auto_abbrev)); +my $GLP = Getopt::Long::Parser->new; +$GLP->configure(qw(gnu_getopt no_ignore_case auto_abbrev)); +my $GLP_PASS = Getopt::Long::Parser->new; +$GLP_PASS->configure(qw(gnu_getopt no_ignore_case auto_abbrev pass_through)); + our %PATH2CFG; # persistent for socket daemon # TBD: this is a documentation mechanism to show a subcommand # (may) pass options through to another command: -sub pass_through { () } +sub pass_through { $GLP_PASS } # TODO: generate shell completion + help using %CMD and %OPTDESC # command => [ positional_args, 1-line description, Getopt::Long option spec ] @@ -97,7 +100,8 @@ our %CMD = ( # sorted in order of importance/use: ], 'config' => [ '[...]', 'git-config(1) wrapper for ~/.config/lei/config', - pass_through('git config') ], + qw(config-file|system|global|file|f=s), # conflict detection + pass_through('git config') ], 'init' => [ '[PATHNAME]', 'initialize storage, default: ~/.local/share/lei/store', qw(quiet|q) ], @@ -231,7 +235,7 @@ sub _help ($;$) { my $cmd_desc = shift(@info); my @opt_desc; my $lpad = 2; - for my $sw (@info) { # qw(prio=s + for my $sw (grep { !ref($_) } @info) { # ("prio=s", "z", $GLP_PASS) my $desc = $OPTDESC{"$cmd\t$sw"} // $OPTDESC{$sw} // next; my $arg_vals = ''; ($arg_vals, $desc) = @$desc if ref($desc) eq 'ARRAY'; @@ -305,6 +309,7 @@ sub optparse ($$$) { my $opt = $client->{opt} = {}; my $info = $CMD{$cmd} // [ '[...]', '(undocumented command)' ]; my ($proto, $desc, @spec) = @$info; + my $glp = ref($spec[-1]) ? pop(@spec) : $GLP; # or $GLP_PASS push @spec, qw(help|h); my $lone_dash; if ($spec[0] =~ s/\|\z//s) { # "stdin|" or "clear|" allows "-" alias @@ -374,7 +379,7 @@ sub dispatch { $cb->($client, @argv); } elsif (grep(/\A-/, $cmd, @argv)) { # --help or -h only my $opt = {}; - $glp->getoptionsfromarray([$cmd, @argv], $opt, qw(help|h)) or + $GLP->getoptionsfromarray([$cmd, @argv], $opt, qw(help|h)) or return _help($client, 'bad arguments or options'); _help($client); } else { @@ -402,7 +407,7 @@ sub _lei_cfg ($;$) { open my $fh, '>>', $f or die "open($f): $!\n"; @st = stat($fh) or die "fstat($f): $!\n"; $cur_st = pack('dd', $st[10], $st[7]); - qerr($client, "I: $f created"); + qerr($client, "I: $f created") if $client->{cmd} ne 'config'; } my $cfg = PublicInbox::Config::git_config_dump($f); $cfg->{-st} = $cur_st; @@ -435,17 +440,10 @@ sub lei_mark { sub lei_config { my ($client, @argv) = @_; + $client->{opt}->{'config-file'} and return fail $client, + "config file switches not supported by `lei config'"; my $env = $client->{env}; - if (defined $env->{GIT_CONFIG}) { - my %copy = %$env; - delete $copy{GIT_CONFIG}; - $env = \%copy; - } - if (my @conflict = (grep(/\A-f=?\z/, @argv), - grep(/\A--(?:global|system| - file|config-file)=?\z/x, @argv))) { - return fail($client, "@conflict not supported by lei config"); - } + delete local $env->{GIT_CONFIG}; my $cfg = _lei_cfg($client, 1); my $cmd = [ qw(git config -f), $cfg->{'-f'}, @argv ]; my %rdr = map { $_ => $client->{$_} } (0..2); diff --git a/t/lei.t b/t/lei.t index 7ecadf7d..b0943962 100644 --- a/t/lei.t +++ b/t/lei.t @@ -22,8 +22,13 @@ 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 $home_trash = [ "$home/.local", "$home/.config" ]; +my $cleanup = sub { + rmtree([@$home_trash, @_]); + $out = $err = ''; +}; -my $test_lei_common = sub { +my $test_help = sub { ok(!$lei->([], undef, $opt), 'no args fails'); is($? >> 8, 1, '$? is 1'); is($out, '', 'nothing in stdout'); @@ -43,17 +48,17 @@ my $test_lei_common = sub { isnt($err, '', 'something in stderr'); is($out, '', 'nothing in stdout'); } +}; - # init tests - $out = $err = ''; - my $ok_err_info = sub { - my ($msg) = @_; - is(grep(!/^I:/, split(/^/, $err)), 0, $msg) or - diag "$msg: err=$err"; - $err = ''; - }; - my $home_trash = [ "$home/.local", "$home/.config" ]; - rmtree($home_trash); +my $ok_err_info = sub { + my ($msg) = @_; + is(grep(!/^I:/, split(/^/, $err)), 0, $msg) or + diag "$msg: err=$err"; + $err = ''; +}; + +my $test_init = sub { + $cleanup->(); ok($lei->(['init'], undef, $opt), 'init w/o args'); $ok_err_info->('after init w/o args'); ok($lei->(['init'], undef, $opt), 'idempotent init w/o args'); @@ -63,17 +68,15 @@ my $test_lei_common = sub { 'init conflict'); is(grep(/^E:/, split(/^/, $err)), 1, 'got error on conflict'); ok(!-e "$home/x", 'nothing created on conflict'); - rmtree($home_trash); + $cleanup->(); - $err = ''; ok($lei->(['init', "$home/x"], undef, $opt), 'init conflict resolved'); $ok_err_info->('init w/ arg'); ok($lei->(['init', "$home/x"], undef, $opt), 'init idempotent w/ path'); $ok_err_info->('init idempotent w/ arg'); ok(-d "$home/x", 'created dir'); - rmtree([ "$home/x", @$home_trash ]); + $cleanup->("$home/x"); - $err = ''; ok(!$lei->(['init', "$home/x", "$home/2" ], undef, $opt), 'too many args fails'); like($err, qr/too many/, 'noted excessive'); @@ -82,7 +85,26 @@ my $test_lei_common = sub { my $base = (split(m!/!, $d))[-1]; ok(!-d $d, "$base not created"); } - is($out, '', 'nothing in stdout'); + is($out, '', 'nothing in stdout on init failure'); +}; + +my $test_config = sub { + $cleanup->(); + ok($lei->([qw(config a.b c)], undef, $opt), 'config set var'); + is($out.$err, '', 'no output on var set'); + ok($lei->([qw(config -l)], undef, $opt), 'config -l'); + is($err, '', 'no errors on listing'); + is($out, "a.b=c\n", 'got expected output'); + ok(!$lei->([qw(config -f), "$home/.config/f", qw(x.y z)], undef, $opt), + 'config set var with -f fails'); + like($err, qr/not supported/, 'not supported noted'); + ok(!-f "$home/config/f", 'no file created'); +}; + +my $test_lei_common = sub { + $test_help->(); + $test_config->(); + $test_init->(); }; my $test_lei_oneshot = $ENV{TEST_LEI_ONESHOT};