Rev 6602: (richard-wilbur) Added keep_dirty kwarg to bzrlib.patches.parse_patches() in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

Patch Queue Manager pqm at pqm.ubuntu.com
Wed Dec 17 18:12:51 UTC 2014


At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 6602 [merge]
revision-id: pqm at pqm.ubuntu.com-20141217181250-ue0ku3dibz7vle02
parent: pqm at pqm.ubuntu.com-20141006163242-c2cll01cwc24grkk
parent: kit.randel at canonical.com-20141215202442-usf2ixhypqg8yh6q
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2014-12-17 18:12:50 +0000
message:
  (richard-wilbur) Added keep_dirty kwarg to bzrlib.patches.parse_patches()
   allowing preservation of dirty patch headers. (Bayard 'kit' Randel)
modified:
  bzrlib/patches.py              patches.py-20050727183609-378c1cc5972ce908
  bzrlib/tests/test_patches.py   test_patches.py-20051231203844-f4974d20f6aea09c
  doc/en/release-notes/bzr-2.7.txt bzr2.7.txt-20130727124539-wnx897hy9l2h9f7x-1
=== modified file 'bzrlib/patches.py'
--- a/bzrlib/patches.py	2011-12-18 15:28:38 +0000
+++ b/bzrlib/patches.py	2014-12-12 03:59:25 +0000
@@ -31,9 +31,10 @@
 
 binary_files_re = 'Binary files (.*) and (.*) differ\n'
 
+
 def get_patch_names(iter_lines):
+    line = iter_lines.next()
     try:
-        line = iter_lines.next()
         match = re.match(binary_files_re, line)
         if match is not None:
             raise BinaryFiles(match.group(1), match.group(2))
@@ -317,7 +318,6 @@
                 if isinstance(line, ContextLine):
                     pos += 1
 
-
 def parse_patch(iter_lines, allow_dirty=False):
     '''
     :arg iter_lines: iterable of lines to parse
@@ -336,7 +336,7 @@
         return patch
 
 
-def iter_file_patch(iter_lines, allow_dirty=False):
+def iter_file_patch(iter_lines, allow_dirty=False, keep_dirty=False):
     '''
     :arg iter_lines: iterable of lines to parse for patches
     :kwarg allow_dirty: If True, allow comments and other non-patch text
@@ -352,10 +352,15 @@
     # (as allow_dirty does).
     regex = re.compile(binary_files_re)
     saved_lines = []
+    dirty_head = []
     orig_range = 0
     beginning = True
+
     for line in iter_lines:
-        if line.startswith('=== ') or line.startswith('*** '):
+        if line.startswith('=== '):
+            dirty_head.append(line)
+            continue
+        if line.startswith('*** '):
             continue
         if line.startswith('#'):
             continue
@@ -369,14 +374,23 @@
                 # parse the patch
                 beginning = False
             elif len(saved_lines) > 0:
-                yield saved_lines
+                if keep_dirty and len(dirty_head) > 0:
+                    yield {'saved_lines': saved_lines,
+                           'dirty_head': dirty_head}
+                    dirty_head = []
+                else:
+                    yield saved_lines
             saved_lines = []
         elif line.startswith('@@'):
             hunk = hunk_from_header(line)
             orig_range = hunk.orig_range
         saved_lines.append(line)
     if len(saved_lines) > 0:
-        yield saved_lines
+        if keep_dirty and len(dirty_head) > 0:
+            yield {'saved_lines': saved_lines,
+                   'dirty_head': dirty_head}
+        else:
+            yield saved_lines
 
 
 def iter_lines_handle_nl(iter_lines):
@@ -400,15 +414,24 @@
         yield last_line
 
 
-def parse_patches(iter_lines, allow_dirty=False):
+def parse_patches(iter_lines, allow_dirty=False, keep_dirty=False):
     '''
     :arg iter_lines: iterable of lines to parse for patches
     :kwarg allow_dirty: If True, allow text that's not part of the patch at
         selected places.  This includes comments before and after a patch
         for instance.  Default False.
+    :kwarg keep_dirty: If True, returns a dict of patches with dirty headers.
+        Default False.
     '''
-    return [parse_patch(f.__iter__(), allow_dirty) for f in
-                        iter_file_patch(iter_lines, allow_dirty)]
+    patches = []
+    for patch_lines in iter_file_patch(iter_lines, allow_dirty, keep_dirty):
+        if 'dirty_head' in patch_lines:
+            patches.append({'patch': parse_patch(
+                patch_lines['saved_lines'], allow_dirty),
+                            'dirty_head': patch_lines['dirty_head']})
+        else:
+            patches.append(parse_patch(patch_lines, allow_dirty))
+    return patches
 
 
 def difference_index(atext, btext):

=== modified file 'bzrlib/tests/test_patches.py'
--- a/bzrlib/tests/test_patches.py	2010-05-20 18:23:17 +0000
+++ b/bzrlib/tests/test_patches.py	2014-12-12 03:59:25 +0000
@@ -58,10 +58,24 @@
         # https://bugs.launchpad.net/bzr/+bug/502076
         # https://code.launchpad.net/~toshio/bzr/allow-dirty-patches/+merge/18854
         lines = ["diff -pruN commands.py",
-            "--- orig/commands.py",
-            "+++ mod/dommands.py"]
+                 "--- orig/commands.py",
+                 "+++ mod/dommands.py"]
         bits = parse_patches(iter(lines), allow_dirty=True)
 
