From 8365ac870abecb34e1adbb6ebbf2052dfb2cb340 Mon Sep 17 00:00:00 2001 From: Dmitry Teselkin Date: Thu, 14 Apr 2016 15:44:24 +0300 Subject: [PATCH 1/3] Guess strip for patch from patch itself Some RPM spec files use non-standart way of applying patches: they don't use %patch macro but call 'patch' directly from inlined script or use 'git apply'. In such cases gbp can't detect patch strip value and fails. This patch adds a bit of logic to guess patch strip value from patch itself is possible. --- gbp/patch_series.py | 59 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/gbp/patch_series.py b/gbp/patch_series.py index c70809d3..32e01fe5 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: + self.strip = strip + else: + self.strip = self._guess_strip() self.info = None self.long_desc = None @@ -136,6 +142,57 @@ 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: + match = re.match(re_diff_git, line.strip()) + if match: + pairs.append([match.group(1), match.group(2)]) + pair = ['', ''] + continue + match = re.match(re_patch_paths, line.strip()) + 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 max(list(strips)) + else: + return None + @property def subject(self): """ From 8dcaba81e0e21261e3334cc97b0954572314dffa Mon Sep 17 00:00:00 2001 From: Dmitry Teselkin Date: Thu, 19 May 2016 17:17:02 +0300 Subject: [PATCH 2/3] Fix guess_strip function --- gbp/patch_series.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/gbp/patch_series.py b/gbp/patch_series.py index 32e01fe5..773fbadc 100644 --- a/gbp/patch_series.py +++ b/gbp/patch_series.py @@ -22,7 +22,7 @@ import tempfile from gbp.errors import GbpError -re_patch_paths = r'^(\-\-\-|\+\+\+)\s+(.+)[\t$]' +re_patch_paths = r'^(\-\-\-|\+\+\+)\s+(.+?)(\t|$)' re_diff_git = r'^diff\s+\-\-git\s+(.+)\s+(.+)$' @@ -45,10 +45,10 @@ class Patch(object): def __init__(self, path, topic=None, strip=None): self.path = path self.topic = topic - if strip: - self.strip = strip - else: + if strip is None: self.strip = self._guess_strip() + else: + self.strip = strip self.info = None self.long_desc = None @@ -153,12 +153,13 @@ def _guess_strip(self): return None for line in patch_file: - match = re.match(re_diff_git, line.strip()) + 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.strip()) + match = re.match(re_patch_paths, line) if match: if pair[0]: pair[1] = match.group(2) @@ -189,7 +190,7 @@ def _guess_strip(self): if len(strips): # Not sure we should allow different strips in one file - return max(list(strips)) + return min(list(strips)) else: return None From 561f8c9e3e7defdd3f37cc66fb6e14de51d25f2b Mon Sep 17 00:00:00 2001 From: Dmitry Teselkin Date: Thu, 19 May 2016 17:17:12 +0300 Subject: [PATCH 3/3] Add tests --- tests/13_test_gbp_pq.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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)