[PATCH RFC 4/6] send-email: --compose takes optional argument to existing file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Now, a user may specify an existing (in-progress) file to use as
the introductory/summary email.

The file is opened for any additional editing as usual.

Signed-off-by: Michael Witten <mfwitten@xxxxxxxxx>
---
 Documentation/git-send-email.txt |    7 ++-
 git-send-email.perl              |  112 ++++++++++++++++++++++----------------
 2 files changed, 71 insertions(+), 48 deletions(-)

diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 4b656ca..bc9ff13 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -57,8 +57,11 @@ The --cc option must be repeated for each user you want on the cc list.
 	or one for all of them at once.
 
 --compose::
-	Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
-	introductory message for the patch series.
+	Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR, or vi to edit an
+	introductory message for the patch series. An existing file may be
+	specified as the basis for the introductory email; it will be opened
+	for editing directly. Otherwise, a new temporary file is created with
+	some default contents.
 +
 When '--compose' is used, git send-email will use the From, Subject, and
 In-Reply-To headers specified in the message. If the body of the message
diff --git a/git-send-email.perl b/git-send-email.perl
index 098c620..481bf36 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -53,7 +53,7 @@ git send-email [options] <file | directory | rev-list options >
     --subject               <str>  * Email "Subject:"
     --in-reply-to           <str>  * Email "In-Reply-To:"
     --annotate                     * Review each patch that will be sent in an editor.
-    --compose                      * Open an editor for introduction.
+    --compose           opt <str>  * Open an editor for introduction.
 
   Sending:
     --delay                 <int>  * Delay (seconds) between sending emails.
@@ -62,7 +62,7 @@ git send-email [options] <file | directory | rev-list options >
                                      is optional. Default 'localhost'.
     --smtp-server-port      <int>  * Outgoing SMTP server port.
     --smtp-user             <str>  * Username for SMTP-AUTH.
-    --smtp-pass             <str>  * Password for SMTP-AUTH; not necessary.
+    --smtp-pass         opt <str>  * Password for SMTP-AUTH; not necessary.
     --smtp-encryption       <str>  * tls or ssl; anything else disables.
     --smtp-ssl                     * Deprecated. Use '--smtp-encryption ssl'.
 
