public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/checks/, src/pkgcheck/checks/
@ 2022-10-27 16:49 Arthur Zamarin
  0 siblings, 0 replies; 5+ messages in thread
From: Arthur Zamarin @ 2022-10-27 16:49 UTC (permalink / raw
  To: gentoo-commits

commit:     beb8b645c88c95bab512c04c1df811e7cf5b3250
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 22 12:35:20 2022 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Wed Oct 26 18:45:13 2022 +0000
URL:        https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=beb8b645

BetterCompressionCheck: detect better compression uris

Resolves: https://github.com/pkgcore/pkgcheck/issues/479
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 44 ++++++++++++++++++++++++++++++++++++++
 tests/checks/test_codingstyle.py   | 42 ++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)

diff --git a/src/pkgcheck/checks/codingstyle.py b/src/pkgcheck/checks/codingstyle.py
index 54d57580..e8a2f45a 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -391,6 +391,50 @@ class ObsoleteUriCheck(Check):
                     yield ObsoleteUri(lineno, uri, regexp.sub(repl, uri), pkg=pkg)
 
 
+class BetterCompressionUri(results.LineResult, results.Style):
+    """URI provider has better compression suggestion.
+
+    The URI used to fetch distfile doesn't use the best compression
+    available from the provider. Using better compression can save
+    bandwidth for the users and mirrors.
+    """
+
+    def __init__(self, replacement, **kwargs):
+        super().__init__(**kwargs)
+        self.replacement = replacement
+
+    @property
+    def desc(self):
+        return (f"line {self.lineno}: better compression URI using extension "
+                f"{self.replacement!r} for {self.line!r}")
+
+
+class BetterCompressionCheck(Check):
+    """Scan ebuild for URIs with better compression."""
+
+    _source = sources.EbuildFileRepoSource
+    known_results = frozenset([BetterCompressionUri])
+
+    REGEXPS = (
+        (r'.*\b(?P<uri>(?P<prefix>https?://[^/]*?gitlab[^/]*?/.*/-/archive/.*?/\S*)\.(?:tar\.gz|tar|zip))',
+         '.tar.bz2'),
+    )
+
+    def __init__(self, *args):
+        super().__init__(*args)
+        self.regexes = tuple((re.compile(regexp), repl) for regexp, repl in self.REGEXPS)
+
+    def feed(self, pkg):
+        for lineno, line in enumerate(pkg.lines, 1):
+            if not line.strip() or line.startswith('#'):
+                continue
+            # searching for multiple matches on a single line is too slow
+            for regexp, replacement in self.regexes:
+                if mo := regexp.match(line):
+                    uri = mo.group('uri')
+                    yield BetterCompressionUri(replacement, lineno=lineno, line=uri, pkg=pkg)
+
+
 class HomepageInSrcUri(results.VersionResult, results.Style):
     """${HOMEPAGE} is referenced in SRC_URI.
 

diff --git a/tests/checks/test_codingstyle.py b/tests/checks/test_codingstyle.py
index 0324b349..3becc919 100644
--- a/tests/checks/test_codingstyle.py
+++ b/tests/checks/test_codingstyle.py
@@ -315,6 +315,48 @@ class TestObsoleteUri(misc.ReportTestCase):
         assert uri in str(r)
 
 
+class TestBetterCompression(misc.ReportTestCase):
+
+    check_kls = codingstyle.BetterCompressionCheck
+
+    def test_github_archive_uri(self):
+        uri = 'https://github.com/foo/bar/archive/${PV}.tar.gz'
+        fake_src = [
+            f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n'
+        ]
+        fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src)
+        self.assertNoReport(self.check_kls(None), fake_pkg)
+
+    def test_comment_uri(self):
+        uri = 'https://gitlab.com/GNOME/${PN}/-/archive/${PV}/${P}.tar'
+        fake_src = [
+            f'#SRC_URI="{uri} -> ${{P}}.tar.gz"\n',
+            " ",
+            "    ",
+            f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n',
+        ]
+        fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src)
+        r = self.assertReport(self.check_kls(None), fake_pkg)
+        assert r.lineno == 4
+
+    @pytest.mark.parametrize('uri', (
+        'https://gitlab.com/GNOME/${PN}/-/archive/${PV}/${P}.tar',
+        'https://gitlab.gnome.org/GNOME/${PN}/-/archive/${PV}/${P}.tar.gz',
+        'https://gitlab.gnome.org/GNOME/${PN}/-/archive/${PV}/${P}.zip',
+        'https://gitlab.freedesktop.org/glvnd/${PN}/-/archive/v${PV}/${PN}-v${PV}.tar.gz',
+    ))
+    def test_gitlab_archive_uri(self, uri):
+        fake_src = [
+            f'SRC_URI="{uri} -> ${{P}}.tar.gz"\n'
+        ]
+        fake_pkg = misc.FakePkg("dev-util/diffball-0.5", lines=fake_src)
+        r = self.assertReport(self.check_kls(None), fake_pkg)
+        assert r.lineno == 1
+        assert r.line == uri
+        assert r.replacement == '.tar.bz2'
+        assert uri in str(r)
+
+
 class TestStaticSrcUri(misc.ReportTestCase):
 
     check_kls = codingstyle.MetadataVarCheck


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/checks/, src/pkgcheck/checks/
@ 2022-10-31 18:53 Arthur Zamarin
  0 siblings, 0 replies; 5+ messages in thread
From: Arthur Zamarin @ 2022-10-31 18:53 UTC (permalink / raw
  To: gentoo-commits

commit:     4e69c9d901c37d631cfff6316103e4be53b214c3
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 30 18:36:27 2022 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Mon Oct 31 18:29:55 2022 +0000
URL:        https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4e69c9d9

AcctCheck: use metadata/qa-policy.conf for dynamic id range

Load UID and GID range from metadata/qa-policy.conf under the repo,
validate the format is as expected, and use the values to set expected
ids.

Resolves: https://github.com/pkgcore/pkgcheck/issues/356
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/acct.py | 60 +++++++++++++++++++++++++++++----------
 tests/checks/test_acct.py   | 69 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 107 insertions(+), 22 deletions(-)

diff --git a/src/pkgcheck/checks/acct.py b/src/pkgcheck/checks/acct.py
index cb0053e3..4f144023 100644
--- a/src/pkgcheck/checks/acct.py
+++ b/src/pkgcheck/checks/acct.py
@@ -2,14 +2,16 @@
 
 import re
 from collections import defaultdict
+from configparser import ConfigParser
 from functools import partial
 from itertools import chain
 
 from pkgcore.ebuild import restricts
 from pkgcore.restrictions import packages
+from snakeoil.osutils import pjoin
 
 from .. import results, sources
-from . import GentooRepoCheck, RepoCheck
+from . import GentooRepoCheck, RepoCheck, SkipCheck
 
 
 class MissingAccountIdentifier(results.VersionResult, results.Warning):
@@ -35,13 +37,16 @@ class ConflictingAccountIdentifiers(results.Error):
 
     @property
     def desc(self):
-        return (
-            f"conflicting {self.kind} id {self.identifier} usage: "
-            f"[ {', '.join(self.pkgs)} ]")
+        pkgs = ', '.join(self.pkgs)
+        return f"conflicting {self.kind} id {self.identifier} usage: [ {pkgs} ]"
 
 
 class OutsideRangeAccountIdentifier(results.VersionResult, results.Error):
-    """UID/GID outside allowed allocation range."""
+    """UID/GID outside allowed allocation range.
+
+    To view the range accepted for this repository, look at the file
+    ``metadata/qa-policy.conf`` in the section ``user-group-ids``.
+    """
 
     def __init__(self, kind, identifier, **kwargs):
         super().__init__(**kwargs)
@@ -50,16 +55,20 @@ class OutsideRangeAccountIdentifier(results.VersionResult, results.Error):
 
     @property
     def desc(self):
-        return (
-            f"{self.kind} id {self.identifier} outside permitted "
-            f"static allocation range (0..499, 60001+)")
+        return (f"{self.kind} id {self.identifier} outside permitted "
+            f"static allocation range")
 
 
 class AcctCheck(GentooRepoCheck, RepoCheck):
     """Various checks for acct-* packages.
 
     Verify that acct-* packages do not use conflicting, invalid or out-of-range
