summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>2013-02-25 12:11:14 +0200
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>2013-04-03 10:11:42 +0300
commit5683c3cde1fcdceba95b8952e9e545df95c5503d (patch)
treee04175b1abfcf4f03fd1d504f6d9223f7f89d332
parentc05e8590e5b563a5040ccb888ffafcb30913e78e (diff)
downloadgit-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__.py25
-rwxr-xr-xgbp/scripts/pq_rpm.py37
-rw-r--r--tests/test_rpm.py14
-rw-r--r--tests/test_rpm_data/specs/gbp-test2-reference.spec2
-rw-r--r--tests/test_rpm_data/specs/gbp-test2-reference2.spec11
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