summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>2013-01-11 16:41:38 +0200
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>2014-06-05 14:20:06 +0300
commit821251cbd8d7076e49729ac88eabd92265caedec (patch)
treefa534727e095d009cf0de865adf09dbfbbaf12a6
parentaecfc649d6825acc147f3009577bfeb688bdc874 (diff)
downloadgit-buildpackage-821251cbd8d7076e49729ac88eabd92265caedec.tar.gz
git-buildpackage-821251cbd8d7076e49729ac88eabd92265caedec.tar.bz2
git-buildpackage-821251cbd8d7076e49729ac88eabd92265caedec.zip
rpm.SpecFile: drop the internal 'patches' structure
To get rid of duplicate data tracking. Also, add test for testing the macro expansion of patch and source names. Also add tests for SpecFile.patchseries. Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
-rw-r--r--gbp/rpm/__init__.py74
-rwxr-xr-xgbp/scripts/import_srpm.py4
-rwxr-xr-xgbp/scripts/pq_rpm.py20
-rw-r--r--tests/test_rpm.py23
-rw-r--r--tests/test_rpm_data/specs/gbp-test-tags.spec7
5 files changed, 74 insertions, 54 deletions
diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py
index 46cea28a..693fe1a6 100644
--- a/gbp/rpm/__init__.py
+++ b/gbp/rpm/__init__.py
@@ -159,7 +159,6 @@ class SpecFile(object):
self.epoch = str(source_header[rpm.RPMTAG_EPOCH]) \
if source_header[rpm.RPMTAG_EPOCH] != None else None
self.packager = source_header[rpm.RPMTAG_PACKAGER]
- self.patches = {}
self.sources = {}
self._tags = {}
self._special_directives = defaultdict(list)
@@ -221,6 +220,12 @@ class SpecFile(object):
return sorted([int(num) for num in data])
return []
+ def _patches(self):
+ """Get all patch tags as a dict"""
+ if 'patch' not in self._tags:
+ return {}
+ return {patch['num']: patch for patch in self._tags['patch']['lines']}
+
def _macro_replace(self, matchobj):
macro_dict = {'name': self.name,
'version': self.upstreamversion,
@@ -276,14 +281,6 @@ class SpecFile(object):
# 'Patch:' tags
elif tagname == 'patch':
tagnum = -1 if tagnum is None else tagnum
- new_patch = {'name': matchobj.group('name').strip(),
- 'filename': matchobj.group('name'),
- 'apply': False,
- 'strip': '0',
- 'macro_line': None,
- 'autoupdate': True,
- 'tag_line': lineobj}
- self.patches[tagnum] = new_patch
# Record all tag locations
try:
@@ -314,16 +311,21 @@ class SpecFile(object):
return tagname
- def _parse_directive(self, lineobj):
- """Parse special directive/scriptlet/macro lines"""
+ @staticmethod
+ def _patch_macro_opts(args):
+ """Parse arguments of the '%patch' macro"""
- # Parser for '%patch' macros
patchparser = OptionParser()
patchparser.add_option("-p", dest="strip")
patchparser.add_option("-s", dest="silence")
patchparser.add_option("-P", dest="patchnum")
patchparser.add_option("-b", dest="backup")
patchparser.add_option("-E", dest="removeempty")
+ arglist = args.split()
+ return patchparser.parse_args(arglist)[0]
+
+ def _parse_directive(self, lineobj):
+ """Parse special directive/scriptlet/macro lines"""
# Parser for '%setup' macros
setupparser = OptionParser()
@@ -345,19 +347,13 @@ class SpecFile(object):
# '%patch' macros
directiveid = None
if directivename == 'patch':
- arglist = matchobj.group('args').split()
- (opts, args) = patchparser.parse_args(arglist)
+ opts = self._patch_macro_opts(matchobj.group('args'))
if matchobj.group('num'):
directiveid = int(matchobj.group('num'))
elif opts.patchnum:
directiveid = int(opts.patchnum)
else:
directiveid = -1
-
- if opts.strip:
- self.patches[directiveid]['strip'] = opts.strip
- self.patches[directiveid]['macro_line'] = lineobj
- self.patches[directiveid]['apply'] = True
# '%setup' macros
elif directivename == 'setup':
arglist = matchobj.group('args').split()
@@ -420,6 +416,7 @@ class SpecFile(object):
# Update sources info (basically possible macros expanded by rpm)
# And, double-check that we parsed spec content correctly
+ patches = self._patches()
for (name, num, typ) in self._specinfo.sources:
# workaround rpm parsing bug
if typ == 1 or typ == 9:
@@ -443,16 +440,11 @@ class SpecFile(object):
# having number (2^31-1), we use number -1
if num >= pow(2,30):
num = -1
- if num in self.patches:
- self.patches[num]['filename'] = name
+ if num in patches:
+ patches[num]['linevalue'] = name
else:
gbp.log.err("BUG: we didn't correctly parse all 'Patch' tags!")
- # Mark ignored patches
- for patchnum in self.patches:
- if patchnum in self.ignorepatches:
- self.patches[patchnum]['autoupdate'] = False
-
def _delete_tag(self, tag, num):
"""Delete a tag"""
key = tag.lower()
@@ -584,7 +576,7 @@ class SpecFile(object):
macro_prev = None
ignored = self.ignorepatches
# Remove 'Patch:̈́' tags
- for tag in self._tags['patch']['lines']:
+ for tag in self._patches().values():
if not tag['num'] in ignored:
tag_prev = self._delete_tag('patch', tag['num'])
# Remove a preceding comment if it seems to originate from GBP
@@ -658,20 +650,26 @@ class SpecFile(object):
macro_line = self._set_special_macro('patch', patchnum, '-p1',
macro_line)
- def patchseries(self):
- """
- Return patches of the RPM as a gbp patchseries
- """
+ def patchseries(self, unapplied=False, ignored=False):
+ """Return non-ignored patches of the RPM as a gbp patchseries"""
series = PatchSeries()
- patchdir = self.specdir
- for n, p in sorted(self.patches.iteritems()):
- if p['autoupdate'] and p['apply']:
- fname = os.path.basename(p['filename'])
- series.append(Patch(os.path.join(patchdir, fname),
- strip = int(p['strip'])))
+ if 'patch' in self._tags:
+ tags = self._patches()
+ macros = {macro['id']: macro['args']
+ for macro in self._special_directives['patch']}
+ ignored = [] if ignored else self.ignorepatches
+
+ for num, tag in sorted(tags.iteritems()):
+ strip = 0
+ if num in macros:
+ opts = self._patch_macro_opts(macros[num])
+ strip = int(opts.strip) if opts.strip else 0
+ if (unapplied or (num in macros)) and num not in ignored:
+ filename = os.path.basename(tag['linevalue'])
+ series.append(Patch(os.path.join(self.specdir, filename),
+ strip=strip))
return series
-
def guess_orig_file(self):
"""
Try to guess the name of the primary upstream/source archive
diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py
index bbaa4328..92bb022b 100755
--- a/gbp/scripts/import_srpm.py
+++ b/gbp/scripts/import_srpm.py
@@ -325,8 +325,8 @@ def main(argv):
raise
# Need to copy files to the packaging directory given by caller
- files = [os.path.basename(patch['filename']) \
- for patch in spec.patches.itervalues()]
+ files = [os.path.basename(patch.path) \
+ for patch in spec.patchseries(unapplied=True, ignored=True)]
for num, src in spec.sources.iteritems():
if num != spec.orig_src_num:
files.append(src['filename'])
diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py
index 8a938fa3..d3da13a8 100755
--- a/gbp/scripts/pq_rpm.py
+++ b/gbp/scripts/pq_rpm.py
@@ -140,17 +140,15 @@ def rm_patch_files(spec):
marked as not maintained by gbp.
"""
# Remove all old patches from the spec dir
- for n, p in spec.patches.iteritems():
- if p['autoupdate']:
- f = os.path.join(spec.specdir, p['filename'])
- gbp.log.debug("Removing '%s'" % f)
- try:
- os.unlink(f)
- except OSError, (e, msg):
- if e != errno.ENOENT:
- raise GbpError, "Failed to remove patch: %s" % msg
- else:
- gbp.log.debug("%s does not exist." % f)
+ for patch in spec.patchseries(unapplied=True):
+ gbp.log.debug("Removing '%s'" % patch.path)
+ try:
+ os.unlink(patch.path)
+ except OSError as err:
+ if err.errno != errno.ENOENT:
+ raise GbpError("Failed to remove patch: %s" % err)
+ else:
+ gbp.log.debug("Patch %s does not exist." % patch.path)
def update_patch_series(repo, spec, start, end, options):
diff --git a/tests/test_rpm.py b/tests/test_rpm.py
index 68886e86..728c8872 100644
--- a/tests/test_rpm.py
+++ b/tests/test_rpm.py
@@ -200,6 +200,7 @@ class TestSpecFile(object):
spec.protected('_delete_tag')('source', 0)
spec.protected('_delete_tag')('patch', 0)
spec.protected('_delete_tag')('patch', -1)
+ assert spec.protected('_patches')() == {}
prev = spec.protected('_delete_tag')('invalidtag', None)
with assert_raises(GbpError):
@@ -249,8 +250,28 @@ class TestSpecFile(object):
assert val['value'] == rval, ("'%s:' is '%s', expecting '%s'" %
(name, val['value'], rval))
assert spec.ignorepatches == []
+ # Check patch numbers and patch filenames
+ patches = {patch['num']: patch['linevalue'] for patch in
+ spec.protected('_tags')['patch']['lines']}
+ assert patches == {0: 'my_patch0', -1: 'my_patch'}
- assert spec.patches.keys() == [0, -1]
+ def test_patch_series(self):
+ """Test the getting the patches as a patchseries"""
+ spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec')
+ spec = SpecFileTester(spec_filepath)
+
+ assert len(spec.patchseries()) == 0
+ spec.update_patches(['1.patch', '2.patch', '3.patch'])
+ assert len(spec.patchseries()) == 3
+ spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"})
+ spec.update_patches(['4.patch'])
+ assert len(spec.patchseries()) == 1
+ assert len(spec.patchseries(ignored=True)) == 2
+ spec.protected('_delete_special_macro')('patch', 0)
+ assert len(spec.patchseries(ignored=True)) == 1
+ series = spec.patchseries(unapplied=True, ignored=True)
+ assert len(series) == 2
+ assert os.path.basename(series[-1].path) == '4.patch'
class TestUtilityFunctions(object):
diff --git a/tests/test_rpm_data/specs/gbp-test-tags.spec b/tests/test_rpm_data/specs/gbp-test-tags.spec
index 47421a9d..ee4c2b94 100644
--- a/tests/test_rpm_data/specs/gbp-test-tags.spec
+++ b/tests/test_rpm_data/specs/gbp-test-tags.spec
@@ -9,6 +9,9 @@
%define test_arch_os_tags %(test -n "$GBP_SKIP_ARCH_OS_TAGS" && echo 0 || echo 1)
+%define source_fn_base source
+%define patch_fn_base patch
+
# Gbp-Undefined-Tag: foobar
# Test that we accept different cases
@@ -27,8 +30,8 @@ Packager: my_packager
Url: my_url
Vcs: my_vcs
Source: my_source
-Patch: my_patch
-Patch0: my_patch0
+Patch: my_%patch_fn_base
+Patch0: my_%{patch_fn_base}0
Nosource: 0
Nopatch: 0
#Icon: my_icon