aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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