[PATCH 0/2] stgit, mail: addresses to send a full series

21 views
Skip to first unread message

Dan Williams

unread,
Mar 1, 2018, 2:28:35 PM3/1/18
to st...@googlegroups.com
[ resend after subscribing to st...@googlegroups.com ]

Recently, Dave reported:

"Dan, can you please stop sending random patches in a patch set
to random lists? Your patchsets are hitting 4 or 5 different
procmail filters here and so it gets split across several different
mailing list buckets. It's really annoying to have to go reconstruct
every patch set you send back into a single series in a single
bucket..."

This feedback is a result of, for example, adding 'Cc: linux-xfs@...' to
a patch in a series that concerns fs/xfs/, but neglecting to include
'--cc=linux-xfs@...' on the 'stg mail' invocation. In addition to
mailing lists there are also some individuals that want to receive the
series even if they are only explicitly Cc'd on a subset of the series.

---

Dan Williams (2):
Make 'extra_cc' a parameter to __send_message()
Support designating addresses to always receive a patch series


stgit/commands/mail.py | 63 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 44 insertions(+), 19 deletions(-)

Dan Williams

unread,
Mar 1, 2018, 2:28:41 PM3/1/18
to st...@googlegroups.com
In preparation for 'stg mail --auto' growing the capability to send all
patches in a series to a designated address, 'addressX', if any patch in
series has 'addressX' in the Cc:, make 'extra_cc' a parameter
__send_message().

Cc: Dave Chinner <da...@fromorbit.com>
Signed-off-by: Dan Williams <dan.j.w...@intel.com>
---
stgit/commands/mail.py | 45 ++++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 4a18dba1e4a8..e238bb6f397a 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -336,7 +336,7 @@ def __update_header(msg, header, addr = '', ignore = ()):
msg[header] = ', '.join(map(email.Utils.formataddr, addr_pairs))
return set(addr for _, addr in addr_pairs)

-def __build_address_headers(msg, options, extra_cc = []):
+def __build_address_headers(msg, options, extra_cc):
"""Build the address headers and check existing headers in the
template.
"""
@@ -459,7 +459,7 @@ def __edit_message(msg):

return msg

-def __build_cover(tmpl, msg_id, options, patches):
+def __build_cover(tmpl, msg_id, options, patches, extra_cc):
"""Build the cover message (series description) to be sent via SMTP
"""
sender = __get_sender()
@@ -531,16 +531,6 @@ def __build_cover(tmpl, msg_id, options, patches):
except Exception, ex:
raise CmdException, 'template parsing error: %s' % str(ex)

- extra_cc = []
- if options.auto:
- for patch in patches:
- p = crt_series.get_patch(patch)
- if p.get_description():
- descr = p.get_description().strip()
- extra_cc.extend(__get_signers_list(descr))
- extra_cc = list(set(extra_cc))
-
-
if not options.git:
__build_address_headers(msg, options, extra_cc)
__build_extra_headers(msg, msg_id, options.in_reply_to)
@@ -548,7 +538,8 @@ def __build_cover(tmpl, msg_id, options, patches):

return msg

-def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id):
+def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id,
+ extra_cc):
"""Build the message to be sent via SMTP
"""
p = crt_series.get_patch(patch)
@@ -656,13 +647,17 @@ def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id):
except Exception, ex:
raise CmdException, 'template parsing error: %s' % str(ex)

+ cc = []
+ # merge the series addresses with local signers
if options.auto:
- extra_cc = __get_signers_list(descr)
- else:
- extra_cc = []
+ cc = __get_signers_list(descr)
+ signer_addrs = [email.Utils.parseaddr(a)[1] for a in cc]
+ extra_addrs = [email.Utils.parseaddr(a)[1] for a in extra_cc]
+ extra_addrs = list(set(extra_addrs).difference(set(signer_addrs)))
+ cc.extend(extra_addrs)

if not options.git:
- __build_address_headers(msg, options, extra_cc)
+ __build_address_headers(msg, options, cc)
__build_extra_headers(msg, msg_id, ref_id)
__encode_message(msg)

@@ -706,6 +701,17 @@ def func(parser, options, args):
# get username/password if sending by SMTP
__set_smtp_credentials(options)

+ # generate unified cc list for cover letter and "series" designated
+ # addresses
+ extra_cc = []
+ if options.auto:
+ for patch in patches:
+ p = crt_series.get_patch(patch)
+ if p.get_description():
+ descr = p.get_description().strip()
+ extra_cc.extend(__get_signers_list(descr))
+ extra_cc = list(set(extra_cc))
+
# send the cover message (if any)
if options.cover or options.edit_cover:
if options.unrelated:
@@ -719,7 +725,7 @@ def func(parser, options, args):
if not tmpl:
raise CmdException, 'No cover message template file found'

- msg_id = __send_message('cover', tmpl, options, patches)
+ msg_id = __send_message('cover', tmpl, options, patches, extra_cc)

