From d74a55c4ccc358a563ed3107f7bceab19106e7f3 Mon Sep 17 00:00:00 2001 From: Olav Vitters Date: Tue, 21 Apr 2020 17:05:00 +0200 Subject: limit clean-spec alternatives to the ones provided only by 1 package --- mgagnome | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 13 deletions(-) diff --git a/mgagnome b/mgagnome index 77c795c..c000d25 100755 --- a/mgagnome +++ b/mgagnome @@ -554,7 +554,7 @@ class SpecFile(object): if (flag & rpm.RPMSENSE_GREATER): ver_cmp += '>' if (flag & rpm.RPMSENSE_EQUAL): ver_cmp += '=' - br[req.decode('utf-8')] = (ver_cmp, ver) + br[req] = (ver_cmp, ver) return br @property @@ -1092,19 +1092,65 @@ class Downstream(object): def packages(self): return sorted(self._packages) - _provides_cache = {} + _provide_to_alternate = {} @classmethod def alternative_provides(cls, search_for): """Give alternative provides for a certain provide - Relies on urpmq. Results are cached. + Relies on urpmf. Results are cached. It will only provide alternatives if + the alternative is only provided by one package. Meaning, if a pkgconfig(foo) + is provided by 2 packages, the pkgconfig(foo) will NOT be given as an + alternative. - Inner working: + Sort of works like: $ urpmq --whatprovides $search_for --provides""" - if search_for not in cls._provides_cache: - cls._provides_cache[search_for] = subprocess.check_output(["urpmq", "--whatprovides", search_for, "--provides"]).decode("utf-8").splitlines() - return cls._provides_cache[search_for] + if not len(cls._provide_to_alternate): + provide_has_multiple_pkgs = set() + _provide_to_pkg = {} + _pkg_to_provide = {} + for myline in subprocess.check_output(['urpmf', "--qf", "%name\t%provides\t%arch", '.']).decode("utf-8").splitlines(): + pkgname, pkgprovide, pkgarch = myline.split("\t") + if pkgarch in ('src', 'i586'): continue + if '-debug' in pkgprovide: continue + + if "[" in pkgprovide and pkgprovide.endswith("]"): + pkgprovidepart = pkgprovide.rstrip("]").partition("[") + else: + pkgprovidepart = pkgprovide.partition("[") + + if pkgprovidepart[0] in _provide_to_pkg: + _provide_to_pkg[pkgprovidepart[0]].add(pkgname) + else: + _provide_to_pkg[pkgprovidepart[0]] = set((pkgname,)) + + if pkgname in _pkg_to_provide: + _pkg_to_provide[pkgname].add(pkgprovidepart[0]) + else: + _pkg_to_provide[pkgname] = set((pkgprovidepart[0],)) + + provide_has_single = set() + for key, stash in _provide_to_pkg.items(): + if len(stash) == 1: + provide_has_single.add(key) + + + for key in provide_has_single: + if '(' in key: continue + + for pkgname in _provide_to_pkg[key]: + for pkgprovide in _pkg_to_provide[pkgname]: + if pkgprovide in provide_has_single and '(' in pkgprovide: + if key in cls._provide_to_alternate: + cls._provide_to_alternate[key].add(pkgprovide) + else: + cls._provide_to_alternate[key] = set((pkgprovide,)) + + + if search_for in cls._provide_to_alternate: + return cls._provide_to_alternate[search_for] + + return set() @classmethod @retry(subprocess.CalledProcessError) @@ -1478,9 +1524,14 @@ def cmd_clean_spec_multi(args): } } + if options.debug: + import pprint + print(pprint.pprint(convert_brs.items())) for convert_br, keys in convert_brs.items(): keys['changes'] = {} br_old = [r for r in list(br.keys()) if keys['check_br'](r)] + if options.debug: + pprint.pprint(br) for req in br_old: provides = Downstream.alternative_provides(req) provides_alt = [clean_pkgconfig_prov(prov) for prov in provides if keys['check_provide'](prov)] @@ -1540,11 +1591,12 @@ def cmd_clean_spec(options, parser): packages = options.package if len(options.package) else (l[0] for l in join_streams()) - with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor: - executor.map(cmd_clean_spec_multi, ((options, package) for package in packages)) -# DEBUG: -# for package in packages: -# cmd_clean_spec_multi((options, package)) + if options.debug: + for package in packages: + cmd_clean_spec_multi((options, package)) + else: + with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor: + executor.map(cmd_clean_spec_multi, ((options, package) for package in packages)) def cmd_new_release(options, parser): success = True @@ -1792,6 +1844,8 @@ def main(): help="File containing upstream names") parser.add_argument("-d", "--distro", action="store", dest="distro", help="Distribution release") + parser.add_argument("--debug", action="store_true", dest="debug", + help="Use for debugging") # SUBPARSERS subparsers = parser.add_subparsers(title='subcommands') @@ -1799,7 +1853,7 @@ def main(): subparser.add_argument("-s", "--submit", action="store_true", dest="submit", help="Increase version for stable upgrades and submit") subparser.set_defaults( - func=cmd_check_latest, submit=False + func=cmd_check_latest, submit=False, debug=False ) subparser = subparsers.add_parser('check-prep', help='check prep phase') -- cgit v1.2.1