[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2024-05-09 Thread Arthur Zamarin
commit: 4f08057161483e92cd64febac44ffbc1dd3bc718
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Thu May  9 19:38:42 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu May  9 19:38:42 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4f080571

NewerEAPIAvailable: fix code

Fixes: 4a7a02f60c9f87ad85670e0e798c5aadb8096c92
Resolves: https://github.com/pkgcore/pkgcheck/issues/679
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index b6777161..d4ab12ff 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -388,7 +388,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 for eclass in new_pkg.inherit
 )
 current_eapi = int(str(new_pkg.eapi))
-common_max_eapi = max(frozenset.intersection(*eclass_eapis), 0)
+common_max_eapi = max(frozenset.intersection(*eclass_eapis), 
default=0)
 if common_max_eapi > current_eapi:
 yield NewerEAPIAvailable(common_max_eapi, pkg=new_pkg)
 



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2024-05-08 Thread Arthur Zamarin
commit: 4a7a02f60c9f87ad85670e0e798c5aadb8096c92
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Wed May  8 16:30:48 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed May  8 16:30:48 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4a7a02f6

NewerEAPIAvailable: handle better when no eclasses EAPI

It might sometimes not find any intersection of eclasses EAPIs, in which
it is better to not report anything then to report a false positive or
worse, to explode with exception.

Resolves: https://github.com/pkgcore/pkgcheck/issues/679
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index a2619491..b6777161 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -388,7 +388,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 for eclass in new_pkg.inherit
 )
 current_eapi = int(str(new_pkg.eapi))
-common_max_eapi = max(frozenset.intersection(*eclass_eapis))
+common_max_eapi = max(frozenset.intersection(*eclass_eapis), 0)
 if common_max_eapi > current_eapi:
 yield NewerEAPIAvailable(common_max_eapi, pkg=new_pkg)
 



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, src/pkgcheck/addons/

2024-05-08 Thread Arthur Zamarin
commit: 298deaf274ff1fdf61de021ee8df060c3ca52033
Author: Lucio Sauer  posteo  net>
AuthorDate: Tue Apr 30 21:28:51 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed May  8 16:23:21 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=298deaf2

fix crash when performing --timeout 0 call to ftp:// site

e.g.
pkgcheck scan --net -c HomepageUrlCheck --timeout 0 app-admin/chrootuid
at checkout 127160ac611d39cc6bb2ca21fcf99a086fe2b176

Python's ftplib raises a ValueError with timeout=0. Use timeout=None to
put the underlying socket in blocking mode. See
https://docs.python.org/3/library/socket.html#socket.socket.settimeout
for legal timeout values.

Signed-off-by: Lucio Sauer  posteo.net>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/addons/__init__.py | 12 +++-
 src/pkgcheck/addons/net.py  |  7 +--
 src/pkgcheck/checks/__init__.py |  2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/pkgcheck/addons/__init__.py b/src/pkgcheck/addons/__init__.py
index 56678669..c621c53b 100644
--- a/src/pkgcheck/addons/__init__.py
+++ b/src/pkgcheck/addons/__init__.py
@@ -274,6 +274,16 @@ class UseAddon(base.Addon):
 class NetAddon(base.Addon):
 """Addon supporting network functionality."""
 
+def __init__(self, *args):
+super().__init__(*args)
+
+if self.options.timeout == 0:
+# set timeout to 0 to never timeout
+self.timeout = None
+else:
+# default to timing out connections after 5 seconds
+self.timeout = self.options.timeout if self.options.timeout is not 
None else 5
+
 @classmethod
 def mangle_argparser(cls, parser):
 group = parser.add_argument_group("network")
@@ -291,7 +301,7 @@ class NetAddon(base.Addon):
 
 return Session(
 concurrent=self.options.tasks,
-timeout=self.options.timeout,
+timeout=self.timeout,
 user_agent=self.options.user_agent,
 )
 except ImportError as e:

diff --git a/src/pkgcheck/addons/net.py b/src/pkgcheck/addons/net.py
index 782d74d1..91101282 100644
--- a/src/pkgcheck/addons/net.py
+++ b/src/pkgcheck/addons/net.py
@@ -18,12 +18,7 @@ class Session(requests.Session):
 
 def __init__(self, concurrent=None, timeout=None, user_agent=None):
 super().__init__()
-if timeout == 0:
-# set timeout to 0 to never timeout
-self.timeout = None
-else:
-# default to timing out connections after 5 seconds
-self.timeout = timeout if timeout is not None else 5
+self.timeout = timeout
 
 # block when urllib3 connection pool is full
 concurrent = concurrent if concurrent is not None else os.cpu_count() 
* 5

diff --git a/src/pkgcheck/checks/__init__.py b/src/pkgcheck/checks/__init__.py
index b5caa244..556f720e 100644
--- a/src/pkgcheck/checks/__init__.py
+++ b/src/pkgcheck/checks/__init__.py
@@ -127,7 +127,7 @@ class NetworkCheck(AsyncCheck, OptionalCheck):
 super().__init__(*args, **kwargs)
 if not self.options.net:
 raise SkipCheck(self, "network checks not enabled")
-self.timeout = self.options.timeout
+self.timeout = net_addon.timeout
 self.session = net_addon.session
 
 



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2024-03-07 Thread Arthur Zamarin
commit: 2ed2a36a62f3bb9801c187c053ec67ec6bb47565
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Mar  2 07:13:16 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Mar  2 07:15:06 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=2ed2a36a

NewerEAPIAvailable: committing new ebuilds with old EAPI

Catch cases where new ebuilds are committed with old EAPIs. This is
checked during `--commits` stage.

Resolves: https://github.com/pkgcore/pkgcheck/issues/666
Signed-off-by: Arthur Zamarin  gentoo.org>

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

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 31f1dc69..a2619491 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -236,6 +236,23 @@ class OldPythonCompat(results.VersionResult, 
results.Warning):
 return f"old PYTHON_COMPAT target{s} listed: [ {targets} ]"
 
 
+class NewerEAPIAvailable(results.VersionResult, results.Warning):
+"""Package is eligible for a newer EAPI.
+
+A new package version was added, using an older EAPI, than all supported by
+inherited eclasses. You should consider bumping the EAPI to the suggested
+value.
+"""
+
+def __init__(self, eapi: int, **kwargs):
+super().__init__(**kwargs)
+self.eapi = eapi
+
+@property
+def desc(self):
+return f"ebuild eligible for newer EAPI={self.eapi}"
+
+
 class _RemovalRepo(UnconfiguredTree):
 """Repository of removed packages stored in a temporary directory."""
 
@@ -295,7 +312,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 """Check unpushed git package commits for various issues."""
 
 _source = (sources.PackageRepoSource, (), (("source", 
GitCommitsRepoSource),))
-required_addons = (git.GitAddon,)
+required_addons = (git.GitAddon, sources.EclassAddon)
 known_results = frozenset(
 {
 DirectStableKeywords,
@@ -311,6 +328,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 PythonPEP517WithoutRevbump,
 EAPIChangeWithoutRevbump,
 OldPythonCompat,
+NewerEAPIAvailable,
 }
 )
 
@@ -321,12 +339,13 @@ class GitPkgCommitsCheck(GentooRepoCheck, 
GitCommitsCheck):
 # package categories that are committed with stable keywords
 allowed_direct_stable = frozenset(["acct-user", "acct-group"])
 
-def __init__(self, *args, git_addon: git.GitAddon):
+def __init__(self, *args, git_addon: git.GitAddon, eclass_addon: 
sources.EclassAddon):
 super().__init__(*args)
 self.today = datetime.today()
 self.repo = self.options.target_repo
 self.valid_arches: frozenset[str] = 
self.options.target_repo.known_arches
 self._git_addon = git_addon
