public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
From: Jim Cromie <jim.cromie@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, Jim Cromie <jim.cromie@gmail.com>,
	Gemini CLI <gemini-cli@google.com>
Subject: [PATCH 1/1] git-send-email.perl: support executable scripts for recipient options
Date: Thu, 19 Mar 2026 09:51:48 -0600	[thread overview]
Message-ID: <20260319155148.1145135-1-jim.cromie@gmail.com> (raw)

Enhance git-send-email to recognize executable scripts passed to --to,
--cc, or --bcc. When a recipient argument is an executable file, run it
in a subshell and use its output as the recipient list.

This allows users to automate recipient selection using scripts like
get_maintainer.pl in the Linux kernel. The script is called with the
corresponding flag (--to, --cc, or --bcc) and all remaining command-line
arguments (typically the patches being sent).

Modify execute_cmd() to support multiple arguments safely using
quotemeta. Add test cases to verify the new functionality and ensure
arguments are correctly passed to the scripts.

Co-developed-by: Gemini CLI <gemini-cli@google.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 git-send-email.perl   | 11 +++++++++--
 t/t9001-send-email.sh | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/git-send-email.perl b/git-send-email.perl
index bb8ddd1eef..2d54d98304 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -579,8 +579,11 @@ sub config_regexp {
 
 # Munge any "either config or getopt, not both" variables
 my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);
+@initial_to = map { (-x $_) ? execute_cmd("to-script", $_, "--to", @ARGV) : $_ } @initial_to;
 my @initial_cc = @getopt_cc ? @getopt_cc : ($no_cc ? () : @config_cc);
+@initial_cc = map { (-x $_) ? execute_cmd("cc-script", $_, "--cc", @ARGV) : $_ } @initial_cc;
 my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);
+@initial_bcc = map { (-x $_) ? execute_cmd("bcc-script", $_, "--bcc", @ARGV) : $_ } @initial_bcc;
 
 usage() if $help;
 my %all_options = (%options, %dump_aliases_options, %identity_options);
@@ -2222,10 +2225,14 @@ sub initialize_modified_loop_vars {
 # lines which do not appear at the end of the output are reported as
 # errors.
 sub execute_cmd {
-	my ($prefix, $cmd, $file) = @_;
+	my ($prefix, $cmd, @args) = @_;
 	my @lines = ();
 	my $seen_blank_line = 0;
-	open my $fh, "-|", "$cmd \Q$file\E"
+	my $full_cmd = $cmd;
+	for my $arg (@args) {
+		$full_cmd .= " " . quotemeta($arg);
+	}
+	open my $fh, "-|", $full_cmd
 		or die sprintf(__("(%s) Could not execute '%s'"), $prefix, $cmd);
 	while (my $line = <$fh>) {
 		die sprintf(__("(%s) Malformed output from '%s'"), $prefix, $cmd)
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 24f6c76aee..fed75c7669 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -2842,4 +2842,46 @@ test_expect_success $PREREQ '--compose handles to headers' '
 	test_cmp expect msgtxt2.to
 '
 
+test_expect_success $PREREQ '--cc=$script' '
+	git init repo &&
+	(
+		cd repo &&
+		test_commit commit &&
+		patches=$(git format-patch -1 HEAD) &&
+		write_script cc-script <<-\EOT &&
+		echo "cc-script@example.com"
+		EOT
+		PERL5LIB="$GIT_BUILD_DIR/perl" "$GIT_BUILD_DIR/git-send-email.perl" \
+			--from="Example <from@example.com>" \
+			--to=nobody@example.com \
+			--cc=./cc-script \
+			--smtp-server="$(pwd)/../fake.sendmail" \
+			--confirm=never \
+			--dry-run \
+			$patches >stdout 2>&1 &&
+		grep "^Cc: cc-script@example\.com" stdout
+	)
+'
+
+test_expect_success $PREREQ '--cc=$script with arguments' '
+	git init repo-args &&
+	(
+		cd repo-args &&
+		test_commit commit &&
+		patches=$(git format-patch -1 HEAD) &&
+		write_script cc-script-args <<-\EOT &&
+		echo "script-args-$2@example.com"
+		EOT
+		PERL5LIB="$GIT_BUILD_DIR/perl" "$GIT_BUILD_DIR/git-send-email.perl" \
+			--from="Example <from@example.com>" \
+			--to=nobody@example.com \
+			--cc=./cc-script-args \
+			--smtp-server="$(pwd)/../fake.sendmail" \
+			--confirm=never \
+			--dry-run \
+			$patches >stdout 2>&1 &&
+		grep "^Cc: script-args-0001-commit\.patch@example\.com" stdout
+	)
+'
+
 test_done
-- 
2.53.0


             reply	other threads:[~2026-03-19 15:52 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-19 15:51 Jim Cromie [this message]
2026-03-19 16:05 ` [PATCH 1/1] git-send-email.perl: support executable scripts for recipient options Kristoffer Haugsbakk
2026-03-19 16:47   ` D. Ben Knoble
2026-03-20  1:35     ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260319155148.1145135-1-jim.cromie@gmail.com \
    --to=jim.cromie@gmail.com \
    --cc=gemini-cli@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox