commit: 4e9dbc12ea3b269c021bca30599b043a448acf26 Author: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> AuthorDate: Fri Jun 30 20:54:40 2023 +0000 Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> CommitDate: Sat Jul 1 09:00:35 2023 +0000 URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4e9dbc12
OldPythonCompat: check for old PYTHON_COMPAT in modified ebuilds Resolves: https://github.com/pkgcore/pkgcheck/issues/591 Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org> src/pkgcheck/checks/git.py | 33 +++++++++++++++++++++++++++++++-- tests/checks/test_git.py | 27 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py index c7785729..8a80fb90 100644 --- a/src/pkgcheck/checks/git.py +++ b/src/pkgcheck/checks/git.py @@ -221,6 +221,20 @@ class SuspiciousSrcUriChange(results.PackageResult, results.Warning): return f"{self.filename!r} has changed SRC_URI from {self.old_uri!r} to {self.new_uri!r}" +class OldPythonCompat(results.VersionResult, results.Warning): + """Package still lists old targets in ``PYTHON_COMPAT``.""" + + def __init__(self, old_targets, **kwargs): + super().__init__(**kwargs) + self.old_targets = tuple(old_targets) + + @property + def desc(self): + s = pluralism(self.old_targets) + targets = ", ".join(self.old_targets) + return f"old PYTHON_COMPAT target{s} listed: [ {targets} ]" + + class _RemovalRepo(UnconfiguredTree): """Repository of removed packages stored in a temporary directory.""" @@ -278,7 +292,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck): _source = (sources.PackageRepoSource, (), (("source", GitCommitsRepoSource),)) required_addons = (git.GitAddon,) known_results = frozenset( - [ + { DirectStableKeywords, DirectNoMaintainer, RdependChange, @@ -291,10 +305,13 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck): SuspiciousSrcUriChange, PythonPEP517WithoutRevbump, EAPIChangeWithoutRevbump, - ] + OldPythonCompat, + } ) python_pep517_regex = re.compile("^DISTUTILS_USE_PEP517=") + python_compat_declare_regex = re.compile(r"^declare -a PYTHON_COMPAT=(?P<value>.+)$") + env_array_elem_regex = re.compile(r'\[\d+\]="(?P<val>.+?)"') # package categories that are committed with stable keywords allowed_direct_stable = frozenset(["acct-user", "acct-group"]) @@ -306,6 +323,10 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck): self.valid_arches: frozenset[str] = self.options.target_repo.known_arches self._git_addon = git_addon self._cleanup = [] + self.valid_python_targets = { + use.removeprefix("python_targets_") + for use, _ in self.repo.use_expand_desc.get("python_targets", ()) + } def cleanup(self): for repo in self._cleanup: @@ -419,6 +440,14 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck): else: yield MissingSlotmove(old_slot, new_slot, pkg=new_pkg) + for env_line in new_pkg.environment.data.splitlines(): + if mo := self.python_compat_declare_regex.match(env_line): + if old_compat := { + m.group("val") + for m in re.finditer(self.env_array_elem_regex, mo.group("value")) + }.difference(self.valid_python_targets): + yield OldPythonCompat(sorted(old_compat), pkg=new_pkg) + def _fetchable_str(self, fetch: fetchable) -> tuple[str, str]: uri = tuple(fetch.uri._uri_source)[0] if isinstance(uri, tuple): diff --git a/tests/checks/test_git.py b/tests/checks/test_git.py index 03687451..ab6efee2 100644 --- a/tests/checks/test_git.py +++ b/tests/checks/test_git.py @@ -394,6 +394,10 @@ class TestGitPkgCommitsCheck(ReportTestCase): # initialize parent repo self.parent_git_repo = make_git_repo() self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo", arches=["amd64"]) + os.makedirs(pjoin(self.parent_git_repo.path, "profiles/desc"), exist_ok=True) + with open(pjoin(self.parent_git_repo.path, "profiles/desc/python_targets.desc"), "w") as f: + f.write("python3_10 - Build with Python 3.10\n") + f.write("python3_11 - Build with Python 3.11\n") self.parent_git_repo.add_all("initial commit") # create a stub pkg and commit it self.parent_repo.create_ebuild("cat/pkg-0", eapi="7") @@ -751,6 +755,29 @@ class TestGitPkgCommitsCheck(ReportTestCase): expected = git_mod.EAPIChangeWithoutRevbump(pkg=CPV("cat/pkg-1")) assert r == expected + def test_old_python_compat(self): + # good compat + self.child_repo.create_ebuild("cat/pkg-0", data="PYTHON_COMPAT=( python3_10 python3_11 )") + self.child_git_repo.add_all("cat/pkg-0") + self.init_check() + self.assertNoReport(self.check, self.source) + # one old compat + self.child_repo.create_ebuild("cat/pkg-0", data="PYTHON_COMPAT=( python3_9 python3_10 )") + self.child_git_repo.add_all("cat/pkg-0") + self.init_check() + r = self.assertReport(self.check, self.source) + expected = git_mod.OldPythonCompat(["python3_9"], pkg=CPV("cat/pkg-0")) + assert r == expected + # two old compat + self.child_repo.create_ebuild( + "cat/pkg-0", data="PYTHON_COMPAT=( python3_9 python3_8 python3_10 )" + ) + self.child_git_repo.add_all("cat/pkg-0") + self.init_check() + r = self.assertReport(self.check, self.source) + expected = git_mod.OldPythonCompat(["python3_8", "python3_9"], pkg=CPV("cat/pkg-0")) + assert r == expected + class TestGitEclassCommitsCheck(ReportTestCase): check_kls = git_mod.GitEclassCommitsCheck