@@ -159,7 +159,7 @@ if ($@) {
 # Behavior modification variables
 my ($quiet, $dry_run) = (0, 0);
 my $format_patch;
-my $compose_filename;
+my ($compose_filename, $compose_final_filename, $compose_final_is_not_empty);
 
 # Handle interactive edition of files.
 my $multiedit;
@@ -224,13 +224,12 @@ sub signal_handler {
 	system "stty echo";
 
 	# tmp files from --compose
-	if (defined $compose_filename) {
-		if (-e $compose_filename) {
-			print "'$compose_filename' contains an intermediate version of the email you were composing.\n";
-		}
-		if (-e ($compose_filename . ".final")) {
-			print "'$compose_filename.final' contains the composed email.\n"
-		}
+	if (defined $compose_filename and -f $compose_filename) {
+		print "'$compose_filename' contains an intermediate version of the email you were composing.\n";
+	}
+
+	if (defined $compose_final_filename and -f $compose_final_filename) {
+		print "'$compose_final_filename' contains the composed email.\n"
 	}
 
 	exit;
@@ -258,7 +257,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
 		    "smtp-encryption=s" => \$smtp_encryption,
 		    "identity=s" => \$identity,
 		    "annotate" => \$annotate,
-		    "compose" => \$compose,
+		    "compose:s" => \$compose,
 		    "quiet" => \$quiet,
 		    "cc-cmd=s" => \$cc_cmd,
 		    "suppress-from!" => \$suppress_from,
@@ -517,21 +516,36 @@ sub get_patch_subject($) {
 	die "'Subject:' line expected in '$patch'";
 }
 
-if ($compose) {
-	# Note that this does not need to be secure, but we will make a small
-	# effort to have it be unique
-	$compose_filename = ($repo ?
-		tempfile(".gitsendemail.msg.XXXXXX", DIR => $repo->repo_path()) :
-		tempfile(".gitsendemail.msg.XXXXXX", DIR => "."))[1];
-	open(C,">",$compose_filename)
-		or die "Failed to open for writing $compose_filename: $!";
+if (defined $compose) {
+
+	my ($tmp_file, $tmp_filename) = tempfile(".gitsendemail.msg.XXXXXX", DIR => ($repo ? $repo->repo_path() : "."));
 
+	my $compose_file;
+	my $compose_final_file;
+
+	if ($compose ne '') {
+
+		$compose_filename = $compose;
+
+		$compose_final_filename = $tmp_filename;
+		$compose_final_file     = $tmp_file
+
+	} else {
 
-	my $tpl_sender = $sender || $repoauthor || $repocommitter || '';
-	my $tpl_subject = $initial_subject || '';
-	my $tpl_reply_to = $initial_reply_to || '';
+		$compose_filename = $tmp_filename;
+		$compose_file     = $tmp_file;
 
-	print C <<EOT;
+		$compose_final_filename = "$compose_filename.final";
+		open $compose_final_file, ">", $compose_final_filename
+			or die "Failed to open '$compose_final_filename' for writing: $!";
+
+		# Help the user out with some instruction and initial headers:
+
+		my $tpl_sender = $sender || $repoauthor || $repocommitter || '';
+		my $tpl_subject = $initial_subject || '';
+		my $tpl_reply_to = $initial_reply_to || '';
+
+		print $compose_file <<EOT;
 From $tpl_sender # This line is ignored.
 GIT: Lines beginning in "GIT:" will be removed.
 GIT: Consider including an overall diffstat or table of contents
@@ -543,10 +557,10 @@ Subject: $tpl_subject
 In-Reply-To: $tpl_reply_to
 
 EOT
-	for my $f (@files) {
-		print C "GIT: ", get_patch_subject($f), "\n";
+		for my $f (@files) {
+			print $compose_file "GIT: ", get_patch_subject($f), "\n";
+		}
 	}
-	close(C);
 
 	my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
 
@@ -556,23 +570,28 @@ EOT
 		do_edit($compose_filename);
 	}
 
-	open(C2,">",$compose_filename . ".final")
-		or die "Failed to open $compose_filename.final : " . $!;
+	# Now transform the user-edited introduction into something
+	# suitable for sending via email; the user's editor may have
+	# unlinked the original file and replaced it with an entirely
+	# new one. If this be the case, then it wouldn't do just to
+	# seek to the beginning and start reading, because then only
+	# the original content would be retrieved. Consequently, the
+	# file must be reopened to be safe (note, the original
+	# filehandle is closed automatically).
 
-	open(C,"<",$compose_filename)
-		or die "Failed to open $compose_filename : " . $!;
+	open $compose_file, "<", $compose_filename
+		or die "Failed to open '$compose_filename' for reading: $!";
 
 	my $need_8bit_cte = file_has_nonascii($compose_filename);
 	my $in_body = 0;
-	my $summary_empty = 1;
-	while(<C>) {
+	while(<$compose_file>) {
 		next if m/^GIT:/;
-		if ($in_body) {
-			$summary_empty = 0 unless (/^\n$/);
+		if ($in_body && not /^\n$/) {
+			 $compose_final_is_not_empty = 1;
 		} elsif (/^\n$/) {
 			$in_body = 1;
 			if ($need_8bit_cte) {
-				print C2 "MIME-Version: 1.0\n",
+				print $compose_final_file "MIME-Version: 1.0\n",
 					 "Content-Type: text/plain; ",
 					   "charset=utf-8\n",
 					 "Content-Transfer-Encoding: 8bit\n";
@@ -597,15 +616,12 @@ EOT
 			print "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n";
 			next;
 		}
-		print C2 $_;
-	}
-	close(C);
-	close(C2);
 
-	if ($summary_empty) {
-		print "Summary email is empty, skipping it\n";
-		$compose = -1;
+		print $compose_final_file $_;
 	}
+
+	print "Summary email is empty, skipping it\n" unless ($compose_final_is_not_empty);
+
 } elsif ($annotate) {
 	do_edit(@files);
 }
@@ -685,9 +701,7 @@ if (!defined $smtp_server) {
 	$smtp_server ||= 'localhost'; # could be 127.0.0.1, too... *shrug*
 }
 
-if ($compose && $compose > 0) {
-	@files = ($compose_filename . ".final", @files);
-}
+unshift(@files, $compose_final_filename) if ($compose_final_is_not_empty);
 
 # Variables we set as part of the loop over files
 our ($message_id, %mail, $subject, $reply_to, $references, $message,
@@ -1153,7 +1167,13 @@ for (my $index = 0; $index < @files; $index++) {
 cleanup_compose_files();
 
 sub cleanup_compose_files() {
-	unlink($compose_filename, $compose_filename . ".final") if $compose;
+	if (defined $compose) {
+		unlink(
+			$compose_final_filename,
+			# Don't delete user-supplied file.
+			$compose ? () : $compose_filename
+		);
+	}
 }
 
 $smtp->quit if $smtp;
-- 
1.6.2.2.448.g61445.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]