+    def test_preserve_dirty_head(self):
+        """Parse a patch containing a dirty header, and preserve lines"""
+        lines = ["=== added directory 'foo/bar'\n",
+                 "=== modified file 'orig/commands.py'\n",
+                 "--- orig/commands.py\n",
+                 "+++ mod/dommands.py\n"]
+        patches = parse_patches(
+            lines.__iter__(), allow_dirty=True, keep_dirty=True)
+        self.assertEqual(patches[0]['dirty_head'],
+                         ["=== added directory 'foo/bar'\n",
+                          "=== modified file 'orig/commands.py'\n"])
+        self.assertEqual(patches[0]['patch'].get_header().splitlines(True),
+                         ["--- orig/commands.py\n", "+++ mod/dommands.py\n"])
+
     def testValidPatchHeader(self):
         """Parse a valid patch header"""
         lines = "--- orig/commands.py\n+++ mod/dommands.py\n".split('\n')
@@ -78,7 +92,7 @@
     def testValidHunkHeader(self):
         """Parse a valid hunk header"""
         header = "@@ -34,11 +50,6 @@\n"
-        hunk = hunk_from_header(header);
+        hunk = hunk_from_header(header)
         self.assertEqual(hunk.orig_pos, 34)
         self.assertEqual(hunk.orig_range, 11)
         self.assertEqual(hunk.mod_pos, 50)
@@ -88,7 +102,7 @@
     def testValidHunkHeader2(self):
         """Parse a tricky, valid hunk header"""
         header = "@@ -1 +0,0 @@\n"
-        hunk = hunk_from_header(header);
+        hunk = hunk_from_header(header)
         self.assertEqual(hunk.orig_pos, 1)
         self.assertEqual(hunk.orig_range, 1)
         self.assertEqual(hunk.mod_pos, 0)
@@ -117,7 +131,7 @@
         self.makeMalformed("@@ -34,11 +50,6.5 @@\n")
         self.makeMalformed("@@ -34,11 +50,-6 @@\n")
 
-    def lineThing(self,text, type):
+    def lineThing(self, text, type):
         line = parse_line(text)
         self.assertIsInstance(line, type)
         self.assertEqual(str(line), text)
@@ -146,7 +160,7 @@
         i = difference_index(patchtext, pstr)
         if i is not None:
             print "%i: \"%s\" != \"%s\"" % (i, patchtext[i], pstr[i])
-        self.assertEqual (patchtext, str(patch))
+        self.assertEqual(patchtext, str(patch))
 
     def testAll(self):
         """Test parsing a whole patch"""
@@ -161,7 +175,7 @@
         self.assertContainsRe(patches[0].oldname, '^bar\t')
         self.assertContainsRe(patches[0].newname, '^qux\t')
         self.assertContainsRe(str(patches[0]),
-                                  'Binary files bar\t.* and qux\t.* differ\n')
+                              'Binary files bar\t.* and qux\t.* differ\n')
 
     def test_parse_binary_after_normal(self):
         patches = parse_patches(self.data_lines("binary-after-normal.patch"))
@@ -170,7 +184,7 @@
         self.assertContainsRe(patches[1].oldname, '^bar\t')
         self.assertContainsRe(patches[1].newname, '^qux\t')
         self.assertContainsRe(str(patches[1]),
-                                  'Binary files bar\t.* and qux\t.* differ\n')
+                              'Binary files bar\t.* and qux\t.* differ\n')
 
     def test_roundtrip_binary(self):
         patchtext = ''.join(self.data_lines("binary.patch"))
@@ -228,7 +242,6 @@
             mod_lines = list(self.datafile(mod))
 
             patched_file = IterableFile(iter_patched(orig_lines, patch))
-            lines = []
             count = 0
             for patch_line in patched_file:
                 self.assertEqual(patch_line, mod_lines[count])
@@ -239,7 +252,6 @@
         binary_lines = self.data_lines('binary.patch')
         e = self.assertRaises(BinaryFiles, iter_patched, [], binary_lines)
 
-
     def test_iter_patched_from_hunks(self):
         """Test a few patch files, and make sure they work."""
         files = [
@@ -256,7 +268,6 @@
             mod_lines = list(self.datafile(mod))
             iter_patched = iter_patched_from_hunks(orig_lines, parsed.hunks)
             patched_file = IterableFile(iter_patched)
-            lines = []
             count = 0
             for patch_line in patched_file:
                 self.assertEqual(patch_line, mod_lines[count])

=== modified file 'doc/en/release-notes/bzr-2.7.txt'
--- a/doc/en/release-notes/bzr-2.7.txt	2014-06-19 09:42:08 +0000
+++ b/doc/en/release-notes/bzr-2.7.txt	2014-12-15 20:24:42 +0000
@@ -26,6 +26,10 @@
 .. Improvements to existing commands, especially improved performance 
    or memory usage, or better results.
 
+* bzrlib.patches.parse_patches can optionally return a list of 'dirty'
+  patch headers (prefixed with '===').
+  (Kit Randel, #1400567)
+
 Bug Fixes
 *********
 




More information about the bazaar-commits mailing list