diff options
author | Arthur Zamarin <arthurzam@gentoo.org> | 2023-06-29 21:27:16 +0300 |
---|---|---|
committer | Arthur Zamarin <arthurzam@gentoo.org> | 2023-06-30 21:36:33 +0300 |
commit | 839a1f4a9a723e642ac4a1b26154bbb8f49e488a (patch) | |
tree | 6386e5e9f9ee8af1782e971924cbe2b9db2b644f /src | |
parent | issues templates: fix command for pkgcore version (diff) | |
download | pkgcheck-839a1f4a9a723e642ac4a1b26154bbb8f49e488a.tar.gz pkgcheck-839a1f4a9a723e642ac4a1b26154bbb8f49e488a.tar.bz2 pkgcheck-839a1f4a9a723e642ac4a1b26154bbb8f49e488a.zip |
RubyCompatCheck: new check for new USE_RUBY compatible values
Resolves: https://github.com/pkgcore/pkgcheck/issues/304
Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/pkgcheck/checks/ruby.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/pkgcheck/checks/ruby.py b/src/pkgcheck/checks/ruby.py new file mode 100644 index 00000000..d7cbb914 --- /dev/null +++ b/src/pkgcheck/checks/ruby.py @@ -0,0 +1,109 @@ +import itertools + +from pkgcore.ebuild.atom import atom +from snakeoil.sequences import iflatten_instance +from snakeoil.strings import pluralism + +from .. import results +from . import Check + + +IUSE_PREFIX = "ruby_targets_" + + +class RubyCompatUpdate(results.VersionResult, results.Info): + """``USE_RUBY`` can be updated to support newer ruby version(s).""" + + def __init__(self, updates, **kwargs): + super().__init__(**kwargs) + self.updates = tuple(updates) + + @property + def desc(self): + s = pluralism(self.updates) + updates = ", ".join(self.updates) + return f"USE_RUBY update{s} available: {updates}" + + +class RubyCompatCheck(Check): + """Check ruby ebuilds for possible ``USE_RUBY`` updates. + + Supports ebuilds inheriting ``ruby-ng``. + """ + + known_results = frozenset({RubyCompatUpdate}) + + whitelist_categories = frozenset({"virtual"}) + + def __init__(self, *args): + super().__init__(*args) + repo = self.options.target_repo + # sorter for ruby targets leveraging USE_EXPAND flag ordering from repo + self.sorter = repo.use_expand_sorter("ruby_targets") + + # determine available USE_RUBY use flags + targets = [] + for target, _desc in repo.use_expand_desc.get(IUSE_PREFIX[:-1], ()): + if target[len(IUSE_PREFIX) :].startswith("ruby"): + targets.append(target[len(IUSE_PREFIX) :]) + self.multi_targets = tuple(sorted(targets, key=self.sorter)) + + def ruby_deps(self, deps, prefix): + for dep in (x for x in deps if x.use): + for x in dep.use: + if x.startswith(("-", "!")): + continue + if x.startswith(prefix): + yield dep.no_usedeps + break + + def deps(self, pkg): + """Set of dependencies for a given package's attributes.""" + return { + p + for attr in (x.lower() for x in pkg.eapi.dep_keys) + for p in iflatten_instance(getattr(pkg, attr), atom) + if not p.blocks + } + + def feed(self, pkg): + if pkg.category in self.whitelist_categories or "ruby-ng" not in pkg.inherited: + return + + deps = self.deps(pkg) + + try: + # determine the latest supported ruby version + latest_target = sorted( + ( + f"ruby{x.slot.replace('.', '')}" + for x in deps + if x.key == "dev-lang/ruby" and x.slot is not None + ), + key=self.sorter, + )[-1] + except IndexError: + return + + # determine ruby impls to target + targets = set( + itertools.takewhile(lambda x: x != latest_target, reversed(self.multi_targets)) + ) + + if targets: + try: + # determine if deps support missing ruby targets + for dep in self.ruby_deps(deps, IUSE_PREFIX): + # TODO: use query caching for repo matching? + latest = sorted(self.options.search_repo.match(dep))[-1] + targets.intersection_update( + f"ruby{x.rsplit('ruby', 1)[-1]}" + for x in latest.iuse_stripped + if x.startswith(IUSE_PREFIX) + ) + if not targets: + return + except IndexError: + return + + yield RubyCompatUpdate(sorted(targets, key=self.sorter), pkg=pkg) |