+self.eclass_cache = eclass_addon.eclasses
 self._cleanup = []
 self.valid_python_targets = {
 use.removeprefix("python_targets_")
@@ -354,6 +373,25 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 """Create/load cached repo of packages added to git."""
 return self._git_addon.cached_repo(git.GitAddedRepo)
 
+def addition_checks(self, pkgs):
+"""Check for issues due to package additions."""
+pkg = pkgs[0]
+try:
+new_pkg = self.repo.match(pkg.versioned_atom)[0]
+except IndexError:
+# ignore missing ebuild
+return
+
+if new_pkg.inherit:
+eclass_eapis = (
+frozenset(map(int, self.eclass_cache[eclass].supported_eapis))
+for eclass in new_pkg.inherit
+)
+current_eapi = int(str(new_pkg.eapi))
+common_max_eapi = max(frozenset.intersection(*eclass_eapis))
+if common_max_eapi > current_eapi:
+yield NewerEAPIAvailable(common_max_eapi, pkg=new_pkg)
+
 def removal_checks(self, pkgs):
 """Check for issues due to package removals."""
 pkg = pkgs[0]
@@ -526,6 +564,9 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 pkg_map["A"].add(pkg)
 pkg_map["D"].add(pkg.old_pkg())
 
+# run added package checks
+if pkg_map["A"]:
+yield from self.addition_checks(list(pkg_map["A"]))
 # run removed package checks
 if pkg_map["D"]:
 yield from self.removal_checks(list(pkg_map["D"]))

diff --git a/tests/checks/test_git.py b/tests/checks/test_git.py
index ab6efee2..12c5e4f0 100644
--- a/tests/checks/test_git.py
+++ b/tests/checks/test_git.py
@@ -38,7 +38,7 @@ class TestGitCommitMessageCheck(ReportTestCase):
 check = git_mod.GitCommitMessageCheck(options)
 
 def test_sign_offs(self):
-# assert that it checks for both author and comitter
+# assert that it 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2024-03-01 Thread Arthur Zamarin
commit: 7e0e513cf05b88f6e13ce93f49c80159507feca5
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Mar  1 20:59:32 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Mar  1 20:59:32 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7e0e513c

PkgBadlyFormedXml: convert to error

Resolves: https://github.com/pkgcore/pkgcheck/issues/668
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata_xml.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/metadata_xml.py 
b/src/pkgcheck/checks/metadata_xml.py
index fb574c0e..cfba70c8 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -28,7 +28,7 @@ class _MissingXml(results.Error):
 return f"{self._attr} is missing {self.filename}"
 
 
-class _BadlyFormedXml(results.Warning):
+class _BadlyFormedXml(results.Error):
 """XML isn't well formed."""
 
 def __init__(self, filename, error, **kwargs):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, src/pkgcheck/scripts/, tests/scripts/

2024-01-26 Thread Arthur Zamarin
commit: fb4dc9bbf2b51732aa4a254d8ba18c0235f8d70c
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Jan 26 08:36:11 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Jan 26 08:36:11 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=fb4dc9bb

reformat with black 24

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/whitespace.py |  3 +--
 src/pkgcheck/scripts/pkgcheck_scan.py |  7 ---
 tests/scripts/test_pkgcheck_cache.py  | 10 ++
 tests/scripts/test_pkgcheck_replay.py |  9 ++---
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/src/pkgcheck/checks/whitespace.py 
b/src/pkgcheck/checks/whitespace.py
index 9987cf7e..247e8f85 100644
--- a/src/pkgcheck/checks/whitespace.py
+++ b/src/pkgcheck/checks/whitespace.py
@@ -7,8 +7,7 @@ from .. import results, sources
 from . import Check, OptionalCheck
 
 
-class _Whitespace(results.LinesResult, results.Style):
-...
+class _Whitespace(results.LinesResult, results.Style): ...
 
 
 class WhitespaceFound(_Whitespace):

diff --git a/src/pkgcheck/scripts/pkgcheck_scan.py 
b/src/pkgcheck/scripts/pkgcheck_scan.py
index c04ff329..7c11f810 100644
--- a/src/pkgcheck/scripts/pkgcheck_scan.py
+++ b/src/pkgcheck/scripts/pkgcheck_scan.py
@@ -371,9 +371,10 @@ def _setup_scan(parser, namespace, args):
 # have to be parsed twice, will probably require a custom snakeoil
 # arghparse method.
 # parse command line args to override config defaults
-with patch(
-"pkgcheck.scripts.argparse_actions.ChecksetArgs.__call__", lambda *a, 
**k: None
-), patch("pkgcheck.scripts.argparse_actions.ExitArgs.__call__", lambda *a, 
**k: None):
+with (
+patch("pkgcheck.scripts.argparse_actions.ChecksetArgs.__call__", 
lambda *a, **k: None),
+patch("pkgcheck.scripts.argparse_actions.ExitArgs.__call__", lambda 
*a, **k: None),
+):
 namespace, _ = parser._parse_known_args(args, namespace)
 
 # Get the current working directory for repo detection and restriction

diff --git a/tests/scripts/test_pkgcheck_cache.py 
b/tests/scripts/test_pkgcheck_cache.py
index 3d9ad139..09c75028 100644
--- a/tests/scripts/test_pkgcheck_cache.py
+++ b/tests/scripts/test_pkgcheck_cache.py
@@ -43,8 +43,9 @@ class TestPkgcheckCache:
 
 # fail to remove it
 for arg in ("-R", "--remove"):
-with patch("pkgcheck.addons.caches.os.unlink") as unlink, patch(
-"sys.argv", self.args + [arg] + ["-t", "profiles"]
+with (
+patch("pkgcheck.addons.caches.os.unlink") as unlink,
+patch("sys.argv", self.args + [arg] + ["-t", "profiles"]),
 ):
 unlink.side_effect = IOError("bad perms")
 with pytest.raises(SystemExit) as excinfo:
@@ -76,8 +77,9 @@ class TestPkgcheckCache:
 self.script()
 
 # fail to forcibly remove all
-with patch("pkgcheck.addons.caches.shutil.rmtree") as rmtree, patch(
-"sys.argv", self.args + ["-Rf"]
+with (
+patch("pkgcheck.addons.caches.shutil.rmtree") as rmtree,
+patch("sys.argv", self.args + ["-Rf"]),
 ):
 rmtree.side_effect = IOError("bad perms")
 with pytest.raises(SystemExit) as excinfo:

diff --git a/tests/scripts/test_pkgcheck_replay.py 
b/tests/scripts/test_pkgcheck_replay.py
index b6b7d606..0fe32a22 100644
--- a/tests/scripts/test_pkgcheck_replay.py
+++ b/tests/scripts/test_pkgcheck_replay.py
@@ -76,9 +76,12 @@ class TestPkgcheckReplay:
 reporter.report(ProfileWarning("profile warning: foo"))
 file.seek(0)
 
-with open(file.name) as stdin, patch("sys.stdin", stdin), patch(
-"sys.argv", [*self.args, "-R", "StrReporter", "-"]
-), pytest.raises(SystemExit) as excinfo:
+with (
+open(file.name) as stdin,
+patch("sys.stdin", stdin),
+patch("sys.argv", [*self.args, "-R", "StrReporter", "-"]),
+pytest.raises(SystemExit) as excinfo,
+):
 self.script()
 out, err = capsys.readouterr()
 assert not err



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/visibility/profiles/updates/, ...

2024-01-16 Thread Arthur Zamarin
commit: c3407ae2317199c301863b5ac25c456845bdcb18
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Tue Jan 16 18:42:59 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed Jan 17 06:37:35 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c3407ae2

OldPackageName: new check for package named after old package name

Resolves: https://github.com/pkgcore/pkgcheck/issues/650
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/visibility.py   | 21 +
 .../VisibilityCheck/OldPackageName/expected.json|  1 +
 .../OldPackageName/OldPackageName-0.ebuild  |  6 ++
 testdata/repos/visibility/profiles/updates/1Q-2024  |  1 +
 4 files changed, 29 insertions(+)

diff --git a/src/pkgcheck/checks/visibility.py 
b/src/pkgcheck/checks/visibility.py
index 874d1bbf..050b923b 100644
--- a/src/pkgcheck/checks/visibility.py
+++ b/src/pkgcheck/checks/visibility.py
@@ -214,6 +214,23 @@ class NonsolvableDepsInExp(NonsolvableDeps):
 _profile = "exp"
 
 
+class OldPackageName(results.PackageResult, results.Error):
+"""Package uses old name which is source of pkgmove.
+
+Package is using ``${CATEGORY}/${PN}`` which is the source of a
+pkgmove. It should be updated to the destination (new name) from
+this repository or one of its master repositories.
+"""
+
+def __init__(self, new_name: str, **kwargs):
+super().__init__(**kwargs)
+self.new_name = new_name
+
+@property
+def desc(self):
+return f"package uses old name which is source of pkgmove, rename into 
{self.new_name!r}"
+
+
 class VisibilityCheck(feeds.EvaluateDepSet, feeds.QueryCache, Check):
 """Visibility dependency scans.
 
@@ -232,6 +249,7 @@ class VisibilityCheck(feeds.EvaluateDepSet, 
feeds.QueryCache, Check):
 NonsolvableDepsInDev,
 NonsolvableDepsInExp,
 DependencyMoved,
+OldPackageName,
 }
 )
 
@@ -269,6 +287,9 @@ class VisibilityCheck(feeds.EvaluateDepSet, 
feeds.QueryCache, Check):
 # vcs ebuild that better not be visible
 yield from self.check_visibility_vcs(pkg)
 
+if pkg.key in self.pkgmoves:
+yield OldPackageName(self.pkgmoves[pkg.key], pkg=pkg)
+
 suppressed_depsets = []
 for attr in (x.lower() for x in pkg.eapi.dep_keys):
 nonexistent = set()

diff --git 
a/testdata/data/repos/visibility/VisibilityCheck/OldPackageName/expected.json 
b/testdata/data/repos/visibility/VisibilityCheck/OldPackageName/expected.json
new file mode 100644
index ..fcc053e4
--- /dev/null
+++ 
b/testdata/data/repos/visibility/VisibilityCheck/OldPackageName/expected.json
@@ -0,0 +1 @@
+{"__class__": "OldPackageName", "category": "VisibilityCheck", "package": 
"OldPackageName", "new_name": "stub/random-pkgname"}

diff --git 
a/testdata/repos/visibility/VisibilityCheck/OldPackageName/OldPackageName-0.ebuild
 
b/testdata/repos/visibility/VisibilityCheck/OldPackageName/OldPackageName-0.ebuild
new file mode 100644
index ..842db9dd
--- /dev/null
+++ 
b/testdata/repos/visibility/VisibilityCheck/OldPackageName/OldPackageName-0.ebuild
@@ -0,0 +1,6 @@
+EAPI=7
+DESCRIPTION="Ebuild with pkgmoved name"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck;
+SLOT="0"
+LICENSE="BSD"
+KEYWORDS="~amd64"

diff --git a/testdata/repos/visibility/profiles/updates/1Q-2024 
b/testdata/repos/visibility/profiles/updates/1Q-2024
index 518e4bf5..dfb9b553 100644
--- a/testdata/repos/visibility/profiles/updates/1Q-2024
+++ b/testdata/repos/visibility/profiles/updates/1Q-2024
@@ -1 +1,2 @@
 move stub/old-name stub/stable
+move VisibilityCheck/OldPackageName stub/random-pkgname



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/visibility/DependencyMoved/DependencyMoved/, ...

2024-01-14 Thread Arthur Zamarin
commit: 1ed31be4c67c2a18c90235f306967169cba31839
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Jan 14 19:44:13 2024 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Jan 14 19:44:13 2024 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=1ed31be4

DependencyMoved: show better error for dependency on pkgmove

Catch cases where we depend on pkgmoved package, and instead of showing
NonexistentDeps and NonsolvableDepsIn* errors, show DependencyMoved
result, with nice and simple suggestion on action to take.

Resolves: https://github.com/pkgcore/pkgcheck/issues/649
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/visibility.py  | 46 +++---
 .../VisibilityCheck/DependencyMoved/expected.json  |  3 ++
 .../DependencyMoved/DependencyMoved-0.ebuild   |  8 
 testdata/repos/visibility/profiles/updates/1Q-2024 |  1 +
 4 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/src/pkgcheck/checks/visibility.py 
b/src/pkgcheck/checks/visibility.py
index 5440db7f..874d1bbf 100644
--- a/src/pkgcheck/checks/visibility.py
+++ b/src/pkgcheck/checks/visibility.py
@@ -146,6 +146,20 @@ class UncheckableDep(results.VersionResult, 
results.Warning):
 return f"depset {self.attr}: could not be checked due to pkgcore 
limitation"
 
 
+class DependencyMoved(results.VersionResult, results.Error):
+"""Ebuild depends on a dependency which was pkgmoved."""
+
+def __init__(self, attr: str, source: str, target: str, **kwargs):
+super().__init__(**kwargs)
+self.attr = attr
+self.source = source
+self.target = target
+
+@property
+def desc(self):
+return f"depset({self.attr}) dependency moved, update {self.source!r} 
to {self.target!r}"
+
+
 class NonsolvableDeps(results.VersionResult, results.AliasResult, 
results.Error):
 """No potential solution for a depset attribute."""
 
@@ -210,19 +224,32 @@ class VisibilityCheck(feeds.EvaluateDepSet, 
feeds.QueryCache, Check):
 
 required_addons = (addons.profiles.ProfileAddon,)
 known_results = frozenset(
-[
+{
 VisibleVcsPkg,
 NonexistentDeps,
 UncheckableDep,
 NonsolvableDepsInStable,
 NonsolvableDepsInDev,
 NonsolvableDepsInExp,
-]
+DependencyMoved,
+}
 )
 
+@staticmethod
+def _collect_pkgmoves(repo):
+pkgmoves: dict[str, str] = {}
+for master in repo.masters:
+pkgmoves.update(VisibilityCheck._collect_pkgmoves(master))
+for (action, *params), *_ in repo.config.updates.values():
+if action == "move":
+source, target = params
+pkgmoves[source.key] = target.key
+return pkgmoves
+
 def __init__(self, *args, profile_addon):
 super().__init__(*args, profile_addon=profile_addon)
 self.profiles = profile_addon
+self.pkgmoves = self._collect_pkgmoves(self.options.target_repo)
 self.report_cls_map = {
 "stable": NonsolvableDepsInStable,
 "dev": NonsolvableDepsInDev,
@@ -271,8 +298,14 @@ class VisibilityCheck(feeds.EvaluateDepSet, 
feeds.QueryCache, Check):
 yield UncheckableDep(attr, pkg=pkg)
 suppressed_depsets.append(attr)
 if nonexistent:
-nonexistent = map(str, sorted(nonexistent))
-yield NonexistentDeps(attr.upper(), nonexistent, pkg=pkg)
+for dep in set(nonexistent):
+if target := self.pkgmoves.get(dep.key):
+new_dep = str(dep).replace(dep.key, target)
+yield DependencyMoved(attr, str(dep), new_dep, pkg=pkg)
+
+nonexistent = {dep for dep in nonexistent if dep.key not in 
self.pkgmoves}
+if nonexistent := sorted(map(str, sorted(nonexistent))):
+yield NonexistentDeps(attr.upper(), nonexistent, pkg=pkg)
 
 for attr in (x.lower() for x in pkg.eapi.dep_keys):
 if attr in suppressed_depsets:
@@ -281,8 +314,9 @@ class VisibilityCheck(feeds.EvaluateDepSet, 
feeds.QueryCache, Check):
 profile_failures = defaultdict(lambda: defaultdict(set))
 for edepset, profiles in self.collapse_evaluate_depset(pkg, attr, 
depset):
 for profile, failures in self.process_depset(pkg, attr, 
depset, edepset, profiles):
-failures = tuple(map(str, sorted(stable_unique(failures
-profile_failures[failures][profile.status].add(profile)
+failures = {failure for failure in failures if failure.key 
not in self.pkgmoves}
+if failures := tuple(map(str, sorted(failures))):
+profile_failures[failures][profile.status].add(profile)
 
 if profile_failures:
 if 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/visibility/profiles/, ...

2023-12-10 Thread Arthur Zamarin
commit: 4776408e959fdde32f05b9dc57141cdf890406c3
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Dec 10 20:08:21 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Dec 10 20:08:21 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4776408e

DeprecatedDep: fix mishandling of slotted deprecates

Resolves: https://github.com/pkgcore/pkgcheck/issues/642
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata.py | 2 +-
 .../repos/visibility/DependencyCheck/DeprecatedDep/expected.json| 4 ++--
 .../data/repos/visibility/DependencyCheck/DeprecatedDep/fix.patch   | 6 +++---
 .../repos/visibility/DeprecatedDep/nonoptional/nonoptional-0.ebuild | 2 +-
 testdata/repos/visibility/DeprecatedDep/optional/optional-0.ebuild  | 4 ++--
 testdata/repos/visibility/profiles/eapi | 1 +
 testdata/repos/visibility/profiles/package.deprecated   | 2 +-
 7 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 3219036f..2aba62f0 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -942,7 +942,7 @@ class DependencyCheck(Check):
 if not atom.blocks and self.deprecated(atom):
 # verify all matching packages are deprecated
 pkgs = self.options.search_repo.match(atom.no_usedeps)
-if all(self.deprecated(x.versioned_atom) for x in 
pkgs):
+if all(map(self.deprecated, pkgs)):
 deprecated[attr].add(atom)
 
 if in_or_restriction and atom.slot_operator == "=":

diff --git 
a/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/expected.json 
b/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/expected.json
index 000727cf..8753cd9d 100644
--- a/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/expected.json
+++ b/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/expected.json
@@ -1,2 +1,2 @@
-{"__class__": "DeprecatedDep", "category": "DeprecatedDep", "package": 
"nonoptional", "version": "0", "attr": "RDEPEND", "atoms": ["stub/deprecated"]}
-{"__class__": "DeprecatedDep", "category": "DeprecatedDep", "package": 
"optional", "version": "0", "attr": "RDEPEND", "atoms": ["stub/deprecated"]}
+{"__class__": "DeprecatedDep", "category": "DeprecatedDep", "package": 
"nonoptional", "version": "0", "attr": "RDEPEND", "atoms": 
["stub/deprecated:0"]}
+{"__class__": "DeprecatedDep", "category": "DeprecatedDep", "package": 
"optional", "version": "0", "attr": "RDEPEND", "atoms": ["stub/deprecated:0"]}

diff --git 
a/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/fix.patch 
b/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/fix.patch
index 46673370..f7fabb76 100644
--- a/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/fix.patch
+++ b/testdata/data/repos/visibility/DependencyCheck/DeprecatedDep/fix.patch
@@ -5,7 +5,7 @@ diff -Naur 
visibility/DeprecatedDep/nonoptional/nonoptional-0.ebuild fixed/Depre
  SLOT="0"
  LICENSE="BSD"
  KEYWORDS="~amd64"
--RDEPEND="stub/deprecated"
+-RDEPEND="stub/deprecated:0"
 +RDEPEND="stub/unstable"
 diff -Naur visibility/DeprecatedDep/optional/optional-0.ebuild 
fixed/DeprecatedDep/optional/optional-0.ebuild
 --- visibility/DeprecatedDep/optional/optional-0.ebuild2019-12-26 
20:39:13.559577724 -0700
@@ -13,7 +13,7 @@ diff -Naur 
visibility/DeprecatedDep/optional/optional-0.ebuild fixed/DeprecatedD
 @@ -6,5 +6,5 @@
  KEYWORDS="~amd64"
  RDEPEND="
-   !stub/deprecated
--  || ( stub/unstable stub/deprecated )
+   !stub/deprecated:0
+-  || ( stub/unstable stub/deprecated:0 )
 +  stub/unstable
  "

diff --git 
a/testdata/repos/visibility/DeprecatedDep/nonoptional/nonoptional-0.ebuild 
b/testdata/repos/visibility/DeprecatedDep/nonoptional/nonoptional-0.ebuild
index 91ea8552..5e5aa2b7 100644
--- a/testdata/repos/visibility/DeprecatedDep/nonoptional/nonoptional-0.ebuild
+++ b/testdata/repos/visibility/DeprecatedDep/nonoptional/nonoptional-0.ebuild
@@ -4,4 +4,4 @@ HOMEPAGE="https://github.com/pkgcore/pkgcheck;
 SLOT="0"
 LICENSE="BSD"
 KEYWORDS="~amd64"
-RDEPEND="stub/deprecated"
+RDEPEND="stub/deprecated:0"

diff --git a/testdata/repos/visibility/DeprecatedDep/optional/optional-0.ebuild 
b/testdata/repos/visibility/DeprecatedDep/optional/optional-0.ebuild
index 5daadc44..9be9564e 100644
--- a/testdata/repos/visibility/DeprecatedDep/optional/optional-0.ebuild
+++ b/testdata/repos/visibility/DeprecatedDep/optional/optional-0.ebuild
@@ -5,6 +5,6 @@ SLOT="0"
 LICENSE="BSD"
 KEYWORDS="~amd64"
 RDEPEND="
-   !stub/deprecated
-   || ( stub/unstable stub/deprecated )
+   !stub/deprecated:0
+   || ( stub/unstable stub/deprecated:0 )
 "

diff --git a/testdata/repos/visibility/profiles/eapi 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-12-10 Thread Arthur Zamarin
commit: 4bda26afd8ee21385dcaadb4fdf7b70db0a1c594
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Dec  8 17:45:14 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Dec 10 18:51:01 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4bda26af

OutdatedProfilePackage: don't warn when version was removed not long ago

Requested-by: Sam James  gentoo.org>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/profiles.py | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 8a8248c7..6b3db0c5 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -19,7 +19,11 @@ from . import Check, RepoCheck
 
 class OutdatedProfilePackage(results.ProfilesResult, results.Warning):
 """Profile files includes package entry that doesn't exist in the repo
-for a mentioned period of time."""
+for a mentioned period of time.
+
+This is only reported if the version was removed more than 3 months ago,
+or all versions of this package were removed (i.e. last-rite).
+"""
 
 def __init__(self, path, atom, age):
 super().__init__()
@@ -261,9 +265,10 @@ class ProfilesCheck(Check):
 removal = max(x.time for x in matches)
 removal = datetime.fromtimestamp(removal)
 years = (self.today - removal).days / 365.2425
-return OutdatedProfilePackage(path, atom, round(years, 2))
-else:
-return UnknownProfilePackage(path, atom)
+# show years value if it's greater than 3 month, or if the package 
was removed
+if years > 0.25 or not 
self.search_repo.match(atom.unversioned_atom):
+return OutdatedProfilePackage(path, atom, round(years, 2))
+return UnknownProfilePackage(path, atom)
 
 @verify_files(("parent", "parents"), ("eapi", "eapi"))
 def _pull_attr(self, *args):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-12-08 Thread Arthur Zamarin
commit: 26f4edff6c429ff7b0d6583683a1a1d1954817e1
Author: Alfred Wingate  protonmail  com>
AuthorDate: Mon Nov 27 10:04:35 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Dec  8 18:32:42 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=26f4edff

MissingRemoteId: expand gitlab matching rules

* Notably handles the particular case with gitlab package hosting.

Bug: https://github.com/pkgcore/pkgcheck/issues/636
Signed-off-by: Alfred Wingate  protonmail.com>
Closes: https://github.com/pkgcore/pkgcheck/pull/637
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata_xml.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/metadata_xml.py 
b/src/pkgcheck/checks/metadata_xml.py
index a3a7b643..fb574c0e 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -645,7 +645,9 @@ class MissingRemoteIdCheck(Check):
 _source = sources.PackageRepoSource
 known_results = frozenset([MissingRemoteId])
 
-_gitlab_match = r"(?P(\w[^/]*/)*\w[^/]*/\w[^/]*)"
+# Exclude api groups and raw project names to conform with 
https://docs.gitlab.com/ee/user/reserved_names.html
+# with the URI's which are most likely to end up in SRC_URI
+_gitlab_match = r"(?P((?!api/)\w[^/]*/)+(?!raw/)\w[^/]*)"
 
 remotes_map = (
 ("bitbucket", r"https://bitbucket.org/(?P[^/]+/[^/]+)"),



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-12-08 Thread Arthur Zamarin
commit: 8edda4238ef614dfd848ff0e05167ccf1e8892f3
Author: Alfred Wingate  protonmail  com>
AuthorDate: Mon Nov 27 10:58:11 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Dec  8 17:52:22 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8edda423

checks.git: Set tarfile filter

* Not setting it triggers a DeprecationWarning in python3.12.
* Despite tarballs by git-archive being trusted, there isn't benefit in
  trusting it as the tarballs don't use metadata that would require it.

Signed-off-by: Alfred Wingate  protonmail.com>
Closes: https://github.com/pkgcore/pkgcheck/pull/638
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 525bf693..31f1dc69 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -283,6 +283,10 @@ class _RemovalRepo(UnconfiguredTree):
 if old_files.poll():
 error = old_files.stderr.read().decode().strip()
 raise PkgcheckUserException(f"failed populating archive repo: 
{error}")
+# 
https://docs.python.org/3.12/library/tarfile.html#tarfile-extraction-filter
+if hasattr(tarfile, "data_filter"):
+# 
https://docs.python.org/3.12/library/tarfile.html#tarfile.TarFile.extraction_filter
+tarfile.TarFile.extraction_filter = 
staticmethod(tarfile.data_filter)
 with tarfile.open(mode="r|", fileobj=old_files.stdout) as tar:
 tar.extractall(path=self.location)
 



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/eclass/InheritsCheck/UnusedInherits/, ...

2023-11-16 Thread Arthur Zamarin
commit: d837ae22cc5381710f63d6600940d48a8e2875f5
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Thu Nov 16 19:51:44 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Nov 16 19:51:44 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d837ae22

UnusedInherits: add whitelist for weak usage by another eclass

Came up as example from elisp eclass, which has automagic calling of
functions from readme.gentoo-r1 eclass if they are found in env. While
weird, this is legal so let's add a simple whitelist support for this,
so it would be simple to extend in future.

Reported-by: Ulrich Müller  gentoo.org>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py  |  8 +++-
 .../InheritsCheck/UnusedInherits/UnusedInherits-2.ebuild|  8 
 testdata/repos/eclass/eclass/elisp.eclass   | 13 +
 testdata/repos/eclass/eclass/readme.gentoo-r1.eclass| 11 +++
 4 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 60f1ce98..90cb03b2 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -848,6 +848,8 @@ class InheritsCheck(Check):
 
 self.unused_eclass_skiplist = 
frozenset(common_mandatory_metadata_keys) - {"IUSE"}
 
+self.weak_eclass_usage = {"elisp": ("readme.gentoo-r1",)}
+
 def get_eclass(self, export, pkg):
 """Return the eclass related to a given exported variable or function 
name."""
 try:
@@ -920,8 +922,12 @@ class InheritsCheck(Check):
 
 # allowed indirect inherits
 indirect_allowed = set().union(*(self.eclass_cache[x].provides for x 
in pkg.inherit))
+all_inherits = set().union(pkg.inherit, indirect_allowed, conditional)
 # missing inherits
-missing = used.keys() - pkg.inherit - indirect_allowed - conditional
+missing = used.keys() - all_inherits
+
+for eclass in all_inherits:
+weak_used_eclasses.update(self.weak_eclass_usage.get(eclass, ()))
 
 unused = set(pkg.inherit) - used.keys() - set(assigned_vars.values()) 
- weak_used_eclasses
 # remove eclasses that use implicit phase functions

diff --git 
a/testdata/repos/eclass/InheritsCheck/UnusedInherits/UnusedInherits-2.ebuild 
b/testdata/repos/eclass/InheritsCheck/UnusedInherits/UnusedInherits-2.ebuild
new file mode 100644
index ..320a61bd
--- /dev/null
+++ b/testdata/repos/eclass/InheritsCheck/UnusedInherits/UnusedInherits-2.ebuild
@@ -0,0 +1,8 @@
+EAPI=8
+
+inherit elisp readme.gentoo-r1
+
+DESCRIPTION="Ebuild with weak usage inheritance"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck;
+SLOT="0"
+LICENSE="BSD"

diff --git a/testdata/repos/eclass/eclass/elisp.eclass 
b/testdata/repos/eclass/eclass/elisp.eclass
new file mode 100644
index ..e72964ea
--- /dev/null
+++ b/testdata/repos/eclass/eclass/elisp.eclass
@@ -0,0 +1,13 @@
+# @ECLASS: elisp.eclass
+# @MAINTAINER:
+# Random Person 
+# @SUPPORTED_EAPIS: 8
+# @BLURB: Stub eclass for testing the UnusedInherit result.
+
+EXPORT_FUNCTIONS src_prepare
+
+# @FUNCTION: elisp_src_prepare
+# @USAGE:
+# @DESCRIPTION:
+# Public src_prepare stub function.
+elisp_src_prepare() { :; }

diff --git a/testdata/repos/eclass/eclass/readme.gentoo-r1.eclass 
b/testdata/repos/eclass/eclass/readme.gentoo-r1.eclass
new file mode 100644
index ..c7f61a09
--- /dev/null
+++ b/testdata/repos/eclass/eclass/readme.gentoo-r1.eclass
@@ -0,0 +1,11 @@
+# @ECLASS: readme.gentoo-r1.eclass
+# @MAINTAINER:
+# Random Person 
+# @SUPPORTED_EAPIS: 8
+# @BLURB: Stub eclass for testing the UnusedInherit result.
+
+# @FUNCTION: readme.gentoo_create_doc
+# @USAGE:
+# @DESCRIPTION:
+# stub function
+readme.gentoo_create_doc() { :; }



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-11-05 Thread Arthur Zamarin
commit: 1b246cfa75d0789b7e77ccf645ea3778340b8eda
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Nov  5 13:20:58 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Nov  5 13:20:58 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=1b246cfa

whitespace: fix double "on" in result text

Resolves: https://github.com/pkgcore/pkgcheck/issues/633
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/whitespace.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/pkgcheck/checks/whitespace.py 
b/src/pkgcheck/checks/whitespace.py
index a853e0b0..9987cf7e 100644
--- a/src/pkgcheck/checks/whitespace.py
+++ b/src/pkgcheck/checks/whitespace.py
@@ -20,7 +20,7 @@ class WhitespaceFound(_Whitespace):
 
 @property
 def desc(self):
-return f"ebuild has {self.leadtrail} whitespace on {self.lines_str}"
+return f"ebuild has {self.leadtrail} whitespace {self.lines_str}"
 
 
 class WrongIndentFound(_Whitespace):
@@ -28,7 +28,7 @@ class WrongIndentFound(_Whitespace):
 
 @property
 def desc(self):
-return f"ebuild has whitespace in indentation on {self.lines_str}"
+return f"ebuild has whitespace in indentation {self.lines_str}"
 
 
 class DoubleEmptyLine(_Whitespace):
@@ -36,7 +36,7 @@ class DoubleEmptyLine(_Whitespace):
 
 @property
 def desc(self):
-return f"ebuild has unneeded empty line on {self.lines_str}"
+return f"ebuild has unneeded empty line {self.lines_str}"
 
 
 class TrailingEmptyLine(results.VersionResult, results.Style):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-11-01 Thread Arthur Zamarin
commit: 013b8d678895caf3f66173f6dfd2379c5219d576
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Wed Nov  1 19:19:43 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed Nov  1 19:19:43 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=013b8d67

MissingInherits: add some specials to exclude list

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 0c33c650..60f1ce98 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -825,7 +825,7 @@ class InheritsCheck(Check):
 self.exported.setdefault(name, set()).add(eclass)
 
 # collect all @USER_VARIABLEs, which are excluded from MissingInherits
-self.user_variables = frozenset(
+user_variables = frozenset(
 {
 x.name
 for eclass_obj in self.eclass_cache.values()
@@ -833,6 +833,7 @@ class InheritsCheck(Check):
 if x.user_variable
 }
 )
+self.exclude_missing_inherit = user_variables | {"CTARGET", 
"BUILD_DIR"}
 
 # register EAPI-related funcs/cmds to ignore
 self.eapi_funcs = {}
@@ -911,7 +912,7 @@ class InheritsCheck(Check):
 if node.parent.type == "unset_command":
 continue
 if name not in self.eapi_vars[pkg.eapi] | assigned_vars.keys():
-if name in self.user_variables:
+if name in self.exclude_missing_inherit:
 continue
 lineno, _colno = node.start_point
 if eclass := self.get_eclass(name, pkg):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-09-23 Thread Arthur Zamarin
commit: 64ea04886ae7769db53bef175652531af240fb83
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Sep 23 10:35:09 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Sep 23 10:35:09 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=64ea0488

EmptyGlobalAssignment: check for empty global assignments

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py  | 21 -
 .../EmptyGlobalAssignment/expected.json |  3 +++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 0e2188db..6f1e3b7f 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -547,6 +547,14 @@ class MultipleKeywordsLines(results.LinesResult, 
results.Style):
 return f"KEYWORDS specified {self.lines_str}"
 
 
+class EmptyGlobalAssignment(results.LineResult, results.Style):
+"""Global scope useless empty assignment."""
+
+@property
+def desc(self):
+return f"line {self.lineno}: empty global assignment: {self.line}"
+
+
 def verify_vars(*variables):
 """Decorator to register raw variable verification methods."""
 
@@ -569,7 +577,13 @@ class MetadataVarCheck(Check):
 
 _source = sources.EbuildParseRepoSource
 known_results = frozenset(
-[HomepageInSrcUri, StaticSrcUri, ReferenceInMetadataVar, 
MultipleKeywordsLines]
+{
+HomepageInSrcUri,
+StaticSrcUri,
+ReferenceInMetadataVar,
+MultipleKeywordsLines,
+EmptyGlobalAssignment,
+}
 )
 
 # mapping between registered variables and verification methods
@@ -644,6 +658,11 @@ class MetadataVarCheck(Check):
 keywords_lines = set()
 for node in pkg.global_query(bash.var_assign_query):
 name = pkg.node_str(node.child_by_field_name("name"))
+value = node.child_by_field_name("value")
+if name in pkg.eapi.eclass_keys:
+if not value or not pkg.node_str(value).strip("\"'"):
+lineno, _ = node.start_point
+yield EmptyGlobalAssignment(line=pkg.node_str(node), 
lineno=lineno + 1, pkg=pkg)
 if name in self.known_variables:
 # RHS value node should be last
 val_node = node.children[-1]

diff --git 
a/testdata/data/repos/standalone/MetadataVarCheck/EmptyGlobalAssignment/expected.json
 
b/testdata/data/repos/standalone/MetadataVarCheck/EmptyGlobalAssignment/expected.json
new file mode 100644
index ..2e861fc0
--- /dev/null
+++ 
b/testdata/data/repos/standalone/MetadataVarCheck/EmptyGlobalAssignment/expected.json
@@ -0,0 +1,3 @@
+{"__class__": "EmptyGlobalAssignment", "category": "DescriptionCheck", 
"package": "BadDescription", "version": "1", "line": "DESCRIPTION=\"\"", 
"lineno": 1}
+{"__class__": "EmptyGlobalAssignment", "category": "MetadataVarCheck", 
"package": "MultipleKeywordsLines", "version": "0", "line": "KEYWORDS=\"\"", 
"lineno": 8}
+{"__class__": "EmptyGlobalAssignment", "category": "MetadataVarCheck", 
"package": "ReferenceInMetadataVar", "version": "3", "line": "LICENSE=\"\"", 
"lineno": 5}



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-09-01 Thread Arthur Zamarin
commit: a159aca5222ca9ef08087ee7aa16325fe136080a
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Sep  1 15:49:58 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Sep  1 15:49:58 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=a159aca5

checks: use stable sorting of fields + strip where needed

In preparation of new tree-sitter-bash, some small issues where found.

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata.py | 2 +-
 src/pkgcheck/checks/profiles.py | 4 ++--
 src/pkgcheck/checks/rust.py | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 555ea9a5..3219036f 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -681,7 +681,7 @@ class UseFlagsWithoutEffectsCheck(GentooRepoCheck):
 
 flags = 
self.warn_use_small_files.intersection(pkg.iuse_stripped).difference(used_flags)
 if flags:
-yield UseFlagWithoutDeps(flags, pkg=pkg)
+yield UseFlagWithoutDeps(sorted(flags), pkg=pkg)
 
 
 class MissingSlotDep(results.VersionResult, results.Warning):

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index b9108f83..8a8248c7 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -303,9 +303,9 @@ class ProfilesCheck(Check):
 for _, disabled, enabled in entries:
 if unknown_disabled := set(disabled) - self.available_iuse:
 flags = ("-" + u for u in unknown_disabled)
-yield UnknownProfileUse(pjoin(node.name, filename), flags)
+yield UnknownProfileUse(pjoin(node.name, filename), 
sorted(flags))
 if unknown_enabled := set(enabled) - self.available_iuse:
-yield UnknownProfileUse(pjoin(node.name, filename), 
unknown_enabled)
+yield UnknownProfileUse(pjoin(node.name, filename), 
sorted(unknown_enabled))
 
 @verify_files(
 ("packages", "packages"),

diff --git a/src/pkgcheck/checks/rust.py b/src/pkgcheck/checks/rust.py
index 1a5e6770..397738b9 100644
--- a/src/pkgcheck/checks/rust.py
+++ b/src/pkgcheck/checks/rust.py
@@ -64,7 +64,7 @@ class RustCheck(Check):
 call_name = pkg.node_str(node.child_by_field_name("name"))
 if call_name == "cargo_crate_uris":
 row, _ = node.start_point
-line = pkg.node_str(node.parent)
+line = pkg.node_str(node.parent).strip()
 if node.child_count == 1 or (
 node.child_count == 2
 and any(



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/standalone/SrcUriCheck/UnstableSrcUri/, ...

2023-09-01 Thread Arthur Zamarin
commit: c6f50b432e9fd3f2235ec86d51f58405e8ab36ce
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Jul  7 14:48:30 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Sep  1 10:33:40 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c6f50b43

UnstableSrcUri: check for unstable SRC_URI

Resolves: https://github.com/pkgcore/pkgcheck/issues/510
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata.py| 33 --
 .../SrcUriCheck/UnstableSrcUri/expected.json   |  1 +
 .../standalone/SrcUriCheck/UnstableSrcUri/Manifest |  2 ++
 .../UnstableSrcUri/UnstableSrcUri-0.ebuild |  8 ++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 7f0a072b..555ea9a5 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -1332,6 +1332,24 @@ class SrcUriFilenameDotPrefix(results.VersionResult, 
results.Error):
 return f"SRC_URI filename {self.filename!r} starts with a dot"
 
 
+class UnstableSrcUri(results.VersionResult, results.Warning):
+"""SRC_URI uses unstable URIs.
+
+This is usually a mistake, as those URIs are not guaranteed to be unchanged
+which might cause checksum mismatch.
+"""
+
+def __init__(self, uris, **kwargs):
+super().__init__(**kwargs)
+self.uris = tuple(uris)
+
+@property
+def desc(self):
+s = pluralism(self.uris)
+uris = " ".join(self.uris)
+return f"unstable SRC_URI{s}: [ {uris} ]"
+
+
 class SrcUriCheck(Check):
 """SRC_URI related checks.
 
@@ -1351,6 +1369,7 @@ class SrcUriCheck(Check):
 UnknownMirror,
 UnstatedIuse,
 SrcUriFilenameDotPrefix,
+UnstableSrcUri,
 }
 )
 
@@ -1363,6 +1382,10 @@ class SrcUriCheck(Check):
 r"https?://(github\.com/.*?/.*?/archive/.+\.zip|"
 r"gitlab\.com/.*?/.*?/-/archive/.+\.zip)"
 )
+self.unstable_uris = re.compile(
+
r"^https?://patch-diff.githubusercontent.com/raw/.*/pull/[0-9]+.(patch|diff)$|"
+r"^https?://github.com/.*/pull/[0-9]+.(patch|diff)$"
+)
 
 def feed(self, pkg):
 lacks_uri = set()
@@ -1370,6 +1393,7 @@ class SrcUriCheck(Check):
 seen = set()
 bad_filenames = set()
 tarball_available = set()
+unstable_uris = set()
 
 report_uris = LogMap("pkgcore.log.logger.info", 
partial(RedundantUriRename, pkg))
 with LogReports(report_uris) as log_reports:
@@ -1395,8 +1419,11 @@ class SrcUriCheck(Check):
 (m, sub_uri) for m, sub_uri in mirrors if isinstance(m, 
unknown_mirror)
 ]
 for mirror, sub_uri in unknown_mirrors:
-uri = f"{mirror}/{sub_uri}"
-yield UnknownMirror(mirror.mirror_name, uri, pkg=pkg)
+yield UnknownMirror(mirror.mirror_name, 
uri=f"{mirror}/{sub_uri}", pkg=pkg)
+
+for uri in f_inst.uri:
+if self.unstable_uris.match(uri):
+unstable_uris.add(uri)
 
 # Check for unspecific filenames of the form ${PN}.ext, ${PV}.ext,
 # and v${PV}.ext as well as archives named using only the raw git
@@ -1432,6 +1459,8 @@ class SrcUriCheck(Check):
 yield BadFilename(sorted(bad_filenames), pkg=pkg)
 if tarball_available:
 yield TarballAvailable(sorted(tarball_available), pkg=pkg)
+if unstable_uris:
+yield UnstableSrcUri(sorted(unstable_uris), pkg=pkg)
 
 
 class BadDescription(results.VersionResult, results.Style):

diff --git 
a/testdata/data/repos/standalone/SrcUriCheck/UnstableSrcUri/expected.json 
b/testdata/data/repos/standalone/SrcUriCheck/UnstableSrcUri/expected.json
new file mode 100644
index ..15fd7646
--- /dev/null
+++ b/testdata/data/repos/standalone/SrcUriCheck/UnstableSrcUri/expected.json
@@ -0,0 +1 @@
+{"__class__": "UnstableSrcUri", "category": "SrcUriCheck", "package": 
"UnstableSrcUri", "version": "0", "uris": 
["https://github.com/pkgcore/pkgcheck/pull/1234.patch;, 
"https://patch-diff.githubusercontent.com/raw/pkgcore/pkgcheck/pull/599.patch"]}

diff --git a/testdata/repos/standalone/SrcUriCheck/UnstableSrcUri/Manifest 
b/testdata/repos/standalone/SrcUriCheck/UnstableSrcUri/Manifest
new file mode 100644
index ..fe4a1b6c
--- /dev/null
+++ b/testdata/repos/standalone/SrcUriCheck/UnstableSrcUri/Manifest
@@ -0,0 +1,2 @@
+DIST 599.patch 100 BLAKE2B 
10004cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836
 SHA512 
15634eab4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST 1234.patch 200 BLAKE2B 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-08-29 Thread Arthur Zamarin
commit: e6df8ff65d9013d9ae76949a171fa65dede462f0
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Tue Aug 29 18:55:19 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Tue Aug 29 18:57:57 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e6df8ff6

RedundantLongDescription: lower too short threshold

Resolves: https://github.com/pkgcore/pkgcheck/issues/614
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata_xml.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/metadata_xml.py 
b/src/pkgcheck/checks/metadata_xml.py
index f2b43af2..1f0a35d6 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -544,7 +544,7 @@ class PackageMetadataXmlCheck(_XmlBaseCheck):
 if match_ratio > 0.75:
 msg = "metadata.xml longdescription closely matches 
DESCRIPTION"
 yield RedundantLongDescription(msg, pkg=pkg)
-elif len(pkg.longdescription) < 100:
+elif len(pkg.longdescription) < 80:
 msg = "metadata.xml longdescription is too short"
 yield RedundantLongDescription(msg, pkg=pkg)
 



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-08-03 Thread Arthur Zamarin
commit: aa668df52b198d1e1baaa3ce9d3836052e50a85f
Author: Ulrich Müller  gentoo  org>
AuthorDate: Wed Aug  2 12:45:53 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Aug  3 17:28:35 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=aa668df5

VariableScopeCheck: BROOT is allowed also in pkg_{pre,post}{inst,rm}

PMS commit:
https://gitweb.gentoo.org/proj/pms.git/commit/?id=1a27729740e17ccd4b7a4527a46011fa62c9efb1

Signed-off-by: Ulrich Müller  gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/609
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 2b7dbafe..c99a8eca 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -986,7 +986,7 @@ class VariableScopeCheck(Check):
 "EROOT": "pkg_",
 "SYSROOT": ("src_", "pkg_setup"),
 "ESYSROOT": ("src_", "pkg_setup"),
-"BROOT": ("src_", "pkg_setup"),
+"BROOT": ("src_", "pkg_setup", "pkg_preinst", "pkg_prerm", 
"pkg_post"),
 "D": ("src_install", "pkg_preinst"),  # pkg_postinst is forbidden 
by QA policy PG 107
 "ED": ("src_install", "pkg_preinst"),  # pkg_postinst is forbidden 
by QA policy PG 107
 "DESTTREE": "src_install",



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-08-02 Thread Arthur Zamarin
commit: a327dcfb96db1aba2499bdf8d84a298fa815adc5
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Wed Aug  2 10:42:32 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed Aug  2 11:22:10 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=a327dcfb

VariableScopeCheck: Disallow D and ED in pkg_postinst (again)

https://projects.gentoo.org/qa/policy-guide/ebuild-format.html#pg0107

Fixes: 2cfc92ccab6ddfedd79ec16b8ebdde4eae8d2ad4
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index a05831cd..2b7dbafe 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -987,8 +987,8 @@ class VariableScopeCheck(Check):
 "SYSROOT": ("src_", "pkg_setup"),
 "ESYSROOT": ("src_", "pkg_setup"),
 "BROOT": ("src_", "pkg_setup"),
-"D": ("src_install", "pkg_preinst", "pkg_postinst"),
-"ED": ("src_install", "pkg_preinst", "pkg_postinst"),
+"D": ("src_install", "pkg_preinst"),  # pkg_postinst is forbidden 
by QA policy PG 107
+"ED": ("src_install", "pkg_preinst"),  # pkg_postinst is forbidden 
by QA policy PG 107
 "DESTTREE": "src_install",
 "INSDESTTREE": "src_install",
 "MERGE_TYPE": "pkg_",



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-07-15 Thread Arthur Zamarin
commit: 56880290ded28c7cca414a958b48be4e8d12a4e1
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Jul 15 10:14:59 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Jul 15 10:14:59 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=56880290

GitPkgCommitsCheck: fix failure during compute of environment

In rare cases, ebd might fail for some ebuilds during the compute of
`.environment` property. For now let's eat up all of those cases since
other checks will catch the issues.

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 8a80fb90..525bf693 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -1,5 +1,6 @@
 """Various git-related checks."""
 
+import contextlib
 import os
 import re
 import subprocess
@@ -440,13 +441,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)
+with contextlib.suppress(Exception):
+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]



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2023-07-15 Thread Arthur Zamarin
commit: 59cfd9b5e53577b59fd513b1cdd9e0cda184ed13
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Jul  2 19:24:58 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Jul 15 08:36:00 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=59cfd9b5

PerlCheck: check versioned virtual perl dependencies

Resolves: https://github.com/pkgcore/pkgcheck/issues/593
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/perl.py | 66 -
 tests/checks/test_perl.py   | 36 +
 2 files changed, 90 insertions(+), 12 deletions(-)

diff --git a/src/pkgcheck/checks/perl.py b/src/pkgcheck/checks/perl.py
index f2c3bd25..2774f990 100644
--- a/src/pkgcheck/checks/perl.py
+++ b/src/pkgcheck/checks/perl.py
@@ -2,8 +2,11 @@ import multiprocessing
 import re
 import subprocess
 
+from pkgcore.ebuild.atom import atom as atom_cls
 from pkgcore.restrictions import packages, values
+from pkgcore.package.errors import MetadataException
 from snakeoil.osutils import pjoin
+from snakeoil.sequences import iflatten_instance
 
 from .. import const, results, sources
 from . import OptionalCheck, SkipCheck
@@ -22,6 +25,24 @@ class MismatchedPerlVersion(results.VersionResult, 
results.Warning):
 return f"DIST_VERSION={self.dist_version} normalizes to 
{self.normalized}"
 
 
+class MissingVersionedVirtualPerlDependency(results.VersionResult, 
results.Warning):
+"""Missing version restriction for virtual perl dependency.
+
+The virtuals ``virtual/perl-*`` stand for packages that have releases both
+as part of ``dev-lang/perl`` and standalone in ``perl-core/*``. Apart from
+rare special cases, if you require "any" version of such a virtual, this
+will always be fulfilled by ``dev-lang/perl``.
+"""
+
+def __init__(self, atom, **kwargs):
+super().__init__(**kwargs)
+self.atom = atom
+
+@property
+def desc(self):
+return f"missing version restriction for virtual perl: {self.atom!r}"
+
+
 class _PerlException(Exception):
 """Generic error during perl script initialization."""
 
@@ -70,12 +91,13 @@ class _PerlConnection:
 class PerlCheck(OptionalCheck):
 """Perl ebuild related checks."""
 
-_restricted_source = (
-sources.RestrictionRepoSource,
-(packages.PackageRestriction("inherited", 
values.ContainmentMatch2("perl-module")),),
+_source = sources.EbuildFileRepoSource
+known_results = frozenset(
+{
+MismatchedPerlVersion,
+MissingVersionedVirtualPerlDependency,
+}
 )
-_source = (sources.EbuildFileRepoSource, (), (("source", 
_restricted_source),))
-known_results = frozenset([MismatchedPerlVersion])
 
 def __init__(self, *args):
 super().__init__(*args)
@@ -86,12 +108,32 @@ class PerlCheck(OptionalCheck):
 # it easier to disable this check if required perl deps are missing.
 try:
 self.perl = _PerlConnection(self.options)
-except _PerlException as e:
-raise SkipCheck(self, str(e))
+except _PerlException as exc:
+raise SkipCheck(self, str(exc))
 
 def feed(self, pkg):
-if mo := self.dist_version_re.search("".join(pkg.lines)):
-dist_version = mo.group("dist_version")
-normalized = self.perl.normalize(dist_version)
-if normalized != pkg.version:
-yield MismatchedPerlVersion(dist_version, normalized, pkg=pkg)
+if "perl-module" in pkg.inherited:
+if mo := self.dist_version_re.search("".join(pkg.lines)):
+dist_version = mo.group("dist_version")
+normalized = self.perl.normalize(dist_version)
+if normalized != pkg.version:
+yield MismatchedPerlVersion(dist_version, normalized, 
pkg=pkg)
+
+missing_virtual_perl = set()
+for attr in (x.lower() for x in pkg.eapi.dep_keys):
+try:
+deps = getattr(pkg, attr)
+except MetadataException:
+continue
+for atom in iflatten_instance(deps, (atom_cls,)):
+if (
+not atom.op
+and atom.key.startswith("virtual/perl-")
+and pkg.key != "dev-lang/perl"
+and pkg.category != "perl-core"
+and not pkg.key.startswith("virtual/perl-")
+):
+missing_virtual_perl.add(str(atom))
+
+for atom in sorted(missing_virtual_perl):
+yield MissingVersionedVirtualPerlDependency(str(atom), pkg=pkg)

diff --git a/tests/checks/test_perl.py b/tests/checks/test_perl.py
index 8de1a795..b2f76eab 100644
--- a/tests/checks/test_perl.py
+++ b/tests/checks/test_perl.py
@@ -73,3 +73,39 @@ class TestPerlCheck(misc.ReportTestCase):
 for verbosity in (0, 1):
 with 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-06-24 Thread Arthur Zamarin
commit: afc779b8a445cf95f1ea907bb1ac651cf9440815
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Wed Jun 21 18:20:57 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Jun 24 05:49:32 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=afc779b8

ProfilesCheck: for unknown packages, mention last match removed

https://github.com/pkgcore/pkgcheck/issues/588
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/profiles.py | 48 +++--
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 3420e471..b9108f83 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -1,5 +1,6 @@
 """Various profile-related checks."""
 
+from datetime import datetime
 import os
 from collections import defaultdict
 from typing import Iterable
@@ -16,6 +17,21 @@ from .. import addons, base, results, sources
 from . import Check, RepoCheck
 
 
+class OutdatedProfilePackage(results.ProfilesResult, results.Warning):
+"""Profile files includes package entry that doesn't exist in the repo
+for a mentioned period of time."""
+
+def __init__(self, path, atom, age):
+super().__init__()
+self.path = path
+self.atom = str(atom)
+self.age = float(age)
+
+@property
+def desc(self):
+return f"{self.path!r}: outdated package entry: {self.atom!r}, last 
match removed {self.age} years ago"
+
+
 class UnknownProfilePackage(results.ProfilesResult, results.Warning):
 """Profile files includes package entry that doesn't exist in the repo."""
 
@@ -190,9 +206,10 @@ class ProfilesCheck(Check):
 """Scan repo profiles for unknown flags/packages."""
 
 _source = sources.ProfilesRepoSource
-required_addons = (addons.UseAddon, addons.KeywordsAddon)
+required_addons = (addons.UseAddon, addons.KeywordsAddon, 
addons.git.GitAddon)
 known_results = frozenset(
 {
+OutdatedProfilePackage,
 UnknownProfilePackage,
 UnmatchedProfilePackageUnmask,
 UnknownProfilePackageUse,
@@ -210,12 +227,20 @@ class ProfilesCheck(Check):
 # mapping between known files and verification methods
 known_files = {}
 
-def __init__(self, *args, use_addon: addons.UseAddon, keywords_addon: 
addons.KeywordsAddon):
+def __init__(
+self,
+*args,
+use_addon: addons.UseAddon,
+keywords_addon: addons.KeywordsAddon,
+git_addon: addons.git.GitAddon,
+):
 super().__init__(*args)
 repo = self.options.target_repo
 self.keywords = keywords_addon
 self.search_repo = self.options.search_repo
 self.profiles_dir = repo.config.profiles_base
+self.today = datetime.today()
+self.existence_repo = git_addon.cached_repo(addons.git.GitRemovedRepo)
 self.use_expand_groups = {
 use.upper(): frozenset({val.removeprefix(f"{use}_") for val, _desc 
in vals})
 for use, vals in repo.config.use_expand_desc.items()
@@ -229,6 +254,17 @@ class ProfilesCheck(Check):
 | use_addon.global_iuse_implicit
 )
 
+def _report_unknown_atom(self, path, atom):
+if not isinstance(atom, atom_cls):
+atom = atom_cls(atom)
+if matches := self.existence_repo.match(atom):
+removal = max(x.time for x in matches)
+removal = datetime.fromtimestamp(removal)
+years = (self.today - removal).days / 365.2425
+return OutdatedProfilePackage(path, atom, round(years, 2))
+else:
+return UnknownProfilePackage(path, atom)
+
 @verify_files(("parent", "parents"), ("eapi", "eapi"))
 def _pull_attr(self, *args):
 """Verification only needs to pull the profile attr."""
@@ -279,7 +315,7 @@ class ProfilesCheck(Check):
 def _pkg_atoms(self, filename, node, vals):
 for x in iflatten_instance(vals, atom_cls):
 if not isinstance(x, bool) and not self.search_repo.match(x):
-yield UnknownProfilePackage(pjoin(node.name, filename), x)
+yield self._report_unknown_atom(pjoin(node.name, filename), x)
 
 @verify_files(
 ("package.mask", "masks"),
@@ -292,10 +328,10 @@ class ProfilesCheck(Check):
 unmasked, masked = vals
 for x in masked:
 if not self.search_repo.match(x):
-yield UnknownProfilePackage(pjoin(node.name, filename), x)
+yield self._report_unknown_atom(pjoin(node.name, filename), x)
 for x in unmasked:
 if not self.search_repo.match(x):
-yield UnknownProfilePackage(pjoin(node.name, filename), x)
+yield self._report_unknown_atom(pjoin(node.name, filename), x)
 elif x not in all_masked:
 yield 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-05-12 Thread Arthur Zamarin
commit: eb6a62d9547f3de6677cbf64e6bd674ff8c5ba82
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri May 12 17:17:44 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri May 12 17:17:44 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=eb6a62d9

ProfilesCheck: fix handling of profiles with neg_action package

When a "packages" file under a profile declares "-*" (meaning to remove
all defaults), pkgcore pushes a special token (`True`) into the packages
set. This is taken by ProfileStack to clean up previous stack, but the
check wasn't expecting this token. Fixes by adding skip for that token.

Resolves: https://github.com/pkgcore/pkgcheck/issues/577
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/profiles.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 5394dca7..3420e471 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -278,7 +278,7 @@ class ProfilesCheck(Check):
 )
 def _pkg_atoms(self, filename, node, vals):
 for x in iflatten_instance(vals, atom_cls):
-if not self.search_repo.match(x):
+if not isinstance(x, bool) and not self.search_repo.match(x):
 yield UnknownProfilePackage(pjoin(node.name, filename), x)
 
 @verify_files(



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-04-24 Thread Arthur Zamarin
commit: fdcf83d0811019e0a465006493fe4acad77043da
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Mon Apr 24 16:39:20 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Apr 24 16:39:20 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=fdcf83d0

MissingEAPIBlankLine: make it optional

Requested by multiple devs, maybe in future we would improve logic, and
un-optional it.

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/whitespace.py  | 29 --
 .../MissingEAPIBlankLine/expected.json |  1 -
 .../WhitespaceCheck/MissingEAPIBlankLine/fix.patch |  9 ---
 .../MissingEAPIBlankLine-0.ebuild  |  5 
 tests/checks/test_whitespace.py| 18 ++
 5 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/src/pkgcheck/checks/whitespace.py 
b/src/pkgcheck/checks/whitespace.py
index 31667f9c..a853e0b0 100644
--- a/src/pkgcheck/checks/whitespace.py
+++ b/src/pkgcheck/checks/whitespace.py
@@ -4,7 +4,7 @@ import re
 from typing import NamedTuple
 
 from .. import results, sources
-from . import Check
+from . import Check, OptionalCheck
 
 
 class _Whitespace(results.LinesResult, results.Style):
@@ -131,7 +131,6 @@ class WhitespaceCheck(Check):
 TrailingEmptyLine,
 NoFinalNewline,
 BadWhitespaceCharacter,
-MissingEAPIBlankLine,
 }
 )
 
@@ -148,14 +147,8 @@ class WhitespaceCheck(Check):
 leading = []
 indent = []
 double_empty = []
-eapi_lineno = None
 
 for lineno, line in enumerate(pkg.lines, 1):
-if line.startswith("EAPI="):
-eapi_lineno = lineno
-elif eapi_lineno is not None and lineno == eapi_lineno + 1 and 
line != "\n":
-yield MissingEAPIBlankLine(pkg=pkg)
-
 for match in self.bad_whitespace_regex.finditer(line):
 yield BadWhitespaceCharacter(
 repr(match.group("char")),
@@ -191,3 +184,23 @@ class WhitespaceCheck(Check):
 # Dealing with empty ebuilds is just paranoia
 if pkg.lines and not pkg.lines[-1].endswith("\n"):
 yield NoFinalNewline(pkg=pkg)
+
+
+class MissingWhitespaceCheck(OptionalCheck):
+"""Scan ebuild for missing whitespace."""
+
+_source = sources.EbuildFileRepoSource
+known_results = frozenset(
+{
+MissingEAPIBlankLine,
+}
+)
+
+def feed(self, pkg):
+eapi_lineno = None
+
+for lineno, line in enumerate(pkg.lines, 1):
+if line.startswith("EAPI="):
+eapi_lineno = lineno
+elif eapi_lineno is not None and lineno == eapi_lineno + 1 and 
line != "\n":
+yield MissingEAPIBlankLine(pkg=pkg)

diff --git 
a/testdata/data/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/expected.json
 
b/testdata/data/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/expected.json
deleted file mode 100644
index d0630087..
--- 
a/testdata/data/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/expected.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__class__": "MissingEAPIBlankLine", "category": "WhitespaceCheck", 
"package": "MissingEAPIBlankLine", "version": "0"}

diff --git 
a/testdata/data/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/fix.patch 
b/testdata/data/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/fix.patch
deleted file mode 100644
index e6b838e3..
--- 
a/testdata/data/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/fix.patch
+++ /dev/null
@@ -1,9 +0,0 @@
-diff -Naur 
standalone/WhitespaceCheck/MissingEAPIBlankLine/MissingEAPIBlankLine-0.ebuild 
fixed/WhitespaceCheck/MissingEAPIBlankLine/MissingEAPIBlankLine-0.ebuild
 
standalone/WhitespaceCheck/MissingEAPIBlankLine/MissingEAPIBlankLine-0.ebuild
-+++ fixed/WhitespaceCheck/MissingEAPIBlankLine/MissingEAPIBlankLine-0.ebuild
-@@ -1,4 +1,5 @@
- EAPI=7
-+
- DESCRIPTION="Ebuild is missing blank line after EAPI"
- HOMEPAGE="https://github.com/pkgcore/pkgcheck;
- SLOT="0"

diff --git 
a/testdata/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/MissingEAPIBlankLine-0.ebuild
 
b/testdata/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/MissingEAPIBlankLine-0.ebuild
deleted file mode 100644
index fc5a6781..
--- 
a/testdata/repos/standalone/WhitespaceCheck/MissingEAPIBlankLine/MissingEAPIBlankLine-0.ebuild
+++ /dev/null
@@ -1,5 +0,0 @@
-EAPI=7
-DESCRIPTION="Ebuild is missing blank line after EAPI"
-HOMEPAGE="https://github.com/pkgcore/pkgcheck;
-SLOT="0"
-LICENSE="BSD"

diff --git a/tests/checks/test_whitespace.py b/tests/checks/test_whitespace.py
index f90495b6..e6324d77 100644
--- a/tests/checks/test_whitespace.py
+++ b/tests/checks/test_whitespace.py
@@ -150,3 +150,21 @@ class TestMultipleChecks(WhitespaceCheckTest):
 
 reports = self.assertReports(self.check, fake_pkg)
 assert 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-03-24 Thread Arthur Zamarin
commit: 5704c77f5cabed06be363df78ca03b6e66566a97
Author: Michał Górny  gentoo  org>
AuthorDate: Tue Mar 21 16:09:02 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Mar 24 13:56:06 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=5704c77f

python: Rewrite "one PyPI URL" check to reuse PYPI_SDIST_URI_RE

Technically this is less optimal than the original code but it opens up
the possibility of enabling PYPI_PN support next.

Signed-off-by: Michał Górny  gentoo.org>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 19b87ef5..95295271 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -815,18 +815,17 @@ class PythonFetchableCheck(Check):
 if len(pypi_uris) == 1:
 uri, filename = pypi_uris[0]
 
-def matches_fn(expected_fn: str) -> bool:
-expected = 
f"{PYPI_URI_PREFIX}source/{pkg.package[0]}/{pkg.package}/{expected_fn}"
-return uri == expected and filename == expected_fn
-
-version = self.translate_version(pkg.version)
-append = len(uris) > 1
-if 
matches_fn(f"{self.normalize_distribution_name(pkg.package)}-{version}.tar.gz"):
-yield PythonInlinePyPIURI(uri, normalize=True, append=append, 
pkg=pkg)
-return
-if matches_fn(f"{pkg.package}-{version}.tar.gz"):
-yield PythonInlinePyPIURI(uri, normalize=False, append=append, 
pkg=pkg)
-return
+if source_match := PYPI_SDIST_URI_RE.match(uri):
+pn, filename_pn, pv, suffix = source_match.groups()
+if pv == self.translate_version(pkg.version) and suffix == 
".tar.gz":
+append = len(uris) > 1
+normalize = filename_pn == 
self.normalize_distribution_name(pn)
+if not normalize and filename_pn != pn:
+# ignore malformed URLs
+return
+if pn == pkg.package:
+yield PythonInlinePyPIURI(uri, normalize=normalize, 
append=append, pkg=pkg)
+return
 
 # otherwise, yield result for every URL, with suggested replacement
 for uri, dist_filename in pypi_uris:



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-03-18 Thread Arthur Zamarin
commit: 6bb4201548e378bb2001610726022de50c79e711
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Mar 18 15:03:54 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Mar 18 15:03:54 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=6bb42015

UnknownCategoryDirs: enable for overlays, ignore scripts dir

Resolves: https://github.com/pkgcore/pkgcheck/issues/564
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/profiles.py | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index a0b8c618..5394dca7 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -536,7 +536,7 @@ class RepoProfilesCheck(RepoCheck):
 _source = (sources.EmptySource, (base.profiles_scope,))
 required_addons = (addons.profiles.ProfileAddon,)
 known_results = frozenset(
-[
+{
 ArchesWithoutProfiles,
 UnusedProfileDirs,
 NonexistentProfilePath,
@@ -548,11 +548,13 @@ class RepoProfilesCheck(RepoCheck):
 BannedProfileEapi,
 DeprecatedProfileEapi,
 ArchesOutOfSync,
-]
+}
 )
 
 # known profile status types for the gentoo repo
-known_profile_statuses = frozenset(["stable", "dev", "exp"])
+known_profile_statuses = frozenset({"stable", "dev", "exp"})
+
+unknown_categories_whitelist = ("scripts",)
 
 def __init__(self, *args, profile_addon):
 super().__init__(*args)
@@ -562,11 +564,10 @@ class RepoProfilesCheck(RepoCheck):
 self.non_profile_dirs = profile_addon.non_profile_dirs
 
 def finish(self):
-if self.options.gentoo_repo:
-if unknown_category_dirs := 
set(self.repo.category_dirs).difference(
-self.repo.categories
-):
-yield UnknownCategoryDirs(sorted(unknown_category_dirs))
+if unknown_category_dirs := set(self.repo.category_dirs).difference(
+self.repo.categories, self.unknown_categories_whitelist
+):
+yield UnknownCategoryDirs(sorted(unknown_category_dirs))
 if nonexistent_categories := 
set(self.repo.config.categories).difference(
 self.repo.category_dirs
 ):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-03-10 Thread Arthur Zamarin
commit: 94a1af3c65f8cecd05feabe1c25ac94d27c8db1c
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Mar 11 07:17:00 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Mar 11 07:17:00 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=94a1af3c

SrcUriChecksumChange: fix false positive with new ebuilds

When ebuilds are added and being modified in the same commit range, they
might result in thinking there is old checksum for the file, when in
fact it is empty dict.

Resolves: https://github.com/pkgcore/pkgcheck/issues/553
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index aec3b05f..c7785729 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -444,6 +444,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 ),
 fetchable,
 )
+if fetch.chksums
 }
 
 old_checksums = {
@@ -457,6 +458,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 ),
 fetchable,
 )
+if fetch.chksums
 }
 except (IndexError, FileNotFoundError, tarfile.ReadError):
 # ignore broken ebuild



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2023-03-10 Thread Arthur Zamarin
commit: 7410c137c57c645b5e502f279eb183a14d7ef216
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Mar 11 07:10:29 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Mar 11 07:10:29 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7410c137

GitPkgCommitsCheck: fix modification check for added ebuild in pkgset

When commit range has modification for multiple versions, with one of
them modifying a newly added version in the same range, it wouldn't find
the correct base commit and fail. Fix it by grouping based on fullver.

The test is special with time.sleep, since I need the commits be in
different seconds, otherwise the sorting by time might be bad.

Resolves: https://github.com/pkgcore/pkgcheck/issues/563
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py |  6 +-
 tests/checks/test_git.py   | 15 +++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 7309a08f..aec3b05f 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -497,7 +497,11 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 yield from self.rename_checks(list(pkg_map["R"]))
 # run modified package checks
 if modified := [pkg for pkg in pkg_map["M"] if pkg not in 
pkg_map["D"]]:
-yield from self.modified_checks(modified, list(pkg_map["A"]))
+version_modifications = defaultdict(list)
+for pkg in modified:
+version_modifications[pkg.fullver].append(pkg)
+for modified in version_modifications.values():
+yield from self.modified_checks(modified, pkg_map["A"])
 
 for git_pkg in pkgset:
 # remaining checks are irrelevant for removed packages

diff --git a/tests/checks/test_git.py b/tests/checks/test_git.py
index 7eb7907a..03687451 100644
--- a/tests/checks/test_git.py
+++ b/tests/checks/test_git.py
@@ -1,5 +1,6 @@
 import os
 import textwrap
+import time
 from datetime import datetime, timedelta
 from unittest.mock import patch
 
@@ -736,6 +737,20 @@ class TestGitPkgCommitsCheck(ReportTestCase):
 self.init_check()
 self.assertNoReport(self.check, self.source)
 
+def test_modified_added_file(self):
+self.child_repo.create_ebuild("cat/pkg-0", 
homepage="https://gentoo.org;)
+self.child_git_repo.add_all("cat/pkg: update HOMEPAGE")
+time.sleep(1)
+self.child_repo.create_ebuild("cat/pkg-1", eapi="7")
+self.child_git_repo.add_all("cat/pkg: add 1")
+time.sleep(1)
+self.child_repo.create_ebuild("cat/pkg-1", eapi="8")
+self.child_git_repo.add_all("cat/pkg: bump EAPI")
+self.init_check()
+r = self.assertReport(self.check, self.source)
+expected = git_mod.EAPIChangeWithoutRevbump(pkg=CPV("cat/pkg-1"))
+assert r == expected
+
 
 class TestGitEclassCommitsCheck(ReportTestCase):
 check_kls = git_mod.GitEclassCommitsCheck



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2023-03-05 Thread Arthur Zamarin
commit: e8d16ecb9765c32694b7a518381aee94ef5d9108
Author: Sam James  gentoo  org>
AuthorDate: Sat Mar  4 09:20:28 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Mar  5 17:13:22 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e8d16ecb

checks: git: add PythonPEP517WithoutRevbump

Warn when DISTUTILS_USE_PEP517 is added or removed from an
ebuild without a new revision.

This is important because PEP517 affects a package's installed
files anyway and it's important to ensure that dependencies
work correctly against it, but also because e.g. config files
or other data files might either now be installed to the wrong
location or not installed at all. Developers must inspect
the image before/after (e.g. using iwdevtools) to avoid
issues.

Fixes: https://github.com/pkgcore/pkgcheck/issues/498
Signed-off-by: Sam James  gentoo.org>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 28 
 tests/checks/test_git.py   | 19 +++
 2 files changed, 47 insertions(+)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 8b272531..22780cbe 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -171,6 +171,18 @@ class MissingMove(results.PackageResult, results.Error):
 return f"renamed package: {self.old} -> {self.new}"
 
 
+class PythonPEP517WithoutRevbump(results.PackageResult, results.Warning):
+"""Package has started/stopped using DISTUTILS_USE_PEP517 without revbump.
+
+The package has started or stopped using DISTUTILS_USE_PEP517 without
+a new revision. PEP517 affects the files installed by a package
+and might lead to some files missing.
+
+"""
+
+desc = "changed DISTUTILS_USE_PEP517 without new revision"
+
+
 class SrcUriChecksumChange(results.PackageResult, results.Error):
 """SRC_URI changing checksum without distfile rename."""
 
@@ -265,9 +277,12 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 MissingMove,
 SrcUriChecksumChange,
 SuspiciousSrcUriChange,
+PythonPEP517WithoutRevbump,
 ]
 )
 
+python_pep517_regex = re.compile("^DISTUTILS_USE_PEP517=")
+
 # package categories that are committed with stable keywords
 allowed_direct_stable = frozenset(["acct-user", "acct-group"])
 
@@ -364,6 +379,19 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 if pkg not in added and old_pkg.rdepend != new_pkg.rdepend:
 yield RdependChange(pkg=new_pkg)
 
+if "distutils-r1" in new_pkg.inherited:
+
+def found_pep517_lines(cmp_pkg):
+return any(
+self.python_pep517_regex.match(line) for line in 
cmp_pkg.ebuild.text_fileobj()
+)
+
+found_old_pep517_line = found_pep517_lines(old_pkg)
+found_new_pep517_line = found_pep517_lines(new_pkg)
+
+if found_old_pep517_line ^ found_new_pep517_line:
+yield PythonPEP517WithoutRevbump(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 57fc28ac..5deaad71 100644
--- a/tests/checks/test_git.py
+++ b/tests/checks/test_git.py
@@ -675,6 +675,25 @@ class TestGitPkgCommitsCheck(ReportTestCase):
 r = self.assertReport(self.check, self.source)
 assert r == git_mod.SrcUriChecksumChange(distfile[1], 
pkg=CP("cat/pkg"))
 
+def test_python_pep517_change(self):
+with open(pjoin(self.parent_git_repo.path, 
"eclass/distutils-r1.eclass"), "w") as f:
+f.write("# Copyright 1999-2019 Gentoo Authors")
+self.parent_git_repo.add_all("eclass: add distutils-r1")
+
+# add pkgs to parent repo
+self.parent_repo.create_ebuild("newcat/newpkg-1", data="inherit 
distutils-r1")
+self.parent_git_repo.add_all("newcat/newpkg: initial import")
+# pull changes to child repo
+self.child_git_repo.run(["git", "pull", "origin", "main"])
+# change an existing ebuild to have DISTUTILS_USE_PEP517 with no 
revbump
+with open(pjoin(self.child_git_repo.path, 
"newcat/newpkg/newpkg-1.ebuild"), "a") as f:
+f.write("\nDISTUTILS_USE_PEP517=setuptools\n")
+self.child_git_repo.add_all("newcat/newpkg: use PEP517")
+self.init_check()
+r = self.assertReport(self.check, self.source)
+expected = 
git_mod.PythonPEP517WithoutRevbump(pkg=CPV("newcat/newpkg-1"))
+assert r == expected
+
 def test_src_uri_change(self):
 distfile = [
 "DIST",



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-03-04 Thread Arthur Zamarin
commit: bf68177d4026b014f96e64ff3c3a632ecc30a5d2
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Mar  4 18:24:17 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Mar  4 18:24:17 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=bf68177d

PythonMissingSCMDependency: update to new pkg names

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 291a56b4..19b87ef5 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -234,16 +234,16 @@ class 
PythonAnyMismatchedDepHasVersionCheck(results.VersionResult, results.Warni
 
 
 class PythonMissingSCMDependency(results.VersionResult, results.Warning):
-"""Package is missing BDEPEND on setuptools_scm or alike.
+"""Package is missing BDEPEND on setuptools-scm or alike.
 
 Packages which define ``SETUPTOOLS_SCM_PRETEND_VERSION`` should BDEPEND
-on ``dev-python/setuptools_scm`` or a similar package [#]_.
+on ``dev-python/setuptools-scm`` or a similar package [#]_.
 
 .. [#] 
https://projects.gentoo.org/python/guide/distutils.html#setuptools-scm-flit-scm-hatch-vcs-and-snapshots
 """
 
 desc = (
-"defines SETUPTOOLS_SCM_PRETEND_VERSION but is missing BDEPEND on 
setuptools_scm or alike"
+"defines SETUPTOOLS_SCM_PRETEND_VERSION but is missing BDEPEND on 
setuptools-scm or alike"
 )
 
 
@@ -291,8 +291,10 @@ class PythonCheck(Check):
 
 setuptools_scm = frozenset(
 {
-"dev-python/setuptools_scm",
-"dev-python/flit_scm",
+"dev-python/setuptools-scm",
+"dev-python/setuptools_scm",  # legacy old name
+"dev-python/flit-scm",
+"dev-python/flit_scm",  # legacy old name
 "dev-python/hatch-vcs",
 }
 )



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2023-03-03 Thread Arthur Zamarin
commit: 861c24ab76bfc36de2ca80a8375866e4123dc51a
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Mar  4 05:56:56 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Mar  4 05:56:56 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=861c24ab

StableRequestCheck: ignore version not keyworded for arches

packages that are not keyworded for relevant arches but keyworded to
another arch, were not ignored by the check. This patch fixes that.

Resolves: https://github.com/pkgcore/pkgcheck/issues/544
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/stablereq.py | 5 +
 tests/checks/test_stablereq.py   | 9 +
 2 files changed, 14 insertions(+)

diff --git a/src/pkgcheck/checks/stablereq.py b/src/pkgcheck/checks/stablereq.py
index 57e41a84..be8e2c7f 100644
--- a/src/pkgcheck/checks/stablereq.py
+++ b/src/pkgcheck/checks/stablereq.py
@@ -71,6 +71,7 @@ class StableRequestCheck(GentooRepoCheck):
 pkg_keywords.update(pkg.keywords)
 
 if stable_pkg_keywords := {x for x in pkg_keywords if x[0] not in 
{"-", "~"}}:
+keyworded_pkg_keywords = {"~" + x for x in stable_pkg_keywords}
 for slot, pkgs in sorted(pkg_slotted.items()):
 slot_keywords = set().union(*(pkg.keywords for pkg in pkgs))
 stable_slot_keywords = 
slot_keywords.intersection(stable_pkg_keywords)
@@ -79,6 +80,10 @@ class StableRequestCheck(GentooRepoCheck):
 if stable_pkg_keywords.intersection(pkg.keywords):
 break
 
+# stop if not keyworded for stable
+if not keyworded_pkg_keywords.intersection(pkg.keywords):
+break
+
 try:
 match = 
next(self.modified_repo.itermatch(pkg.versioned_atom))
 except StopIteration:

diff --git a/tests/checks/test_stablereq.py b/tests/checks/test_stablereq.py
index 43f4380b..efb94b7a 100644
--- a/tests/checks/test_stablereq.py
+++ b/tests/checks/test_stablereq.py
@@ -118,6 +118,15 @@ class TestStableRequestCheck(ReportTestCase):
 expected = StableRequest("1", ["~amd64"], 30, 
pkg=VersionedCPV("cat/pkg-2"))
 assert r == expected
 
+def test_unkeyworded_new_pkg(self):
+self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"])
+self.parent_git_repo.add_all("cat/pkg-1")
+self.parent_repo.create_ebuild("cat/pkg-2", keywords=["~x86"])
+self.parent_git_repo.add_all("cat/pkg-2")
+self.child_git_repo.run(["git", "pull", "origin", "main"])
+self.init_check(future=30)
+self.assertNoReport(self.check, self.source)
+
 def test_moved_category(self):
 self.parent_repo.create_ebuild("cat/pkg-1", keywords=["amd64"])
 self.parent_git_repo.add_all("cat/pkg-1")



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-02-18 Thread Arthur Zamarin
commit: e02e7c0db8c358e4fa2b9acb1fa9e2c04754fef7
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Feb 17 10:09:15 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Feb 17 10:09:15 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e02e7c0d

SuspiciousSrcUriChange: fix mirrors in fetchables

Resolves: https://github.com/pkgcore/pkgcheck/issues/548
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 23f984b4..8b272531 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -392,13 +392,27 @@ class GitPkgCommitsCheck(GentooRepoCheck, 
GitCommitsCheck):
 new_checksums = {
 fetch.filename: (fetch.chksums, self._fetchable_str(fetch))
 for pkg in self.repo.match(pkg)
-for fetch in iflatten_instance(pkg.fetchables, fetchable)
+for fetch in iflatten_instance(
+pkg.generate_fetchables(
+allow_missing_checksums=True,
+ignore_unknown_mirrors=True,
+skip_default_mirrors=True,
+),
+fetchable,
+)
 }
 
 old_checksums = {
 fetch.filename: (fetch.chksums, self._fetchable_str(fetch))
 for pkg in self.modified_repo(pkgset).match(pkg)
-for fetch in iflatten_instance(pkg.fetchables, fetchable)
+for fetch in iflatten_instance(
+pkg.generate_fetchables(
+allow_missing_checksums=True,
+ignore_unknown_mirrors=True,
+skip_default_mirrors=True,
+),
+fetchable,
+)
 }
 except (IndexError, FileNotFoundError, tarfile.ReadError):
 # ignore broken ebuild



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-02-17 Thread Arthur Zamarin
commit: fcdd1698e17876d0f45bf07de09320275b512898
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Feb 17 10:04:19 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Feb 17 10:04:19 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=fcdd1698

InvalidCommitTag: fix false positive for advanced fixes format

Support more advanced format for Fixes and Reverts, which can have
explanation text after the commit hash, and can end in a dot.

Resolves: https://github.com/pkgcore/pkgcheck/issues/546
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 4a9466c6..23f984b4 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -507,7 +507,7 @@ class InvalidCommitTag(results.CommitResult, results.Style):
 .. [#] https://www.gentoo.org/glep/glep-0066.html#commit-messages
 """
 
-def __init__(self, tag, value, error, **kwargs):
+def __init__(self, tag: str, value: str, error: str, **kwargs):
 super().__init__(**kwargs)
 self.tag, self.value, self.error = tag, value, error
 
@@ -571,18 +571,19 @@ class GitCommitMessageCheck(GentooRepoCheck, 
GitCommitsCheck):
 
 _source = GitCommitsSource
 known_results = frozenset(
-[
+{
 MissingSignOff,
 InvalidCommitTag,
 InvalidCommitMessage,
 BadCommitSummary,
-]
+}
 )
 
 # mapping between known commit tags and verification methods
 known_tags = {}
 _commit_footer_regex = re.compile(r"^(?P[a-zA-Z0-9_-]+): 
(?P.*)$")
 _git_cat_file_regex = re.compile(r"^(?P.+?) (?P.+)$")
+_commit_ref_regex = re.compile(r"^(?P[0-9a-fA-F]+?)( 
\(.+?\))?\.?$")
 
 # categories exception for rule of having package version in summary
 skipped_categories = frozenset(
@@ -642,15 +643,23 @@ class GitCommitMessageCheck(GentooRepoCheck, 
GitCommitsCheck):
 @verify_tags("Fixes", "Reverts")
 def _commit_tag(self, tag, values, commit: git.GitCommit):
 """Verify referenced commits exist for Fixes/Reverts tags."""
-self.git_cat_file.stdin.write("\n".join(values) + "\n")
+commits: dict[str, str] = {}
+for value in values:
+if mo := self._commit_ref_regex.match(value):
+commits[mo.group("object")] = value
+else:
+yield InvalidCommitTag(tag, value, "invalid format", 
commit=commit)
+self.git_cat_file.stdin.write("\n".join(commits.keys()) + "\n")
 if self.git_cat_file.poll() is None:
-for _ in range(len(values)):
+for _ in range(len(commits)):
 line = self.git_cat_file.stdout.readline().strip()
 if mo := self._git_cat_file_regex.match(line):
 value = mo.group("object")
 status = mo.group("status")
 if not status.startswith("commit "):
-yield InvalidCommitTag(tag, value, f"{status} commit", 
commit=commit)
+yield InvalidCommitTag(
+tag, commits[value], f"{status} commit", 
commit=commit
+)
 
 def feed(self, commit: git.GitCommit):
 if len(commit.message) == 0:



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-02-16 Thread Arthur Zamarin
commit: 8f39dd01df91dd64c33f54b2c95ae3bcc337
Author: Michał Górny  gentoo  org>
AuthorDate: Mon Feb 13 07:03:36 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed Feb 15 17:49:27 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8f39

python: Use a more generic name for the project normalization regex

Do not reference PEP 503 in the project name normalization regex.
The same regex will be used for other kinds of project name
normalization, notably wheel and sdist normalization.

Signed-off-by: Michał Górny  gentoo.org>
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 29b3db8e..7cff5f12 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -25,7 +25,7 @@ GITHUB_ARCHIVE_RE = 
re.compile(r"^https://github\.com/[^/]+/[^/]+/archive/;)
 SNAPSHOT_RE = re.compile(r"[a-fA-F0-9]{40}\.tar\.gz$")
 USE_FLAGS_PYTHON_USEDEP = re.compile(r"\[(.+,)?\$\{PYTHON_USEDEP\}(,.+)?\]$")
 
-PEP503_SYMBOL_NORMALIZE_RE = re.compile(r"[-_.]+")
+PROJECT_SYMBOL_NORMALIZE_RE = re.compile(r"[-_.]+")
 
 
 def get_python_eclass(pkg):
@@ -768,7 +768,7 @@ class PythonPackageNameCheck(Check):
 
 https://peps.python.org/pep-0503/#normalized-names
 """
-return PEP503_SYMBOL_NORMALIZE_RE.sub("-", project).lower()
+return PROJECT_SYMBOL_NORMALIZE_RE.sub("-", project).lower()
 
 pypi_name = pypi_remotes[0].name
 if normalize(pkg.package) != normalize(pypi_name):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-02-05 Thread Arthur Zamarin
commit: 5727b3be6b1b99ae6d47873585a8e92e96147a9f
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Feb  5 17:53:32 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Feb  5 17:53:32 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=5727b3be

UnusedInherits: fix false positives for eclasses defining special vars

Skip unused warning for eclasses which define special variables like
SRC_URI, HOMEPAGE, etc. In practice it makes any inherit for pypi,
ruby-fakegem, ruby-ng-gnome2, gstreamer-meson to never be considered
unused.

Resolves: https://github.com/pkgcore/pkgcheck/issues/361
Resolves: https://github.com/pkgcore/pkgcheck/issues/540
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 6fec22ca..a9eb70fa 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -3,7 +3,7 @@
 import re
 from collections import defaultdict
 
-from pkgcore.ebuild.eapi import EAPI
+from pkgcore.ebuild.eapi import EAPI, common_mandatory_metadata_keys
 from snakeoil.mappings import ImmutableDict
 from snakeoil.sequences import stable_unique
 from snakeoil.strings import pluralism
@@ -758,10 +758,9 @@ class InheritsCheck(Check):
 
 # register EAPI-related vars to ignore
 # TODO: add ebuild env vars via pkgcore setting, e.g. PN, PV, P, 
FILESDIR, etc
-self.eapi_vars = {}
-for eapi in EAPI.known_eapis.values():
-s = set(eapi.eclass_keys)
-self.eapi_vars[eapi] = frozenset(s)
+self.eapi_vars = {eapi: frozenset(eapi.eclass_keys) for eapi in 
EAPI.known_eapis.values()}
+
+self.unused_eclass_skiplist = 
frozenset(common_mandatory_metadata_keys) - {"IUSE"}
 
 def get_eclass(self, export, pkg):
 """Return the eclass related to a given exported variable or function 
name."""
@@ -851,10 +850,12 @@ class InheritsCheck(Check):
 # ignore eclasses with parsing failures
 unused.discard(eclass)
 else:
-exported_eclass_keys = pkg.eapi.eclass_keys.intersection(
+exported_eclass_keys: set[str] = 
pkg.eapi.eclass_keys.intersection(
 self.eclass_cache[eclass].exported_variable_names
 )
-if not self.eclass_cache[eclass].exported_function_names and 
exported_eclass_keys:
+if 
exported_eclass_keys.intersection(self.unused_eclass_skiplist):
+unused.discard(eclass)
+elif not self.eclass_cache[eclass].exported_function_names and 
exported_eclass_keys:
 # ignore eclasses that export ebuild metadata (e.g.
 # SRC_URI, S, ...) and no functions
 unused.discard(eclass)



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-02-05 Thread Arthur Zamarin
commit: f0afcf79495fb4220258bae1acd1304a755dbc66
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Feb  5 17:15:31 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Feb  5 17:15:31 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=f0afcf79

SuspiciousSrcUriChange: compare with expanded mirror

Resolves: https://github.com/pkgcore/pkgcheck/issues/542
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index c7c78bc8..4a9466c6 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -375,13 +375,15 @@ class GitPkgCommitsCheck(GentooRepoCheck, 
GitCommitsCheck):
 else:
 yield MissingSlotmove(old_slot, new_slot, pkg=new_pkg)
 
-@staticmethod
-def _fetchable_str(fetch: fetchable) -> str:
+def _fetchable_str(self, fetch: fetchable) -> tuple[str, str]:
 uri = tuple(fetch.uri._uri_source)[0]
 if isinstance(uri, tuple):
-return f"mirror://{uri[0].mirror_name}/{uri[1]}"
+mirror = uri[0].mirror_name
+expands = self.repo.mirrors.get(mirror)
+expand = (expands or (f"mirror://{mirror}",))[0].lstrip("/")
+return f"{expand}/{uri[1]}", 
f"mirror://{uri[0].mirror_name}/{uri[1]}"
 else:
-return str(uri)
+return (str(uri),) * 2
 
 def src_uri_changes(self, pkgset):
 pkg = pkgset[0].unversioned_atom
@@ -403,11 +405,11 @@ class GitPkgCommitsCheck(GentooRepoCheck, 
GitCommitsCheck):
 return
 
 for filename in old_checksums.keys() & new_checksums.keys():
-old_checksum, old_uri = old_checksums[filename]
-new_checksum, new_uri = new_checksums[filename]
+old_checksum, (old_expand, old_uri) = old_checksums[filename]
+new_checksum, (new_expand, new_uri) = new_checksums[filename]
 if old_checksum != new_checksum:
 yield SrcUriChecksumChange(filename, pkg=pkg)
-elif old_uri != new_uri:
+elif old_expand != new_expand:
 yield SuspiciousSrcUriChange(old_uri, new_uri, filename, 
pkg=pkg)
 
 def feed(self, pkgset: list[git.GitPkgChange]):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-02-03 Thread Arthur Zamarin
commit: 87226810dca088b8eec5d03639b3d830293c82aa
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Tue Jan 31 18:00:51 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Feb  3 13:03:35 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=87226810

PythonCheck: check for missing scm dep when needed

Resolves: https://github.com/pkgcore/pkgcheck/issues/537
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py  | 37 --
 .../PythonMissingSCMDependency/expected.json   |  1 +
 .../PythonMissingSCMDependency/fix.patch   |  8 +
 .../PythonMissingSCMDependency-0.ebuild| 13 
 .../PythonMissingSCMDependency/metadata.xml|  4 +++
 5 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 2b20ee93..11ebc1e1 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -1,6 +1,7 @@
-from collections import defaultdict
 import itertools
 import re
+from collections import defaultdict
+from operator import attrgetter
 
 from pkgcore import fetch
 from pkgcore.ebuild.atom import atom
@@ -222,6 +223,20 @@ class 
PythonAnyMismatchedDepHasVersionCheck(results.VersionResult, results.Warni
 return f"{self.dep_category}: missing check for 
{self.dep_atom}[{use_flags}] in {self.location!r}"
 
 
+class PythonMissingSCMDependency(results.VersionResult, results.Warning):
+"""Package is missing BDEPEND on setuptools_scm or alike.
+
+Packages which define ``SETUPTOOLS_SCM_PRETEND_VERSION`` should BDEPEND
+on ``dev-python/setuptools_scm`` or a similar package [#]_.
+
+.. [#] 
https://projects.gentoo.org/python/guide/distutils.html#setuptools-scm-flit-scm-hatch-vcs-and-snapshots
+"""
+
+desc = (
+"defines SETUPTOOLS_SCM_PRETEND_VERSION but is missing BDEPEND on 
setuptools_scm or alike"
+)
+
+
 class PythonCheck(Check):
 """Python eclass checks.
 
@@ -242,6 +257,7 @@ class PythonCheck(Check):
 PythonHasVersionMissingPythonUseDep,
 PythonAnyMismatchedUseHasVersionCheck,
 PythonAnyMismatchedDepHasVersionCheck,
+PythonMissingSCMDependency,
 ]
 )
 
@@ -263,6 +279,14 @@ class PythonCheck(Check):
 "python-r1": "python_gen_any_dep",
 }
 
+setuptools_scm = frozenset(
+{
+"dev-python/setuptools_scm",
+"dev-python/flit_scm",
+"dev-python/hatch-vcs",
+}
+)
+
 def scan_tree_recursively(self, deptree, expected_cls):
 for x in deptree:
 if not isinstance(x, expected_cls):
@@ -319,6 +343,7 @@ class PythonCheck(Check):
 """
 has_distutils_optional = None
 has_distutils_deps = False
+uses_setuptools_scm = False
 pep517_value = None
 
 for var_node, _ in bash.var_assign_query.captures(pkg.tree.root_node):
@@ -328,21 +353,29 @@ class PythonCheck(Check):
 has_distutils_optional = True
 elif var_name == "DISTUTILS_USE_PEP517":
 pep517_value = pkg.node_str(var_node.children[-1])
+elif var_name == "SETUPTOOLS_SCM_PRETEND_VERSION":
+uses_setuptools_scm = True
 
 if "DISTUTILS_DEPS" in pkg.node_str(var_node.parent):
 # If they're referencing the eclass' dependency variable,
 # there's nothing for us to do anyway.
 has_distutils_deps = True
 
+bdepends = frozenset(map(attrgetter("key"), 
iflatten_instance(pkg.bdepend, atom)))
+
 if pep517_value is None:
 yield DistutilsNonPEP517Build(pkg=pkg)
 elif has_distutils_optional and not has_distutils_deps and 
pep517_value != "no":
 # We always need BDEPEND for these if != no.
 # We are looking for USE-conditional on appropriate target
 # flag, with dep on dev-python/gpep517.
-if "dev-python/gpep517" not in iflatten_instance(pkg.bdepend, 
atom):
+if "dev-python/gpep517" not in bdepends:
 yield PythonMissingDeps("BDEPEND", pkg=pkg, 
dep_value="DISTUTILS_DEPS")
 
+if uses_setuptools_scm:
+if not self.setuptools_scm.intersection(bdepends):
+yield PythonMissingSCMDependency(pkg=pkg)
+
 @staticmethod
 def _prepare_deps(deps: str):
 try:

diff --git 
a/testdata/data/repos/python/PythonCheck/PythonMissingSCMDependency/expected.json
 
b/testdata/data/repos/python/PythonCheck/PythonMissingSCMDependency/expected.json
new file mode 100644
index ..9297a0d5
--- /dev/null
+++ 
b/testdata/data/repos/python/PythonCheck/PythonMissingSCMDependency/expected.json
@@ -0,0 +1 @@
+{"__class__": "PythonMissingSCMDependency", "category": "PythonCheck", 
"package": "PythonMissingSCMDependency", "version": "0"}

diff --git 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-01-31 Thread Arthur Zamarin
commit: e8a4b35b90c6c3ab1b7029770d2e47c4be0dbeb2
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Tue Jan 31 17:07:00 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Tue Jan 31 17:07:00 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e8a4b35b

checks.python: small modernization

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py | 27 +++
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 41edac21..2b20ee93 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -41,7 +41,7 @@ def is_python_interpreter(pkg):
 # ignore python:2.7 deps since they are being phased out from eclass
 # support
 return pkg.slot is None or not pkg.slot.startswith("2")
-return pkg.key in ["dev-python/pypy3"]
+return pkg.key in ("dev-python/pypy3",)
 
 
 class MissingPythonEclass(results.VersionResult, results.Warning):
@@ -74,9 +74,7 @@ class PythonMissingRequiredUse(results.VersionResult, 
results.Warning):
 used conditionally, it can be wrapped in appropriate USE conditionals.
 """
 
-@property
-def desc(self):
-return 'missing REQUIRED_USE="${PYTHON_REQUIRED_USE}"'
+desc = 'missing REQUIRED_USE="${PYTHON_REQUIRED_USE}"'
 
 
 class PythonMissingDeps(results.VersionResult, results.Warning):
@@ -138,9 +136,7 @@ class PythonEclassError(results.VersionResult, 
results.Error):
 class DistutilsNonPEP517Build(results.VersionResult, results.Warning):
 """Ebuild uses the deprecated non-PEP517 build"""
 
-@property
-def desc(self):
-return "uses deprecated non-PEP517 build mode, please switch to " 
"DISTUTILS_USE_PEP517=..."
+desc = "uses deprecated non-PEP517 build mode, please switch to 
DISTUTILS_USE_PEP517=..."
 
 
 class PythonHasVersionUsage(results.LinesResult, results.Style):
@@ -173,7 +169,7 @@ class 
PythonHasVersionMissingPythonUseDep(results.LineResult, results.Error):
 @property
 def desc(self):
 return (
-f'line: {self.lineno}: missing [${{PYTHON_USEDEP}}] suffix for 
argument "{self.line}"'
+f"line: {self.lineno}: missing [${{PYTHON_USEDEP}}] suffix for 
argument {self.line!r}"
 )
 
 
@@ -270,8 +266,7 @@ class PythonCheck(Check):
 def scan_tree_recursively(self, deptree, expected_cls):
 for x in deptree:
 if not isinstance(x, expected_cls):
-for y in self.scan_tree_recursively(x, expected_cls):
-yield y
+yield from self.scan_tree_recursively(x, expected_cls)
 yield deptree
 
 def check_required_use(self, requse, flags, prefix, container_cls):
@@ -576,12 +571,12 @@ class PythonCompatCheck(Check):
 def deps(self, pkg, attrs=None):
 """Set of dependencies for a given package's attributes."""
 attrs = attrs if attrs is not None else pkg.eapi.dep_keys
-deps = set()
-for attr in (x.lower() for x in attrs):
-for p in iflatten_instance(getattr(pkg, attr), atom):
-if not p.blocks:
-deps.add(p)
-return deps
+return {
+p
+for attr in (x.lower() for x in attrs)
+for p in iflatten_instance(getattr(pkg, attr), atom)
+if not p.blocks
+}
 
 def feed(self, pkg):
 try:



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-01-31 Thread Arthur Zamarin
commit: 4438566500fdf116ba36c3c407022e89541867d6
Author: Michał Górny  gentoo  org>
AuthorDate: Sun Jan 29 14:50:41 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Tue Jan 31 16:17:53 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=44385665

checks: Add a check for Python pkgnames matching PyPI

Signed-off-by: Michał Górny  gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/534
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 510689bb..6965d2a9 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -24,6 +24,8 @@ GITHUB_ARCHIVE_RE = 
re.compile(r"^https://github\.com/[^/]+/[^/]+/archive/;)
 SNAPSHOT_RE = re.compile(r"[a-fA-F0-9]{40}\.tar\.gz$")
 USE_FLAGS_PYTHON_USEDEP = re.compile(r"\[(.+,)?\$\{PYTHON_USEDEP\}(,.+)?\]$")
 
+PEP503_SYMBOL_NORMALIZE_RE = re.compile(r"[-_.]")
+
 
 def get_python_eclass(pkg):
 eclasses = ECLASSES.intersection(pkg.inherited)
@@ -694,3 +696,48 @@ class PythonGHDistfileSuffixCheck(Check):
 if GITHUB_ARCHIVE_RE.match(uri):
 yield PythonGHDistfileSuffix(f.filename, uri, pkg=pkg)
 break
+
+
+class PythonMismatchedPackageName(results.PackageResult, results.Info):
+"""Package name does not follow PyPI-based naming policy"""
+
+def __init__(self, recommended: str, **kwargs):
+super().__init__(**kwargs)
+self.recommended = recommended
+
+@property
+def desc(self) -> str:
+return ("package name does not match remote-id, recommended name: "
+f"{self.recommended!r}")
+
+
+class PythonPackageNameCheck(Check):
+"""Check ebuild names in dev-python/*."""
+
+_source = sources.PackageRepoSource
+known_results = frozenset([PythonMismatchedPackageName])
+
+def feed(self, pkgs):
+pkg = next(iter(pkgs))
+
+# the policy applies to dev-python/* only
+if pkg.category != "dev-python":
+return
+
+# consider only packages with a single pypi remote-id
+pypi_remotes = [x for x in pkg.upstreams if x.type == "pypi"]
+if len(pypi_remotes) != 1:
+return
+
+def normalize(project: str) -> str:
+"""
+Normalize project name using PEP 503 rules
+
+https://peps.python.org/pep-0503/#normalized-names
+"""
+return PEP503_SYMBOL_NORMALIZE_RE.sub("-", project).lower()
+
+pypi_name = pypi_remotes[0].name
+if normalize(pkg.package) != normalize(pypi_name):
+yield PythonMismatchedPackageName(pypi_name.replace(".", "-"),
+  pkg=pkg)



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-01-30 Thread Arthur Zamarin
commit: 088136ddc8008856eb6c3d3e432e15af8d704ba3
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Thu Jan 26 18:24:50 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Jan 26 18:24:50 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=088136dd

InvalidMetadataRestrict: check for invalid restricts in metadata.xml

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata_xml.py| 34 ++
 .../InvalidMetadataRestrict/expected.json  |  1 +
 .../InvalidMetadataRestrict-0.ebuild   |  8 +
 .../InvalidMetadataRestrict/metadata.xml   | 10 +++
 4 files changed, 53 insertions(+)

diff --git a/src/pkgcheck/checks/metadata_xml.py 
b/src/pkgcheck/checks/metadata_xml.py
index 0fcc31ac..adba0bdb 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -294,6 +294,19 @@ class InvalidRemoteID(results.PackageResult, 
results.Warning):
 )
 
 
+class InvalidMetadataRestrict(results.PackageResult, results.Error):
+"""Invalid package restrictions used in metadata.xml."""
+
+def __init__(self, restrict: str, msg: str, **kwargs):
+super().__init__(**kwargs)
+self.restrict = restrict
+self.msg = msg
+
+@property
+def desc(self):
+return f"metadata.xml: invalid package restrictions {self.restrict!r}: 
{self.msg}"
+
+
 class _XmlBaseCheck(Check):
 """Base class for metadata.xml scans."""
 
@@ -433,6 +446,7 @@ class PackageMetadataXmlCheck(_XmlBaseCheck):
 NonexistentProjectMaintainer,
 WrongMaintainerType,
 InvalidRemoteID,
+InvalidMetadataRestrict,
 ]
 )
 
@@ -534,6 +548,26 @@ class PackageMetadataXmlCheck(_XmlBaseCheck):
 msg = "metadata.xml longdescription is too short"
 yield RedundantLongDescription(msg, pkg=pkg)
 
+def _check_restricts(self, pkg, loc, doc):
+restricts = (
+c.get("restrict")
+for path in ("maintainer", "use/flag")
+for c in doc.xpath(f"/pkgmetadata/{path}[string(@restrict)]")
+)
+for restrict_str in restricts:
+try:
+restrict = atom(restrict_str, eapi="0")
+if restrict.key != pkg.key:
+yield InvalidMetadataRestrict(
+restrict_str, "references another package", pkg=pkg
+)
+if restrict.use:
+yield InvalidMetadataRestrict(
+restrict_str, "USE-conditionals are prohibited", 
pkg=pkg
+)
+except MalformedAtom as exc:
+yield InvalidMetadataRestrict(restrict_str, exc, pkg=pkg)
+
 def _check_remote_id(self, pkg, loc, doc):
 for u in pkg.upstreams:
 # empty values are already reported as PkgMetadataXmlEmptyElement

diff --git 
a/testdata/data/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/expected.json
 
b/testdata/data/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/expected.json
new file mode 100644
index ..aca61195
--- /dev/null
+++ 
b/testdata/data/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/expected.json
@@ -0,0 +1 @@
+{"__class__": "InvalidMetadataRestrict", "category": 
"PackageMetadataXmlCheck", "package": "InvalidMetadataRestrict", "restrict": 
"<=PackageMetadataXmlCheck2/InvalidMetadataRestrict-5", "msg": "references 
another package"}

diff --git 
a/testdata/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/InvalidMetadataRestrict-0.ebuild
 
b/testdata/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/InvalidMetadataRestrict-0.ebuild
new file mode 100644
index ..eb5d8297
--- /dev/null
+++ 
b/testdata/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/InvalidMetadataRestrict-0.ebuild
@@ -0,0 +1,8 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+DESCRIPTION="Package metadata.xml with invalid restrict"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck;
+SLOT="0"
+LICENSE="BSD"
+IUSE="flag1"

diff --git 
a/testdata/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/metadata.xml
 
b/testdata/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/metadata.xml
new file mode 100644
index ..52cd01df
--- /dev/null
+++ 
b/testdata/repos/gentoo/PackageMetadataXmlCheck/InvalidMetadataRestrict/metadata.xml
@@ -0,0 +1,10 @@
+
+http://www.gentoo.org/dtd/metadata.dtd;>
+
+   
+   random.gentoo@gentoo.org
+   
+   
+   Some 
explanation
+   
+



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-01-24 Thread Arthur Zamarin
commit: 0883521640398078ae4f363ffad78eaa1626ee55
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Tue Jan 24 18:57:01 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Tue Jan 24 18:57:01 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=08835216

RdependChange: skip when revbumped in same batch

Resolves: https://github.com/pkgcore/pkgcheck/issues/459
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index adc16874..c7c78bc8 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -340,7 +340,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 else:
 yield MissingMove(old_key, new_key, pkg=pkg)
 
-def modified_checks(self, pkgs):
+def modified_checks(self, pkgs, added):
 """Check for issues due to package modifications."""
 pkg = pkgs[0]
 
@@ -361,7 +361,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 # ignore broken ebuild
 return
 
-if old_pkg.rdepend != new_pkg.rdepend:
+if pkg not in added and old_pkg.rdepend != new_pkg.rdepend:
 yield RdependChange(pkg=new_pkg)
 
 old_slot, new_slot = old_pkg.slot, new_pkg.slot
@@ -437,7 +437,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 yield from self.rename_checks(list(pkg_map["R"]))
 # run modified package checks
 if modified := [pkg for pkg in pkg_map["M"] if pkg not in 
pkg_map["D"]]:
-yield from self.modified_checks(modified)
+yield from self.modified_checks(modified, list(pkg_map["A"]))
 
 for git_pkg in pkgset:
 # remaining checks are irrelevant for removed packages



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2023-01-21 Thread Arthur Zamarin
commit: 7d50c226b79d158ed08e925369560727993fb0b7
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Jan 21 09:44:17 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Jan 21 09:44:17 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7d50c226

SuspiciousSrcUriChange: fix false positive with mirrors

The original code for comparing for URL change was giving false
positives when the URI is mirror based, since an object was used to
compare. Pre-compute the URI string and use strings for comparison.
Also add a test for that failure.

Resolves: https://github.com/pkgcore/pkgcheck/issues/531
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 26 ++
 tests/checks/test_git.py   |  6 ++
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 764dfc5d..adc16874 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -186,16 +186,10 @@ class SrcUriChecksumChange(results.PackageResult, 
results.Error):
 class SuspiciousSrcUriChange(results.PackageResult, results.Warning):
 """Suspicious SRC_URI changing URI without distfile rename."""
 
-def __init__(self, old_uri, new_uri, filename, **kwargs):
+def __init__(self, old_uri: str, new_uri: str, filename: str, **kwargs):
 super().__init__(**kwargs)
-if isinstance(old_uri, tuple):
-self.old_uri = f"mirror://{old_uri[0].mirror_name}/{old_uri[1]}"
-else:
-self.old_uri = str(old_uri)
-if isinstance(new_uri, tuple):
-self.new_uri = f"mirror://{new_uri[0].mirror_name}/{new_uri[1]}"
-else:
-self.new_uri = str(new_uri)
+self.old_uri = old_uri
+self.new_uri = new_uri
 self.filename = filename
 
 @property
@@ -381,18 +375,26 @@ class GitPkgCommitsCheck(GentooRepoCheck, 
GitCommitsCheck):
 else:
 yield MissingSlotmove(old_slot, new_slot, pkg=new_pkg)
 
+@staticmethod
+def _fetchable_str(fetch: fetchable) -> str:
+uri = tuple(fetch.uri._uri_source)[0]
+if isinstance(uri, tuple):
+return f"mirror://{uri[0].mirror_name}/{uri[1]}"
+else:
+return str(uri)
+
 def src_uri_changes(self, pkgset):
 pkg = pkgset[0].unversioned_atom
 
 try:
 new_checksums = {
-fetch.filename: (fetch.chksums, tuple(fetch.uri._uri_source))
+fetch.filename: (fetch.chksums, self._fetchable_str(fetch))
 for pkg in self.repo.match(pkg)
 for fetch in iflatten_instance(pkg.fetchables, fetchable)
 }
 
 old_checksums = {
-fetch.filename: (fetch.chksums, tuple(fetch.uri._uri_source))
+fetch.filename: (fetch.chksums, self._fetchable_str(fetch))
 for pkg in self.modified_repo(pkgset).match(pkg)
 for fetch in iflatten_instance(pkg.fetchables, fetchable)
 }
@@ -406,7 +408,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 if old_checksum != new_checksum:
 yield SrcUriChecksumChange(filename, pkg=pkg)
 elif old_uri != new_uri:
-yield SuspiciousSrcUriChange(old_uri[0], new_uri[0], filename, 
pkg=pkg)
+yield SuspiciousSrcUriChange(old_uri, new_uri, filename, 
pkg=pkg)
 
 def feed(self, pkgset: list[git.GitPkgChange]):
 # Mapping of commit types to pkgs, available commit types can be seen

diff --git a/tests/checks/test_git.py b/tests/checks/test_git.py
index b69893d8..eed40e13 100644
--- a/tests/checks/test_git.py
+++ b/tests/checks/test_git.py
@@ -702,6 +702,12 @@ class TestGitPkgCommitsCheck(ReportTestCase):
 self.init_check()
 r = self.assertReport(self.check, self.source)
 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.init_check()
+self.assertNoReport(self.check, self.source)
 
 
 class TestGitEclassCommitsCheck(ReportTestCase):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2023-01-20 Thread Arthur Zamarin
commit: 09559c09f2389246ea98261832e281a9baaedbdf
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Nov 26 17:06:06 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Jan 20 20:36:42 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=09559c09

GitPkgCommitsCheck: catch SRC_URI mistakes

Resolves: https://github.com/pkgcore/pkgcheck/issues/493
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 67 +-
 tests/checks/test_git.py   | 55 -
 2 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 6e48d47f..764dfc5d 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -13,9 +13,11 @@ from urllib.parse import urlparse
 
 from pkgcore.ebuild.misc import sort_keywords
 from pkgcore.ebuild.repository import UnconfiguredTree
+from pkgcore.fetch import fetchable
 from snakeoil import klass
 from snakeoil.mappings import ImmutableDict
 from snakeoil.osutils import pjoin
+from snakeoil.sequences import iflatten_instance
 from snakeoil.strings import pluralism
 
 from .. import base, results, sources
@@ -169,6 +171,38 @@ class MissingMove(results.PackageResult, results.Error):
 return f"renamed package: {self.old} -> {self.new}"
 
 
+class SrcUriChecksumChange(results.PackageResult, results.Error):
+"""SRC_URI changing checksum without distfile rename."""
+
+def __init__(self, filename, **kwargs):
+super().__init__(**kwargs)
+self.filename = filename
+
+@property
+def desc(self):
+return f"{self.filename!r} has different checksums across commits"
+
+
+class SuspiciousSrcUriChange(results.PackageResult, results.Warning):
+"""Suspicious SRC_URI changing URI without distfile rename."""
+
+def __init__(self, old_uri, new_uri, filename, **kwargs):
+super().__init__(**kwargs)
+if isinstance(old_uri, tuple):
+self.old_uri = f"mirror://{old_uri[0].mirror_name}/{old_uri[1]}"
+else:
+self.old_uri = str(old_uri)
+if isinstance(new_uri, tuple):
+self.new_uri = f"mirror://{new_uri[0].mirror_name}/{new_uri[1]}"
+else:
+self.new_uri = str(new_uri)
+self.filename = filename
+
+@property
+def desc(self):
+return f"{self.filename!r} has changed SRC_URI from {self.old_uri!r} 
to {self.new_uri!r}"
+
+
 class _RemovalRepo(UnconfiguredTree):
 """Repository of removed packages stored in a temporary directory."""
 
@@ -235,6 +269,8 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 DroppedUnstableKeywords,
 MissingSlotmove,
 MissingMove,
+SrcUriChecksumChange,
+SuspiciousSrcUriChange,
 ]
 )
 
@@ -345,7 +381,34 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 else:
 yield MissingSlotmove(old_slot, new_slot, pkg=new_pkg)
 
-def feed(self, pkgset):
+def src_uri_changes(self, pkgset):
+pkg = pkgset[0].unversioned_atom
+
+try:
+new_checksums = {
+fetch.filename: (fetch.chksums, tuple(fetch.uri._uri_source))
+for pkg in self.repo.match(pkg)
+for fetch in iflatten_instance(pkg.fetchables, fetchable)
+}
+
+old_checksums = {
+fetch.filename: (fetch.chksums, tuple(fetch.uri._uri_source))
+for pkg in self.modified_repo(pkgset).match(pkg)
+for fetch in iflatten_instance(pkg.fetchables, fetchable)
+}
+except (IndexError, FileNotFoundError, tarfile.ReadError):
+# ignore broken ebuild
+return
+
+for filename in old_checksums.keys() & new_checksums.keys():
+old_checksum, old_uri = old_checksums[filename]
+new_checksum, new_uri = new_checksums[filename]
+if old_checksum != new_checksum:
+yield SrcUriChecksumChange(filename, pkg=pkg)
+elif old_uri != new_uri:
+yield SuspiciousSrcUriChange(old_uri[0], new_uri[0], filename, 
pkg=pkg)
+
+def feed(self, pkgset: list[git.GitPkgChange]):
 # Mapping of commit types to pkgs, available commit types can be seen
 # under the --diff-filter option in git log parsing support and are
 # disambiguated as follows:
@@ -407,6 +470,8 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 if not pkg.maintainers and newly_added:
 yield DirectNoMaintainer(pkg=pkg)
 
+yield from self.src_uri_changes(pkgset)
+
 
 class MissingSignOff(results.CommitResult, results.Error):
 """Local commit with missing sign offs.

diff --git a/tests/checks/test_git.py b/tests/checks/test_git.py
index 0294f0b3..b69893d8 100644
--- 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-01-20 Thread Arthur Zamarin
commit: 59e9fd40f4a696f262f302b71daec703c719c413
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Jan 20 15:01:36 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Jan 20 15:01:36 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=59e9fd40

checks.git: add type annotations

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 29 +
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index a54ce61e..6e48d47f 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -34,7 +34,7 @@ class GitCommitsRepoSource(sources.RepoSource):
 
 required_addons = (git.GitAddon,)
 
-def __init__(self, options, git_addon):
+def __init__(self, options, git_addon: git.GitAddon):
 source = git_addon.commits_repo(git.GitChangedRepo)
 super().__init__(options, source)
 
@@ -49,7 +49,7 @@ class GitCommitsSource(sources.Source):
 scope = base.commit_scope
 required_addons = (git.GitAddon,)
 
-def __init__(self, *args, git_addon):
+def __init__(self, *args, git_addon: git.GitAddon):
 super().__init__(*args, source=git_addon.commits())
 
 
@@ -100,9 +100,7 @@ class _DroppedKeywords(results.PackageResult):
 def desc(self):
 s = pluralism(self.keywords)
 keywords = ", ".join(self.keywords)
-return (
-f"commit {self.commit} (or later) dropped {self._status} " 
f"keyword{s}: [ {keywords} ]"
-)
+return f"commit {self.commit} (or later) dropped {self._status} 
keyword{s}: [ {keywords} ]"
 
 
 class DroppedUnstableKeywords(_DroppedKeywords, results.Error):
@@ -243,11 +241,11 @@ class GitPkgCommitsCheck(GentooRepoCheck, 
GitCommitsCheck):
 # package categories that are committed with stable keywords
 allowed_direct_stable = frozenset(["acct-user", "acct-group"])
 
-def __init__(self, *args, git_addon):
+def __init__(self, *args, git_addon: git.GitAddon):
 super().__init__(*args)
 self.today = datetime.today()
 self.repo = self.options.target_repo
-self.valid_arches = self.options.target_repo.known_arches
+self.valid_arches: frozenset[str] = 
self.options.target_repo.known_arches
 self._git_addon = git_addon
 self._cleanup = []
 
@@ -280,7 +278,7 @@ class GitPkgCommitsCheck(GentooRepoCheck, GitCommitsCheck):
 old_keywords = set().union(*(p.keywords for p in 
removal_repo.match(pkg.unversioned_atom)))
 new_keywords = set().union(*(p.keywords for p in 
self.repo.match(pkg.unversioned_atom)))
 
-dropped_keywords = old_keywords - new_keywords
+dropped_keywords: set[str] = old_keywords - new_keywords
 dropped_stable_keywords = dropped_keywords & self.valid_arches
 dropped_unstable_keywords = set()
 for keyword in (x for x in dropped_keywords if x[0] == "~"):
@@ -482,7 +480,7 @@ class BadCommitSummary(results.CommitResult, results.Style):
 return f"commit {self.commit}, {self.error}: {self.summary!r}"
 
 
-def verify_tags(*tags, required=False):
+def verify_tags(*tags: str, required: bool = False):
 """Decorator to register commit tag verification methods."""
 
 class decorator:
@@ -534,21 +532,20 @@ class GitCommitMessageCheck(GentooRepoCheck, 
GitCommitsCheck):
 )
 
 @verify_tags("Signed-off-by", required=True)
-def _signed_off_by_tag(self, tag, values, commit):
+def _signed_off_by_tag(self, tag: str, values: list[str], commit: 
git.GitCommit):
 """Verify commit contains all required sign offs in accordance with 
GLEP 76."""
 required_sign_offs = {commit.author, commit.committer}
-missing_sign_offs = required_sign_offs.difference(values)
-if missing_sign_offs:
+if missing_sign_offs := required_sign_offs.difference(values):
 yield MissingSignOff(sorted(missing_sign_offs), commit=commit)
 
 @verify_tags("Gentoo-Bug")
-def _deprecated_tag(self, tag, values, commit):
+def _deprecated_tag(self, tag: str, values: list[str], commit: 
git.GitCommit):
 """Flag deprecated tags that shouldn't be used."""
 for value in values:
 yield InvalidCommitTag(tag, value, f"{tag} tag is no longer 
valid", commit=commit)
 
 @verify_tags("Bug", "Closes")
-def _bug_tag(self, tag, values, commit):
+def _bug_tag(self, tag: str, values: list[str], commit: git.GitCommit):
 """Verify values are URLs for Bug/Closes tags."""
 for value in values:
 parsed = urlparse(value)
@@ -574,7 +571,7 @@ class GitCommitMessageCheck(GentooRepoCheck, 
GitCommitsCheck):
 )
 
 @verify_tags("Fixes", "Reverts")
-def _commit_tag(self, tag, values, commit):
+def _commit_tag(self, tag, values, commit: git.GitCommit):
 """Verify referenced commits exist for Fixes/Reverts 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-01-20 Thread Arthur Zamarin
commit: c81bc6cde6a37c9f590a5f9a42346fe1f5fd220e
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Jan 20 14:59:55 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Jan 20 14:59:55 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c81bc6cd

EmptyDirsCheck: mark results' level as error

This check is done at repo level, so if you are inside a package dir, it
will be skipped. As a solution, mark those results as errors, so the bot
will fail to regen metadata and we can notice the issue.

Resolves: https://github.com/pkgcore/pkgcheck/issues/499
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/repo.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/pkgcheck/checks/repo.py b/src/pkgcheck/checks/repo.py
index 8b12f68d..eefc523e 100644
--- a/src/pkgcheck/checks/repo.py
+++ b/src/pkgcheck/checks/repo.py
@@ -50,7 +50,7 @@ class RepoDirCheck(GentooRepoCheck, RepoCheck):
 yield BinaryFile(rel_path)
 
 
-class EmptyCategoryDir(results.CategoryResult, results.Warning):
+class EmptyCategoryDir(results.CategoryResult, results.Error):
 """Empty category directory in the repository."""
 
 scope = base.repo_scope
@@ -60,7 +60,7 @@ class EmptyCategoryDir(results.CategoryResult, 
results.Warning):
 return f"empty category directory: {self.category}"
 
 
-class EmptyPackageDir(results.PackageResult, results.Warning):
+class EmptyPackageDir(results.PackageResult, results.Error):
 """Empty package directory in the repository."""
 
 scope = base.repo_scope
@@ -74,7 +74,7 @@ class EmptyDirsCheck(GentooRepoCheck, RepoCheck):
 """Scan for empty category or package directories."""
 
 _source = (sources.EmptySource, (base.repo_scope,))
-known_results = frozenset([EmptyCategoryDir, EmptyPackageDir])
+known_results = frozenset({EmptyCategoryDir, EmptyPackageDir})
 
 def __init__(self, *args):
 super().__init__(*args)



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-01-20 Thread Arthur Zamarin
commit: 33a0fe9e379839667e84cb8a92207012be2783c1
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Jan 20 13:17:49 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Jan 20 13:17:49 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=33a0fe9e

MissingManifest: fix behavior under thick repos

Resolves: https://github.com/pkgcore/pkgcheck/issues/530
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/repo_metadata.py | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/pkgcheck/checks/repo_metadata.py 
b/src/pkgcheck/checks/repo_metadata.py
index 003ff891..21df0745 100644
--- a/src/pkgcheck/checks/repo_metadata.py
+++ b/src/pkgcheck/checks/repo_metadata.py
@@ -4,6 +4,7 @@ from difflib import SequenceMatcher
 from itertools import chain
 
 from pkgcore import fetch
+from pkgcore.ebuild.digest import Manifest
 from snakeoil.sequences import iflatten_instance
 from snakeoil.strings import pluralism
 
@@ -80,14 +81,14 @@ class PackageUpdatesCheck(RepoCheck):
 
 _source = (sources.EmptySource, (base.profiles_scope,))
 known_results = frozenset(
-[
+{
 MultiMovePackageUpdate,
 OldMultiMovePackageUpdate,
 OldPackageUpdate,
 MovedPackageUpdate,
 BadPackageUpdate,
 RedundantPackageUpdate,
-]
+}
 )
 
 def __init__(self, *args):
@@ -377,17 +378,16 @@ class GlobalUseCheck(RepoCheck):
 """Check global USE and USE_EXPAND flags for various issues."""
 
 _source = (sources.RepositoryRepoSource, (), (("source", 
sources.PackageRepoSource),))
-required_addons = (addons.UseAddon,)
 known_results = frozenset(
-[
+{
 PotentialLocalUse,
 PotentialGlobalUse,
 UnusedGlobalUse,
 UnusedGlobalUseExpand,
-]
+}
 )
 
-def __init__(self, *args, use_addon):
+def __init__(self, *args):
 super().__init__(*args)
 self.global_flag_usage = defaultdict(set)
 self.repo = self.options.target_repo
@@ -405,8 +405,8 @@ class GlobalUseCheck(RepoCheck):
 """Yield groups of packages with similar local USE flag 
descriptions."""
 # calculate USE flag description difference ratios
 diffs = {}
-for i, (i_pkg, i_desc) in enumerate(pkgs):
-for j, (j_pkg, j_desc) in enumerate(pkgs[i + 1 :]):
+for i, (_i_pkg, i_desc) in enumerate(pkgs):
+for j, (_j_pkg, j_desc) in enumerate(pkgs[i + 1 :]):
 diffs[(i, i + j + 1)] = SequenceMatcher(None, i_desc, 
j_desc).ratio()
 
 # create an adjacency list using all closely matching flags pairs
@@ -571,17 +571,17 @@ class ManifestCheck(Check):
 required_addons = (addons.UseAddon,)
 _source = sources.PackageRepoSource
 known_results = frozenset(
-[
+{
 MissingChksum,
 MissingManifest,
 UnknownManifest,
 UnnecessaryManifest,
 DeprecatedChksum,
 InvalidManifest,
-]
+}
 )
 
-def __init__(self, *args, use_addon):
+def __init__(self, *args, use_addon: addons.UseAddon):
 super().__init__(*args)
 repo = self.options.target_repo
 self.preferred_checksums = frozenset(
@@ -593,7 +593,8 @@ class ManifestCheck(Check):
 self.iuse_filter = use_addon.get_filter("fetchables")
 
 def feed(self, pkgset):
-pkg_manifest = pkgset[0].manifest
+pkg_manifest: Manifest = pkgset[0].manifest
+pkg_manifest.allow_missing = True
 manifest_distfiles = set(pkg_manifest.distfiles.keys())
 seen = set()
 for pkg in pkgset:
@@ -625,14 +626,13 @@ class ManifestCheck(Check):
 seen.add(f_inst.filename)
 
 if pkg_manifest.thin:
-unnecessary_manifests = []
+unnecessary_manifests = set()
 for attr in ("aux_files", "ebuilds", "misc"):
-unnecessary_manifests.extend(getattr(pkg_manifest, attr, []))
+unnecessary_manifests.update(getattr(pkg_manifest, attr, ()))
 if unnecessary_manifests:
 yield UnnecessaryManifest(sorted(unnecessary_manifests), 
pkg=pkgset[0])
 
-unknown_manifests = manifest_distfiles.difference(seen)
-if unknown_manifests:
+if unknown_manifests := manifest_distfiles.difference(seen):
 yield UnknownManifest(sorted(unknown_manifests), pkg=pkgset[0])
 
 
@@ -753,6 +753,6 @@ class ProjectMetadataCheck(RepoCheck):
 self.repo = self.options.target_repo
 
 def finish(self):
-for key, project in self.repo.projects_xml.projects.items():
+for _key, project in self.repo.projects_xml.projects.items():
 if not project.recursive_members:
 yield EmptyProject(project)



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-01-17 Thread Arthur Zamarin
commit: 9e43d725ce4c2049e53e9df444b47c388bf98573
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Jan 15 20:31:16 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Jan 15 20:31:16 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9e43d725

ProfilesCheck: check for unknown USE & IUSE_IMPLICIT in make.defaults

Related: https://github.com/pkgcore/pkgcheck/issues/524
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/profiles.py| 7 +++
 .../repos/profiledir/ProfilesCheck/UnknownProfileUse/expected.json | 1 +
 .../repos/profiledir/ProfilesCheck/UnknownProfileUse/fix.patch | 4 +++-
 testdata/repos/profiledir/profiles/unknown_use/make.defaults   | 2 ++
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 00d7c069..6d113519 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -290,6 +290,13 @@ class ProfilesCheck(Check):
 
 @verify_files(("make.defaults", "make_defaults"))
 def _make_defaults(self, filename: str, node, vals: dict[str, str]):
+if use_flags := {
+use.removeprefix("-")
+for use_group in ("USE", "IUSE_IMPLICIT")
+for use in vals.get(use_group, "").split()
+}:
+if unknown := use_flags - self.available_iuse:
+yield UnknownProfileUse(pjoin(node.name, filename), 
sorted(unknown))
 if defined := set(vals.get("USE_EXPAND", "").split()):
 if unknown := defined - self.use_expand_groups:
 yield UnknownProfileUseExpand(pjoin(node.name, filename), 
sorted(unknown))

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/expected.json 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/expected.json
index 36f7f55c..b7b1c988 100644
--- 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/expected.json
+++ 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/expected.json
@@ -1,3 +1,4 @@
+{"__class__": "UnknownProfileUse", "path": "unknown_use/make.defaults", 
"flags": ["defaults_iuse_implicit", "defaults_use"]}
 {"__class__": "UnknownProfileUse", "path": 
"unknown_use/unknown_stable_use/use.force", "flags": ["-use_force"]}
 {"__class__": "UnknownProfileUse", "path": 
"unknown_use/unknown_stable_use/use.stable.force", "flags": 
["use_stable_force"]}
 {"__class__": "UnknownProfileUse", "path": 
"unknown_use/unknown_stable_use_mask/use.mask", "flags": ["-use_mask"]}

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/fix.patch 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/fix.patch
index 1541f627..d4003eb4 100644
--- a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/fix.patch
+++ b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUse/fix.patch
@@ -1,9 +1,11 @@
 diff -Naur profiledir/profiles/use.desc fixed/profiles/use.desc
 --- profiledir/profiles/use.desc   2020-11-23 10:54:01.018477444 -0700
 +++ fixed/profiles/use.desc2020-11-23 11:54:08.071178614 -0700
-@@ -1 +1,5 @@
+@@ -1 +1,7 @@
  used - used global flag
 +use_force - use.force
 +use_mask - use.mask
 +use_stable_force - use.stable.force
 +use_stable_mask - use.stable.mask
++defaults_use - make.defaults USE
++defaults_iuse_implicit - make.defaults IUSE_IMPLICIT

diff --git a/testdata/repos/profiledir/profiles/unknown_use/make.defaults 
b/testdata/repos/profiledir/profiles/unknown_use/make.defaults
new file mode 100644
index ..4699667b
--- /dev/null
+++ b/testdata/repos/profiledir/profiles/unknown_use/make.defaults
@@ -0,0 +1,2 @@
+USE="defaults_use used"
+IUSE_IMPLICIT="defaults_iuse_implicit used"



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-01-17 Thread Arthur Zamarin
commit: bca5e4880d0bbe1b4a34fc0185885bbbcca76230
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Mon Jan 16 20:09:10 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Jan 16 20:09:10 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=bca5e488

ProfilesCheck: check USE_EXPAND_VALUES_* in make.defaults

Related: https://github.com/pkgcore/pkgcheck/issues/524
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/profiles.py| 32 ++
 .../UnknownProfileUseExpand/expected.json  |  1 +
 .../UnknownProfileUseExpandValue/expected.json |  2 ++
 .../UnknownProfileUseExpandValue/fix.patch | 13 +
 4 files changed, 48 insertions(+)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 7929a10c..ed6d1263 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -110,6 +110,22 @@ class UnknownProfileUseExpand(results.ProfilesResult, 
results.Warning):
 return f"{self.path!r}: unknown USE_EXPAND group{s} in {self.var!r}: 
{groups}"
 
 
+class UnknownProfileUseExpandValue(results.ProfilesResult, results.Warning):
+"""Profile defines unknown default values for USE_EXPAND group."""
+
+def __init__(self, path: str, group: str, values: Iterable[str]):
+super().__init__()
+self.path = path
+self.group = group
+self.values = tuple(values)
+
+@property
+def desc(self):
+s = pluralism(self.values)
+values = ", ".join(self.values)
+return f"{self.path!r}: unknown value{s} for {self.group!r}: {values}"
+
+
 class UnknownProfileArch(results.ProfilesResult, results.Warning):
 """Profile includes unknown ARCH."""
 
@@ -168,6 +184,7 @@ class ProfilesCheck(Check):
 UnknownProfileUse,
 UnknownProfilePackageKeywords,
 UnknownProfileUseExpand,
+UnknownProfileUseExpandValue,
 UnknownProfileArch,
 ProfileWarning,
 ProfileError,
@@ -313,6 +330,21 @@ class ProfilesCheck(Check):
 yield UnknownProfileUseExpand(
 pjoin(node.name, filename), use_group, sorted(unknown)
 )
+for key, val in vals.items():
+if key.startswith("USE_EXPAND_VALUES_"):
+use_group = key[18:]
+if use_group in implicit_use_expands:
+continue
+elif allowed_values := self.use_expand_groups.get(use_group, 
None):
+if unknown := set(val.split()) - allowed_values:
+yield UnknownProfileUseExpandValue(
+pjoin(node.name, filename), key, sorted(unknown)
+)
+else:
+yield UnknownProfileUseExpand(pjoin(node.name, filename), 
key, [use_group])
+for key in vals.keys() & self.use_expand_groups.keys():
+if unknown := set(vals.get(key, "").split()) - 
self.use_expand_groups[key]:
+yield UnknownProfileUseExpandValue(pjoin(node.name, filename), 
key, sorted(unknown))
 if arch := vals.get("ARCH", None):
 if arch not in self.keywords.arches:
 yield UnknownProfileArch(pjoin(node.name, filename), arch)

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/expected.json
 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/expected.json
index 5817a2e1..8e465239 100644
--- 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/expected.json
+++ 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/expected.json
@@ -1,2 +1,3 @@
 {"__class__": "UnknownProfileUseExpand", "path": "unknown_use/make.defaults", 
"var": "USE_EXPAND", "groups": ["PYTHON_SINGLE_TARGET"]}
 {"__class__": "UnknownProfileUseExpand", "path": "unknown_use/make.defaults", 
"var": "USE_EXPAND_UNPREFIXED", "groups": ["LUA_TARGETS"]}
+{"__class__": "UnknownProfileUseExpand", "path": "unknown_use/make.defaults", 
"var": "USE_EXPAND_VALUES_LUA_TARGETS", "groups": ["LUA_TARGETS"]}

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpandValue/expected.json
 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpandValue/expected.json
new file mode 100644
index ..6fcd75f7
--- /dev/null
+++ 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpandValue/expected.json
@@ -0,0 +1,2 @@
+{"__class__": "UnknownProfileUseExpandValue", "path": 
"unknown_use/make.defaults", "group": "PYTHON_TARGETS", "values": ["python3_9"]}
+{"__class__": "UnknownProfileUseExpandValue", "path": 
"unknown_use/make.defaults", "group": "USE_EXPAND_VALUES_PYTHON_TARGETS", 
"values": ["python3_9"]}

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpandValue/fix.patch
 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2023-01-14 Thread Arthur Zamarin
commit: d10bd72a993057c7faab0c49fdc852444da9ef09
Author: Ulrich Müller  gentoo  org>
AuthorDate: Sat Jan 14 19:04:53 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Jan 14 20:30:58 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d10bd72a

VariableScopeCheck: Disallow D and ED in pkg_postinst

According to QA policy PG 107:
https://projects.gentoo.org/qa/policy-guide/ebuild-format.html#pg0107

(Note that "pkg_postinst" was misspelt as "pkg_postint", so it would
have warned already.)

Signed-off-by: Ulrich Müller  gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/523
Closes: https://github.com/pkgcore/pkgcheck/issues/516
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index ea315259..2145e2de 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -966,8 +966,8 @@ class VariableScopeCheck(Check):
 "SYSROOT": ("src_", "pkg_setup"),
 "ESYSROOT": ("src_", "pkg_setup"),
 "BROOT": ("src_", "pkg_setup"),
-"D": ("src_install", "pkg_preinst", "pkg_postint"),
-"ED": ("src_install", "pkg_preinst", "pkg_postint"),
+"D": ("src_install", "pkg_preinst"),
+"ED": ("src_install", "pkg_preinst"),
 "DESTTREE": "src_install",
 "INSDESTTREE": "src_install",
 "MERGE_TYPE": "pkg_",



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-01-14 Thread Arthur Zamarin
commit: 357f6104cb08913d840b749659096eeb2d0fa325
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Thu Jan 12 20:40:27 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Jan 12 20:40:27 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=357f6104

EclassUsageCheck: check for setting user variables in ebuilds

Check ebuilds for overriding eclass' user variables.

Resolves: https://github.com/pkgcore/pkgcheck/issues/512
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/eclass.py  | 37 +-
 .../EclassUserVariableUsage/expected.json  |  1 +
 .../EclassUserVariableUsage-0.ebuild   | 12 +++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/eclass.py b/src/pkgcheck/checks/eclass.py
index 862dbb91..935ed960 100644
--- a/src/pkgcheck/checks/eclass.py
+++ b/src/pkgcheck/checks/eclass.py
@@ -47,6 +47,18 @@ class DeprecatedEclassVariable(results.LineResult, 
results.Warning):
 return f"uses deprecated variable on line {self.lineno}: 
{self.variable} ({replacement})"
 
 
+class EclassUserVariableUsage(results.LineResult, results.Warning):
+"""Package uses a user variable from an eclass."""
+
+def __init__(self, eclass, **kwargs):
+super().__init__(**kwargs)
+self.eclass = eclass
+
+@property
+def desc(self):
+return f"line {self.lineno}: uses user variable {self.line!r} from 
eclass {self.eclass!r}"
+
+
 class DeprecatedEclassFunction(results.LineResult, results.Warning):
 """Package uses a deprecated function from an eclass."""
 
@@ -125,6 +137,7 @@ class EclassUsageCheck(Check):
 DeprecatedEclassVariable,
 DeprecatedEclassFunction,
 DuplicateEclassInherit,
+EclassUserVariableUsage,
 MisplacedEclassVar,
 ProvidedEclassInherit,
 }
@@ -156,6 +169,27 @@ class EclassUsageCheck(Check):
 line = pkg.node_str(node)
 yield MisplacedEclassVar(var_name, line=line, 
lineno=lineno + 1, pkg=pkg)
 
+def check_user_variables(self, pkg: bash.ParseTree, inherits: 
list[tuple[list[str], int]]):
+"""Check for usage of @USER_VARIABLE variables."""
+# determine if any inherited eclasses have @USER_VARIABLE variables
+user_variables = {
+var.name: eclass
+for eclasses, _ in inherits
+for eclass in eclasses
+for var in self.eclass_cache[eclass].variables
+if var.user_variable
+}
+
+# scan for usage of @USER_VARIABLE variables
+if user_variables:
+for node, _ in bash.var_assign_query.captures(pkg.tree.root_node):
+var_name = pkg.node_str(node.child_by_field_name("name"))
+if var_name in user_variables:
+lineno, _colno = node.start_point
+yield EclassUserVariableUsage(
+user_variables[var_name], line=var_name, lineno=lineno 
+ 1, pkg=pkg
+)
+
 def check_deprecated_variables(self, pkg, inherits: list[tuple[list[str], 
int]]):
 """Check for usage of @DEPRECATED variables."""
 # determine if any inherited eclasses have @DEPRECATED variables
@@ -220,7 +254,7 @@ class EclassUsageCheck(Check):
 
 def feed(self, pkg):
 if pkg.inherit:
-inherited = set()
+inherited: set[str] = set()
 inherits: list[tuple[list[str], int]] = []
 for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
 name = pkg.node_str(node.child_by_field_name("name"))
@@ -241,6 +275,7 @@ class EclassUsageCheck(Check):
 )
 
 yield from self.check_provided_eclasses(pkg, inherits)
+yield from self.check_user_variables(pkg, inherits)
 # verify @PRE_INHERIT variable placement
 yield from self.check_pre_inherits(pkg, inherits)
 # verify @DEPRECATED variables or functions

diff --git 
a/testdata/data/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/expected.json
 
b/testdata/data/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/expected.json
new file mode 100644
index ..03b11f6a
--- /dev/null
+++ 
b/testdata/data/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/expected.json
@@ -0,0 +1 @@
+{"__class__": "EclassUserVariableUsage", "category": "EclassUsageCheck", 
"package": "EclassUserVariableUsage", "version": "0", "line": "EBZR_STORE_DIR", 
"lineno": 8, "eclass": "unquotedvariable"}

diff --git 
a/testdata/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/EclassUserVariableUsage-0.ebuild
 
b/testdata/repos/eclass/EclassUsageCheck/EclassUserVariableUsage/EclassUserVariableUsage-0.ebuild
new file mode 100644
index ..dae4c7d1
--- /dev/null
+++ 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/eclass/InheritsCheck/MissingInherits/

2023-01-09 Thread Arthur Zamarin
commit: d2a5afc73f39786877d7a3353be94f4cbcb5a2a2
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Mon Jan  9 18:25:52 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Jan  9 18:25:52 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d2a5afc7

MissingInherits: don't show for functions defined in ebuild

Resolves: https://github.com/pkgcore/pkgcheck/issues/513
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py| 10 --
 .../MissingInherits/MissingInherits-2.ebuild  | 15 +++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 6d3e53ca..ea315259 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -783,6 +783,12 @@ class InheritsCheck(Check):
 def feed(self, pkg):
 conditional = set()
 
+# collect globally defined functions in ebuild
+defined_funcs = {
+pkg.node_str(func_node.child_by_field_name("name"))
+for func_node, _ in bash.func_query.captures(pkg.tree.root_node)
+}
+
 # register variables assigned in ebuilds
 assigned_vars = dict()
 for node, _ in bash.var_assign_query.captures(pkg.tree.root_node):
@@ -802,8 +808,8 @@ class InheritsCheck(Check):
 conditional.update(eclasses)
 # Also ignore vars since any used in arithmetic expansions, i.e.
 # $((...)), are captured as commands.
-elif name not in self.eapi_funcs[pkg.eapi] | assigned_vars.keys():
-lineno, colno = node.start_point
+elif name not in self.eapi_funcs[pkg.eapi] | assigned_vars.keys() 
| defined_funcs:
+lineno, _colno = node.start_point
 if eclass := self.get_eclass(name, pkg):
 used[eclass].append((lineno + 1, name, call.split("\n", 
1)[0]))
 

diff --git 
a/testdata/repos/eclass/InheritsCheck/MissingInherits/MissingInherits-2.ebuild 
b/testdata/repos/eclass/InheritsCheck/MissingInherits/MissingInherits-2.ebuild
new file mode 100644
index ..9aa0432e
--- /dev/null
+++ 
b/testdata/repos/eclass/InheritsCheck/MissingInherits/MissingInherits-2.ebuild
@@ -0,0 +1,15 @@
+EAPI=7
+
+DESCRIPTION="Ebuild missing an eclass inherit"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck;
+SLOT="0"
+LICENSE="BSD"
+
+src_prepare() {
+   inherit_public_func
+   unset EBUILD_TEST
+}
+
+inherit_public_func() {
+   echo "inherit_public_func"
+}



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2023-01-02 Thread Arthur Zamarin
commit: 4247e10d9c266ac1f6aac48b0c67f1092dde1d78
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Dec 30 19:27:23 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Jan  2 20:11:43 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4247e10d

ProvidedEclassInherit: new check for inheriting provided eclases

Resolves: https://github.com/pkgcore/pkgcheck/issues/504
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/eclass.py  | 103 ++---
 .../ProvidedEclassInherit/expected.json|   1 +
 .../ProvidedEclassInherit/fix.patch|  10 ++
 .../ProvidedEclassInherit-0.ebuild |  11 +++
 4 files changed, 93 insertions(+), 32 deletions(-)

diff --git a/src/pkgcheck/checks/eclass.py b/src/pkgcheck/checks/eclass.py
index 5c4f205f..862dbb91 100644
--- a/src/pkgcheck/checks/eclass.py
+++ b/src/pkgcheck/checks/eclass.py
@@ -98,18 +98,36 @@ class MisplacedEclassVar(results.LineResult, results.Error):
 return f"invalid pre-inherit placement, line {self.lineno}: 
{self.line!r}"
 
 
+class ProvidedEclassInherit(results.LineResult, results.Style):
+"""Ebuild inherits an eclass which is already provided by another eclass.
+
+When inheriting an eclass which declares ``@PROVIDES``, those referenced
+eclasses are guaranteed to be provided by the eclass. Therefore, inheriting
+them in ebuilds is redundant and should be removed.
+"""
+
+def __init__(self, provider, **kwargs):
+super().__init__(**kwargs)
+self.provider = provider
+
+@property
+def desc(self):
+return f"line {self.lineno}: redundant eclass inherit {self.line!r}, 
provided by {self.provider!r}"
+
+
 class EclassUsageCheck(Check):
 """Scan packages for various eclass-related issues."""
 
 _source = sources.EbuildParseRepoSource
 known_results = frozenset(
-[
+{
 DeprecatedEclass,
 DeprecatedEclassVariable,
 DeprecatedEclassFunction,
 DuplicateEclassInherit,
 MisplacedEclassVar,
-]
+ProvidedEclassInherit,
+}
 )
 required_addons = (addons.eclass.EclassAddon,)
 
@@ -118,15 +136,16 @@ class EclassUsageCheck(Check):
 self.deprecated_eclasses = eclass_addon.deprecated
 self.eclass_cache = eclass_addon.eclasses
 
-def check_pre_inherits(self, pkg, inherits):
+def check_pre_inherits(self, pkg, inherits: list[tuple[list[str], int]]):
 """Check for invalid @PRE_INHERIT variable placement."""
-pre_inherits = {}
 # determine if any inherited eclasses have @PRE_INHERIT variables
-for eclasses, lineno in inherits:
-for eclass in eclasses:
-for var in self.eclass_cache[eclass].variables:
-if var.pre_inherit:
-pre_inherits[var.name] = lineno
+pre_inherits = {
+var.name: lineno
+for eclasses, lineno in inherits
+for eclass in eclasses
+for var in self.eclass_cache[eclass].variables
+if var.pre_inherit
+}
 
 # scan for any misplaced @PRE_INHERIT variables
 if pre_inherits:
@@ -137,22 +156,23 @@ class EclassUsageCheck(Check):
 line = pkg.node_str(node)
 yield MisplacedEclassVar(var_name, line=line, 
lineno=lineno + 1, pkg=pkg)
 
-def check_deprecated_variables(self, pkg, inherits):
-"""Check for usage of @DEPRECATED variables or functions."""
-deprecated = {}
+def check_deprecated_variables(self, pkg, inherits: list[tuple[list[str], 
int]]):
+"""Check for usage of @DEPRECATED variables."""
 # determine if any inherited eclasses have @DEPRECATED variables
-for eclasses, _ in inherits:
-for eclass in eclasses:
-for var in self.eclass_cache[eclass].variables:
-if var.deprecated:
-deprecated[var.name] = var.deprecated
+deprecated = {
+var.name: var.deprecated
+for eclasses, _ in inherits
+for eclass in eclasses
+for var in self.eclass_cache[eclass].variables
+if var.deprecated
+}
 
 # scan for usage of @DEPRECATED variables
 if deprecated:
 for node, _ in bash.var_query.captures(pkg.tree.root_node):
 var_name = pkg.node_str(node)
-lineno, _colno = node.start_point
 if var_name in deprecated:
+lineno, _colno = node.start_point
 line = pkg.node_str(node)
 replacement = deprecated[var_name]
 if not isinstance(replacement, str):
@@ -161,22 +181,23 @@ class EclassUsageCheck(Check):
 var_name, replacement, line=line, lineno=lineno + 1, 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2022-12-27 Thread Arthur Zamarin
commit: 5870fb301a195c17d481af90a3669e9ee8338085
Author: Brian Harring  gmail  com>
AuthorDate: Tue Dec 27 08:51:19 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Tue Dec 27 19:08:53 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=5870fb30

Fix API compatibility w/ pkgcore revision eb6f4edd2

In that revision, USE flag validation is moved to eapi objects; EAPI
ultimately arbitrates that, and it cleaned up some internal issues in atom.

However, it broke pkgcheck's metadata check which was using that regex
directly; that code's broken anyways- any demandloaded object must not be
imported into another scope; the lazy replacement only affects the original 
scope,
thus that `self.valid_use = ` was pinning the proxied regex.

Either way; since EAPI objects now have a use flag validation method, use that.

Resolves: https://github.com/pkgcore/pkgcheck/issues/502
Signed-off-by: Brian Harring  gmail.com>
Closes: https://github.com/pkgcore/pkgcheck/pull/503
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 6e087c5f..56d54529 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -210,11 +210,10 @@ class IuseCheck(Check):
 def __init__(self, *args, use_addon):
 super().__init__(*args)
 self.iuse_handler = use_addon
-self.valid_use = atom_mod.valid_use_flag.match
 self.bad_defaults = tuple(['-'] + [f'+{x}_' for x in 
self.use_expand_groups])
 
 def feed(self, pkg):
-if invalid := sorted(x for x in pkg.iuse_stripped if not 
self.valid_use(x)):
+if invalid := sorted(x for x in pkg.iuse_stripped if not 
pkg.eapi.is_valid_use_flag(x)):
 yield InvalidUseFlags(invalid, pkg=pkg)
 
 if pkg.eapi.options.iuse_defaults and (bad_defaults := sorted(



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2022-12-13 Thread Arthur Zamarin
commit: 9b634116478cefbce700acdfd5d819828f17863e
Author: Michał Górny  gentoo  org>
AuthorDate: Sat Dec 10 15:52:48 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Tue Dec 13 19:58:46 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9b634116

MissingRemoteIdCheck: give ready  sample

Instead of verbose description of what to put in the missing remote-id
element, just print a ready-to-use XML snippet.

Signed-off-by: Michał Górny  gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/500
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata_xml.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/metadata_xml.py 
b/src/pkgcheck/checks/metadata_xml.py
index 06d62cf3..2182585b 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -577,8 +577,8 @@ class MissingRemoteId(results.PackageResult, results.Info):
 
 @property
 def desc(self):
-return (f'missing remote-id of type {self.remote_type!r} with '
-f'value {self.value!r} (inferred from URI {self.uri!r})')
+return (f'missing '
+f'{self.value} (inferred from URI {self.uri!r})')
 
 
 class MissingRemoteIdCheck(Check):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2022-11-26 Thread Arthur Zamarin
commit: 7938bcce6cf79addfd1c0b6e7bedee7a51b564e2
Author: Michał Górny  gentoo  org>
AuthorDate: Thu Nov 24 18:58:28 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Nov 24 18:58:28 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7938bcce

PythonCheck: remove obsolete pypy packages

Unlist the removed dev-python/pypy*-bin and virtual/pypy* packages
from PythonCheck, as well as the no-longer-relevant virtual/pypy*
exceptions.

Signed-off-by: Michał Górny  gentoo.org>

 src/pkgcheck/checks/python.py | 11 ---
 tests/checks/test_python.py   |  6 --
 2 files changed, 17 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 5d6a8a1a..bb4825e2 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -22,14 +22,8 @@ INTERPRETERS = frozenset([
 'dev-lang/python',
 'dev-python/pypy',
 'dev-python/pypy3',
-'dev-python/pypy-bin',
-'dev-python/pypy3-bin',
-'virtual/pypy',
-'virtual/pypy3',
 ])
 
-CHECK_EXCLUDE = frozenset(['virtual/pypy', 'virtual/pypy3'])
-
 IUSE_PREFIX = 'python_targets_'
 IUSE_PREFIX_S = 'python_single_target_'
 
@@ -439,11 +433,6 @@ class PythonCheck(Check):
 return
 
 if eclass is None:
-# virtual/pypy* need to be exempted as they serve as slot-matchers
-# for other packages
-if pkg.key in CHECK_EXCLUDE:
-return
-
 # check whether we should be using one
 highest_found = None
 for attr in (x.lower() for x in pkg.eapi.dep_keys):

diff --git a/tests/checks/test_python.py b/tests/checks/test_python.py
index 411fff7f..992b7dce 100644
--- a/tests/checks/test_python.py
+++ b/tests/checks/test_python.py
@@ -105,12 +105,6 @@ class TestPythonCheck(misc.ReportTestCase):
 self.assertReport(self.check, 
self.mk_pkg(RDEPEND='dev-python/pypy')),
 python.MissingPythonEclass)
 
-# special exception: virtual/pypy
-self.assertNoReport(self.check, self.mk_pkg(cpv='virtual/pypy-4.1',
-RDEPEND='|| ( dev-python/pypy:0/41 dev-python/pypy-bin:0/41 )'))
-self.assertNoReport(self.check, self.mk_pkg(cpv='virtual/pypy3-4.1',
-RDEPEND='|| ( dev-python/pypy3:0/41 dev-python/pypy3-bin:0/41 )'))
-
 def test_missing_eclass_pdepend(self):
 self.assertNoReport(
 self.check,



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2022-11-26 Thread Arthur Zamarin
commit: 0c533a1ece525ff7e010b92dd2423b49328e04ff
Author: Michał Górny  gentoo  org>
AuthorDate: Thu Nov 24 19:01:52 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Nov 24 19:01:52 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=0c533a1e

PythonCheck: stop testing for pypy(2.7)

The eclasses no longer support the pypy target, so stop checking
for dev-python/pypy.

Signed-off-by: Michał Górny  gentoo.org>

 src/pkgcheck/checks/python.py |  1 -
 tests/checks/test_python.py   | 12 
 2 files changed, 13 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index bb4825e2..918b5d5b 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -20,7 +20,6 @@ ECLASSES = frozenset(['python-r1', 'python-single-r1', 
'python-any-r1'])
 # NB: dev-java/jython omitted as not supported by the eclasses atm
 INTERPRETERS = frozenset([
 'dev-lang/python',
-'dev-python/pypy',
 'dev-python/pypy3',
 ])
 

diff --git a/tests/checks/test_python.py b/tests/checks/test_python.py
index 992b7dce..dd32147e 100644
--- a/tests/checks/test_python.py
+++ b/tests/checks/test_python.py
@@ -43,9 +43,6 @@ class TestPythonCheck(misc.ReportTestCase):
 self.check,
 self.mk_pkg(DEPEND='|| ( dev-lang/python:2.7 
dev-lang/python:3.6 )')),
 python.MissingPythonEclass)
-assert isinstance(
-self.assertReport(self.check, 
self.mk_pkg(DEPEND='dev-python/pypy')),
-python.MissingPythonEclass)
 
 def test_missing_eclass_bdepend(self):
 self.assertNoReport(
@@ -70,9 +67,6 @@ class TestPythonCheck(misc.ReportTestCase):
 self.check,
 self.mk_pkg(BDEPEND='|| ( dev-lang/python:2.7 
dev-lang/python:3.6 )')),
 python.MissingPythonEclass)
-assert isinstance(
-self.assertReport(self.check, 
self.mk_pkg(BDEPEND='dev-python/pypy')),
-python.MissingPythonEclass)
 
 def test_missing_eclass_rdepend(self):
 self.assertNoReport(
@@ -101,9 +95,6 @@ class TestPythonCheck(misc.ReportTestCase):
 self.check,
 self.mk_pkg(RDEPEND='|| ( dev-lang/python:2.7 
dev-lang/python:3.6 )')),
 python.MissingPythonEclass)
-assert isinstance(
-self.assertReport(self.check, 
self.mk_pkg(RDEPEND='dev-python/pypy')),
-python.MissingPythonEclass)
 
 def test_missing_eclass_pdepend(self):
 self.assertNoReport(
@@ -131,9 +122,6 @@ class TestPythonCheck(misc.ReportTestCase):
 self.check,
 self.mk_pkg(PDEPEND='|| ( dev-lang/python:2.7 
dev-lang/python:3.6 )')),
 python.MissingPythonEclass)
-assert isinstance(
-self.assertReport(self.check, 
self.mk_pkg(PDEPEND='dev-python/pypy')),
-python.MissingPythonEclass)
 
 def test_valid_packages(self):
 self.assertNoReport(



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2022-10-30 Thread Arthur Zamarin
commit: 5e05fd7c59d0853e6472bf65d619cedafb4880b7
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Oct 30 18:02:16 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Oct 30 18:02:16 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=5e05fd7c

MissingRemoteIdCheck: fix bad suggestion for downloads.sourceforge.net

For sourceforge, the order of regexes was bad, resulting in it catching
`downloads.sourceforge.net` as project under `sourceforge.net` instead,
which is very wrong. Fix the order, and update the test to check for
this case specially.

On the same note, add support for `sourceforge.io` as a site - cause
looks like it also appears in the wild.

Resolves: https://github.com/pkgcore/pkgcheck/issues/488
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata_xml.py | 6 +++---
 .../MissingRemoteIdCheck/MissingRemoteId/expected.json  | 2 +-
 .../MissingRemoteIdCheck/MissingRemoteId/MissingRemoteId-2.ebuild   | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/pkgcheck/checks/metadata_xml.py 
b/src/pkgcheck/checks/metadata_xml.py
index 56dd2c94..06d62cf3 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -601,9 +601,9 @@ class MissingRemoteIdCheck(Check):
 ('pypi', 
r'https://files.pythonhosted.org/packages/source/\S/(?P[^/]+)'),
 ('savannah', r'https://savannah.gnu.org/projects/(?P[^/]+)'),
 ('savannah-nongnu', 
r'https://savannah.nongnu.org/projects/(?P[^/]+)'),
-('sourceforge', r'https://(?P[^/]+).sourceforge.net/'),
-('sourceforge', r'https://sourceforge.net/projects/(?P[^/]+)'),
-('sourceforge', 
r'https://downloads.sourceforge.net/(?:project/)?(?P[^/]+)'),
+('sourceforge', 
r'https://downloads.sourceforge.(net|io)/(?:project/)?(?P[^/]+)'),
+('sourceforge', 
r'https://sourceforge.(net|io)/projects/(?P[^/]+)'),
+('sourceforge', r'https://(?P[^/]+).sourceforge.(net|io)/'),
 ('sourcehut', r'https://sr.ht/(?P[^/]+/[^/]+)'),
 )
 

diff --git 
a/testdata/data/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/expected.json
 
b/testdata/data/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/expected.json
index ab5ae2d4..9d74b4e9 100644
--- 
a/testdata/data/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/expected.json
+++ 
b/testdata/data/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/expected.json
@@ -1,4 +1,4 @@
 {"__class__": "MissingRemoteId", "category": "MissingRemoteIdCheck", 
"package": "MissingRemoteId", "remote_type": "gitlab", "value": 
"pkgcore/pkgcheck/extra/MissingRemoteId", "uri": 
"https://gitlab.com/pkgcore/pkgcheck/extra/MissingRemoteId/-/archive/1/MissingRemoteId-1.tar.bz2"}
 {"__class__": "MissingRemoteId", "category": "MissingRemoteIdCheck", 
"package": "MissingRemoteId", "remote_type": "heptapod", "value": 
"pkgcore/pkgcore", "uri": 
"https://foss.heptapod.net/pkgcore/pkgcore/-/archive/4/MissingRemoteId-4.tar.bz2"}
 {"__class__": "MissingRemoteId", "category": "MissingRemoteIdCheck", 
"package": "MissingRemoteId", "remote_type": "pypi", "value": 
"MissingRemoteId", "uri": 
"https://files.pythonhosted.org/packages/source/M/MissingRemoteId/MissingRemoteId-1.tar.gz"}
-{"__class__": "MissingRemoteId", "category": "MissingRemoteIdCheck", 
"package": "MissingRemoteId", "remote_type": "sourceforge", "value": 
"pkgcheck", "uri": "https://pkgcheck.sourceforge.net/"}
+{"__class__": "MissingRemoteId", "category": "MissingRemoteIdCheck", 
"package": "MissingRemoteId", "remote_type": "sourceforge", "value": 
"pkgcheck", "uri": 
"https://downloads.sourceforge.net/pkgcheck/MissingRemoteId-2.tar.gz"}

diff --git 
a/testdata/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/MissingRemoteId-2.ebuild
 
b/testdata/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/MissingRemoteId-2.ebuild
index ed226b8e..2ee1bda2 100644
--- 
a/testdata/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/MissingRemoteId-2.ebuild
+++ 
b/testdata/repos/eapis-testing/MissingRemoteIdCheck/MissingRemoteId/MissingRemoteId-2.ebuild
@@ -1,7 +1,7 @@
 EAPI=7
 
 DESCRIPTION="Check homepage"
-HOMEPAGE="https://pkgcheck.sourceforge.net/;
-SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz"
+HOMEPAGE="https://pkgcore.github.io/pkgcheck/;
+SRC_URI="mirror://sourceforge/pkgcheck/${P}.tar.gz"
 LICENSE="BSD"
 SLOT="0"



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2022-10-29 Thread Arthur Zamarin
commit: 01b68ca982ce815c46330b9fabf2aefb7fd965b6
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Oct 29 18:45:23 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Oct 29 18:45:23 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=01b68ca9

PythonGHDistfileSuffix: add common solution to docs

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index fc9a58e7..5d6a8a1a 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -621,6 +621,10 @@ class PythonGHDistfileSuffix(results.VersionResult, 
results.Warning):
 published on PyPI.  Since both kinds of distfiles often have the same name,
 ".gh.tar.gz" suffix is often used for the former to avoid filename
 collisions with official archives published upstream.
+
+To solve this warning, rename the distfile in ``SRC_URI`` to include the
+suffix. There is no need to contact upstream, as it is done simply by
+adding ``-> ${P}.gh.tar.gz`` after the URI.
 """
 
 def __init__(self, filename, uri, **kwargs):



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/eapis-testing/profiles/, ...

2022-10-29 Thread Arthur Zamarin
commit: c1f105c44cd43f073d892ea06c371b6e0a6fe28d
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Oct 28 19:25:34 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Oct 29 15:10:59 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c1f105c4

MissingRemoteIdCheck: check for missing remote-id

Scans HOMEPAGE and SRC_URI for uris matching regexes using which it
extracts remote-id. Skips already defined remote-id types. Skips URIS
that end with ".diff" or ".patch". Prefers to take remote-id from newer
package versions, in case URL updated.

Resolves: https://github.com/pkgcore/pkgcheck/issues/475
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/metadata_xml.py| 78 ++
 .../MissingRemoteId/expected.json  |  4 ++
 .../MissingRemoteIdCheck/MissingRemoteId/fix.patch | 13 
 .../StableKeywordsOnTestingEapi-0.ebuild   |  2 +-
 .../StableKeywordsOnTestingEapi-1.ebuild   |  2 +-
 .../MissingRemoteIdCheck/MissingRemoteId/Manifest  |  8 +++
 .../MissingRemoteId/MissingRemoteId-0.ebuild   | 16 +
 .../MissingRemoteId/MissingRemoteId-1.ebuild   | 10 +++
 .../MissingRemoteId/MissingRemoteId-2.ebuild   |  7 ++
 .../MissingRemoteId/MissingRemoteId-3.ebuild   |  9 +++
 .../MissingRemoteId/MissingRemoteId-4.ebuild   | 11 +++
 .../MissingRemoteId/metadata.xml   | 10 +++
 .../repos/eapis-testing/profiles/thirdpartymirrors |  2 +
 tests/scripts/test_pkgcheck_scan.py|  4 +-
 14 files changed, 172 insertions(+), 4 deletions(-)

diff --git a/src/pkgcheck/checks/metadata_xml.py 
b/src/pkgcheck/checks/metadata_xml.py
index 67f0f42c..56dd2c94 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -1,11 +1,15 @@
 import os
 import re
 from difflib import SequenceMatcher
+from itertools import chain
 
 from lxml import etree
 from pkgcore import const as pkgcore_const
 from pkgcore.ebuild.atom import MalformedAtom, atom
+from pkgcore.restrictions.packages import Conditional
+from pkgcore.fetch import fetchable
 from snakeoil.osutils import pjoin
+from snakeoil.sequences import iflatten_instance
 from snakeoil.strings import pluralism
 
 from .. import results, sources
@@ -553,3 +557,77 @@ class CategoryMetadataXmlCheck(_XmlBaseCheck):
 def _get_xml_location(self, pkg):
 """Return the metadata.xml location for a given package's category."""
 return pjoin(self.repo_base, pkg.category, 'metadata.xml')
+
+
+class MissingRemoteId(results.PackageResult, results.Info):
+"""Missing remote-id which was inferred from ebuilds.
+
+Based on URIs found in SRC_URI and HOMEPAGE, a remote-id can be suggested.
+If a remote-id of same type is already defined in ``metadata.xml``, the
+suggestion won't be reported. It ignores URIs ending with ``.diff`` or
+``.patch``, as they might point to a fork or developer's space. It also
+ignores URIs that are conditional on USE flags.
+"""
+
+def __init__(self, remote_type: str, value: str, uri: str, **kwarg):
+super().__init__(**kwarg)
+self.remote_type = remote_type
+self.value = value
+self.uri = uri
+
+@property
+def desc(self):
+return (f'missing remote-id of type {self.remote_type!r} with '
+f'value {self.value!r} (inferred from URI {self.uri!r})')
+
+
+class MissingRemoteIdCheck(Check):
+"""Detect missing remote-ids based on SRC_URI and HOMEPAGE."""
+
+_source = sources.PackageRepoSource
+known_results = frozenset([MissingRemoteId])
+
+_gitlab_match = r'(?P(\w[^/]*/)*\w[^/]*/\w[^/]*)'
+
+remotes_map = (
+('bitbucket', r'https://bitbucket.org/(?P[^/]+/[^/]+)'),
+('freedesktop-gitlab', 
rf'https://gitlab.freedesktop.org/{_gitlab_match}'),
+('github', r'https://github.com/(?P[^/]+/[^/]+)'),
+('gitlab', rf'https://gitlab.com/{_gitlab_match}'),
+('gnome-gitlab', rf'https://gitlab.gnome.org/{_gitlab_match}'),
+('heptapod', rf'https://foss.heptapod.net/{_gitlab_match}'),
+('launchpad', r'https://launchpad.net/(?P[^/]+)'),
+('pypi', r'https://pypi.org/project/(?P[^/]+)'),
+('pypi', 
r'https://files.pythonhosted.org/packages/source/\S/(?P[^/]+)'),
+('savannah', r'https://savannah.gnu.org/projects/(?P[^/]+)'),
+('savannah-nongnu', 
r'https://savannah.nongnu.org/projects/(?P[^/]+)'),
+('sourceforge', r'https://(?P[^/]+).sourceforge.net/'),
+('sourceforge', r'https://sourceforge.net/projects/(?P[^/]+)'),
+('sourceforge', 
r'https://downloads.sourceforge.net/(?:project/)?(?P[^/]+)'),
+('sourcehut', r'https://sr.ht/(?P[^/]+/[^/]+)'),
+)
+
+def __init__(self, options, **kwargs):
+super().__init__(options, **kwargs)
+self.remotes_map = tuple((remote_type, re.compile(regex)) for 
remote_type, regex in 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2022-10-28 Thread Arthur Zamarin
commit: d2ff093fae54ee3507a97c6d91c86fd093e46c29
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Oct 29 05:20:50 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sat Oct 29 05:20:50 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d2ff093f

BetterCompressionCheck: fix false positive when fixed

When the issue is fixed, we get a url which looks like "${URL}.tar.bz2",
but this URL was matching for the ".tar" extension in previous regex
variant. Fix this by forcing the after ".tar" a ".bz2" doesn't appear.

Resolves: https://github.com/pkgcore/pkgcheck/issues/487
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 0933c492..b6ef8c34 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -416,7 +416,7 @@ class BetterCompressionCheck(Check):
 known_results = frozenset([BetterCompressionUri])
 
 REGEXPS = (
-
(r'.*\b(?P(?Phttps?://[^/]*?gitlab[^/]*?/.*/-/archive/.*?/\S*)\.(?:tar\.gz|tar|zip))',
+
(r'.*\b(?Phttps?://[^/]*?gitlab[^/]*?/.*/-/archive/.*?/\S*\.(?:tar\.gz|tar(?!.bz2)|zip))',
  '.tar.bz2'),
 )
 



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, tests/checks/

2022-10-28 Thread Arthur Zamarin
commit: c415e94f833acc4b824cf2b6db332244e97313e9
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Oct 22 08:21:13 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Oct 28 13:15:03 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c415e94f

ExcessiveLineCheck: check for too long lines

Closes: https://bugs.gentoo.org/440686
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/codingstyle.py | 39 +
 tests/checks/test_codingstyle.py   | 59 ++
 2 files changed, 98 insertions(+)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index e8a2f45a..0933c492 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -1079,3 +1079,42 @@ class 
EclassUnquotedVariablesCheck(_UnquotedVariablesCheck):
 def feed(self, eclass):
 for var_name, lines in self._feed(eclass):
 yield EclassUnquotedVariable(var_name, lines=lines, 
eclass=eclass.name)
+
+
+class ExcessiveLineLength(results.LinesResult, results.Style):
+"""Line is longer than 120 characters."""
+
+line_length = 120
+word_length = 110
+
+@property
+def desc(self):
+return f'excessive line length (over {self.line_length} characters) 
{self.lines_str}'
+
+
+class LineLengthCheck(Check):
+"""Scan ebuild for lines with excessive length."""
+
+_source = sources.EbuildFileRepoSource
+known_results = frozenset([ExcessiveLineLength])
+
+def __init__(self, options, **kwargs):
+super().__init__(options, **kwargs)
+self.exception = re.compile(r'\s*(?:DESCRIPTION|KEYWORDS|IUSE)=')
+str_length = f'[^\'\"]{{{ExcessiveLineLength.word_length},}}'
+self.long_string = re.compile(rf'"{str_length}"|\'{str_length}\'')
+
+def feed(self, pkg):
+lines = []
+for lineno, line in enumerate(pkg.lines, 1):
+if len(line) <= ExcessiveLineLength.line_length:
+continue
+if self.exception.match(line):
+continue # exception variables which are fine to be long
+if max(map(len, line.split())) > ExcessiveLineLength.word_length:
+continue # if one part of the line is very long word
+if self.long_string.search(line):
+continue # skip lines with long quoted string
+lines.append(lineno)
+if lines:
+yield ExcessiveLineLength(lines=lines, pkg=pkg)

diff --git a/tests/checks/test_codingstyle.py b/tests/checks/test_codingstyle.py
index 3becc919..1c6a0075 100644
--- a/tests/checks/test_codingstyle.py
+++ b/tests/checks/test_codingstyle.py
@@ -433,3 +433,62 @@ class TestStaticSrcUri(misc.ReportTestCase):
 r = self.assertReport(self.check, 
self._prepare_pkg('Diffball-0.1.2.3', pkgver='Diffball-0.1.2.3'))
 assert r.static_str == 'Diffball-0.1.2.3'
 assert r.replacement == '${P}'
+
+
+class TestExcessiveLineLength(misc.ReportTestCase):
+
+check_kls = codingstyle.LineLengthCheck
+check = check_kls(None)
+word_length = codingstyle.ExcessiveLineLength.word_length
+
+
+@staticmethod
+def _prepare_pkg(*lines: str):
+fake_pkg = misc.FakePkg("dev-util/diffball-0", ebuild=''.join(lines), 
lines=lines)
+data = ''.join(lines).encode()
+return _ParsedPkg(data, pkg=fake_pkg)
+
+def test_normal_length(self):
+self.assertNoReport(self.check, self._prepare_pkg('echo "short line"'))
+
+def test_long_line(self):
+r = self.assertReport(self.check, self._prepare_pkg(f'echo {"a " * 
codingstyle.ExcessiveLineLength.line_length}'))
+assert r.lines == (1, )
+
+def test_multiple_lines(self):
+r = self.assertReport(self.check, self._prepare_pkg(
+f'echo {"a " * codingstyle.ExcessiveLineLength.line_length}',
+'echo "short line"',
+f'echo {"Hello " * codingstyle.ExcessiveLineLength.line_length}',
+))
+assert r.lines == (1, 3)
+
+@pytest.mark.parametrize('variable', ('DESCRIPTION', 'KEYWORDS', 'IUSE'))
+def test_special_variables(self, variable):
+self.assertNoReport(self.check, self._prepare_pkg(
+f'{variable}="{"a " * 
codingstyle.ExcessiveLineLength.line_length}"',
+f'{variable}="{"a " * 
codingstyle.ExcessiveLineLength.line_length}"',
+f'\t\t{variable}="{"a " * 
codingstyle.ExcessiveLineLength.line_length}"',
+))
+
+def test_long_words(self):
+long_word = 'a' * self.word_length + 'b'
+medium_word = 'a' * (self.word_length // 2)
+r = self.assertReport(self.check, self._prepare_pkg(
+f'echo {"a" * codingstyle.ExcessiveLineLength.line_length}',
+f'echo {medium_word} {long_word}',
+f'echo {medium_word} {long_word[:-5]}',
+))
+assert r.lines == (3, )
+
+def 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...

2022-10-13 Thread Arthur Zamarin
commit: b9dc3859c9a507639548ce292656388a4b6418e6
Author: Michał Górny  gentoo  org>
AuthorDate: Thu Oct 13 13:28:47 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Thu Oct 13 17:05:35 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b9dc3859

PythonCheck: warn about use of distutils-r1 non-PEP517 mode

Closes: https://github.com/pkgcore/pkgcheck/issues/467
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/python.py  | 33 --
 .../DistutilsNonPEP517Build/expected.json  |  1 +
 .../PythonCheck/DistutilsNonPEP517Build/fix.patch  | 10 +++
 .../DistutilsNonPEP517Build-0.ebuild   | 10 +++
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 9bfa0bad..a1d5ff5f 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -139,6 +139,17 @@ class PythonEclassError(results.VersionResult, 
results.Error):
 return self.msg
 
 
+class DistutilsNonPEP517Build(results.VersionResult, results.Warning):
+"""Ebuild uses the deprecated non-PEP517 build"""
+
+@property
+def desc(self):
+return (
+"uses deprecated non-PEP517 build mode, please switch to "
+"DISTUTILS_USE_PEP517=..."
+)
+
+
 class PythonCheck(Check):
 """Python eclass checks.
 
@@ -150,6 +161,7 @@ class PythonCheck(Check):
 known_results = frozenset([
 MissingPythonEclass, PythonMissingRequiredUse,
 PythonMissingDeps, PythonRuntimeDepInAnyR1, PythonEclassError,
+DistutilsNonPEP517Build,
 ])
 
 def scan_tree_recursively(self, deptree, expected_cls):
@@ -240,6 +252,20 @@ class PythonCheck(Check):
 
 return True
 
+def check_pep517_mode(self, item):
+"""Check whether PEP517 mode is used."""
+# We're not interested in testing fake objects from TestPythonCheck
+if not isinstance(item, sources._ParsedPkg) or not hasattr(item, 
'tree'): # pragma: no cover
+return True
+
+for var_node, _ in bash.var_assign_query.captures(item.tree.root_node):
+var_name = item.node_str(var_node.child_by_field_name('name'))
+
+if var_name == "DISTUTILS_USE_PEP517":
+return True
+
+return False
+
 def feed(self, pkg):
 try:
 eclass = get_python_eclass(pkg)
@@ -285,8 +311,11 @@ class PythonCheck(Check):
 yield PythonMissingRequiredUse(pkg=pkg)
 if not self.check_depend(pkg.rdepend, *(req_use_args[:2])):
 yield PythonMissingDeps('RDEPEND', pkg=pkg)
-if 'distutils-r1' in pkg.inherited and not 
self.check_pep517_depend(pkg):
-yield PythonMissingDeps("BDEPEND", pkg=pkg, 
dep_value="DISTUTILS_DEPS")
+if "distutils-r1" in pkg.inherited:
+if not self.check_pep517_mode(pkg):
+yield DistutilsNonPEP517Build(pkg=pkg)
+if not self.check_pep517_depend(pkg):
+yield PythonMissingDeps("BDEPEND", pkg=pkg, 
dep_value="DISTUTILS_DEPS")
 else:  # python-any-r1
 for attr in ("rdepend", "pdepend"):
 for p in iflatten_instance(getattr(pkg, attr), atom):

diff --git 
a/testdata/data/repos/python/PythonCheck/DistutilsNonPEP517Build/expected.json 
b/testdata/data/repos/python/PythonCheck/DistutilsNonPEP517Build/expected.json
new file mode 100644
index ..db292bed
--- /dev/null
+++ 
b/testdata/data/repos/python/PythonCheck/DistutilsNonPEP517Build/expected.json
@@ -0,0 +1 @@
+{"__class__": "DistutilsNonPEP517Build", "category": "PythonCheck", "package": 
"DistutilsNonPEP517Build", "version": "0"}

diff --git 
a/testdata/data/repos/python/PythonCheck/DistutilsNonPEP517Build/fix.patch 
b/testdata/data/repos/python/PythonCheck/DistutilsNonPEP517Build/fix.patch
new file mode 100644
index ..6ad28c31
--- /dev/null
+++ b/testdata/data/repos/python/PythonCheck/DistutilsNonPEP517Build/fix.patch
@@ -0,0 +1,10 @@
+diff -Naur 
python/PythonCheck/DistutilsNonPEP517Build/DistutilsNonPEP517Build-0.ebuild 
fixed/PythonCheck/DistutilsNonPEP517Build/DistutilsNonPEP517Build-0.ebuild
+--- 
python/PythonCheck/DistutilsNonPEP517Build/DistutilsNonPEP517Build-0.ebuild 
   2022-10-13 15:21:07.676924455 +0200
 fixed/PythonCheck/DistutilsNonPEP517Build/DistutilsNonPEP517Build-0.ebuild 
2022-10-13 15:24:54.005682963 +0200
+@@ -1,5 +1,6 @@
+ EAPI=7
+ 
++DISTUTILS_USE_PEP517=setuptools
+ PYTHON_COMPAT=( python3_10 )
+ 
+ inherit distutils-r1

diff --git 
a/testdata/repos/python/PythonCheck/DistutilsNonPEP517Build/DistutilsNonPEP517Build-0.ebuild
 
b/testdata/repos/python/PythonCheck/DistutilsNonPEP517Build/DistutilsNonPEP517Build-0.ebuild
new file mode 100644
index ..03ff2937
--- /dev/null
+++ 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2022-10-12 Thread Arthur Zamarin
commit: da9e7499dd6ec5e965d539c03e1534bd9ab37509
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Wed Oct 12 17:51:00 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed Oct 12 17:51:19 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=da9e7499

GitCommitsCheck: use Sequential runner

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/__init__.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/pkgcheck/checks/__init__.py b/src/pkgcheck/checks/__init__.py
index 67fa4503..f0959257 100644
--- a/src/pkgcheck/checks/__init__.py
+++ b/src/pkgcheck/checks/__init__.py
@@ -100,6 +100,8 @@ class OptionalCheck(Check):
 class GitCommitsCheck(OptionalCheck):
 """Check that is only run when explicitly enabled via the --commits git 
option."""
 
+runner_cls = runners.SequentialCheckRunner
+
 def __init__(self, *args):
 super().__init__(*args)
 if not self.options.commits:



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2022-10-07 Thread Arthur Zamarin
commit: bedfeffb24829004d9ac918d6ae2f89be1ba07fa
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Fri Oct  7 11:15:59 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Oct  7 12:24:24 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=bedfeffb

GitPkgCommitsCheck: fix archival repo from multiple removals

When we are performing `--commits` scan over a commit range that have at
least 2 commits that drop a version from the same package, we can have a
state of the temporary "removal repo" that it expects one of the removed
ebuilds.

This is because the check is fed package after package, with the list of
all removals of this package in a list. When creating the archival repo,
we need to select the commit from which to "archive", and we select the
first commit in the list. This is not always the right commit, as it can
be the second or third commit that removes the a version. As a result we
have an archival repo that expects all version to exist, but one of them
might be missing.

By selecting the commit with the lowest commit date, we ensure the right
commit is selected, and all removed ebuilds are present.

On the same note, sometimes we have another exception, which involves a
failure to check the EAPI of the repo is supported, because of missing
`profiles` directory in archival repo, so also include it in the archive.

Resolves: https://github.com/pkgcore/pkgcheck/issues/460
Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/git.py | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/pkgcheck/checks/git.py b/src/pkgcheck/checks/git.py
index 046f1843..c06c8278 100644
--- a/src/pkgcheck/checks/git.py
+++ b/src/pkgcheck/checks/git.py
@@ -7,6 +7,7 @@ import tarfile
 from collections import defaultdict
 from datetime import datetime
 from itertools import chain
+from operator import attrgetter
 from tempfile import TemporaryDirectory
 from urllib.parse import urlparse
 
@@ -204,10 +205,11 @@ class _RemovalRepo(UnconfiguredTree):
 
 def _populate(self, pkgs):
 """Populate the repo with a given sequence of historical packages."""
-pkg = pkgs[0]
+pkg = min(pkgs, key=attrgetter('time'))
 paths = [pjoin(pkg.category, pkg.package)]
-if os.path.exists(pjoin(self.__parent_repo.location, 'eclass')):
-paths.append('eclass')
+for subdir in ('eclass', 'profiles'):
+if os.path.exists(pjoin(self.__parent_repo.location, subdir)):
+paths.append(subdir)
 old_files = subprocess.Popen(
 ['git', 'archive', f'{pkg.commit}~1'] + paths,
 stdout=subprocess.PIPE, stderr=subprocess.PIPE,



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/

2022-10-05 Thread Arthur Zamarin
commit: 8be0a6a08313552e30bee6ddf376faba9bf57083
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Wed Oct  5 16:45:08 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Wed Oct  5 16:45:08 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8be0a6a0

profiles: remove code duplication

The function `traverse_parents_tree` is already implemented in pkgcore
as `ProfileStack.stack`.

Signed-off-by: Arthur Zamarin  gentoo.org>

 src/pkgcheck/checks/profiles.py | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 73e2898e..db49cf38 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -168,14 +168,6 @@ class ProfilesCheck(Check):
 local_iuse | use_addon.global_iuse |
 use_addon.global_iuse_expand | use_addon.global_iuse_implicit)
 
-@staticmethod
-def traverse_parents_tree(profile):
-def _traverse(node):
-for parent in node.parents:
-yield parent
-yield from _traverse(parent)
-return set(_traverse(profile))
-
 @verify_files(('parent', 'parents'),
   ('eapi', 'eapi'))
 def _pull_attr(self, *args):
@@ -230,9 +222,8 @@ class ProfilesCheck(Check):
 
 @verify_files(('package.mask', 'masks'),)
 def _pkg_masks(self, filename, node, vals):
-all_parents = self.traverse_parents_tree(node)
 all_masked = set().union(*(masked[1]
-for p in all_parents if (masked := p.masks)))
+for p in profiles_mod.ProfileStack(node.path).stack if (masked := 
p.masks)))
 
 unmasked, masked = vals
 for x in masked: