summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/README.MAIL68
-rw-r--r--po/de.po51
-rw-r--r--po/fr.po40
-rw-r--r--po/ja.po40
-rw-r--r--po/quilt.pot38
-rw-r--r--quilt.changes14
-rw-r--r--quilt.quiltrc37
-rw-r--r--quilt/files.in4
-rw-r--r--quilt/mail.in205
-rw-r--r--test/mail.test85
10 files changed, 475 insertions, 107 deletions
diff --git a/doc/README.MAIL b/doc/README.MAIL
index 08df3fd..517a593 100644
--- a/doc/README.MAIL
+++ b/doc/README.MAIL
@@ -10,39 +10,52 @@ required. The template body is used only for the introduction.
In the template, the headers can be modified, additional headers added,
and unneeeded headers can be removed. The template header also contains
-a special Subject-Prefix header which defines a prefix to prefix each
-subject header with. The @num@ and @total@ macros in the Subject-Prefix
-header are replaced with the patch number and the total number of
-patches, respectively. The patch number @num@ is zero-padded to the
-same width that @total@ has.
+a special Subject-Prefix header which defines a prefix for each subject
+header. The @num@ and @total@ macros in the Subject-Prefix header are
+replaced with the patch number and the total number of patches,
+respectively. The patch number @num@ is zero-padded to the same width
+that @total@ has.
Each message is assigned a unique Message-Id header, and all messages
other than the introduction are made to refer to the introduction (using
a References header) for proper message threading in mail clients.
Patch filenames are stored in Content-Disposition headers so that mail
-clients know the original filename. The message timestamps in Date
-headers in each message is incremented one second per message starting
-from the timestamp of the introduction.
+clients will know the original filename. The message timestamps in Date
+headers in each message is incremented by one second per message, starting
+with the timestamp of the introduction.
If a ~/.signature file exists, this file is appended to each message
generated.
Recipients and headers can be added, and existing headers can be
replaced, individually in each message based on the headers in the
-introduction. Quilt does not enforce a specific patch file format.
-Instead, to customize the messages generated, a filter function called
-quilt_mail_patch_filter may be defined in .quiltrc, or
-/etc/quilt.quiltrc if no ~/.quiltrc exists. This function is passed the
-patch name as argument (without the $QUILT_PATCHES prefix). It shall
-read the patch from standard input, and write a RFC 2822 message header
-and the patch to standard output. Headers of the form ``Recipient-$X:
-...'' denote recipients to be added to the $X header (for example,
-``Recipient-Cc: agruen@suse.de''). Headers of the form ``Replace-$X:
-...'' specify that header $X is to be replaced by this header (for
-eaxmple, ``Replace-Subject: Patch description''). All other headers
-are appended to the existing headers.
-
-A quilt_mail_patch_filter example is found in the example quilt.quiltrc.
+introduction. Quilt does not enforce a specific patch file format. The
+mail command has a built-in heuristic for extracting subjects from
+patches, though:
+
+ * if The patch starts with something that looks like a mail
+ header, and there is a Subject header, use this as the subject,
+ or else
+
+ * if the patch has DESC a line followed by an EDESC line, use
+ the text in between as the subject, or else
+
+ * if the first paragraph is short enough to serve as a subject
+ (150 characters or less), use the first paragraph as the
+ subject.
+
+If no subject can be extracted from a patch, or there are duplicate
+subjects, the mail command will print an error message and abort.
+
+In case a patch header contains a line starting with `Cc:', `Acked-by:',
+or `Signed-off-by:', the email address specified is added to the
+CC header for this patch. If a patch header contains a line starting
+with `To:', the email address specified is added to To header for this
+patch.
+
+If the user specified in `To:', `Cc:', `Acked-by:', or `Signed-off-by:'
+equals the current user's name ($LOGNAME or $(whoami) if LOGNAME is
+undefined), this does not add a recipient.
Each recipient will occur in the resulting message only once. Duplicates
are filtered out. This happens as the headers are read, so the relative
@@ -54,3 +67,14 @@ characters must be quoted, and 8-bit characters must be encoded. In
practice it probably makes little sense to use anything fancy right now;
this area still needs some work. Character set recognition and proper
qualifying is also still missing.
+
+The heuristic can be overridden by defining a quilt_mail_patch_filter
+function in ~/.quiltrc or /etc/quilt.quiltrc. This function is passed
+the patch name as argument (without the $QUILT_PATCHES prefix). It
+shall read the patch from standard input, and write a RFC 2822 message
+header and the patch to standard output. Headers of the form
+``Recipient-$X: ...'' denote recipients to be added to the $X header
+(for example, ``Recipient-Cc: agruen@suse.de''). Headers of the form
+``Replace-$X: ...'' specify that header $X is to be replaced by this
+header (for eaxmple, ``Replace-Subject: Patch description''). All other
+headers are appended to the existing headers.
diff --git a/po/de.po b/po/de.po
index 05bcede..902fc73 100644
--- a/po/de.po
+++ b/po/de.po
@@ -357,6 +357,7 @@ msgid "Usage: quilt files [-v] [-a] [-l] [--combine patch] [patch]\\n"
msgstr "Verwendung: quilt files [-v] [-a] [-l] [--combine patch] [patch]\\n"
#: quilt/files.in:25
+#, fuzzy
msgid ""
"\n"
"Print the list of files that the topmost or specified patch changes.\n"
@@ -369,8 +370,8 @@ msgid ""
"\n"
"--combine patch\n"
"\tCreate a listing for all patches between this patch and\n"
-"\tthe topmost applied patch. A patch name of \\\"-\\\" is equivalent\n"
-"\tto specifying the first applied patch.\n"
+"\tthe topmost or specified patch. A patch name of \\\"-\\\" is\n"
+"\tequivalent to specifying the first applied patch.\n"
"\n"
msgstr ""
"\n"
@@ -715,8 +716,16 @@ msgid ""
"\n"
"Create mail messages from all patches in the series file, and either store\n"
"them in a mailbox file, or send them immediately. The editor is opened\n"
-"with a template for the introductory message. Please see the file\n"
-"%s for details.\n"
+"with a template for the introduction. Please see %s for details.\n"
+"\n"
+"-m text\n"
+"\tText to use as the text in the introduction. When this option is\n"
+"\tused, the editor will not be invoked, and the patches will be\n"
+"\tprocessed immediately.\n"
+"\n"
+"--prefix prefix\n"
+"\tUse an alternate prefix in the bracketed part of the subjects\n"
+"\tgenerated. Defaults to \\`patch'.\n"
"\n"
"--mbox file\n"
"\tStore all messages in the specified file in mbox format. The mbox\n"
@@ -739,10 +748,18 @@ msgstr ""
"\n"
"Erzeuge E-Mail-Nachrichten für alle Patches in der series-Datei, und\n"
"speichere sie in einer Mailbox-Datei, oder versende sie sofort. Der Editor\n"
-"wird mit der Vorlage einer Einleitungs-Nachricht geöffnet. Für Details "
-"siehe\n"
+"wird mit der Vorlage einer Einleitung geöffnet. Für Details siehe\n"
"%s.\n"
"\n"
+"-m text\n"
+"\tText, der für die Einleitung verwendet werden soll. Wenn\n"
+"\tdiese Option verwendet wird, wird der Editor nicht gestartet, und\n"
+"\tdie Patches werden sofort abgearbeitet.\n"
+"\n"
+"--prefix Prefix\n"
+"\tVerwende einen anderen Prefix als \\`patch' in dem eckig umklammerten\n"
+"\tText in der Subject-Kopfzeile.\n"
+"\n"
"--mbox datei\n"
"\tAlle Nachrichten in der angegebenen Datei im mbox-Format speichern. Die\n"
"\tMailbox kann dann später mit formail o.ä. verschickt werden.\n"
@@ -760,11 +777,31 @@ msgstr ""
"--to, --cc, --bcc\n"
"\tFüre einen Empfänger an die To, Cc, or Bcc-Kopfzeilen an.\n"
-#: quilt/mail.in:145
+#: quilt/mail.in:161
msgid "Could not determine the envelope sender address. Please use --sender."
msgstr ""
"Konnte die Envelope-Adresse nicht feststellen. Bitte verwenden Sie --sender."
+#: quilt/mail.in:294
+msgid "Unable to extract a subject header from %s\\n"
+msgstr "Konnte keine Subject-Kopfzeile aus %s extrahieren\\n"
+
+#: quilt/mail.in:307
+msgid "Patches %s have duplicate subject headers.\\n"
+msgstr "Die Patches %s haben die selben Subject-Kopfzeilen.\\n"
+
+#: quilt/mail.in:349
+msgid "Introduction has no subject header (saved as %s)\\n"
+msgstr "Die Einleitung hat keine Subject-Kopfzeile (gespeichert als %s)\\n"
+
+#: quilt/mail.in:352
+msgid "Introduction has no subject header\\n"
+msgstr "Die Einleitung hat keine Subject-Kopfzeile\\n"
+
+#: quilt/mail.in:439
+msgid "Introduction saved as %s\\n"
+msgstr "Einleitung gespeichert als %s\\n"
+
#: quilt/new.in:22
msgid "Usage: quilt new {patchname}\\n"
msgstr "Verwendung: new {patchname}\\n"
diff --git a/po/fr.po b/po/fr.po
index 198412a..6555ea4 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -359,6 +359,7 @@ msgid "Usage: quilt files [-v] [-a] [-l] [--combine patch] [patch]\\n"
msgstr "Usage : quilt files [-v] [-a] [-l] [--combine patch] [patch]\\n"
#: quilt/files.in:25
+#, fuzzy
msgid ""
"\n"
"Print the list of files that the topmost or specified patch changes.\n"
@@ -371,8 +372,8 @@ msgid ""
"\n"
"--combine patch\n"
"\tCreate a listing for all patches between this patch and\n"
-"\tthe topmost applied patch. A patch name of \\\"-\\\" is equivalent\n"
-"\tto specifying the first applied patch.\n"
+"\tthe topmost or specified patch. A patch name of \\\"-\\\" is\n"
+"\tequivalent to specifying the first applied patch.\n"
"\n"
msgstr ""
"\n"
@@ -714,12 +715,21 @@ msgstr ""
"to ...] [--cc ...] [--bcc ...] [--subject ...]\\n"
#: quilt/mail.in:27
+#, fuzzy
msgid ""
"\n"
"Create mail messages from all patches in the series file, and either store\n"
"them in a mailbox file, or send them immediately. The editor is opened\n"
-"with a template for the introductory message. Please see the file\n"
-"%s for details.\n"
+"with a template for the introduction. Please see %s for details.\n"
+"\n"
+"-m text\n"
+"\tText to use as the text in the introduction. When this option is\n"
+"\tused, the editor will not be invoked, and the patches will be\n"
+"\tprocessed immediately.\n"
+"\n"
+"--prefix prefix\n"
+"\tUse an alternate prefix in the bracketed part of the subjects\n"
+"\tgenerated. Defaults to \\`patch'.\n"
"\n"
"--mbox file\n"
"\tStore all messages in the specified file in mbox format. The mbox\n"
@@ -762,10 +772,30 @@ msgstr ""
"\tAjoute un destinataire dans le champ d'en-tte A, Copie ou Copie\n"
"\tcache, respectivement.\n"
-#: quilt/mail.in:145
+#: quilt/mail.in:161
msgid "Could not determine the envelope sender address. Please use --sender."
msgstr "Impossible de dterminer l'adresse d'expditeur. Utilisez --sender."
+#: quilt/mail.in:294
+msgid "Unable to extract a subject header from %s\\n"
+msgstr ""
+
+#: quilt/mail.in:307
+msgid "Patches %s have duplicate subject headers.\\n"
+msgstr ""
+
+#: quilt/mail.in:349
+msgid "Introduction has no subject header (saved as %s)\\n"
+msgstr ""
+
+#: quilt/mail.in:352
+msgid "Introduction has no subject header\\n"
+msgstr ""
+
+#: quilt/mail.in:439
+msgid "Introduction saved as %s\\n"
+msgstr ""
+
#: quilt/new.in:22
msgid "Usage: quilt new {patchname}\\n"
msgstr "Usage : quilt new {nom_de_patch}\\n"
diff --git a/po/ja.po b/po/ja.po
index 8adcc24..922ca74 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -347,6 +347,7 @@ msgid "Usage: quilt files [-v] [-a] [-l] [--combine patch] [patch]\\n"
msgstr "使い方: quilt files [-v] [-a] [-l] [--combine パッチ] [パッチ]\\n"
#: quilt/files.in:25
+#, fuzzy
msgid ""
"\n"
"Print the list of files that the topmost or specified patch changes.\n"
@@ -359,8 +360,8 @@ msgid ""
"\n"
"--combine patch\n"
"\tCreate a listing for all patches between this patch and\n"
-"\tthe topmost applied patch. A patch name of \\\"-\\\" is equivalent\n"
-"\tto specifying the first applied patch.\n"
+"\tthe topmost or specified patch. A patch name of \\\"-\\\" is\n"
+"\tequivalent to specifying the first applied patch.\n"
"\n"
msgstr ""
"\n"
@@ -689,12 +690,21 @@ msgstr ""
"to ...] [--cc ...] [--bcc ...] [--subject ...]\\n"
#: quilt/mail.in:27
+#, fuzzy
msgid ""
"\n"
"Create mail messages from all patches in the series file, and either store\n"
"them in a mailbox file, or send them immediately. The editor is opened\n"
-"with a template for the introductory message. Please see the file\n"
-"%s for details.\n"
+"with a template for the introduction. Please see %s for details.\n"
+"\n"
+"-m text\n"
+"\tText to use as the text in the introduction. When this option is\n"
+"\tused, the editor will not be invoked, and the patches will be\n"
+"\tprocessed immediately.\n"
+"\n"
+"--prefix prefix\n"
+"\tUse an alternate prefix in the bracketed part of the subjects\n"
+"\tgenerated. Defaults to \\`patch'.\n"
"\n"
"--mbox file\n"
"\tStore all messages in the specified file in mbox format. The mbox\n"
@@ -738,12 +748,32 @@ msgstr ""
"--to, --cc, --bcc\n"
"\tToやCC、BCCへの受信者の追加。\n"
-#: quilt/mail.in:145
+#: quilt/mail.in:161
msgid "Could not determine the envelope sender address. Please use --sender."
msgstr ""
"エンベロープの送信者アドレスを確定できませんでした。--senderオプション\n"
"を使用してください。"
+#: quilt/mail.in:294
+msgid "Unable to extract a subject header from %s\\n"
+msgstr ""
+
+#: quilt/mail.in:307
+msgid "Patches %s have duplicate subject headers.\\n"
+msgstr ""
+
+#: quilt/mail.in:349
+msgid "Introduction has no subject header (saved as %s)\\n"
+msgstr ""
+
+#: quilt/mail.in:352
+msgid "Introduction has no subject header\\n"
+msgstr ""
+
+#: quilt/mail.in:439
+msgid "Introduction saved as %s\\n"
+msgstr ""
+
#: quilt/new.in:22
msgid "Usage: quilt new {patchname}\\n"
msgstr "使い方: quilt new {パッチ名}\\n"
diff --git a/po/quilt.pot b/po/quilt.pot
index 0c47d2b..88841c3 100644
--- a/po/quilt.pot
+++ b/po/quilt.pot
@@ -256,8 +256,8 @@ msgid ""
"\n"
"--combine patch\n"
"\tCreate a listing for all patches between this patch and\n"
-"\tthe topmost applied patch. A patch name of \\\"-\\\" is equivalent\n"
-"\tto specifying the first applied patch.\n"
+"\tthe topmost or specified patch. A patch name of \\\"-\\\" is\n"
+"\tequivalent to specifying the first applied patch.\n"
"\n"
msgstr ""
@@ -482,8 +482,16 @@ msgid ""
"\n"
"Create mail messages from all patches in the series file, and either store\n"
"them in a mailbox file, or send them immediately. The editor is opened\n"
-"with a template for the introductory message. Please see the file\n"
-"%s for details.\n"
+"with a template for the introduction. Please see %s for details.\n"
+"\n"
+"-m text\n"
+"\tText to use as the text in the introduction. When this option is\n"
+"\tused, the editor will not be invoked, and the patches will be\n"
+"\tprocessed immediately.\n"
+"\n"
+"--prefix prefix\n"
+"\tUse an alternate prefix in the bracketed part of the subjects\n"
+"\tgenerated. Defaults to \\`patch'.\n"
"\n"
"--mbox file\n"
"\tStore all messages in the specified file in mbox format. The mbox\n"
@@ -504,10 +512,30 @@ msgid ""
"\tAppend a recipient to the To, Cc, or Bcc header.\n"
msgstr ""
-#: quilt/mail.in:145
+#: quilt/mail.in:161
msgid "Could not determine the envelope sender address. Please use --sender."
msgstr ""
+#: quilt/mail.in:294
+msgid "Unable to extract a subject header from %s\\n"
+msgstr ""
+
+#: quilt/mail.in:307
+msgid "Patches %s have duplicate subject headers.\\n"
+msgstr ""
+
+#: quilt/mail.in:349
+msgid "Introduction has no subject header (saved as %s)\\n"
+msgstr ""
+
+#: quilt/mail.in:352
+msgid "Introduction has no subject header\\n"
+msgstr ""
+
+#: quilt/mail.in:439
+msgid "Introduction saved as %s\\n"
+msgstr ""
+
#: quilt/new.in:22
msgid "Usage: quilt new {patchname}\\n"
msgstr ""
diff --git a/quilt.changes b/quilt.changes
index 9903857..b3cf870 100644
--- a/quilt.changes
+++ b/quilt.changes
@@ -1,4 +1,18 @@
-------------------------------------------------------------------
+Sun Jan 29 22:46:14 CET 2006 - agruen@suse.de
+
+- quilt/mail.in:
+ + Add -m and --prefix options so that the mail command can be
+ used without invoking an editor.
+ + Verify that each message generated will have a unique subject.
+ + Verify that the introduction has a subject header.
+ + Fix a bug in the heuristic for adding recipients.
+ + Add a heuristic for extracting subject headers
+ + Clarify some messages.
+ + Add a test case.
+ + Update the documentation.
+
+-------------------------------------------------------------------
Sun Jan 29 22:30:57 CET 2006 - agruen@suse.de
- Makefile.in: Add a missing dependency.
diff --git a/quilt.quiltrc b/quilt.quiltrc
index cc0a352..5855b88 100644
--- a/quilt.quiltrc
+++ b/quilt.quiltrc
@@ -21,40 +21,3 @@ QUILT_PATCHES_PREFIX=yes
# Use a specific editor for quilt (defaults to the value of $EDITOR before
# sourcing this configuration file, or vi if $EDITOR wasn't set).
#EDITOR=nedit
-
-# The following ``mail'' command filter recognizes the format we use for
-# kernel patches inside SUSE. The format is as follows (slightly
-# simplified; Signed-off-by and Acked-by lines optional):
-#
-# From: author@some.where
-# Subject: One-line summary
-#
-# Patch description
-#
-# Signed-off-by: reviewer@some.where
-# Acked-by: reviewer@some.where
-#
-# <<patch>>
-#
-# To enable, remove or comment out the lines above and below the function.
-
-: <<'EOF'
-quilt_mail_patch_filter() {
- local x=$(cat)
- # Replace subject with patch summary, add anybody in To or Cc
- # headers as recipients, and take all people in Signed-off-by
- # and Acked-by into the Cc (excluding myself).
- echo "$x" \
- | sed -n -e "/${LOGNAME:-$(whoami)}@$(hostname -d)/d" \
- -e 's/^\(To\|Cc\):/Recipient-\1:/ip' \
- -e 's/^\(Signed-off-by\|Acked-by\):/Recipient-Cc:/ip' \
- -e 's/^Subject:/Replace-Subject:/ip' \
- -e '/^\*\*\*\|---/q'
- echo
- # Discard the patch header, and pass on the rest
- echo "$x" | awk '
- in_body { print }
- /^$/ { in_body = 1 }
- '
-}
-EOF
diff --git a/quilt/files.in b/quilt/files.in
index 0374a29..df0d9db 100644
--- a/quilt/files.in
+++ b/quilt/files.in
@@ -33,8 +33,8 @@ Print the list of files that the topmost or specified patch changes.
--combine patch
Create a listing for all patches between this patch and
- the topmost applied patch. A patch name of \"-\" is equivalent
- to specifying the first applied patch.
+ the topmost or specified patch. A patch name of \"-\" is
+ equivalent to specifying the first applied patch.
"
exit 0
diff --git a/quilt/mail.in b/quilt/mail.in
index f6364bd..d2c231b 100644
--- a/quilt/mail.in
+++ b/quilt/mail.in
@@ -27,8 +27,16 @@ usage()
printf $"
Create mail messages from all patches in the series file, and either store
them in a mailbox file, or send them immediately. The editor is opened
-with a template for the introductory message. Please see the file
-%s for details.
+with a template for the introduction. Please see %s for details.
+
+-m text
+ Text to use as the text in the introduction. When this option is
+ used, the editor will not be invoked, and the patches will be
+ processed immediately.
+
+--prefix prefix
+ Use an alternate prefix in the bracketed part of the subjects
+ generated. Defaults to \`patch'.
--mbox file
Store all messages in the specified file in mbox format. The mbox
@@ -84,8 +92,9 @@ process_mail()
rm -f $tmpfile
}
-options=`getopt -o h --long from:,to:,cc:,bcc:,subject: \
- --long send,mbox:,charset:,sender: -- "$@"`
+options=`getopt -o m:h --long from:,to:,cc:,bcc:,subject: \
+ --long send,mbox:,charset:,sender: \
+ --long prefix: -- "$@"`
if [ $? -ne 0 ]
then
@@ -94,9 +103,13 @@ fi
eval set -- "$options"
+opt_prefix=patch
while true
do
case "$1" in
+ -m)
+ opt_message=$2
+ shift 2 ;;
--sender)
opt_sender=$2
shift 2 ;;
@@ -115,6 +128,9 @@ do
--subject)
opt_subject=$2
shift 2 ;;
+ --prefix)
+ opt_prefix=$2
+ shift 2 ;;
--send)
opt_send=1
shift ;;
@@ -162,15 +178,138 @@ fi
if [ "$(type -t quilt_mail_patch_filter 2> /dev/null)" != function ]; then
quilt_mail_patch_filter() {
- echo # We don't have a mail header
- cat
- # We could quote everything that looks like a mail
- # header instead:
- #sed -e $'s/^[\41-\176]\\+:/>&/'
+ local patch=$(cat)
+ local header=$(echo "$patch" | patch_header) body
+ local -a mh
+
+ # Does this patch have a Subject: line?
+ local subject=$(echo $(echo "$header" \
+ | sed -n -e '/^$/q' \
+ -e $'s/^Subject:[ \\t]//ip'))
+ if [ -n "$subject" ]
+ then
+ mh=( "Replace-Subject: $subject" )
+ body=$(echo "$patch" | awk '
+ in_body { print }
+ /^$/ { in_body = 1 }
+ ')
+ fi
+
+ # Does this patch have DESC // subject // EDESC?
+ if [ ${#mh[@]} -eq 0 ]
+ then
+ local desc=$(echo $(echo "$header" | awk '
+ /^EDESC\>/ { desc = 0 }
+ desc { print }
+ /^DESC\>/ { desc = 1 }
+ '))
+ if [ -n "$desc" ]
+ then
+ mh=( "Replace-Subject: $desc" )
+ body=$(echo "$patch" | awk '
+ /^DESC/ { desc = 1 }
+ ! desc { print }
+ /^EDESC/ { desc = 0 }
+ ')
+ fi
+ fi
+
+ # Does the first paragraph look like a mail header?
+ if [ ${#mh[@]} -eq 0 ]
+ then
+ if echo "$header" | awk '
+ /^$/ { exit (!mh || not_mh) }
+ END { exit (!mh || not_mh) }
+ { if ($0 ~ /^[a-z]+:[ \t]/i)
+ mh = 1
+ else
+ not_mh = 1
+ }'
+ then
+ return 1
+ fi
+ fi
+
+ # Is the first paragraph short enough to be used as the subject?
+ if [ ${#mh[@]} -eq 0 ]
+ then
+ local para=$(echo $(echo "$header" \
+ | sed -e $'/^[ \t]*$/q'))
+ if [ ${#para} > 0 -a ${#para} -lt 150 ]
+ then
+ mh=( "Replace-Subject: $para" )
+ body="$(echo "$patch" | awk '
+ in_body { print }
+ /^[ \t]*$/ { in_body = 1 }
+ ')"
+ fi
+ fi
+
+ #if ${#mh[@]} -eq 0 ]
+ #then
+ # # Use the patch name as the subject.
+ # mh=( "Replace-Subject: $1" )
+ # body=$patch
+ #fi
+
+ if [ ${#mh[@]} -eq 0 ]
+ then
+ return 1
+ fi
+
+ # Add recipients defined by some recognized keywords
+ local saved_IFS=$IFS; IFS=$'\n'
+ mh=( "${mh[@]}"
+ $(echo "$header" \
+ | sed -n -e "/\<${LOGNAME:-$(whoami)}@/d" \
+ -e 's/^\(To\|Cc\):/Recipient-\1:/ip' \
+ -e 's/^\(Signed-off-by\|Acked-by\):/Recipient-Cc:/ip') )
+ IFS=$saved_IFS
+
+ printf "%s\n" "${mh[@]}"
+ echo
+ echo "$body"
}
fi
-introduction=$(gen_tempfile)
+patches=( $(cat_series) )
+total=${#patches[@]}
+
+tmpdir=$(gen_tempfile -d)
+trap "rm -rf $tmpdir" EXIT
+
+for patch in "${patches[@]}"
+do
+ mkdir -p "$tmpdir/$(dirname "$patch")"
+ cat_file "$(patch_file_name "$patch")" \
+ | quilt_mail_patch_filter "$patch" > "$tmpdir/$patch"
+ status=${PIPESTATUS[1]}
+
+ subject=$(echo $(sed -n -e '/^$/q' \
+ -e $'s/^Replace-Subject:[ \t]*//ip' \
+ "$tmpdir/$patch"))
+ if [ $status -ne 0 -o -z "$subject" ]
+ then
+ printf \
+$"Unable to extract a subject header from %s\n" "$(print_patch "$patch")" >&2
+ rm -rf $tmpdir
+ exit 1
+ fi
+ subjects[${#subjects[@]}]="$patch"$'\t'"$subject"
+done
+
+dup_subjects=( $(
+ printf "%s\n" "${subjects[@]}" \
+ | sort -k2 \
+ | uniq -D -f1 \
+ | cut -f1) )
+if [ ${#dup_subjects[@]} -ne 0 ]; then
+ printf $"Patches %s have duplicate subject headers.\n" \
+ "$(set -- "${dup_subjects[*]/%/, }"; echo ${1%, })"
+ exit 1
+fi
+
+introduction="$(gen_tempfile)"
(
cat <<-EOF
Message-Id: <$(msgid)>
@@ -180,18 +319,40 @@ introduction=$(gen_tempfile)
To: $(IFS=,; echo "${opt_to[*]}")
Cc: $(IFS=,; echo "${opt_cc[*]}")
Bcc: $(IFS=,; echo "${opt_bcc[*]}")
- Subject-Prefix: [patch @num@/@total@]
+ Subject-Prefix: [$opt_prefix @num@/@total@]
Subject: $opt_subject
- --
EOF
+ if [ -n "$opt_message" ]
+ then
+ echo "$opt_message"
+ echo
+ fi
+ echo "--"
[ -r $HOME/.signature ] && cat $HOME/.signature
) | $QUILT_DIR/scripts/edmail --charset $opt_charset > $introduction
-$EDITOR $introduction || exit 1
+if [ -z "$opt_message" ]
+then
+ if ! $EDITOR $introduction; then
+ rm -f $introduction
+ exit 1
+ fi
+fi
-set -- $(cat_series)
-total=$#
+if [ -z "$(sed -n -e '/^$/q' \
+ -e $'s/^Subject:[ \t]*//ip' \
+ $introduction)" ]
+then
+ if [ -z "$opt_message" ]
+ then
+ printf $"Introduction has no subject header (saved as %s)\n" \
+ "$introduction" >&2
+ else
+ printf $"Introduction has no subject header\n"
+ fi
+ exit 1
+fi
if [ -n "$opt_mbox" ]; then
exec 1> $opt_mbox
@@ -222,8 +383,8 @@ fi
last_ts=$(date '+%s' -d "$(sed -ne $'s/^Date:[ \t]*//p' $introduction)")
num=1
-body=$(gen_tempfile)
-for patch in "$@"; do
+for patch in "${patches[@]}"; do
+ body=$tmpdir/$patch
#echo -n '.' >&2
# Timestamps that are a few seconds in the future don't hurt usually
#while [ $(date '+%s') -le $last_ts ]; do
@@ -232,8 +393,6 @@ for patch in "$@"; do
((last_ts++))
new_date="$(date --rfc-822 -d "1970/01/01 UTC $last_ts seconds")"
- cat_file $(patch_file_name $patch) \
- | quilt_mail_patch_filter $patch > $body
modify="$(awk '
sub(/^Recipient-/, "") { r = $0
sub(/:.*/, "", r)
@@ -245,7 +404,7 @@ for patch in "$@"; do
sub(/^Replace-/, "") { r = $0
sub(/:.*/, "", r)
s = $0
- sub(/^[^:]*:[ \t]*/, s)
+ sub(/^[^:]*:[ \t]*/, "", s)
gsub(/'\''/, "'\'\''", s)
print "--replace-header " r "='\''" s "'\''"
}
@@ -277,8 +436,7 @@ for patch in "$@"; do
| process_mail
if [ ${PIPESTATUS[1]} -ne 0 ]; then
- echo "Introductory message saved as $introduction" >&2
- rm -f $body
+ printf $"Introduction saved as %s\n" "$introduction" >&2
exit 1
fi
@@ -296,8 +454,7 @@ for patch in "$@"; do
((num++))
done
-rm -f $introduction $body
-#echo >&2
+rm -f $introduction
### Local Variables:
### mode: shell-script
### End:
diff --git a/test/mail.test b/test/mail.test
new file mode 100644
index 0000000..a8eaf6b
--- /dev/null
+++ b/test/mail.test
@@ -0,0 +1,85 @@
+ $ rm -rf d
+ $ mkdir -p d/patches
+ $ cd d
+
+ $ cat > no-subject
+ < Here goes a longer description of the patch, which is
+ < totally useless except as a test case for the quilt mail
+ < command. This paragraph is longer than 150 characters so
+ < that it won't be taken for a subject header itself.
+ <
+ < Index: anything
+
+ $ cat no-subject > patches/1.diff
+ $ ls patches/ > series
+ $ quilt mail --mbox mbox --prefix "test" --subject "This is a test" -m "Message"
+ > Unable to extract a subject header from patches/1.diff
+
+ $ cat /dev/stdin no-subject > patches/1.diff
+ < Subject: Subject of 1.diff
+ <
+ < Acked-by: Dummy <dummy@some.where>
+ <
+
+ $ quilt mail --mbox mbox --prefix "test" -m "Message"
+ > Introduction has no subject header
+
+ $ cat /dev/stdin no-subject > patches/2.diff
+ < DESC
+ < Subject of 2.diff
+ < is: split
+ < into multiple
+ < lines
+ < EDESC
+ <
+ < Signed-off-by: Dummy <dummy@some.where>
+ <
+
+ $ cat /dev/stdin no-subject > patches/3.diff
+ < Subject of 3.diff
+ <
+ < To: Dummy <dummy@some.where>
+ <
+
+ $ cat /dev/stdin no-subject > patches/4.diff
+ < First paragraph used as
+ < subject of 4.diff.
+ <
+ < Cc: Dummy <dummy@some.where>
+ <
+
+ $ cat /dev/stdin no-subject > patches/5.diff
+ < Subject of 1.diff
+ <
+
+ $ ls patches/ > series
+ $ quilt mail --mbox mbox --prefix "test" --subject "This is a test" -m "Message"
+ > Patches 1.diff, 5.diff have duplicate subject headers.
+
+ $ cat /dev/stdin no-subject > patches/5.diff
+ < Subject of 5.diff
+ <
+
+ $ quilt mail --mbox mbox --prefix "test" --subject "This is a test" -m "Message"
+ $ grep -e '^Subject:' -e '^To:' -e '^Cc:' -e '^--$' mbox
+ > Subject: [test 0/5] This is a test
+ > --
+ > Cc: Dummy <dummy@some.where>
+ > Subject: [test 1/5] Subject of 1.diff
+ > --
+ > Cc: Dummy <dummy@some.where>
+ > Subject: [test 2/5] Subject of 2.diff is: split into multiple lines
+ > --
+ > To: Dummy <dummy@some.where>
+ > Subject: [test 3/5] Subject of 3.diff
+ > To: Dummy <dummy@some.where>
+ > --
+ > Cc: Dummy <dummy@some.where>
+ > Subject: [test 4/5] First paragraph used as subject of 4.diff.
+ > Cc: Dummy <dummy@some.where>
+ > --
+ > Subject: [test 5/5] Subject of 5.diff
+ > --
+
+ $ cd ..
+ $ rm -rf d