-    UIDs/GIDs.
+    UIDs/GIDs. This check uses a special file ``metadata/qa-policy.conf``
+    located within the repository. It should contain a ``user-group-ids``
+    section containing two keys: ``uid-range`` and ``gid-range``, which consist
+    of a comma separated list, either ``<n>`` for a single value or ``<m>-<n>``
+    for a range of values (including both ends). In case this file doesn't
+    exist or is wrongly defined, this check is skipped.
     """
 
     _restricted_source = (sources.RestrictionRepoSource, (packages.OrRestriction(*(
@@ -76,14 +85,37 @@ class AcctCheck(GentooRepoCheck, RepoCheck):
             r'ACCT_(?P<var>USER|GROUP)_ID=(?P<quot>[\'"]?)(?P<id>[0-9]+)(?P=quot)')
         self.seen_uids = defaultdict(partial(defaultdict, list))
         self.seen_gids = defaultdict(partial(defaultdict, list))
+        uid_range, gid_range = self.load_ids_from_configuration(self.options.target_repo)
         self.category_map = {
-            'acct-user': (self.seen_uids, 'USER', (65534,)),
-            'acct-group': (self.seen_gids, 'GROUP', (65533, 65534)),
+            'acct-user': (self.seen_uids, 'USER', tuple(uid_range)),
+            'acct-group': (self.seen_gids, 'GROUP', tuple(gid_range)),
         }
 
+    def parse_config_id_range(self, config: ConfigParser, config_key: str):
+        id_ranges = config['user-group-ids'].get(config_key, None)
+        if not id_ranges:
+            raise SkipCheck(self, f"metadata/qa-policy.conf: missing value for {config_key}")
+        try:
+            for id_range in map(str.strip, id_ranges.split(',')):
+                start, *end = map(int, id_range.split('-', maxsplit=1))
+                if len(end) == 0:
+                    yield range(start, start + 1)
+                else:
+                    yield range(start, end[0] + 1)
+        except ValueError:
+            raise SkipCheck(self, f"metadata/qa-policy.conf: invalid value for {config_key}")
+
+    def load_ids_from_configuration(self, repo):
+        config = ConfigParser()
+        if not config.read(pjoin(repo.location, 'metadata', 'qa-policy.conf')):
+            raise SkipCheck(self, "failed loading 'metadata/qa-policy.conf'")
+        if 'user-group-ids' not in config:
+            raise SkipCheck(self, "metadata/qa-policy.conf: missing section user-group-ids")
+        return self.parse_config_id_range(config, 'uid-range'), self.parse_config_id_range(config, 'gid-range')
+
     def feed(self, pkg):
         try:
-            seen_id_map, expected_var, extra_allowed_ids = self.category_map[pkg.category]
+            seen_id_map, expected_var, allowed_ids = self.category_map[pkg.category]
         except KeyError:
             return
 
@@ -96,9 +128,7 @@ class AcctCheck(GentooRepoCheck, RepoCheck):
             yield MissingAccountIdentifier(f"ACCT_{expected_var}_ID", pkg=pkg)
             return
 
-        # all UIDs/GIDs must be in <750, with special exception
-        # of nobody/nogroup which use 65534/65533
-        if found_id >= 750 and found_id not in extra_allowed_ids:
+        if not any(found_id in id_range for id_range in allowed_ids):
             yield OutsideRangeAccountIdentifier(expected_var.lower(), found_id, pkg=pkg)
             return
 

diff --git a/tests/checks/test_acct.py b/tests/checks/test_acct.py
index cd8f852f..57273705 100644
--- a/tests/checks/test_acct.py
+++ b/tests/checks/test_acct.py
@@ -1,4 +1,7 @@
-from pkgcheck.checks import acct
+import textwrap
+
+import pytest
+from pkgcheck.checks import acct, SkipCheck
 from pkgcore.test.misc import FakeRepo
 from snakeoil.cli import arghparse
 
@@ -11,17 +14,27 @@ class TestAcctUser(misc.ReportTestCase):
 
     kind = 'user'
 
+    @pytest.fixture(autouse=True)
+    def _setup(self, tmp_path):
+        (metadata := tmp_path / 'metadata').mkdir()
+        (metadata / 'qa-policy.conf').write_text(textwrap.dedent("""\
+            [user-group-ids]
+            uid-range = 0-749,65534
+            gid-range = 0-749,65533,65534
+        """))
+        self.location = str(tmp_path)
+
     def mk_check(self, pkgs):
-        self.repo = FakeRepo(pkgs=pkgs, repo_id='test')
-        check = self.check_kls(arghparse.Namespace(target_repo=self.repo, gentoo_repo=True))
+        repo = FakeRepo(pkgs=pkgs, repo_id='test', location=self.location)
+        check = self.check_kls(arghparse.Namespace(target_repo=repo, gentoo_repo=True))
         return check
 
     def mk_pkg(self, name, identifier, version=1, ebuild=None):
         if ebuild is None:
-            ebuild = f'''
-inherit acct-{self.kind}
-ACCT_{self.kind.upper()}_ID="{identifier}"
-'''
+            ebuild = textwrap.dedent(f'''\
+                inherit acct-{self.kind}
+                ACCT_{self.kind.upper()}_ID="{identifier}"
+            ''')
         return misc.FakePkg(f'acct-{self.kind}/{name}-{version}', ebuild=ebuild)
 
     def test_unmatching_pkgs(self):
@@ -33,6 +46,7 @@ ACCT_{self.kind.upper()}_ID="{identifier}"
     def test_correct_ids(self):
         pkgs = (self.mk_pkg('foo', 100),
                 self.mk_pkg('bar', 200),
+                self.mk_pkg('test', 749),
                 self.mk_pkg('nobody', 65534))
         check = self.mk_check(pkgs)
         self.assertNoReport(check, pkgs)
@@ -110,3 +124,44 @@ class TestAcctGroup(TestAcctUser):
         pkg = self.mk_pkg('nogroup', 65533)
         check = self.mk_check((pkg,))
         self.assertNoReport(check, pkg)
+
+
+class TestQaPolicyValidation(misc.ReportTestCase):
+
+    def mk_check(self, tmp_path, content):
+        if content:
+            (metadata := tmp_path / 'metadata').mkdir()
+            (metadata / 'qa-policy.conf').write_text(textwrap.dedent(content))
+        repo = FakeRepo(repo_id='test', location=str(tmp_path))
+        return acct.AcctCheck(arghparse.Namespace(target_repo=repo, gentoo_repo=True))
+
+    def test_missing_qa_policy(self, tmp_path):
+        with pytest.raises(SkipCheck, match="failed loading 'metadata/qa-policy.conf'"):
+            self.mk_check(tmp_path, None)
+
+    def test_missing_section(self, tmp_path):
+        with pytest.raises(SkipCheck, match="missing section user-group-ids"):
+            self.mk_check(tmp_path, '''\
+                [random]
+                x = 5
+            ''')
+
+    def test_missing_config(self, tmp_path):
+        with pytest.raises(SkipCheck, match="missing value for gid-range"):
+            self.mk_check(tmp_path, '''\
+                [user-group-ids]
+                uid-range = 0-749
+            ''')
+
+    @pytest.mark.parametrize('value', (
+        'start-end',
+        '0-749-1500',
+        ',150',
+    ))
+    def test_invalid_value(self, tmp_path, value):
+        with pytest.raises(SkipCheck, match="invalid value for uid-range"):
+            self.mk_check(tmp_path, f'''\
+                [user-group-ids]
+                uid-range = {value}
+                gid-range = 0-749
+            ''')


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/checks/, src/pkgcheck/checks/
@ 2023-03-06 19:53 Arthur Zamarin
  0 siblings, 0 replies; 5+ messages in thread
From: Arthur Zamarin @ 2023-03-06 19:53 UTC (permalink / raw
  To: gentoo-commits

commit:     ea78fb2ea4bf99253d31afea9b6141f8ffc5b6dc
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Sun Mar  5 17:51:56 2023 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Sun Mar  5 17:51:56 2023 +0000
URL:        https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=ea78fb2e

GitPkgCommitsCheck: add check for EAPI change without revbump

Resolves: https://github.com/pkgcore/pkgcheck/issues/557
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/git.py | 16 ++++++++++++++++
 tests/checks/test_git.py   | 16 +++++++++++++---
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 22780cbe..7309a08f 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -183,6 +183,18 @@ class PythonPEP517WithoutRevbump(results.PackageResult, results.Warning):
     desc = "changed DISTUTILS_USE_PEP517 without new revision"
 
 
+class EAPIChangeWithoutRevbump(results.PackageResult, results.Warning):
+    """Package has changed EAPI without revbump.
+
+    The package has changed EAPI without a new revision. An EAPI bump
+    might affect the installed files (EAPI changes, eclass functions
+    may change behavior, new portage features might be used, etc.).
+    The change should also be reflected in the vdb's EAPI file.
+    """
+
+    desc = "changed EAPI without new revision"
+
+
 class SrcUriChecksumChange(results.PackageResult, results.Error):
     """SRC_URI changing checksum without distfile rename."""
 
@@ -278,6 +290,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
             SrcUriChecksumChange,
             SuspiciousSrcUriChange,
             PythonPEP517WithoutRevbump,
+            EAPIChangeWithoutRevbump,
         ]
     )
 
@@ -392,6 +405,9 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
             if found_old_pep517_line ^ found_new_pep517_line:
                 yield PythonPEP517WithoutRevbump(pkg=new_pkg)
 
+        if old_pkg.eapi != new_pkg.eapi:
+            yield EAPIChangeWithoutRevbump(pkg=new_pkg)
+
         old_slot, new_slot = old_pkg.slot, new_pkg.slot
         if old_slot != new_slot:
             slotmoves = (

diff --git a/tests/checks/test_git.py b/tests/checks/test_git.py
index 5deaad71..7eb7907a 100644
--- a/tests/checks/test_git.py
+++ b/tests/checks/test_git.py
@@ -395,7 +395,7 @@ class TestGitPkgCommitsCheck(ReportTestCase):
         self.parent_repo = make_repo(self.parent_git_repo.path, repo_id="gentoo", arches=["amd64"])
         self.parent_git_repo.add_all("initial commit")
         # create a stub pkg and commit it
-        self.parent_repo.create_ebuild("cat/pkg-0")
+        self.parent_repo.create_ebuild("cat/pkg-0", eapi="7")
         self.parent_git_repo.add_all("cat/pkg-0")
 
         # initialize child repo
@@ -694,6 +694,16 @@ class TestGitPkgCommitsCheck(ReportTestCase):
         expected = git_mod.PythonPEP517WithoutRevbump(pkg=CPV("newcat/newpkg-1"))
         assert r == expected
 
+    def test_eapi_change(self):
+        # bump eapi
+        self.child_repo.create_ebuild("cat/pkg-0", eapi="8")
+        self.child_git_repo.add_all("cat/pkg-0")
+        # pull changes to child repo
+        self.init_check()
+        r = self.assertReport(self.check, self.source)
+        expected = git_mod.EAPIChangeWithoutRevbump(pkg=CPV("cat/pkg-0"))
+        assert r == expected
+
     def test_src_uri_change(self):
         distfile = [
             "DIST",
@@ -721,8 +731,8 @@ class TestGitPkgCommitsCheck(ReportTestCase):
         assert r == git_mod.SuspiciousSrcUriChange(old_url, new_url, distfile[1], pkg=CP("cat/pkg"))
         # revert change and check for no report with same mirror url
         self.child_git_repo.run(["git", "reset", "--hard", "origin/main"])
-        self.child_repo.create_ebuild("cat/pkg-1", src_uri=old_url, eapi="8")
-        self.child_git_repo.add_all("cat/pkg: bump EAPI", signoff=True)
+        self.child_repo.create_ebuild("cat/pkg-1", src_uri=old_url, homepage="https://gentoo.org")
+        self.child_git_repo.add_all("cat/pkg: update HOMEPAGE", signoff=True)
         self.init_check()
         self.assertNoReport(self.check, self.source)
 


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/checks/, src/pkgcheck/checks/
@ 2023-07-01  9:12 Arthur Zamarin
  0 siblings, 0 replies; 5+ messages in thread
From: Arthur Zamarin @ 2023-07-01  9:12 UTC (permalink / raw
  To: gentoo-commits

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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/checks/, src/pkgcheck/checks/
@ 2024-07-19  6:22 Arthur Zamarin
  0 siblings, 0 replies; 5+ messages in thread
From: Arthur Zamarin @ 2024-07-19  6:22 UTC (permalink / raw
  To: gentoo-commits

commit:     04c8872e3a47e5ad32690c0483bc5c4001ee8412
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 19 06:21:53 2024 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Fri Jul 19 06:21:53 2024 +0000
URL:        https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=04c8872e

BadDependency: catch := slot operator in PDEPEND

Resolves: https://github.com/pkgcore/pkgcheck/issues/693
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/metadata.py | 13 +++++++++----
 tests/checks/test_metadata.py   |  7 +++++++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 2cbb8985..3c3b4bf9 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -942,10 +942,15 @@ class DependencyCheck(Check):
                         if all(map(self.deprecated, pkgs)):
                             deprecated[attr].add(atom)
 
-                    if in_or_restriction and atom.slot_operator == "=":
-                        yield BadDependency(
-                            attr, atom, "= slot operator used inside || block", pkg=pkg
-                        )
+                    if atom.slot_operator == "=":
+                        if in_or_restriction:
+                            yield BadDependency(
+                                attr, atom, "= slot operator used inside || block", pkg=pkg
+                            )
+                        elif attr == "pdepend" and not atom.blocks:
+                            # prohibited by PMS at the "Slot dependencies" section
+                            msg = "':=' operator is invalid in"
+                            yield BadDependency(attr, atom, msg, pkg=pkg)
 
                     if pkg.eapi.options.has_use_dep_defaults and atom.use is not None:
                         missing_use_deps = self._check_use_deps(attr, atom)

diff --git a/tests/checks/test_metadata.py b/tests/checks/test_metadata.py
index f6c2f00b..be5ae182 100644
--- a/tests/checks/test_metadata.py
+++ b/tests/checks/test_metadata.py
@@ -928,6 +928,13 @@ class TestDependencyCheck(use_based(), misc.ReportTestCase):
         assert "= slot operator used in blocker" in str(r)
         assert f'{attr.upper()}="!dev-libs/foo:="' in str(r)
 
+        if attr == "PDEPEND":
+            # check for := in PDEPEND
+            r = self.assertReport(chk, mk_pkg(eapi="5", depset="dev-libs/foo:="))
+            assert isinstance(r, metadata.BadDependency)
+            assert "':=' operator" in str(r)
+            assert f'{attr.upper()}="dev-libs/foo:="' in str(r)
+
         # check for missing package revisions
         self.assertNoReport(chk, mk_pkg("=dev-libs/foo-1-r0"))
         r = self.assertReport(chk, mk_pkg(eapi="6", depset="=dev-libs/foo-1"))


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-07-19  6:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-27 16:49 [gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/checks/, src/pkgcheck/checks/ Arthur Zamarin
  -- strict thread matches above, loose matches on Subject: below --
2022-10-31 18:53 Arthur Zamarin
2023-03-06 19:53 Arthur Zamarin
2023-07-01  9:12 Arthur Zamarin
2024-07-19  6:22 Arthur Zamarin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox