diff options
author | Markus Lehtonen <markus.lehtonen@linux.intel.com> | 2013-02-25 12:11:14 +0200 |
---|---|---|
committer | Markus Lehtonen <markus.lehtonen@linux.intel.com> | 2013-04-03 10:11:42 +0300 |
commit | 5683c3cde1fcdceba95b8952e9e545df95c5503d (patch) | |
tree | e04175b1abfcf4f03fd1d504f6d9223f7f89d332 | |
parent | c05e8590e5b563a5040ccb888ffafcb30913e78e (diff) | |
download | git-buildpackage-5683c3cde1fcdceba95b8952e9e545df95c5503d.tar.gz git-buildpackage-5683c3cde1fcdceba95b8952e9e545df95c5503d.tar.bz2 git-buildpackage-5683c3cde1fcdceba95b8952e9e545df95c5503d.zip |
rpm: support conditionals in patch-export
One can now define conditional patches that are enclosed in '%if' or
'%ifarch' when the spec file is updated. One can do this by defining
'Gbp-Rpm-If: <conditional>' and 'Gbp-Rpm-IfArch: <conditional>' in the
commit message.
Only one conditional per patch is supported, i.e. you cannot define
'IfArch' and 'If' for the same patch.
Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
-rw-r--r-- | gbp/rpm/__init__.py | 25 | ||||
-rwxr-xr-x | gbp/scripts/pq_rpm.py | 37 | ||||
-rw-r--r-- | tests/test_rpm.py | 14 | ||||
-rw-r--r-- | tests/test_rpm_data/specs/gbp-test2-reference.spec | 2 | ||||
-rw-r--r-- | tests/test_rpm_data/specs/gbp-test2-reference2.spec | 11 |
5 files changed, 66 insertions, 23 deletions
diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 57275774..8b4a9c76 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -544,7 +544,7 @@ class SpecFile(object): self._special_directives[key].append(linerec) return ret - def update_patches(self, patchfilenames): + def update_patches(self, patches): """Update spec with new patch tags and patch macros""" # Remove non-ignored patches tag_prev = None @@ -562,14 +562,21 @@ class SpecFile(object): # Remove '%patch:' macros for macro in self._special_directives['patch']: if not macro['id'] in ignored: + macro_prev = self._delete_special_macro('patch', macro['id']) + # Remove surrounding if-else + macro_next = macro_prev.next + if (str(macro_prev).startswith('%if') and + str(macro_next).startswith('%endif')): + self._content.delete(macro_next) + macro_prev = self._content.delete(macro_prev) + # Remove a preceding comment line if it ends with '.patch' or # '.diff' plus an optional compression suffix - macro_prev = self._delete_special_macro('patch', macro['id']) if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", str(macro_prev), flags=re.I): macro_prev = self._content.delete(macro_prev) - if len(patchfilenames) == 0: + if len(patches) == 0: return # Determine where to add Patch tag lines @@ -616,7 +623,9 @@ class SpecFile(object): # Add a comment indicating gbp generated patch tags comment_text = "# Patches auto-generated by git-buildpackage:\n" tag_line = self._content.insert_after(tag_line, comment_text) - for ind, name in enumerate(patchfilenames): + for ind, patch in enumerate(patches): + name = patch[0] + cmds = patch[1] if patch[1] else {} patchnum = startnum + ind tag_line = self._set_tag("Patch", patchnum, name, tag_line) # Add '%patch' macro and a preceding comment line @@ -624,6 +633,14 @@ class SpecFile(object): macro_line = self._content.insert_after(macro_line, comment_text) macro_line = self._set_special_macro('patch', patchnum, '-p1', macro_line) + for cmd, args in cmds.iteritems(): + if cmd in ('if', 'ifarch'): + self._content.insert_before(macro_line, '%%%s %s\n' % + (cmd, args)) + macro_line = self._content.insert_after(macro_line, + '%endif\n') + # We only support one command per patch, for now + break def patchseries(self, unapplied=False, ignored=False): """Return non-ignored patches of the RPM as a gbp patchseries""" diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 9b1f1662..40906c8e 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -47,12 +47,13 @@ def compress_patches(patches, compress_size=0): ret_patches = [] for num, patch in enumerate(patches): # Compress if patch file is larger than "threshold" value - if compress_size and os.path.getsize(patch) > compress_size: - gbp.log.debug("Compressing %s" % os.path.basename(patch)) - subprocess.Popen(['gzip', '-n', patch]).communicate() - patch += ".gz" + suffix = '' + if compress_size and os.path.getsize(patch[0]) > compress_size: + gbp.log.debug("Compressing %s" % os.path.basename(patch[0])) + subprocess.Popen(['gzip', '-n', patch[0]]).communicate() + suffix = '.gz' - ret_patches.append(os.path.basename(patch)) + ret_patches.append((os.path.basename(patch[0]) + suffix, patch[1])) return ret_patches @@ -132,6 +133,21 @@ def patch_path_filter(file_status, exclude_regex=None): return include_paths +def parse_export_cmds(info): + """Parse export commands from commit message""" + cmd_re = re.compile(r'^\s*gbp-rpm-(?P<cmd>[a-z-]+):\s*(?P<args>\S.*)', + flags=re.I) + commands = {} + for line in info['body'].splitlines(): + match = re.match(cmd_re, line) + if match: + cmd = match.group('cmd').lower() + if cmd in ('if', 'ifarch'): + commands[cmd] = match.group('args') + else: + gbp.log.warn("Ignoring unknow gbp-command '%s' in commit %s" + % (line, info['id'])) + return commands def generate_patches(repo, start, squash_point, end, squash_diff_name, outdir, options): @@ -184,7 +200,7 @@ def generate_patches(repo, start, squash_point, end, squash_diff_name, diff_filepath = os.path.join(outdir, diff_filename) if write_diff_file(repo, diff_filepath, start_sha1, squash_sha1, paths): - patches.append(diff_filepath) + patches.append((diff_filepath, None)) start = squash_sha1 # Generate patches @@ -201,7 +217,8 @@ def generate_patches(repo, start, squash_point, end, squash_diff_name, signature=False, paths=paths, filter_fn=patch_content_filter) if patch_fn: - patches.append(patch_fn) + export_cmds = parse_export_cmds(info) + patches.append((patch_fn, export_cmds)) if options.patch_numbers: patch_num += 1 @@ -216,7 +233,7 @@ def generate_patches(repo, start, squash_point, end, squash_diff_name, (diff_filename, end_commit, end)) diff_filepath = os.path.join(outdir, diff_filename) if write_diff_file(repo, diff_filepath, end_commit, end, paths): - patches.append(diff_filepath) + patches.append((diff_filepath, None)) # Compress patches = compress_patches(patches, options.patch_export_compress) @@ -256,9 +273,7 @@ def update_patch_series(repo, spec, start, end, options): patches = generate_patches(repo, start, squash_point, end, squash_name, spec.specdir, options) - - filenames = [os.path.basename(patch) for patch in patches] - spec.update_patches(filenames) + spec.update_patches(patches) spec.write_spec_file() diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 9d5a49bb..4d430778 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -156,7 +156,7 @@ class TestSpecFile(object): reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference.spec') spec = SpecFile(tmp_spec) - spec.update_patches(['new.patch']) + spec.update_patches([('new.patch', None)]) spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True @@ -173,14 +173,15 @@ class TestSpecFile(object): reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') spec = SpecFile(tmp_spec) - spec.update_patches(['1.patch', '2.patch']) + spec.update_patches([('1.patch', {'if': 'true'}), + ('2.patch', {'ifarch': '%ix86'})]) spec.set_tag('VCS', None, 'myvcstag') - spec.update_patches(['new.patch']) spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True - # Test removing the VCS tag + # Test updating patches again and removing the VCS tag reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') + spec.update_patches([('new.patch', {'if': '1'})]) spec.set_tag('VCS', None, '') spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True @@ -263,10 +264,11 @@ class TestSpecFile(object): spec = SpecFileTester(spec_filepath) assert len(spec.patchseries()) == 0 - spec.update_patches(['1.patch', '2.patch', '3.patch']) + spec.update_patches([('1.patch', None), ('2.patch', None), + ('3.patch', None)]) assert len(spec.patchseries()) == 3 spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"}) - spec.update_patches(['4.patch']) + spec.update_patches([('4.patch', None)]) assert len(spec.patchseries()) == 1 assert len(spec.patchseries(ignored=True)) == 2 spec.protected('_delete_special_macro')('patch', 0) diff --git a/tests/test_rpm_data/specs/gbp-test2-reference.spec b/tests/test_rpm_data/specs/gbp-test2-reference.spec index e31930d7..dfd4b91f 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference.spec @@ -27,7 +27,9 @@ echo "Do things" # Gbp-Patch-Macros # new.patch +%if 1 %patch0 -p1 +%endif %build make diff --git a/tests/test_rpm_data/specs/gbp-test2-reference2.spec b/tests/test_rpm_data/specs/gbp-test2-reference2.spec index 095600d3..0b93f0fa 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference2.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference2.spec @@ -11,7 +11,8 @@ Source20: bar.tar.gz # Gbp-Ignore-Patches: -1 Patch: my.patch # Patches auto-generated by git-buildpackage: -Patch0: new.patch +Patch0: 1.patch +Patch1: 2.patch Packager: Markus Lehtonen <markus.lehtonen@linux.intel.com> VCS: myvcstag @@ -27,8 +28,14 @@ Package for testing the RPM functionality of git-buildpackage. echo "Do things" # Gbp-Patch-Macros -# new.patch +# 1.patch +%if true %patch0 -p1 +%endif +# 2.patch +%ifarch %ix86 +%patch1 -p1 +%endif %build make |