# subsequent e-mails are seen as replies to the first one
if not options.no_thread:
@@ -739,7 +745,8 @@ def func(parser, options, args):
raise CmdException, 'No e-mail template file found'

for (p, n) in zip(patches, range(1, total_nr + 1)):
- msg_id = __send_message('patch', tmpl, options, p, n, total_nr, ref_id)
+ msg_id = __send_message('patch', tmpl, options, p, n, total_nr,
+ ref_id, [])

# subsequent e-mails are seen as replies to the first one
if not options.no_thread and not options.unrelated and not ref_id:

Dan Williams

unread,
Mar 1, 2018, 2:28:46 PM3/1/18
to st...@googlegroups.com
Dave reports:

"Dan, can you please stop sending random patches in a patch set
to random lists? Your patchsets are hitting 4 or 5 different
procmail filters here and so it gets split across several different
mailing list buckets. It's really annoying to have to go reconstruct
every patch set you send back into a single series in a single
bucket..."

This a result of, for example, adding 'Cc: linux-xfs@...' to a patch in
a series that concerns fs/xfs/, but neglecting to include
'--cc=linux-xfs@...' on the 'stg mail' invocation. In addition to
mailing lists there are also some individuals that want to receive the
series even if they are only explicitly Cc'd on a subset of the series.

In order to balance not spamming folks that do not care about receiving
patches outside their area with individuals and lists that *do* want the
whole series whenever they appear in any Cc, add support for consulting
a '[mail "series"]' configuration section. The '[mail "series"]'
section includes addresses that will be added to all patches in a series
even if they are only explicitly Cc'd on a subset.

Reported-by: Dave Chinner <da...@fromorbit.com>
Reported-by: Christoph Hellwig <h...@infradead.org>
Signed-off-by: Dan Williams <dan.j.w...@intel.com>
---
stgit/commands/mail.py | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index e238bb6f397a..6c03f349bd0a 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -663,6 +663,20 @@ def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id,

return msg

