summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlav Vitters <olav@vitters.nl>2020-05-06 16:58:29 +0200
committerOlav Vitters <olav@vitters.nl>2020-05-06 16:58:29 +0200
commitc71a0b35380f07191d157d895fcd1d0fb89f7d13 (patch)
treed4f9f90e5c526cdb7e942c7a7199cfddcb851681
parent834a2b921846e5644872ba03a7f95bb12b867f01 (diff)
downloadmgagnome-c71a0b35380f07191d157d895fcd1d0fb89f7d13.tar
mgagnome-c71a0b35380f07191d157d895fcd1d0fb89f7d13.tar.gz
mgagnome-c71a0b35380f07191d157d895fcd1d0fb89f7d13.tar.bz2
mgagnome-c71a0b35380f07191d157d895fcd1d0fb89f7d13.tar.xz
mgagnome-c71a0b35380f07191d157d895fcd1d0fb89f7d13.zip
SpecFile: introduce the convert_buildrequires function (logic moved from cmd_clean_spec_multi)
-rwxr-xr-xmgagnome359
1 files changed, 193 insertions, 166 deletions
diff --git a/mgagnome b/mgagnome
index 276573a..00f2a16 100755
--- a/mgagnome
+++ b/mgagnome
@@ -51,6 +51,7 @@ import collections
# for debugging output
import pprint
+import logging
# check-latest
import requests
@@ -443,6 +444,174 @@ class SpecFile():
"""Return the sources"""
return self._sources_and_patches(flag=1)
+ def convert_buildrequires(self):
+ """Converts BuildRequires into their preferred form
+
+ Requires SpecFile to be initialized with its package argument"""
+
+ made_changes = False
+ re_prov_get_version = re.compile(r'^[^(]+\([^)]+-(?P<version>[0-9]+\.[0-9][0-9.]*)\)$')
+ no_alt = set()
+ no_change = {}
+
+ buildreqs = self.buildrequires
+
+ log = logging.getLogger(None)
+ debug_enabled = log.isEnabledFor(log.DEBUG)
+
+ convert_brs = {
+ 'pkgconfig': {
+ 'desc': 'convert -devel buildrequires into pkgconfig',
+ 'check_br': lambda req: req.endswith('-devel'),
+ 'check_provide': lambda prov: prov.startswith('pkgconfig('),
+ 'basereqs': lambda req: [req[:-len('-devel')]],
+ 'basereq_no_version': lambda basereqs: [basereq.rstrip('1234567890.') for basereq in basereqs
+ if basereq[-1] in '1234567890'],
+ 'versions_from_basereq': lambda basereqs: set((basereq[len(basereq.rstrip('01234567890.')):]
+ for basereq in basereqs if basereq[-1] in '1234567890')),
+ 'versions_basereq_extra': lambda versions: set(("%s.0" % version for version in versions
+ if '.' not in version)),
+ 'extra': lambda basereqs, versions: \
+ ['pkgconfig(%s)' % basereq for basereq in basereqs] +
+ ['pkgconfig(%s)' % basereq[len('lib'):]
+ if basereq.startswith('lib') else 'pkgconfig(lib%s)' % basereq
+ for basereq in basereqs] +
+ ['pkgconfig(%s-%s)' % (basereq, version) for basereq in basereqs for version in versions],
+ },
+ 'perl': {
+ 'desc': 'convert perl- buildrequires into perl()',
+ 'check_br': lambda req: req.startswith('perl-'),
+ 'check_provide': lambda prov: prov.startswith('perl('),
+ 'basereqs': lambda req: [req[len('perl-'):]],
+ 'extra': lambda basereqs, versions: ['perl(%s)' % basereq.replace('-', '::') for basereq in basereqs],
+ },
+ # PySolFC.spec:BuildRequires: python3-setuptools
+ # $ rpm -q python3-setuptools --provides | grep python3dist
+ # python3dist(setuptools)
+ # python3dist(setuptools) = 46.1.3
+ #
+ # There's also provides such as:
+ # python3.8dist(setuptools)
+ # pythonegg(3)(setuptools)
+ 'python-pkg': {
+ 'disabled': True,
+ 'desc': 'convert python buildrequires into python3dist()',
+ 'check_br': lambda req: req.startswith('python3-'),
+ 'check_provide': lambda prov: prov.startswith('python3dist('),
+ 'basereqs': lambda req: [req[len('python3-'):]],
+ 'extra': lambda basereqs, versions: ['python3dist(%s)' % basereq for basereq in basereqs],
+ },
+ 'python-egg': {
+ 'desc': 'convert pythonegg(3) into python3dist()',
+ 'check_br': lambda req: req.startswith('pythonegg(3)(') and req.endswith(')'),
+ 'check_provide': lambda prov: prov.startswith('python3dist('),
+ 'basereqs': lambda req: [req[len('pythonegg(3)('):-1]],
+ 'extra': lambda basereqs, versions: ['python3dist(%s)' % basereq for basereq in basereqs],
+ },
+ }
+
+ for keys in convert_brs.values():
+ if 'disabled' in keys and keys['disabled']:
+ continue
+
+ keys['changes'] = {}
+ br_old = [r for r in list(buildreqs.keys()) if keys['check_br'](r)]
+ if debug_enabled and br_old:
+ pprint.pprint(br_old)
+ for req in br_old:
+ every_provides, every_ignored_provide = Downstream.alternative_provides(req)
+ # XXX - document what clean_pkgconfig_prov is for
+ # maybe integrate clean_pkgconfig_prov in alternative_provides function?
+ provides = [clean_pkgconfig_prov(prov)
+ for prov in every_provides
+ if keys['check_provide'](prov)]
+ provides_ignored = [clean_pkgconfig_prov(prov)
+ for prov in every_ignored_provide
+ if keys['check_provide'](prov)]
+ change_to = None
+ if len(provides) == 1 and not provides_ignored:
+ if debug_enabled:
+ print("NOTICE: Only one available option, using %s" % provides[0])
+
+ change_to = provides[0]
+ elif provides and 'extra' in keys:
+ # Determine base require (e.g. gtk+3.0-devel --> gtk+3.0)
+ basereqs = keys['basereqs'](req)
+
+ # Determine version matches
+ versions = set()
+ if 'versions_from_basereq' in keys:
+ # Determine if the basereq has a version at the end (e.g. gtk+3.0 --> 3.0)
+ versions.update(keys['versions_from_basereq'](basereqs))
+ if versions and 'basereq_no_version' in keys:
+ basereqs.extend(keys['basereq_no_version'](basereqs))
+ # Make it unique again, but keep the order
+ #
+ # This is done so that e.g. python3-devel changes to pkgconfig(python3),
+ # even if pkgconfig(python) might be available
+ basereqs = list(distinct(basereqs))
+ if 'versions_basereq_extra' in keys:
+ versions.update(keys['versions_basereq_extra'](versions))
+
+ if not versions:
+ # In case no versions were retrieved from the basereq,
+ # match with any version found from the alternative
+ # provides (heuristic matching)
+ #
+ # This is only done as a last resort to avoid matching
+ # e.g. gtk+3.0-devel --> pkgconfig(gtk+2.0)
+ for prov in provides:
+ for match in re_prov_get_version.finditer(prov):
+ if debug_enabled:
+ print("NOTICE: Heuristically adding version %s from provide %s" \
+ % (match.group('version'), prov))
+ versions.add(match.group('version'))
+
+ check_for = keys['extra'](basereqs, versions)
+
+ if debug_enabled and versions:
+ pprint.pprint(versions)
+
+ for check in check_for:
+ if check in provides:
+ if debug_enabled:
+ print("NOTICE: Matched: %s => %s" % (check, provides))
+ change_to = check
+ break
+
+ if change_to is None and provides:
+ provides_no_versions = []
+ for prov in provides:
+ if re_prov_get_version.fullmatch(prov) is None:
+ provides_no_versions.append(prov)
+
+ if len(provides_no_versions) == 1 and not provides_ignored:
+ change_to = provides_no_versions[0]
+ if debug_enabled:
+ print("NOTICE: Only one available versionless option, using %s" % change_to)
+
+
+ if provides:
+ if change_to is None:
+ no_change[req] = (provides, check_for)
+ else:
+ no_alt.add(req)
+
+ if change_to is not None:
+ keys['changes'][req] = change_to
+
+ keys_with_changes = [keys for keys in convert_brs.values() if 'changes' in keys and keys['changes']]
+# XXX - seems to cause false messages
+# if not keys_with_changes:
+# keys_with_changes.append({'changes': [], 'desc': 'unsplit BRs'})
+
+ for keys in keys_with_changes:
+ if self.update_br(keys['changes'], change_description=keys['desc']):
+ made_changes = True
+
+ return made_changes
+
+
def clean_spec(self):
"""Clean the spec file of deprecated statements"""
@@ -1806,174 +1975,23 @@ def _cmd_clean_spec_multi(args):
# Convert perl- and -devel buildrequires into perl() and pkgconfig() requires
if options.convert_br:
- re_prov_get_version = re.compile(r'^[^(]+\([^)]+-(?P<version>[0-9]+\.[0-9][0-9.]*)\)$')
- buildreqs = spec.buildrequires
- no_alt = set()
- no_change = {}
- convert_brs = {
- 'pkgconfig': {
- 'desc': 'convert -devel buildrequires into pkgconfig',
- 'check_br': lambda req: req.endswith('-devel'),
- 'check_provide': lambda prov: prov.startswith('pkgconfig('),
- 'basereqs': lambda req: [req[:-len('-devel')]],
- 'basereq_no_version': lambda basereqs: [basereq.rstrip('1234567890.') for basereq in basereqs
- if basereq[-1] in '1234567890'],
- 'versions_from_basereq': lambda basereqs: set((basereq[len(basereq.rstrip('01234567890.')):]
- for basereq in basereqs if basereq[-1] in '1234567890')),
- 'versions_basereq_extra': lambda versions: set(("%s.0" % version for version in versions
- if '.' not in version)),
- 'extra': lambda basereqs, versions: \
- ['pkgconfig(%s)' % basereq for basereq in basereqs] +
- ['pkgconfig(%s)' % basereq[len('lib'):]
- if basereq.startswith('lib') else 'pkgconfig(lib%s)' % basereq
- for basereq in basereqs] +
- ['pkgconfig(%s-%s)' % (basereq, version) for basereq in basereqs for version in versions],
- },
- 'perl': {
- 'desc': 'convert perl- buildrequires into perl()',
- 'check_br': lambda req: req.startswith('perl-'),
- 'check_provide': lambda prov: prov.startswith('perl('),
- 'basereqs': lambda req: [req[len('perl-'):]],
- 'extra': lambda basereqs, versions: ['perl(%s)' % basereq.replace('-', '::') for basereq in basereqs],
- },
- # PySolFC.spec:BuildRequires: python3-setuptools
- # $ rpm -q python3-setuptools --provides | grep python3dist
- # python3dist(setuptools)
- # python3dist(setuptools) = 46.1.3
- #
- # There's also provides such as:
- # python3.8dist(setuptools)
- # pythonegg(3)(setuptools)
- 'python-pkg': {
- 'disabled': True,
- 'desc': 'convert python buildrequires into python3dist()',
- 'check_br': lambda req: req.startswith('python3-'),
- 'check_provide': lambda prov: prov.startswith('python3dist('),
- 'basereqs': lambda req: [req[len('python3-'):]],
- 'extra': lambda basereqs, versions: ['python3dist(%s)' % basereq for basereq in basereqs],
- },
- 'python-egg': {
- 'desc': 'convert pythonegg(3) into python3dist()',
- 'check_br': lambda req: req.startswith('pythonegg(3)(') and req.endswith(')'),
- 'check_provide': lambda prov: prov.startswith('python3dist('),
- 'basereqs': lambda req: [req[len('pythonegg(3)('):-1]],
- 'extra': lambda basereqs, versions: ['python3dist(%s)' % basereq for basereq in basereqs],
- },
- }
-
- for keys in convert_brs.values():
- if 'disabled' in keys and keys['disabled']:
- continue
-
- keys['changes'] = {}
- br_old = [r for r in list(buildreqs.keys()) if keys['check_br'](r)]
- if options.debug and br_old:
- pprint.pprint(br_old)
- for req in br_old:
- every_provides, every_ignored_provide = Downstream.alternative_provides(req)
- # XXX - document what clean_pkgconfig_prov is for
- # maybe integrate clean_pkgconfig_prov in alternative_provides function?
- provides = [clean_pkgconfig_prov(prov)
- for prov in every_provides
- if keys['check_provide'](prov)]
- provides_ignored = [clean_pkgconfig_prov(prov)
- for prov in every_ignored_provide
- if keys['check_provide'](prov)]
- change_to = None
- if len(provides) == 1 and not provides_ignored:
- if options.debug:
- print("NOTICE: Only one available option, using %s" % provides[0])
-
- change_to = provides[0]
- elif provides and 'extra' in keys:
- # Determine base require (e.g. gtk+3.0-devel --> gtk+3.0)
- basereqs = keys['basereqs'](req)
-
- # Determine version matches
- versions = set()
- if 'versions_from_basereq' in keys:
- # Determine if the basereq has a version at the end (e.g. gtk+3.0 --> 3.0)
- versions.update(keys['versions_from_basereq'](basereqs))
- if versions and 'basereq_no_version' in keys:
- basereqs.extend(keys['basereq_no_version'](basereqs))
- # Make it unique again, but keep the order
- #
- # This is done so that e.g. python3-devel changes to pkgconfig(python3),
- # even if pkgconfig(python) might be available
- basereqs = list(distinct(basereqs))
- if 'versions_basereq_extra' in keys:
- versions.update(keys['versions_basereq_extra'](versions))
-
- if not versions:
- # In case no versions were retrieved from the basereq,
- # match with any version found from the alternative
- # provides (heuristic matching)
- #
- # This is only done as a last resort to avoid matching
- # e.g. gtk+3.0-devel --> pkgconfig(gtk+2.0)
- for prov in provides:
- for match in re_prov_get_version.finditer(prov):
- if options.debug:
- print("NOTICE: Heuristically adding version %s from provide %s" \
- % (match.group('version'), prov))
- versions.add(match.group('version'))
-
- check_for = keys['extra'](basereqs, versions)
-
- if options.debug and versions:
- pprint.pprint(versions)
-
- for check in check_for:
- if check in provides:
- if options.debug:
- print("NOTICE: Matched: %s => %s" % (check, provides))
- change_to = check
- break
-
- if change_to is None and provides:
- provides_no_versions = []
- for prov in provides:
- if re_prov_get_version.fullmatch(prov) is None:
- provides_no_versions.append(prov)
-
- if len(provides_no_versions) == 1 and not provides_ignored:
- change_to = provides_no_versions[0]
- if options.debug:
- print("NOTICE: Only one available versionless option, using %s" % change_to)
-
-
- if provides:
- if change_to is None:
- no_change[req] = (provides, check_for)
- else:
- no_alt.add(req)
-
- if change_to is not None:
- keys['changes'][req] = change_to
-
- if not options.doit:
- if options.debug:
- for keys in list(convert_brs.items()):
- if 'changes' in keys and keys['changes']:
- pprint.pprint(keys['changes'])
-
- if no_alt:
- print("WARNING: no alternatives found for: %s" % ", ".join(sorted(no_alt)))
-
- if no_change and options.debug:
- pprint.pprint(no_change)
- else:
- convert_brs = {}
-
- keys_with_changes = [keys for keys in convert_brs.values() if 'changes' in keys and keys['changes']]
-# XXX - seems to cause false messages
-# if not keys_with_changes:
-# keys_with_changes.append({'changes': [], 'desc': 'unsplit BRs'})
-
- for keys in keys_with_changes:
- if spec.update_br(keys['changes'], change_description=keys['desc']):
+ if spec.convert_buildrequires():
made_changes = True
+# if not options.doit:
+# if options.debug:
+# for keys in list(convert_brs.items()):
+# if 'changes' in keys and keys['changes']:
+# pprint.pprint(keys['changes'])
+#
+# if no_alt:
+# print("WARNING: no alternatives found for: %s" % ", ".join(sorted(no_alt)))
+#
+# if no_change and options.debug:
+# pprint.pprint(no_change)
+# else:
+# convert_brs = {}
+
if spec.clean_spec():
made_changes = True
@@ -2469,6 +2487,15 @@ def main():
"Core {0} Updates Testing Source".format(options.distro)
Downstream.DISTRO = options.distro
+ log_format = '%(levelname): %(message)s'
+ logging.basicConfig(format=log_format)
+ log = logging.getLogger(None)
+ if options.debug:
+ log.setLevel(logging.DEBUG)
+ else:
+ log.setLevel(logging.INFO)
+
+
try:
options.func(options)
except KeyboardInterrupt: