aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Ryabitsev <konstantin@linuxfoundation.org>2020-03-18 18:06:10 -0400
committerKonstantin Ryabitsev <konstantin@linuxfoundation.org>2020-03-18 18:06:10 -0400
commit8a0a359c76a25d74c3e2de6a350422ae9ca67798 (patch)
tree30b9f66dbb64f3eba2ffa7f3afb24f011d5c6b7b
parentbe9d8fa6de85e317facd0839e5a67f918f95f21a (diff)
downloadb4-8a0a359c76a25d74c3e2de6a350422ae9ca67798.tar.gz
Handle vN that only exists in the cover letter
There are special cases where we have: cover: [PATCH v3 00/NN] Foo \- [PATCH 01/NN] Patch 1 - [PATCH 02/NN] Patch 2 While the submitter *should* be setting "v3" in all patches, it's not uncommon to have that inferred from the cover letter. When cover letter is properly upthread from the patch that has an inferred v1 revision, we can check the revision on the cover letter and fix the patch revision to match. Reported-by: Mark Brown <broonie@kernel.org> Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
-rw-r--r--b4/__init__.py92
1 files changed, 54 insertions, 38 deletions
diff --git a/b4/__init__.py b/b4/__init__.py
index d4760d5..85b8298 100644
--- a/b4/__init__.py
+++ b/b4/__init__.py
@@ -19,7 +19,7 @@ from email import charset
charset.add_charset('utf-8', None)
emlpolicy = email.policy.EmailPolicy(utf8=True, cte_type='8bit', max_line_length=None)
-VERSION = '0.3.3'
+VERSION = '0.3.4-pre'
ATTESTATION_FORMAT_VER = '0.1'
logger = logging.getLogger('b4')
@@ -107,6 +107,7 @@ class LoreMailbox:
def __init__(self):
self.msgid_map = dict()
self.series = dict()
+ self.covers = dict()
self.followups = list()
self.unknowns = list()
@@ -149,8 +150,11 @@ class LoreMailbox:
logger.critical('All patches in series v%s are missing.', lser.revision)
return None
- # Do we have a cover letter for it?
- if not lser.has_cover:
+ # Grab our cover letter if we have one
+ if revision in self.covers.keys():
+ lser.add_patch(self.covers[revision])
+ lser.has_cover = True
+ else:
# Let's find the first patch with an in-reply-to and see if that
# is our cover letter
for member in lser.patches:
@@ -223,42 +227,58 @@ class LoreMailbox:
logger.debug('Looking at: %s', lmsg.full_subject)
self.msgid_map[lmsg.msgid] = lmsg
- if lmsg.has_diff or lmsg.has_diffstat:
- if lmsg.revision not in self.series:
- self.series[lmsg.revision] = LoreSeries(lmsg.revision, lmsg.expected)
- if len(self.series) > 1:
- logger.info('Found new series v%s', lmsg.revision)
- if lmsg.has_diff:
- # Attempt to auto-number series from the same author who did not bother
- # to set v2, v3, etc in the patch revision
- if (lmsg.counter == 1 and lmsg.counters_inferred
- and not lmsg.reply and lmsg.lsubject.patch and not lmsg.lsubject.resend):
- omsg = self.series[lmsg.revision].patches[lmsg.counter]
- if (omsg is not None and omsg.counters_inferred and lmsg.fromemail == omsg.fromemail
- and omsg.date < lmsg.date):
- lmsg.revision = len(self.series) + 1
- self.series[lmsg.revision] = LoreSeries(lmsg.revision, lmsg.expected)
- logger.info('Assuming new revision: v%s (%s)', lmsg.revision, lmsg.full_subject)
- logger.debug(' adding as patch')
- self.series[lmsg.revision].add_patch(lmsg)
- elif lmsg.counter == 0 and lmsg.has_diffstat:
- # Bona-fide cover letter
- logger.debug(' adding as cover letter')
- self.series[lmsg.revision].add_cover(lmsg)
- elif lmsg.reply:
- # We'll figure out where this belongs later
- logger.debug(' adding to followups')
- self.followups.append(lmsg)
- elif lmsg.reply:
+ if lmsg.counter == 0 and lmsg.has_diffstat:
+ # Cover letter
+ # Add it to covers -- we'll deal with them later
+ logger.debug(' adding as v%s cover letter', lmsg.revision)
+ self.covers[lmsg.revision] = lmsg
+ return
+
+ if lmsg.reply:
+ # We'll figure out where this belongs later
logger.debug(' adding to followups')
self.followups.append(lmsg)
- elif re.search(r'^Comment: att-fmt-ver:', lmsg.body, re.I | re.M):
+ return
+
+ if re.search(r'^Comment: att-fmt-ver:', lmsg.body, re.I | re.M):
logger.debug('Found attestation message')
LoreAttestationDocument.load_from_string(lmsg.msgid, lmsg.body)
# We don't keep it, because it's not useful for us beyond this point
- else:
- logger.debug(' adding to unknowns')
- self.unknowns.append(lmsg)
+ return
+
+ if lmsg.has_diff:
+ if lmsg.revision not in self.series:
+ if lmsg.revision_inferred and lmsg.in_reply_to:
+ # We have an inferred revision here.
+ # Do we have an upthread cover letter that specifies a revision?
+ irt = self.get_by_msgid(lmsg.in_reply_to)
+ if irt is not None and irt.has_diffstat and not irt.has_diff:
+ # Yes, this is very likely our cover letter
+ logger.debug(' fixed revision to v%s', irt.revision)
+ lmsg.revision = irt.revision
+
+ # Run our check again
+ if lmsg.revision not in self.series:
+ self.series[lmsg.revision] = LoreSeries(lmsg.revision, lmsg.expected)
+ if len(self.series) > 1:
+ logger.info('Found new series v%s', lmsg.revision)
+
+ # Attempt to auto-number series from the same author who did not bother
+ # to set v2, v3, etc in the patch revision
+ if (lmsg.counter == 1 and lmsg.counters_inferred
+ and not lmsg.reply and lmsg.lsubject.patch and not lmsg.lsubject.resend):
+ omsg = self.series[lmsg.revision].patches[lmsg.counter]
+ if (omsg is not None and omsg.counters_inferred and lmsg.fromemail == omsg.fromemail
+ and omsg.date < lmsg.date):
+ lmsg.revision = len(self.series) + 1
+ self.series[lmsg.revision] = LoreSeries(lmsg.revision, lmsg.expected)
+ logger.info('Assuming new revision: v%s (%s)', lmsg.revision, lmsg.full_subject)
+ logger.debug(' adding as patch')
+ self.series[lmsg.revision].add_patch(lmsg)
+ return
+
+ logger.debug(' adding to unknowns')
+ self.unknowns.append(lmsg)
class LoreSeries:
@@ -311,10 +331,6 @@ class LoreSeries:
self.patches[lmsg.counter] = lmsg
self.complete = not (None in self.patches[1:])
- def add_cover(self, lmsg):
- self.add_patch(lmsg)
- self.has_cover = True
-
def get_slug(self):
# Find the first non-None entry
lmsg = None