diff --git a/gbp/patch_series.py b/gbp/patch_series.py index c70809d3..773fbadc 100644 --- a/gbp/patch_series.py +++ b/gbp/patch_series.py @@ -22,6 +22,9 @@ import tempfile from gbp.errors import GbpError +re_patch_paths = r'^(\-\-\-|\+\+\+)\s+(.+?)(\t|$)' +re_diff_git = r'^diff\s+\-\-git\s+(.+)\s+(.+)$' + class Patch(object): """ @@ -42,7 +45,10 @@ class Patch(object): def __init__(self, path, topic=None, strip=None): self.path = path self.topic = topic - self.strip = strip + if strip is None: + self.strip = self._guess_strip() + else: + self.strip = strip self.info = None self.long_desc = None @@ -136,6 +142,58 @@ def _get_info_field(self, key, get_val=None): else: return get_val() if get_val else None + def _guess_strip(self): + pairs = [] + strips = set() + pair = ['', ''] + + try: + patch_file = open(self.path, 'r') + except: + return None + + for line in patch_file: + line = line.strip() + match = re.match(re_diff_git, line) + if match: + pairs.append([match.group(1), match.group(2)]) + pair = ['', ''] + continue + match = re.match(re_patch_paths, line) + if match: + if pair[0]: + pair[1] = match.group(2) + pairs.append(pair) + else: + pair[0] = match.group(2) + continue + pair = ['', ''] + patch_file.close() + + for pair in pairs: + parts = map(lambda x: x.split('/'), pair) + if len(filter(lambda x: x[0] == '', parts)): + # It looks like one of the paths is absolute + # so can't guess the strip + continue + if len(set(map(lambda x: len(x), parts))) > 1: + # Paths have different number of parts, + # can't guess the strip + continue + strip = len(parts[0]) + for part in reversed(zip(*parts)): + if part[0] == part[1]: + strip -= 1 + else: + break + strips.add(strip) + + if len(strips): + # Not sure we should allow different strips in one file + return min(list(strips)) + else: + return None + @property def subject(self): """ diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py index 8e8d2c3a..89c7e35d 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -252,5 +252,22 @@ def test_filter_cmd(self): self.assertEquals(body, 'Foo') +class TestGuessPatchStrip(unittest.TestCase): + def test_strip1(self): + patch = gbp.patch_series.Patch(_patch_path('rpm/rpmbuild/SOURCES/my.patch')) + strip = patch._guess_strip() + self.assertEqual(strip, 0) + + def test_strip2(self): + patch = gbp.patch_series.Patch(_patch_path('rpm/rpmbuild/SOURCES/my2.patch')) + strip = patch._guess_strip() + self.assertEqual(strip, 1) + + def test_strip3(self): + patch = gbp.patch_series.Patch(_patch_path('rpm/rpmbuild/SOURCES/my3.patch')) + strip = patch._guess_strip() + self.assertEqual(strip, 1) + + def _patch_path(name): return os.path.join(context.projectdir, 'tests/data', name)