diff mbox series

[v6,2/3] send-email: programmatically generate bash completions

Message ID 20211007033652.80793-3-tbperrotta@gmail.com (mailing list archive)
State New, archived
Headers show
Series [v6,1/3] send-email: terminate --git-completion-helper with LF | expand

Commit Message

Thiago Perrotta Oct. 7, 2021, 3:36 a.m. UTC
"git send-email --git-completion-helper" only prints "format-patch"
flags. Make it print "send-email" flags as well, generating them
programmatically from the usage.

Extract flags from the three existing `GetOptions`.

Introduce a uniq subroutine, otherwise --cc-cover, --to-cover and other
flags would show up twice.

Remove two extraneous flags: --h and --git-completion-helper.

Add a completion test for "send-email --validate", a send-email flag.

Signed-off-by: Thiago Perrotta <tbperrotta@gmail.com>
Based-on-patch-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 contrib/completion/git-completion.bash | 11 +------
 git-send-email.perl                    | 43 +++++++++++++++++++-------
 t/t9902-completion.sh                  |  3 ++
 3 files changed, 36 insertions(+), 21 deletions(-)

Comments

Carlo Marcelo Arenas Belón Oct. 9, 2021, 6:38 a.m. UTC | #1
On Wed, Oct 06, 2021 at 11:36:51PM -0400, Thiago Perrotta wrote:
> diff --git a/git-send-email.perl b/git-send-email.perl
> index d1731c1755..465e9867b9 100755
> --- a/git-send-email.perl
> +++ b/git-send-email.perl
> @@ -40,7 +40,7 @@ package main;
>  
>  sub usage {
>  	print <<EOT;
> -git send-email [options] <file | directory | rev-list options >
> +git send-email [options] <file | directory | rev-list options>

this change isn't really needed now that you are not using the usage()
to get the options, and should probably go into an independent patch,
or even better, as part of patch 3 so it is consistent.

> @@ -113,8 +113,23 @@ sub usage {
>  	exit(1);
>  }
>  
> +sub uniq {
> +    my %seen;
> +    grep !$seen{$_}++, @_;
> +}

indentation in this file is a little odd, but will be better if you use the
most common one (tab), instead of your own version here (4 or 2 spaces) and
in the rest of the code.

>  sub completion_helper {
> -    print Git::command('format-patch', '--git-completion-helper'), "\n";
> +    my ($options) = @_;
> +    my @send_email_opts = map {
> +      "--$_"
> +    } map {
> +      s/(?:[:=][si]|!)$//;
> +      split /\|/, $_;
> +    } keys %$options;
> +    my @format_patch_opts = Git::command('format-patch', '--git-completion-helper');
> +    my @options = uniq @send_email_opts, @format_patch_opts;

reusing "options" here makes this code more confusing than it needs to be
maybe something like :

diff --git a/git-send-email.perl b/git-send-email.perl
index a1338dd774..d47543bc0d 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -119,13 +119,13 @@ sub uniq {
 }

 sub completion_helper {
-    my ($options) = @_;
+    my ($original_opts) = @_;
     my @send_email_opts = map {
       "--$_"
     } map {
       s/(?:[:=][si]|!)$//;
-      split /\|/, $_;
-    } keys %$options;
+      split /\|/;
+    } keys %$original_opts;
     my @format_patch_opts = Git::command('format-patch', '--git-completion-helper');
     my @options = uniq @send_email_opts, @format_patch_opts;
     @options = grep !/--git-completion-helper|--h/, @options;

might help on top

Carlo
diff mbox series

Patch

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 4bdd27ddc8..1b73a4dcc0 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2359,16 +2359,7 @@  _git_send_email ()
 		return
 		;;
 	--*)
-		__gitcomp_builtin send-email "--annotate --bcc --cc --cc-cmd --chain-reply-to
-			--compose --confirm= --dry-run --envelope-sender
-			--from --identity
-			--in-reply-to --no-chain-reply-to --no-signed-off-by-cc
-			--no-suppress-from --no-thread --quiet --reply-to
-			--signed-off-by-cc --smtp-pass --smtp-server
-			--smtp-server-port --smtp-encryption= --smtp-user
-			--subject --suppress-cc= --suppress-from --thread --to
-			--validate --no-validate
-			$__git_format_patch_extra_options"
+		__gitcomp_builtin send-email "$__git_format_patch_extra_options"
 		return
 		;;
 	esac
diff --git a/git-send-email.perl b/git-send-email.perl
index d1731c1755..465e9867b9 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -40,7 +40,7 @@  package main;
 
 sub usage {
 	print <<EOT;
-git send-email [options] <file | directory | rev-list options >
+git send-email [options] <file | directory | rev-list options>
 git send-email --dump-aliases
 
   Composing:
@@ -113,8 +113,23 @@  sub usage {
 	exit(1);
 }
 
+sub uniq {
+    my %seen;
+    grep !$seen{$_}++, @_;
+}
+
 sub completion_helper {
-    print Git::command('format-patch', '--git-completion-helper'), "\n";
+    my ($options) = @_;
+    my @send_email_opts = map {
+      "--$_"
+    } map {
+      s/(?:[:=][si]|!)$//;
+      split /\|/, $_;
+    } keys %$options;
+    my @format_patch_opts = Git::command('format-patch', '--git-completion-helper');
+    my @options = uniq @send_email_opts, @format_patch_opts;
+    @options = grep !/--git-completion-helper|--h/, @options;
+    print "@options\n";
     exit(0);
 }
 
@@ -425,10 +440,11 @@  sub config_regexp {
 	my $key = "sendemail.identity";
 	$identity = Git::config(@repo, $key) if exists $known_config_keys{$key};
 }
-my $rc = GetOptions(
-	"identity=s" => \$identity,
-	"no-identity" => \$no_identity,
+my %identity_options = (
+  "identity=s" => \$identity,
+  "no-identity" => \$no_identity,
 );
+my $rc = GetOptions(%identity_options);
 usage() unless $rc;
 undef $identity if $no_identity;
 
@@ -444,14 +460,17 @@  sub config_regexp {
 
 my $help;
 my $git_completion_helper;
-$rc = GetOptions("h" => \$help,
-                 "dump-aliases" => \$dump_aliases);
+my %dump_aliases_options = (
+  "h" => \$help,
+  "dump-aliases" => \$dump_aliases,
+);
+$rc = GetOptions(%dump_aliases_options);
 usage() unless $rc;
 die __("--dump-aliases incompatible with other options\n")
     if !$help and $dump_aliases and @ARGV;
-$rc = GetOptions(
+my %options = (
 		    "sender|from=s" => \$sender,
-                    "in-reply-to=s" => \$initial_in_reply_to,
+		    "in-reply-to=s" => \$initial_in_reply_to,
 		    "reply-to=s" => \$reply_to,
 		    "subject=s" => \$initial_subject,
 		    "to=s" => \@getopt_to,
@@ -508,7 +527,8 @@  sub config_regexp {
 		    "batch-size=i" => \$batch_size,
 		    "relogin-delay=i" => \$relogin_delay,
 		    "git-completion-helper" => \$git_completion_helper,
-	 );
+);
+$rc = GetOptions(%options);
 
 # Munge any "either config or getopt, not both" variables
 my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);
@@ -516,7 +536,8 @@  sub config_regexp {
 my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);
 
 usage() if $help;
-completion_helper() if $git_completion_helper;
+my %all_options = (%options, %dump_aliases_options, %identity_options);
+completion_helper(\%all_options) if $git_completion_helper;
 unless ($rc) {
     usage();
 }
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 11573936d5..a4faf64184 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2139,6 +2139,9 @@  test_expect_success PERL 'send-email' '
 	--cover-from-description=Z
 	--cover-letter Z
 	EOF
+	test_completion "git send-email --val" <<-\EOF &&
+	--validate Z
+	EOF
 	test_completion "git send-email ma" "main "
 '