+def __series_cc(extra_cc):
+ """From a union of all signers select the addresses that should be
+ cc'd on all patches in the series based on the 'addresses' variable
+ in the [mail "series"] configuration section.
+ """
+ series_addrs = config.get("mail.series.addresses")
+ if series_addrs:
+ series_addrs = series_addrs.split()
+ series_addrs = [ email.Utils.parseaddr(a)[1] for a in series_addrs ]
+ extra_addrs = [ email.Utils.parseaddr(a)[1] for a in extra_cc ]
+ cc = list(set(series_addrs).intersection(set(extra_addrs)))
+ return cc
+ return []
+
def func(parser, options, args):
"""Send the patches by e-mail using the patchmail.tmpl file as
a template
@@ -744,9 +758,13 @@ def func(parser, options, args):
if not tmpl:
raise CmdException, 'No e-mail template file found'

+ # identify "series" receivers to autocc
+ if options.auto:
+ extra_cc = __series_cc(extra_cc)
+
for (p, n) in zip(patches, range(1, total_nr + 1)):
msg_id = __send_message('patch', tmpl, options, p, n, total_nr,
- ref_id, [])
+ ref_id, extra_cc)

# subsequent e-mails are seen as replies to the first one

Dan Williams

unread,
Mar 1, 2018, 3:13:57 PM3/1/18
to catalin...@gmail.com, Dave Chinner, Christoph Hellwig, st...@googlegroups.com
Recently, Dave reported:

"Dan, can you please stop sending random patches in a patch set
to random lists? Your patchsets are hitting 4 or 5 different
procmail filters here and so it gets split across several different
mailing list buckets. It's really annoying to have to go reconstruct
every patch set you send back into a single series in a single
bucket..."

This feedback is a result of, for example, adding 'Cc: linux-xfs@...' to
a patch in a series that concerns fs/xfs/, but neglecting to include
'--cc=linux-xfs@...' on the 'stg mail' invocation. In addition to
mailing lists there are also some individuals that want to receive the
series even if they are only explicitly Cc'd on a subset of the series.

Dan Williams

unread,
Mar 1, 2018, 3:13:57 PM3/1/18
to catalin...@gmail.com, Dave Chinner, h...@infradead.org, st...@googlegroups.com
In preparation for 'stg mail --auto' growing the capability to send all
patches in a series to a designated address, 'addressX', if any patch in
series has 'addressX' in the Cc:, make 'extra_cc' a parameter
__send_message().

Cc: Dave Chinner <da...@fromorbit.com>
Signed-off-by: Dan Williams <dan.j.w...@intel.com>
---
stgit/commands/mail.py | 45 ++++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 4a18dba1e4a8..e238bb6f397a 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
+ signer_addrs = [email.Utils.parseaddr(a)[1] for a in cc]
+ extra_addrs = [email.Utils.parseaddr(a)[1] for a in extra_cc]
+ extra_addrs = list(set(extra_addrs).difference(set(signer_addrs)))
+ cc.extend(extra_addrs)

if not options.git:
- __build_address_headers(msg, options, extra_cc)
+ __build_address_headers(msg, options, cc)
__build_extra_headers(msg, msg_id, ref_id)
__encode_message(msg)

@@ -706,6 +701,17 @@ def func(parser, options, args):
# get username/password if sending by SMTP
__set_smtp_credentials(options)

+ # generate unified cc list for cover letter and "series" designated
+ # addresses
+ extra_cc = []
+ if options.auto:
+ for patch in patches:
+ p = crt_series.get_patch(patch)
+ if p.get_description():
+ descr = p.get_description().strip()
+ extra_cc.extend(__get_signers_list(descr))
+ extra_cc = list(set(extra_cc))
+
# send the cover message (if any)
if options.cover or options.edit_cover:
if options.unrelated:
@@ -719,7 +725,7 @@ def func(parser, options, args):
if not tmpl:
raise CmdException, 'No cover message template file found'

- msg_id = __send_message('cover', tmpl, options, patches)
+ msg_id = __send_message('cover', tmpl, options, patches, extra_cc)

# subsequent e-mails are seen as replies to the first one
if not options.no_thread:
@@ -739,7 +745,8 @@ def func(parser, options, args):
raise CmdException, 'No e-mail template file found'

for (p, n) in zip(patches, range(1, total_nr + 1)):
- msg_id = __send_message('patch', tmpl, options, p, n, total_nr, ref_id)
+ msg_id = __send_message('patch', tmpl, options, p, n, total_nr,
+ ref_id, [])

Dan Williams

unread,
Mar 1, 2018, 3:13:57 PM3/1/18
to catalin...@gmail.com, Dave Chinner, Christoph Hellwig, st...@googlegroups.com
Dave reports:

"Dan, can you please stop sending random patches in a patch set
to random lists? Your patchsets are hitting 4 or 5 different
procmail filters here and so it gets split across several different
mailing list buckets. It's really annoying to have to go reconstruct
every patch set you send back into a single series in a single
bucket..."

This a result of, for example, adding 'Cc: linux-xfs@...' to a patch in
a series that concerns fs/xfs/, but neglecting to include
'--cc=linux-xfs@...' on the 'stg mail' invocation. In addition to
mailing lists there are also some individuals that want to receive the
series even if they are only explicitly Cc'd on a subset of the series.

In order to balance not spamming folks that do not care about receiving
patches outside their area with individuals and lists that *do* want the
whole series whenever they appear in any Cc, add support for consulting
a '[mail "series"]' configuration section. The '[mail "series"]'
section includes addresses that will be added to all patches in a series
even if they are only explicitly Cc'd on a subset.

Reported-by: Dave Chinner <da...@fromorbit.com>
Reported-by: Christoph Hellwig <h...@infradead.org>
Signed-off-by: Dan Williams <dan.j.w...@intel.com>
---
stgit/commands/mail.py | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index e238bb6f397a..6c03f349bd0a 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -663,6 +663,20 @@ def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id,

return msg

+def __series_cc(extra_cc):
+ """From a union of all signers select the addresses that should be
+ cc'd on all patches in the series based on the 'addresses' variable
+ in the [mail "series"] configuration section.
+ """
+ series_addrs = config.get("mail.series.addresses")
+ if series_addrs:
+ series_addrs = series_addrs.split()
+ series_addrs = [ email.Utils.parseaddr(a)[1] for a in series_addrs ]
+ extra_addrs = [ email.Utils.parseaddr(a)[1] for a in extra_cc ]
+ cc = list(set(series_addrs).intersection(set(extra_addrs)))
+ return cc
+ return []
+
def func(parser, options, args):
"""Send the patches by e-mail using the patchmail.tmpl file as
a template
@@ -744,9 +758,13 @@ def func(parser, options, args):
if not tmpl:
raise CmdException, 'No e-mail template file found'

+ # identify "series" receivers to autocc
+ if options.auto:
+ extra_cc = __series_cc(extra_cc)
+
for (p, n) in zip(patches, range(1, total_nr + 1)):
msg_id = __send_message('patch', tmpl, options, p, n, total_nr,
- ref_id, [])
+ ref_id, extra_cc)

# subsequent e-mails are seen as replies to the first one

Christoph Hellwig

unread,
Mar 2, 2018, 2:11:30 AM3/2/18
to Dan Williams, catalin...@gmail.com, Dave Chinner, Christoph Hellwig, st...@googlegroups.com
I'm not a stgit user, but here is the script I use for sending mail as
in:

# sh ~/bin/patchbomb.sh lazytime.txt HEAD^^..HEAD

where latzytime.txt is the coverletetter including the To and CC lists
in normal email format:

---- snip ----
#!/bin/sh

COVERLETTER=$1
PATCHES=$2

git send-email --to-cover --cc-cover $1 $2

Reply all
Reply to author
Forward
0 new messages