Skip to content

Commit 4e9dbc1

Browse files
committed
OldPythonCompat: check for old PYTHON_COMPAT in modified ebuilds
Resolves: #591 Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
1 parent 839a1f4 commit 4e9dbc1

2 files changed

Lines changed: 58 additions & 2 deletions

File tree

src/pkgcheck/checks/git.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,20 @@ def desc(self):
221221
return f"{self.filename!r} has changed SRC_URI from {self.old_uri!r} to {self.new_uri!r}"
222222

223223

224+
class OldPythonCompat(results.VersionResult, results.Warning):
225+
"""Package still lists old targets in ``PYTHON_COMPAT``."""
226+
227+
def __init__(self, old_targets, **kwargs):
228+
super().__init__(**kwargs)
229+
self.old_targets = tuple(old_targets)
230+
231+
@property
232+
def desc(self):
233+
s = pluralism(self.old_targets)
234+
targets = ", ".join(self.old_targets)
235+
return f"old PYTHON_COMPAT target{s} listed: [ {targets} ]"
236+
237+
224238
class _RemovalRepo(UnconfiguredTree):
225239
"""Repository of removed packages stored in a temporary directory."""
226240

@@ -278,7 +292,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
278292
_source = (sources.PackageRepoSource, (), (("source", GitCommitsRepoSource),))
279293
required_addons = (git.GitAddon,)
280294
known_results = frozenset(
281-
[
295+
{
282296
DirectStableKeywords,
283297
DirectNoMaintainer,
284298
RdependChange,
@@ -291,10 +305,13 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
291305
SuspiciousSrcUriChange,
292306
PythonPEP517WithoutRevbump,
293307
EAPIChangeWithoutRevbump,
294-
]
308+
OldPythonCompat,
309+
}
295310
)
296311

297312
python_pep517_regex = re.compile("^DISTUTILS_USE_PEP517=")
313+
python_compat_declare_regex = re.compile(r"^declare -a PYTHON_COMPAT=(?P<value>.+)$")
314+
env_array_elem_regex = re.compile(r'\[\d+\]="(?P<val>.+?)"')
298315

299316
# package categories that are committed with stable keywords
300317
allowed_direct_stable = frozenset(["acct-user", "acct-group"])
@@ -306,6 +323,10 @@ def __init__(self, *args, git_addon: git.GitAddon):
306323
self.valid_arches: frozenset[str] = self.options.target_repo.known_arches
307324
self._git_addon = git_addon
308325
self._cleanup = []
326+
self.valid_python_targets = {
327+
use.removeprefix("python_targets_")
328+
for use, _ in self.repo.use_expand_desc.get("python_targets", ())
329+
}
309330

310331
def cleanup(self):
311332
for repo in self._cleanup:
@@ -419,6 +440,14 @@ def found_pep517_lines(cmp_pkg):
419440
else:
420441
yield MissingSlotmove(old_slot, new_slot, pkg=new_pkg)
421442

443+
for env_line in new_pkg.environment.data.splitlines():
444+
if mo := self.python_compat_declare_regex.match(env_line):
445+
if old_compat := {
446+
m.group("val")
447+
for m in re.finditer(self.env_array_elem_regex, mo.group("value"))
448+
}.difference(self.valid_python_targets):
449+
yield OldPythonCompat(sorted(old_compat), pkg=new_pkg)
450+
422451
def _fetchable_str(self, fetch: fetchable) -> tuple[str, str]:
423452
uri = tuple(fetch.uri._uri_source)[0]
424453
if isinstance(uri, tuple):

tests/checks/test_git.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ def _setup(self, tmp_path, tool, make_repo, make_git_repo):
394394
# initialize parent repo
395395
self.parent_git_repo = make_git_repo()
396396
self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo", arches=["amd64"])
397+
os.makedirs(pjoin(self.parent_git_repo.path, "profiles/desc"), exist_ok=True)
398+
with open(pjoin(self.parent_git_repo.path, "profiles/desc/python_targets.desc"), "w") as f:
399+
f.write("python3_10 - Build with Python 3.10\n")
400+
f.write("python3_11 - Build with Python 3.11\n")
397401
self.parent_git_repo.add_all("initial commit")
398402
# create a stub pkg and commit it
399403
self.parent_repo.create_ebuild("cat/pkg-0", eapi="7")
@@ -751,6 +755,29 @@ def test_modified_added_file(self):
751755
expected = git_mod.EAPIChangeWithoutRevbump(pkg=CPV("cat/pkg-1"))
752756
assert r == expected
753757

758+
def test_old_python_compat(self):
759+
# good compat
760+
self.child_repo.create_ebuild("cat/pkg-0", data="PYTHON_COMPAT=( python3_10 python3_11 )")
761+
self.child_git_repo.add_all("cat/pkg-0")
762+
self.init_check()
763+
self.assertNoReport(self.check, self.source)
764+
# one old compat
765+
self.child_repo.create_ebuild("cat/pkg-0", data="PYTHON_COMPAT=( python3_9 python3_10 )")
766+
self.child_git_repo.add_all("cat/pkg-0")
767+
self.init_check()
768+
r = self.assertReport(self.check, self.source)
769+
expected = git_mod.OldPythonCompat(["python3_9"], pkg=CPV("cat/pkg-0"))
770+
assert r == expected
771+
# two old compat
772+
self.child_repo.create_ebuild(
773+
"cat/pkg-0", data="PYTHON_COMPAT=( python3_9 python3_8 python3_10 )"
774+
)
775+
self.child_git_repo.add_all("cat/pkg-0")
776+
self.init_check()
777+
r = self.assertReport(self.check, self.source)
778+
expected = git_mod.OldPythonCompat(["python3_8", "python3_9"], pkg=CPV("cat/pkg-0"))
779+
assert r == expected
780+
754781

755782
class TestGitEclassCommitsCheck(ReportTestCase):
756783
check_kls = git_mod.GitEclassCommitsCheck

0 commit comments

Comments
 (0)