def testParsePatches(self): """Make sure file names can be extracted from tricky unified diffs""" patchtext = \ b"""--- orig-7 +++ mod-7 @@ -1,10 +1,10 @@ -- a --- b +++ c xx d xx e ++ f -++ g +-- h xx i xx j -- k --- l +++ m --- orig-8 +++ mod-8 @@ -1 +1 @@ --- A +++ B @@ -1 +1 @@ --- C +++ D """ filenames = [(b'orig-7', b'mod-7'), (b'orig-8', b'mod-8')] patches = parse_patches(patchtext.splitlines(True)) patch_files = [] for patch in patches: patch_files.append((patch.oldname, patch.newname)) self.assertEqual(patch_files, filenames)
def test_parse_patches_leading_noise(self): # https://bugs.launchpad.net/bzr/+bug/502076 # https://code.launchpad.net/~toshio/bzr/allow-dirty-patches/+merge/18854 lines = [ b"diff -pruN commands.py", b"--- orig/commands.py", b"+++ mod/dommands.py" ] bits = list(parse_patches(iter(lines), allow_dirty=True))
def test_parse_binary_after_normal(self): patches = list( parse_patches(self.data_lines("binary-after-normal.patch"))) self.assertIs(BinaryPatch, patches[1].__class__) self.assertIs(Patch, patches[0].__class__) self.assertContainsRe(patches[1].oldname, b'^bar\t') self.assertContainsRe(patches[1].newname, b'^qux\t') self.assertContainsRe(patches[1].as_bytes(), b'Binary files bar\t.* and qux\t.* differ\n')
def test_parse_binary(self): """Test parsing a whole patch""" patches = list(parse_patches(self.data_lines("binary.patch"))) self.assertIs(BinaryPatch, patches[0].__class__) self.assertIs(Patch, patches[1].__class__) self.assertContainsRe(patches[0].oldname, b'^bar\t') self.assertContainsRe(patches[0].newname, b'^qux\t') self.assertContainsRe(patches[0].as_bytes(), b'Binary files bar\t.* and qux\t.* differ\n')
def read_quilt_patches(tree, directory=DEFAULT_DEBIAN_PATCHES_DIR): """Read patch contents from quilt directory. Args: tree: Tree to read directory: Patch directory Returns: list of Patch objects """ series_path = osutils.pathjoin(directory, "series") try: series_lines = tree.get_file_lines(series_path) except NoSuchFile: return [] for entry in read_quilt_series(series_lines): if entry.quoted: continue # TODO(jelmer): Pass on options? with tree.get_file(osutils.pathjoin(directory, entry.name)) as f: for patch in parse_patches(f, allow_dirty=True, keep_dirty=False): yield patch
def test_preserve_dirty_head(self): """Parse a patch containing a dirty header, and preserve lines""" lines = [ b"=== added directory 'foo/bar'\n", b"=== modified file 'orig/commands.py'\n", b"--- orig/commands.py\n", b"+++ mod/dommands.py\n", b"=== modified file 'orig/another.py'\n", b"--- orig/another.py\n", b"+++ mod/another.py\n" ] patches = list( parse_patches(lines.__iter__(), allow_dirty=True, keep_dirty=True)) self.assertLength(2, patches) self.assertEqual(patches[0]['dirty_head'], [ b"=== added directory 'foo/bar'\n", b"=== modified file 'orig/commands.py'\n" ]) self.assertEqual(patches[0]['patch'].get_header().splitlines(True), [b"--- orig/commands.py\n", b"+++ mod/dommands.py\n"]) self.assertEqual(patches[1]['dirty_head'], [b"=== modified file 'orig/another.py'\n"]) self.assertEqual(patches[1]['patch'].get_header().splitlines(True), [b"--- orig/another.py\n", b"+++ mod/another.py\n"])
def test_roundtrip_binary(self): patchtext = b''.join(self.data_lines("binary.patch")) patches = parse_patches(patchtext.splitlines(True)) self.assertEqual(patchtext, b''.join(p.as_bytes() for p in patches))