mq: smarter handling of plain headers
authorMads Kiilerich <madski@unity3d.com>
Fri, 28 Nov 2014 03:09:06 +0100
changeset 23442 a5c94ea3b8af
parent 23441 d289ba74dba3
child 23443 3b653c2fd6ba
mq: smarter handling of plain headers 6333412245ec and 5ccced6eab0b fixed issue4453 with a simple insertplainheader function that fixed the regression but didn't make the implementation more stable. Now we introduce plain header handling similar to how we handle hg patches. The whole header is scanned for fields to update while determining the best position for inserting the field if it is missing. It also makes sure there is an empty line between headers and body.
hgext/mq.py
tests/test-mq-header-date.t
--- a/hgext/mq.py	Sun Nov 30 23:30:31 2014 -0500
+++ b/hgext/mq.py	Fri Nov 28 03:09:06 2014 +0100
@@ -114,6 +114,12 @@
     '# Node ID ',
     '# Parent  ', # can occur twice for merges - but that is not relevant for mq
     ]
+# The order of headers in plain 'mail style' patches:
+PLAINHEADERS = {
+    'from': 0,
+    'date': 1,
+    'subject': 2,
+    }
 
 def inserthgheader(lines, header, value):
     """Assuming lines contains a HG patch header, add a header line with value.
@@ -156,9 +162,40 @@
     return lines
 
 def insertplainheader(lines, header, value):
-    if lines and lines[0] and ':' not in lines[0]:
-        lines.insert(0, '')
-    lines.insert(0, '%s: %s' % (header, value))
+    """For lines containing a plain patch header, add a header line with value.
+    >>> insertplainheader([], 'Date', 'z')
+    ['Date: z']
+    >>> insertplainheader([''], 'Date', 'z')
+    ['Date: z', '']
+    >>> insertplainheader(['x'], 'Date', 'z')
+    ['Date: z', '', 'x']
+    >>> insertplainheader(['From: y', 'x'], 'Date', 'z')
+    ['From: y', 'Date: z', '', 'x']
+    >>> insertplainheader([' date : x', ' from : y', ''], 'From', 'z')
+    [' date : x', 'From: z', '']
+    >>> insertplainheader(['', 'Date: y'], 'Date', 'z')
+    ['Date: z', '', 'Date: y']
+    >>> insertplainheader(['foo: bar', 'DATE: z', 'x'], 'From', 'y')
+    ['From: y', 'foo: bar', 'DATE: z', '', 'x']
+    """
+    newprio = PLAINHEADERS[header.lower()]
+    bestpos = len(lines)
+    for i, line in enumerate(lines):
+        if ':' in line:
+            lheader = line.split(':', 1)[0].strip().lower()
+            lprio = PLAINHEADERS.get(lheader, newprio + 1)
+            if lprio == newprio:
+                lines[i] = '%s: %s' % (header, value)
+                return lines
+            if lprio > newprio and i < bestpos:
+                bestpos = i
+        else:
+            if line:
+                lines.insert(i, '')
+            if i < bestpos:
+                bestpos = i
+            break
+    lines.insert(bestpos, '%s: %s' % (header, value))
     return lines
 
 class patchheader(object):
--- a/tests/test-mq-header-date.t	Sun Nov 30 23:30:31 2014 -0500
+++ b/tests/test-mq-header-date.t	Fri Nov 28 03:09:06 2014 +0100
@@ -412,8 +412,8 @@
   1: Three (again) - test
   0: [mq]: 1.patch - test
   ==== qref -d
+  From: jane
   Date: 12 0
-  From: jane
   
   diff -r ... 6
   --- /dev/null
@@ -465,8 +465,8 @@
   1: Three (again) - test
   0: [mq]: 1.patch - test
   ==== qref -u -d
+  From: john
   Date: 14 0
-  From: john
   
   diff -r ... 8
   --- /dev/null
@@ -495,8 +495,8 @@
   1: Three (again) - test
   0: [mq]: 1.patch - test
   ==== qref -u -d
+  From: john
   Date: 15 0
-  From: john
   
   Nine