[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: 3ffbd0e34f5e5698fef0302eb72dc2c2c09333cd
Author: Arthur Zamarin gentoo org>
AuthorDate: Sun Feb 1 17:19:38 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sun Feb 1 17:19:38 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=3ffbd0e3
EclassDocMissingInternal: new check for missing @INTERNAL
Requested-by: Ulrich Müller gentoo.org>
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/eclass.py | 30 --
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/checks/eclass.py b/src/pkgcheck/checks/eclass.py
index 5a6b6430..e8ab8434 100644
--- a/src/pkgcheck/checks/eclass.py
+++ b/src/pkgcheck/checks/eclass.py
@@ -435,17 +435,37 @@ class EclassDocMissingVar(results.EclassResult,
results.Warning):
return f"{self.eclass}: undocumented variable{s}: {variables}"
+class EclassDocMissingInternal(results.EclassResult, results.Warning):
+"""Eclass function missing an @INTERNAL doc tag.
+
+Eclass functions with a leading underscore should be documented with the
+``@INTERNAL`` doc tag to indicate they are not part of the public API,
+since Gentoo's convention is that leading underscores indicate internal
use.
+"""
+
+whitelist = frozenset({"_elibtoolize"})
+
+def __init__(self, function: str, **kwargs):
+super().__init__(**kwargs)
+self.function = function
+
+@property
+def desc(self):
+return f"{self.eclass}: {self.function!r} starts with '_' but is not
labeled as internal"
+
+
class EclassCheck(Check):
"""Scan eclasses for various issues."""
_source = sources.EclassRepoSource
known_results = frozenset(
-[
+{
EclassBashSyntaxError,
EclassDocError,
EclassDocMissingFunc,
EclassDocMissingVar,
-]
+EclassDocMissingInternal,
+}
)
def __init__(self, *args):
@@ -501,6 +521,12 @@ class EclassCheck(Check):
if vars_missing_docs:
yield EclassDocMissingVar(sorted(vars_missing_docs), eclass=eclass)
+missing_internal = {
+f.name for f in eclass_obj.functions if f.name.startswith("_") and
not f.internal
+} - EclassDocMissingInternal.whitelist
+for f in sorted(missing_internal):
+yield EclassDocMissingInternal(f, eclass=eclass)
+
class GoMissingDeps(results.VersionResult, results.Warning):
"""Package sets ``GO_OPTIONAL`` but does not depend on ``dev-lang/go``."""
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/data/repos/eclass/EclassCheck/EclassDocMissingInternal/, ...
commit: 330746b6001475441774be202b2f8536017fcdea
Author: Arthur Zamarin gentoo org>
AuthorDate: Sun Feb 1 16:19:43 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sun Feb 1 16:19:43 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=330746b6
EclassDocMissingInternal: new check for missing @INTERNAL
Requested-by: Ulrich Müller gentoo.org>
Signed-off-by: Arthur Zamarin gentoo.org>
.../EclassCheck/EclassDocMissingInternal/expected.json| 1 +
.../eclass/EclassCheck/EclassDocMissingInternal/fix.patch | 10 ++
testdata/repos/eclass/eclass/missing-internal.eclass | 15 +++
3 files changed, 26 insertions(+)
diff --git
a/testdata/data/repos/eclass/EclassCheck/EclassDocMissingInternal/expected.json
b/testdata/data/repos/eclass/EclassCheck/EclassDocMissingInternal/expected.json
new file mode 100644
index ..dbf24e4a
--- /dev/null
+++
b/testdata/data/repos/eclass/EclassCheck/EclassDocMissingInternal/expected.json
@@ -0,0 +1 @@
+{"__class__": "EclassDocMissingInternal", "eclass": "missing-internal",
"function": "_missing_internal_func"}
diff --git
a/testdata/data/repos/eclass/EclassCheck/EclassDocMissingInternal/fix.patch
b/testdata/data/repos/eclass/EclassCheck/EclassDocMissingInternal/fix.patch
new file mode 100644
index ..dab29bd1
--- /dev/null
+++ b/testdata/data/repos/eclass/EclassCheck/EclassDocMissingInternal/fix.patch
@@ -0,0 +1,10 @@
+--- eclass/eclass/missing-internal.eclass
fixed/eclass/missing-internal.eclass
+@@ -10,6 +10,7 @@
+ _elibtoolize() { :; }
+
+ # @FUNCTION: _missing_internal_func
++# @INTERNAL
+ # @DESCRIPTION:
+ # missing internal tag
+ _missing_internal_func() { :; }
diff --git a/testdata/repos/eclass/eclass/missing-internal.eclass
b/testdata/repos/eclass/eclass/missing-internal.eclass
new file mode 100644
index ..2ccbd501
--- /dev/null
+++ b/testdata/repos/eclass/eclass/missing-internal.eclass
@@ -0,0 +1,15 @@
+# @ECLASS: missing-internal.eclass
+# @MAINTAINER:
+# Random Person
+# @SUPPORTED_EAPIS: 6 7
+# @BLURB: Stub eclass with missing internal for function documentation.
+
+# @FUNCTION: _elibtoolize
+# @DESCRIPTION:
+# in whitelist
+_elibtoolize() { :; }
+
+# @FUNCTION: _missing_internal_func
+# @DESCRIPTION:
+# missing internal tag
+_missing_internal_func() { :; }
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: eddd506089fad7ccc4984e67962a7ea23fcf66bc Author: Brian Harring gmail com> AuthorDate: Sat Jan 10 19:27:37 2026 + Commit: Arthur Zamarin gentoo org> CommitDate: Wed Jan 21 18:44:47 2026 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=eddd5060 require pytest 9.0 Also wipe some dead pyproject definitions. Signed-off-by: Brian Harring gmail.com> NEWS.rst | 9 + pyproject.toml | 7 +++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index 5b12e13d..545c2e2e 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,15 @@ Release Notes = +- +pkgcheck 0.10.40 (unreleased) +- + +Packaging +~ + +- ``pytest >= 9.0`` is now required + - pkgcheck 0.10.39 (2026-01-03) - diff --git a/pyproject.toml b/pyproject.toml index 52f118c6..9df03530 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,13 +51,15 @@ dependencies = [ [project.optional-dependencies] test = [ - "pytest>=6.0", + "pytest>=9.0", "pytest-cov", "requests", ] + doc = [ "sphinx", ] + network = [ "requests", ] @@ -93,9 +95,6 @@ ignore = [ "E741", # ambiguous variable name ] -[tool.black] -line-length = 100 - [tool.pytest.ini_options] minversion = "6.0" addopts = "-vv -ra -l"
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: cb233b5628fe75595a91536d381ac58ce4e1f15b Author: Brian Harring gmail com> AuthorDate: Wed Jan 21 18:44:57 2026 + Commit: Arthur Zamarin gentoo org> CommitDate: Wed Jan 21 18:44:57 2026 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=cb233b56 add vulture configuration Signed-off-by: Brian Harring gmail.com> pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 9df03530..2273075e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -99,3 +99,6 @@ ignore = [ minversion = "6.0" addopts = "-vv -ra -l" testpaths = ["tests"] + +[tool.vulture] +paths = ["src/pkgcheck/"]
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: d0e04d69ea44c1ee51630c4f2f4c4288ddccd4a4
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 9 19:28:54 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Jan 10 10:11:31 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d0e04d69
start work on 0.10.40
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pkgcheck/__init__.py b/src/pkgcheck/__init__.py
index 40168b9e..f4fef252 100644
--- a/src/pkgcheck/__init__.py
+++ b/src/pkgcheck/__init__.py
@@ -4,4 +4,4 @@ from .results import Result
__all__ = ("scan", "PkgcheckException", "Result")
__title__ = "pkgcheck"
-__version__ = "0.10.39"
+__version__ = "0.10.40"
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: , ...
commit: 88c2e6a742e41f81b7485876523b27ab2581b0da
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Jan 10 10:11:02 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Jan 10 10:11:31 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=88c2e6a7
StabilizationGroupsCheck: add checks for invalid and non-existing groups
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/repo_metadata.py | 47 ++
.../StabilizationGroupSourcingError/expected.json | 1 +
.../UnknownStabilizationGroupPackage/expected.json | 1 +
.../metadata/stabilization-groups/invalid.group| 5 +++
.../stabilization-groups/non-existing.group| 2 +
5 files changed, 56 insertions(+)
diff --git a/src/pkgcheck/checks/repo_metadata.py
b/src/pkgcheck/checks/repo_metadata.py
index bd60a456..9aaced90 100644
--- a/src/pkgcheck/checks/repo_metadata.py
+++ b/src/pkgcheck/checks/repo_metadata.py
@@ -814,3 +814,50 @@ class RepoManifestHashCheck(RepoCheck):
def finish(self):
if deprecated_hashes :=
DEPRECATED_HASHES.intersection(self.repo.config.manifests.hashes):
yield DeprecatedRepoHash(sorted(deprecated_hashes))
+
+
+class StabilizationGroupSourcingError(results.LogError):
+"""Misformed stabilization group file."""
+
+
+class UnknownStabilizationGroupPackage(results.Error):
+"""Packages listed in stabilization group that doesn't exist."""
+
+def __init__(self, group: str, packages: list[str]):
+super().__init__()
+self.group = group
+self.packages = tuple(packages)
+
+@property
+def desc(self):
+s = pluralism(self.packages)
+packages = ", ".join(self.packages)
+return f"stabilization group {self.group!r} has unknown package{s}: [
{packages} ]"
+
+
+class StabilizationGroupsCheck(RepoCheck):
+"""Check stabilization groups"""
+
+_source = (sources.EmptySource, (base.repo_scope,))
+known_results = frozenset({StabilizationGroupSourcingError,
UnknownStabilizationGroupPackage})
+
+def __init__(self, *args):
+super().__init__(*args)
+self.repo = self.options.target_repo
+
+def finish(self):
+_logmap = (
+base.LogMap("pkgcore.log.logger.warning",
StabilizationGroupSourcingError),
+base.LogMap("pkgcore.log.logger.error",
StabilizationGroupSourcingError),
+)
+with base.LogReports(*_logmap) as log_reports:
+groups = self.repo.stabilization_groups
+yield from log_reports
+
+for group, packages in groups.items():
+unknown_packages = set()
+for pkg in packages:
+if not self.repo.match(pkg):
+unknown_packages.add(pkg.key)
+if unknown_packages:
+yield UnknownStabilizationGroupPackage(group,
sorted(unknown_packages))
diff --git
a/testdata/data/repos/standalone/StabilizationGroupsCheck/StabilizationGroupSourcingError/expected.json
b/testdata/data/repos/standalone/StabilizationGroupsCheck/StabilizationGroupSourcingError/expected.json
new file mode 100644
index ..2d0646b9
--- /dev/null
+++
b/testdata/data/repos/standalone/StabilizationGroupsCheck/StabilizationGroupSourcingError/expected.json
@@ -0,0 +1 @@
+{"__class__": "StabilizationGroupSourcingError", "msg":
"/metadata/stabilization-groups/invalid.group, line 3: parsing error: invalid
package atom: 'cat-cat'"}
diff --git
a/testdata/data/repos/standalone/StabilizationGroupsCheck/UnknownStabilizationGroupPackage/expected.json
b/testdata/data/repos/standalone/StabilizationGroupsCheck/UnknownStabilizationGroupPackage/expected.json
new file mode 100644
index ..33385f3d
--- /dev/null
+++
b/testdata/data/repos/standalone/StabilizationGroupsCheck/UnknownStabilizationGroupPackage/expected.json
@@ -0,0 +1 @@
+{"__class__": "UnknownStabilizationGroupPackage", "group": "non-existing",
"packages": ["dev-lang/doesnot-exist"]}
diff --git
a/testdata/repos/standalone/metadata/stabilization-groups/invalid.group
b/testdata/repos/standalone/metadata/stabilization-groups/invalid.group
new file mode 100644
index ..a8823487
--- /dev/null
+++ b/testdata/repos/standalone/metadata/stabilization-groups/invalid.group
@@ -0,0 +1,5 @@
+# cat/pkg
+# cat-cat
+cat-cat
+<=dev-lang/rust-5.0
+dev-lang/rust
diff --git
a/testdata/repos/standalone/metadata/stabilization-groups/non-existing.group
b/testdata/repos/standalone/metadata/stabilization-groups/non-existing.group
new file mode 100644
index ..675e77d3
--- /dev/null
+++ b/testdata/repos/standalone/metadata/stabilization-groups/non-existing.group
@@ -0,0 +1,2 @@
+dev-lang/rust
+dev-lang/doesnot-exist
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/addons/
commit: c49575826b8193e31b7b4b00c9fd703c3f2db10a
Author: Brian Harring gmail com>
AuthorDate: Sat Jan 10 10:03:49 2026 +
Commit: Brian Harring gmail com>
CommitDate: Sat Jan 10 10:03:49 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c4957582
clarify allowed keyword rules
https://projects.gentoo.org/pms/9/pms.html#keyword-names documents
what's allowed, but #767 showed we should improve the inline code
comments to be clearer.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/addons/__init__.py | 4
1 file changed, 4 insertions(+)
diff --git a/src/pkgcheck/addons/__init__.py b/src/pkgcheck/addons/__init__.py
index c621c53b..6cdc0a89 100644
--- a/src/pkgcheck/addons/__init__.py
+++ b/src/pkgcheck/addons/__init__.py
@@ -88,6 +88,10 @@ class KeywordsAddon(base.Addon):
def __init__(self, *args):
super().__init__(*args)
+# see https://projects.gentoo.org/pms/9/pms.html#keyword-names .
+# usage of '-' indicates that the named arch is never to be considered
as a target
+# for stabilization. `-*` is shorthand to state that any arch not
explicitly marked
+# as stable or unstable, is not to be considered for stabilization.
special = {"-*"}
self.arches: frozenset[str] = self.options.target_repo.known_arches
unstable = {"~" + x for x in self.arches}
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /, src/pkgcheck/
commit: 7b6e43ddd731d6d71b5c45ba4acb3e1c33e839fd
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Jan 3 16:44:07 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Jan 3 16:44:07 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7b6e43dd
new release 0.10.39
Signed-off-by: Arthur Zamarin gentoo.org>
NEWS.rst | 7 +++
src/pkgcheck/__init__.py | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/NEWS.rst b/NEWS.rst
index 7266ed23..5b12e13d 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -2,6 +2,13 @@
Release Notes
=
+-
+pkgcheck 0.10.39 (2026-01-03)
+-
+
+- Dockerfile: use alpine as base image for an image with bash-5.3 (Arthur
+ Zamarin)
+
-
pkgcheck 0.10.38 (2026-01-02)
-
diff --git a/src/pkgcheck/__init__.py b/src/pkgcheck/__init__.py
index 301838af..40168b9e 100644
--- a/src/pkgcheck/__init__.py
+++ b/src/pkgcheck/__init__.py
@@ -4,4 +4,4 @@ from .results import Result
__all__ = ("scan", "PkgcheckException", "Result")
__title__ = "pkgcheck"
-__version__ = "0.10.38"
+__version__ = "0.10.39"
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 8b8aa915b063f22485b0b65393d8ec75f1c9bb99
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Jan 3 07:57:24 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Jan 3 07:57:24 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8b8aa915
Dockerfile: use alpine as base image
- We require bash-5.3, and the debian base image only provides up to
bash-5.2. Alpine provides bash-5.3, so switch to that.
- It is also smaller, which is a nice bonus.
- Also disabled git safe-directory check, as I don't think any usage
of this image would involve untrusted repositories, so this is just
an annoyance.
When we have python docker images based on newer debian with bash-5.3,
we can consider switching back to debian, or even giving users a choice
between debian and alpine based images.
Resolves: https://github.com/pkgcore/pkgcheck-action/issues/21
Signed-off-by: Arthur Zamarin gentoo.org>
Dockerfile | 14 --
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index bafd6060..08a58325 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,9 +1,11 @@
-FROM python:3-slim
+FROM python:3-alpine
ARG PKGCHECK_VERSION
-RUN apt-get update && apt-get install -y --no-install-recommends git zstd
cpanminus make && \
+RUN apk add --no-cache "bash>=5.3" git perl xz zstd && \
+apk add --no-cache --virtual .cpanm make perl-app-cpanminus && \
cpanm --quiet --notest Gentoo::PerlMod::Version && \
-apt remove --autoremove -y make cpanminus && \
-rm -rf /var/lib/apt/lists/ /var/cache/apt /var/cache/dpkg && \
-pip install pkgcheck==${PKGCHECK_VERSION} setuptools requests && \
-pip cache purge
+apk del .cpanm make perl-app-cpanminus && \
+pip install --root-user-action=ignore pkgcheck==${PKGCHECK_VERSION}
setuptools requests && \
+pip cache purge && \
+ln -sv /bin/bash /usr/bin/bash && \
+git config --global --add safe.directory '*'
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: 3e2c45bd42735c0baa45fb4504d2faae6ff06377 Author: Arthur Zamarin gentoo org> AuthorDate: Fri Jan 2 21:10:21 2026 + Commit: Arthur Zamarin gentoo org> CommitDate: Fri Jan 2 21:19:02 2026 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=3e2c45bd ci: github release should be draft Signed-off-by: Arthur Zamarin gentoo.org> .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c40b71f..d89fabc8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -98,6 +98,7 @@ jobs: with: files: '*.tar.*' fail_on_unmatched_files: true +draft: true - name: Publish to PyPi server uses: pypa/gh-action-pypi-publish@release/v1.13
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: f78f0476a4fa7426d1e1897ca5a2cc6651025ef7 Author: Arthur Zamarin gentoo org> AuthorDate: Fri Jan 2 21:08:35 2026 + Commit: Arthur Zamarin gentoo org> CommitDate: Fri Jan 2 21:19:02 2026 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=f78f0476 new release 0.10.38 Signed-off-by: Arthur Zamarin gentoo.org> NEWS.rst | 26 ++ 1 file changed, 26 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 2fc47215..7266ed23 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,32 @@ Release Notes = +- +pkgcheck 0.10.38 (2026-01-02) +- + +- Massive refactoring done by Brian Harring + +- bash-completion: fix subcommand completion (Arthur Zamarin) + +**New Checks:** + +- PythonCheck: check for redundant ``PYTEST_DISABLE_PLUGIN_AUTOLOAD`` (Michał + Górny, #753) + +- PythonCheck: suggest opportunities for ``EPYTEST_PLUGINS`` (Michał Górny, + #754) + +- SystemSetMissingKeywords: check for missing keywords in system set packages + (Arthur Zamarin, #755) + +- PyPIAttestationAvailableCheck: add check pypi attestation available (Michał Górny, + #757) + +**Check Updates:** + +- UnusedInherits: Whitelist ``branding.eclass`` (James Le Cuirot, #756) + - pkgcheck 0.10.37 (2025-07-24) -
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/
commit: dbc1fc5a20369cf0e4dbe65b932bfa7d31cb42d8
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 2 21:18:47 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 21:19:02 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=dbc1fc5a
fix formatting
Signed-off-by: Arthur Zamarin gentoo.org>
testdata/pkgcheck | 33 +
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/testdata/pkgcheck b/testdata/pkgcheck
index 6cd18e8f..ba98c6c6 100755
--- a/testdata/pkgcheck
+++ b/testdata/pkgcheck
@@ -13,35 +13,36 @@ from pkgcore import const as pkgcore_const
# make sure to use git repo version of pkgcheck
main_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-src_dir = pjoin(main_dir, 'src')
+src_dir = pjoin(main_dir, "src")
sys.path.insert(0, src_dir)
from pkgcheck.scripts import run
-
-with tempfile.TemporaryDirectory(prefix='pkgcheck-test-config-') as tempdir:
-stubrepo = pjoin(pkgcore_const.DATA_PATH, 'stubrepo')
-repo_dir = pjoin(main_dir, 'testdata', 'repos')
-with open(pjoin(tempdir, 'repos.conf'), 'w') as f:
-f.write(textwrap.dedent(f"""\
+with tempfile.TemporaryDirectory(prefix="pkgcheck-test-config-") as tempdir:
+stubrepo = pjoin(pkgcore_const.DATA_PATH, "stubrepo")
+repo_dir = pjoin(main_dir, "testdata", "repos")
+with open(pjoin(tempdir, "repos.conf"), "w") as f:
+f.write(
+textwrap.dedent(f"""\
[DEFAULT]
main-repo = stubrepo
[stubrepo]
location = {stubrepo}
-"""))
+""")
+)
for repo in os.listdir(repo_dir):
-f.write(f'[{repo}]\nlocation = {pjoin(repo_dir, repo)}\n')
+f.write(f"[{repo}]\nlocation = {pjoin(repo_dir, repo)}\n")
# create make.profile symlink
-profile_path = pjoin(stubrepo, 'profiles', 'default')
-os.symlink(profile_path, pjoin(tempdir, 'make.profile'))
+profile_path = pjoin(stubrepo, "profiles", "default")
+os.symlink(profile_path, pjoin(tempdir, "make.profile"))
args = sys.argv[1:]
try:
-if args[0] == 'scan':
+if args[0] == "scan":
# ignore system/user config settings
-args = ['scan', '--config', 'no', '--cache-dir', tempdir] +
args[1:]
+args = ["scan", "--config", "no", "--cache-dir", tempdir] +
args[1:]
except IndexError:
pass
-args = ['pkgcheck', '--config', tempdir] + args
-with patch('sys.argv', args):
-run('pkgcheck')
+args = ["pkgcheck", "--config", tempdir] + args
+with patch("sys.argv", args):
+run("pkgcheck")
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/scripts/
commit: ffc8e3bd69757580edaa0bd029bc09bdcfcf7798
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 2 11:09:47 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 11:09:47 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=ffc8e3bd
rename {snakeoil.contexts -> contextlib}.chdir
Signed-off-by: Arthur Zamarin gentoo.org>
tests/scripts/test_pkgcheck_scan.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/scripts/test_pkgcheck_scan.py
b/tests/scripts/test_pkgcheck_scan.py
index bb9ad6bc..7aee972e 100644
--- a/tests/scripts/test_pkgcheck_scan.py
+++ b/tests/scripts/test_pkgcheck_scan.py
@@ -9,6 +9,7 @@ import subprocess
import textwrap
import typing
from collections import defaultdict
+from contextlib import chdir
from dataclasses import dataclass
from functools import partial
from io import StringIO
@@ -20,7 +21,7 @@ import pytest
from pkgcore import const as pkgcore_const
from pkgcore.ebuild import atom, restricts
from pkgcore.restrictions import packages
-from snakeoil.contexts import chdir, os_environ
+from snakeoil.contexts import os_environ
from snakeoil.fileutils import touch
from snakeoil.formatters import PlainTextFormatter
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/addons/, src/pkgcheck/, src/pkgcheck/scripts/, tests/scripts/, ...
commit: a33f39cf78987acb4f22d42f6b2101d58017fb8e
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 2 11:04:35 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 11:09:01 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=a33f39cf
rename {snakeoil.osutils -> os.path}.pjoin
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/addons/caches.py | 2 +-
src/pkgcheck/addons/eclass.py | 2 +-
src/pkgcheck/addons/git.py | 2 +-
src/pkgcheck/addons/profiles.py| 2 +-
src/pkgcheck/checks/acct.py| 2 +-
src/pkgcheck/checks/git.py | 2 +-
src/pkgcheck/checks/glsa.py| 2 +-
src/pkgcheck/checks/metadata_xml.py| 2 +-
src/pkgcheck/checks/perl.py| 2 +-
src/pkgcheck/checks/pkgdir.py | 4 +++-
src/pkgcheck/checks/profiles.py| 2 +-
src/pkgcheck/checks/repo.py| 3 +--
src/pkgcheck/scripts/pkgcheck_cache.py | 2 +-
src/pkgcheck/scripts/pkgcheck_scan.py | 2 +-
src/pkgcheck/sources.py| 3 ++-
testdata/pkgcheck | 2 +-
tests/addons/test_addons.py| 2 +-
tests/addons/test_eclass.py| 2 +-
tests/addons/test_git.py | 2 +-
tests/checks/test_git.py | 2 +-
tests/checks/test_glsa.py | 2 +-
tests/checks/test_metadata.py | 2 +-
tests/checks/test_pkgdir.py| 3 ++-
tests/checks/test_repo.py | 3 ++-
tests/checks/test_repo_metadata.py | 2 +-
tests/checks/test_stablereq.py | 2 +-
tests/conftest.py | 2 +-
tests/misc.py | 2 +-
tests/scripts/test_pkgcheck_scan.py| 2 +-
tests/test_feeds.py| 3 ++-
30 files changed, 36 insertions(+), 31 deletions(-)
diff --git a/src/pkgcheck/addons/caches.py b/src/pkgcheck/addons/caches.py
index a6c94b73..e78c062a 100644
--- a/src/pkgcheck/addons/caches.py
+++ b/src/pkgcheck/addons/caches.py
@@ -10,12 +10,12 @@ from collections import UserDict
from dataclasses import dataclass
from hashlib import blake2b
from operator import attrgetter
+from os.path import join as pjoin
from snakeoil import klass
from snakeoil.compatibility import IGNORED_EXCEPTIONS
from snakeoil.fileutils import AtomicWriteFile
from snakeoil.mappings import ImmutableDict
-from snakeoil.osutils import pjoin
from ..base import Addon, PkgcheckException, PkgcheckUserException
from ..log import logger
diff --git a/src/pkgcheck/addons/eclass.py b/src/pkgcheck/addons/eclass.py
index 5e5e77ee..30f5b559 100644
--- a/src/pkgcheck/addons/eclass.py
+++ b/src/pkgcheck/addons/eclass.py
@@ -2,11 +2,11 @@
import os
from functools import total_ordering
+from os.path import join as pjoin
from pkgcore.ebuild.eclass import EclassDoc
from snakeoil.klass import jit_attr_none
from snakeoil.mappings import ImmutableDict
-from snakeoil.osutils import pjoin
from .. import base
from . import caches
diff --git a/src/pkgcheck/addons/git.py b/src/pkgcheck/addons/git.py
index 2c8f1094..f735b15e 100644
--- a/src/pkgcheck/addons/git.py
+++ b/src/pkgcheck/addons/git.py
@@ -13,6 +13,7 @@ from dataclasses import dataclass
from datetime import datetime
from functools import partial
from itertools import takewhile
+from os.path import join as pjoin
from pathspec import PathSpec
from pkgcore.ebuild import cpv
@@ -25,7 +26,6 @@ from snakeoil.cli import arghparse
from snakeoil.contexts import GitStash
from snakeoil.klass import jit_attr
from snakeoil.mappings import ImmutableDict, OrderedSet
-from snakeoil.osutils import pjoin
from snakeoil.process import CommandNotFound, find_binary
from snakeoil.strings import pluralism
diff --git a/src/pkgcheck/addons/profiles.py b/src/pkgcheck/addons/profiles.py
index e5a3ec37..d0ad5217 100644
--- a/src/pkgcheck/addons/profiles.py
+++ b/src/pkgcheck/addons/profiles.py
@@ -5,6 +5,7 @@ import stat
from collections import defaultdict
from functools import partial
from itertools import chain
+from os.path import join as pjoin
from pkgcore.ebuild import domain, misc
from pkgcore.ebuild import profiles as profiles_mod
@@ -14,7 +15,6 @@ from snakeoil.containers import ProtectedSet
from snakeoil.decorators import coroutine
from snakeoil.klass import jit_attr
from snakeoil.mappings import ImmutableDict
-from snakeoil.osutils import pjoin
from .. import base
from ..base import PkgcheckUserException
diff --git a/src/pkgcheck/checks/acct.py b/src/pkgcheck/checks/acct.py
index 47015953..cf068734 100644
--- a/src/pkgcheck/checks/acct.py
+++ b/src/pkgcheck/checks/acct.py
@@ -5,10 +5,10 @@ from collections import defaultdict
from configparser import ConfigParser
from functools import partial
from itertools import chain
+from os.path import join as pjoin
from pkgcore.ebuild import restricts
from pkgcore.restrictions import packages
-from snakeoil.osutils import pjoin
from .
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/scripts/, src/pkgcheck/, .github/workflows/, src/pkgcheck/checks/, ...
commit: 1bd59594c858106f8d61f3c50e65d37364c8094d
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 2 10:54:48 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 10:58:04 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=1bd59594
enable ruff linter
Signed-off-by: Arthur Zamarin gentoo.org>
.github/workflows/test.yml | 4
pyproject.toml | 3 +++
src/pkgcheck/checks/imlate.py| 4 ++--
src/pkgcheck/checks/network.py | 4 ++--
src/pkgcheck/reporters.py| 4 +++-
src/pkgcheck/scripts/argparse_actions.py | 4 +++-
tests/checks/test_metadata.py| 15 +++
tests/scripts/test_pkgcheck_scan.py | 2 +-
8 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1a772f19..4d241988 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -126,6 +126,10 @@ jobs:
- name: Run linting tools
run: pylint --exit-zero src/pkgcheck
+- uses: astral-sh/ruff-action@v3
+ with:
+args: "check --diff"
+
format:
runs-on: ubuntu-latest
if: inputs.disable-format-check == ''
diff --git a/pyproject.toml b/pyproject.toml
index ab822cdf..52f118c6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -89,6 +89,9 @@ line-length = 100
target-version = "py311"
[tool.ruff.lint]
extend-select = ["I"]
+ignore = [
+ "E741", # ambiguous variable name
+]
[tool.black]
line-length = 100
diff --git a/src/pkgcheck/checks/imlate.py b/src/pkgcheck/checks/imlate.py
index ee0da6d8..661b6a50 100644
--- a/src/pkgcheck/checks/imlate.py
+++ b/src/pkgcheck/checks/imlate.py
@@ -105,14 +105,14 @@ class ImlateCheck(Check):
lagging -= {"~" + x for x in newer_slot_stables}
lagging -= stable
if lagging:
-stable_kwds = (x for x in pkg.keywords if not x[0] in
("~", "-"))
+stable_kwds = (x for x in pkg.keywords if x[0] not in
("~", "-"))
yield LaggingStable(slot, sorted(stable_kwds),
sorted(lagging), pkg=pkg)
unstable_keywords = {x for x in pkg.keywords if x[0] == "~"}
potential = self.target_arches.intersection(unstable_keywords)
potential -= lagging | stable
if potential:
-stable_kwds = (x for x in pkg.keywords if not x[0] in
("~", "-"))
+stable_kwds = (x for x in pkg.keywords if x[0] not in
("~", "-"))
yield PotentialStable(slot, sorted(stable_kwds),
sorted(potential), pkg=pkg)
break
diff --git a/src/pkgcheck/checks/network.py b/src/pkgcheck/checks/network.py
index fb5e2fd1..3ea8214a 100644
--- a/src/pkgcheck/checks/network.py
+++ b/src/pkgcheck/checks/network.py
@@ -388,10 +388,10 @@ class PyPIAttestationAvailableCheck(NetworkCheck):
result = None
try:
self.session.head(url, allow_redirects=False)
-except RequestError as e:
+except RequestError:
pass
except SSLError as e:
-result = SSLCertificateError(attr, url, str(e), pkg=pkg)
+result = SSLCertificateError("SRC_URI", url, str(e), pkg=pkg)
else:
result = PyPIAttestationAvailable(filename, pkg=pkg)
return result
diff --git a/src/pkgcheck/reporters.py b/src/pkgcheck/reporters.py
index 0a6119cf..5ced131e 100644
--- a/src/pkgcheck/reporters.py
+++ b/src/pkgcheck/reporters.py
@@ -177,7 +177,9 @@ class JsonReporter(StreamReporter):
def _consume_reports_generator(self) -> T_process_report:
# arbitrarily nested defaultdicts
-json_dict = lambda: defaultdict(json_dict)
+def json_dict():
+return defaultdict(json_dict)
+
# scope to data conversion mapping
scope_map = {
base.version_scope: lambda data, r:
data[r.category][r.package][r.version],
diff --git a/src/pkgcheck/scripts/argparse_actions.py
b/src/pkgcheck/scripts/argparse_actions.py
index 4507e10f..508b0f8e 100644
--- a/src/pkgcheck/scripts/argparse_actions.py
+++ b/src/pkgcheck/scripts/argparse_actions.py
@@ -282,8 +282,10 @@ class KeywordArgs(arghparse.CommaSeparatedNegations):
"""Filter enabled keywords by selected keywords."""
def __call__(self, parser, namespace, values, option_string=None):
+def replace_aliases(x):
+return objects.KEYWORDS.aliases.get(x, [x])
+
disabled, enabled = self.parse_values(values)
-replace_aliases = lambda x: objects.KEYWORDS.aliases.get(x, [x])
# expand keyword aliases to keyword lists
disabled = list(chain.from_iterable(map(replace_aliases, disabled)))
diff --git a/tests/checks/test_metadata.py b/tests/checks/test_metadata.py
index 6e0d310b..b194b726 100644
--- a/tests/check
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /, src/pkgcheck/, src/pkgcheck/scripts/, tests/checks/, .github/workflows/, ...
commit: eb91f50e973309d4868acc50352870aa3993fa99
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 2 10:54:48 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 10:57:07 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=eb91f50e
enable ruff linter
Signed-off-by: Arthur Zamarin gentoo.org>
.github/workflows/test.yml | 4
pyproject.toml | 3 +++
src/pkgcheck/checks/imlate.py| 4 ++--
src/pkgcheck/checks/network.py | 4 ++--
src/pkgcheck/reporters.py| 4 +++-
src/pkgcheck/scripts/argparse_actions.py | 4 +++-
tests/checks/test_metadata.py| 15 +++
tests/scripts/test_pkgcheck_scan.py | 2 +-
8 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1a772f19..4d241988 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -126,6 +126,10 @@ jobs:
- name: Run linting tools
run: pylint --exit-zero src/pkgcheck
+- uses: astral-sh/ruff-action@v3
+ with:
+args: "check --diff"
+
format:
runs-on: ubuntu-latest
if: inputs.disable-format-check == ''
diff --git a/pyproject.toml b/pyproject.toml
index ab822cdf..52f118c6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -89,6 +89,9 @@ line-length = 100
target-version = "py311"
[tool.ruff.lint]
extend-select = ["I"]
+ignore = [
+ "E741", # ambiguous variable name
+]
[tool.black]
line-length = 100
diff --git a/src/pkgcheck/checks/imlate.py b/src/pkgcheck/checks/imlate.py
index ee0da6d8..661b6a50 100644
--- a/src/pkgcheck/checks/imlate.py
+++ b/src/pkgcheck/checks/imlate.py
@@ -105,14 +105,14 @@ class ImlateCheck(Check):
lagging -= {"~" + x for x in newer_slot_stables}
lagging -= stable
if lagging:
-stable_kwds = (x for x in pkg.keywords if not x[0] in
("~", "-"))
+stable_kwds = (x for x in pkg.keywords if x[0] not in
("~", "-"))
yield LaggingStable(slot, sorted(stable_kwds),
sorted(lagging), pkg=pkg)
unstable_keywords = {x for x in pkg.keywords if x[0] == "~"}
potential = self.target_arches.intersection(unstable_keywords)
potential -= lagging | stable
if potential:
-stable_kwds = (x for x in pkg.keywords if not x[0] in
("~", "-"))
+stable_kwds = (x for x in pkg.keywords if x[0] not in
("~", "-"))
yield PotentialStable(slot, sorted(stable_kwds),
sorted(potential), pkg=pkg)
break
diff --git a/src/pkgcheck/checks/network.py b/src/pkgcheck/checks/network.py
index fb5e2fd1..3ea8214a 100644
--- a/src/pkgcheck/checks/network.py
+++ b/src/pkgcheck/checks/network.py
@@ -388,10 +388,10 @@ class PyPIAttestationAvailableCheck(NetworkCheck):
result = None
try:
self.session.head(url, allow_redirects=False)
-except RequestError as e:
+except RequestError:
pass
except SSLError as e:
-result = SSLCertificateError(attr, url, str(e), pkg=pkg)
+result = SSLCertificateError("SRC_URI", url, str(e), pkg=pkg)
else:
result = PyPIAttestationAvailable(filename, pkg=pkg)
return result
diff --git a/src/pkgcheck/reporters.py b/src/pkgcheck/reporters.py
index 0a6119cf..5ced131e 100644
--- a/src/pkgcheck/reporters.py
+++ b/src/pkgcheck/reporters.py
@@ -177,7 +177,9 @@ class JsonReporter(StreamReporter):
def _consume_reports_generator(self) -> T_process_report:
# arbitrarily nested defaultdicts
-json_dict = lambda: defaultdict(json_dict)
+def json_dict():
+return defaultdict(json_dict)
+
# scope to data conversion mapping
scope_map = {
base.version_scope: lambda data, r:
data[r.category][r.package][r.version],
diff --git a/src/pkgcheck/scripts/argparse_actions.py
b/src/pkgcheck/scripts/argparse_actions.py
index 4507e10f..508b0f8e 100644
--- a/src/pkgcheck/scripts/argparse_actions.py
+++ b/src/pkgcheck/scripts/argparse_actions.py
@@ -282,8 +282,10 @@ class KeywordArgs(arghparse.CommaSeparatedNegations):
"""Filter enabled keywords by selected keywords."""
def __call__(self, parser, namespace, values, option_string=None):
+def replace_aliases(x):
+return objects.KEYWORDS.aliases.get(x, [x])
+
disabled, enabled = self.parse_values(values)
-replace_aliases = lambda x: objects.KEYWORDS.aliases.get(x, [x])
# expand keyword aliases to keyword lists
disabled = list(chain.from_iterable(map(replace_aliases, disabled)))
diff --git a/tests/checks/test_metadata.py b/tests/checks/test_metadata.py
index 6e0d310b..b194b726 100644
--- a/tests/check
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/addons/, /, src/pkgcheck/checks/, tests/, tests/checks/, tests/scripts/
commit: e1129c0bcd15f5eeae0dca7f2c5ad0aa08edf431
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 2 10:37:48 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 10:37:48 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e1129c0b
sort all imports
Signed-off-by: Arthur Zamarin gentoo.org>
Makefile | 1 +
pyproject.toml | 2 ++
src/pkgcheck/checks/codingstyle.py | 3 +--
src/pkgcheck/checks/metadata.py| 3 ++-
src/pkgcheck/checks/metadata_xml.py| 2 +-
src/pkgcheck/checks/overlays.py| 2 +-
src/pkgcheck/checks/perl.py| 1 -
src/pkgcheck/checks/profiles.py| 2 +-
src/pkgcheck/checks/repo_metadata.py | 1 -
src/pkgcheck/checks/ruby.py| 1 -
src/pkgcheck/checks/visibility.py | 2 +-
tests/addons/test_addons.py| 5 +++--
tests/addons/test_eclass.py| 7 ---
tests/addons/test_git.py | 9 +
tests/checks/test_acct.py | 3 ++-
tests/checks/test_all.py | 1 +
tests/checks/test_cleanup.py | 3 ++-
tests/checks/test_codingstyle.py | 3 ++-
tests/checks/test_dropped_keywords.py | 3 ++-
tests/checks/test_git.py | 10 ++
tests/checks/test_glsa.py | 3 ++-
tests/checks/test_header.py| 3 ++-
tests/checks/test_imlate.py| 3 ++-
tests/checks/test_metadata.py | 5 +++--
tests/checks/test_network.py | 3 ++-
tests/checks/test_perl.py | 3 ++-
tests/checks/test_pkgdir.py| 6 +++---
tests/checks/test_repo.py | 5 +++--
tests/checks/test_repo_metadata.py | 3 ++-
tests/checks/test_stablereq.py | 5 +++--
tests/conftest.py | 11 ++-
tests/misc.py | 7 ---
tests/scripts/test_argparse_actions.py | 5 +++--
tests/scripts/test_pkgcheck.py | 2 +-
tests/scripts/test_pkgcheck_cache.py | 1 +
tests/scripts/test_pkgcheck_ci.py | 3 ++-
tests/scripts/test_pkgcheck_show.py| 1 +
tests/test_cli.py | 3 ++-
tests/test_feeds.py| 3 ++-
39 files changed, 83 insertions(+), 56 deletions(-)
diff --git a/Makefile b/Makefile
index 2efc1390..4c98f26e 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ clean:
.PHONY: format
format:
+ $(PYTHON) -m ruff check --select I --fix . && \
$(PYTHON) -m ruff format
.PHONY: dev-environment
diff --git a/pyproject.toml b/pyproject.toml
index 4ab13310..ab822cdf 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -87,6 +87,8 @@ exclude = [
[tool.ruff]
line-length = 100
target-version = "py311"
+[tool.ruff.lint]
+extend-select = ["I"]
[tool.black]
line-length = 100
diff --git a/src/pkgcheck/checks/codingstyle.py
b/src/pkgcheck/checks/codingstyle.py
index 6cd07148..7091c45c 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -8,8 +8,7 @@ from snakeoil.mappings import ImmutableDict
from snakeoil.sequences import stable_unique
from snakeoil.strings import pluralism
-from .. import addons, bash
-from .. import results, sources
+from .. import addons, bash, results, sources
from . import Check
PREFIX_VARIABLES = ("EROOT", "ED", "EPREFIX")
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 1ca5ad77..f9dd1e04 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -8,7 +8,8 @@ from functools import partial
from operator import attrgetter
from pkgcore.ebuild import restricts
-from pkgcore.ebuild.atom import atom as atom_cls, transitive_use_atom
+from pkgcore.ebuild.atom import atom as atom_cls
+from pkgcore.ebuild.atom import transitive_use_atom
from pkgcore.ebuild.eapi import get_eapi
from pkgcore.ebuild.misc import sort_keywords
from pkgcore.fetch import fetchable, unknown_mirror
diff --git a/src/pkgcheck/checks/metadata_xml.py
b/src/pkgcheck/checks/metadata_xml.py
index 49bd3cfb..2f6d3c4e 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -6,8 +6,8 @@ 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 pkgcore.restrictions.packages import Conditional
from snakeoil.osutils import pjoin
from snakeoil.sequences import iflatten_instance
from snakeoil.strings import pluralism
diff --git a/src/pkgcheck/checks/overlays.py b/src/pkgcheck/checks/overlays.py
index f44b2aa6..122efee9 100644
--- a/src/pkgcheck/checks/overlays.py
+++ b/src/pkgcheck/checks/overlays.py
@@ -2,7 +2,7 @@ from snakeoil.sequences import iflatten_instance
from snakeoil.strings import pluralism
from .
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/, src/pkgcheck/scripts/, /, tests/checks/, src/pkgcheck/checks/, ...
commit: 7a17fbda4e1faab973adc6720aed633cfd7e48d9
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jan 2 10:54:48 2026 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 10:55:05 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7a17fbda
enable ruff linter
Signed-off-by: Arthur Zamarin gentoo.org>
.github/workflows/test.yml | 4
pyproject.toml | 3 +++
src/pkgcheck/checks/imlate.py| 4 ++--
src/pkgcheck/checks/network.py | 4 ++--
src/pkgcheck/reporters.py| 4 +++-
src/pkgcheck/scripts/argparse_actions.py | 4 +++-
tests/checks/test_metadata.py| 15 +++
tests/scripts/test_pkgcheck_scan.py | 2 +-
8 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1a772f19..646eafb3 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -126,6 +126,10 @@ jobs:
- name: Run linting tools
run: pylint --exit-zero src/pkgcheck
+- uses: astral-sh/ruff-action@v3
+ with:
+args: "check --check --diff"
+
format:
runs-on: ubuntu-latest
if: inputs.disable-format-check == ''
diff --git a/pyproject.toml b/pyproject.toml
index ab822cdf..52f118c6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -89,6 +89,9 @@ line-length = 100
target-version = "py311"
[tool.ruff.lint]
extend-select = ["I"]
+ignore = [
+ "E741", # ambiguous variable name
+]
[tool.black]
line-length = 100
diff --git a/src/pkgcheck/checks/imlate.py b/src/pkgcheck/checks/imlate.py
index ee0da6d8..661b6a50 100644
--- a/src/pkgcheck/checks/imlate.py
+++ b/src/pkgcheck/checks/imlate.py
@@ -105,14 +105,14 @@ class ImlateCheck(Check):
lagging -= {"~" + x for x in newer_slot_stables}
lagging -= stable
if lagging:
-stable_kwds = (x for x in pkg.keywords if not x[0] in
("~", "-"))
+stable_kwds = (x for x in pkg.keywords if x[0] not in
("~", "-"))
yield LaggingStable(slot, sorted(stable_kwds),
sorted(lagging), pkg=pkg)
unstable_keywords = {x for x in pkg.keywords if x[0] == "~"}
potential = self.target_arches.intersection(unstable_keywords)
potential -= lagging | stable
if potential:
-stable_kwds = (x for x in pkg.keywords if not x[0] in
("~", "-"))
+stable_kwds = (x for x in pkg.keywords if x[0] not in
("~", "-"))
yield PotentialStable(slot, sorted(stable_kwds),
sorted(potential), pkg=pkg)
break
diff --git a/src/pkgcheck/checks/network.py b/src/pkgcheck/checks/network.py
index fb5e2fd1..3ea8214a 100644
--- a/src/pkgcheck/checks/network.py
+++ b/src/pkgcheck/checks/network.py
@@ -388,10 +388,10 @@ class PyPIAttestationAvailableCheck(NetworkCheck):
result = None
try:
self.session.head(url, allow_redirects=False)
-except RequestError as e:
+except RequestError:
pass
except SSLError as e:
-result = SSLCertificateError(attr, url, str(e), pkg=pkg)
+result = SSLCertificateError("SRC_URI", url, str(e), pkg=pkg)
else:
result = PyPIAttestationAvailable(filename, pkg=pkg)
return result
diff --git a/src/pkgcheck/reporters.py b/src/pkgcheck/reporters.py
index 0a6119cf..5ced131e 100644
--- a/src/pkgcheck/reporters.py
+++ b/src/pkgcheck/reporters.py
@@ -177,7 +177,9 @@ class JsonReporter(StreamReporter):
def _consume_reports_generator(self) -> T_process_report:
# arbitrarily nested defaultdicts
-json_dict = lambda: defaultdict(json_dict)
+def json_dict():
+return defaultdict(json_dict)
+
# scope to data conversion mapping
scope_map = {
base.version_scope: lambda data, r:
data[r.category][r.package][r.version],
diff --git a/src/pkgcheck/scripts/argparse_actions.py
b/src/pkgcheck/scripts/argparse_actions.py
index 4507e10f..508b0f8e 100644
--- a/src/pkgcheck/scripts/argparse_actions.py
+++ b/src/pkgcheck/scripts/argparse_actions.py
@@ -282,8 +282,10 @@ class KeywordArgs(arghparse.CommaSeparatedNegations):
"""Filter enabled keywords by selected keywords."""
def __call__(self, parser, namespace, values, option_string=None):
+def replace_aliases(x):
+return objects.KEYWORDS.aliases.get(x, [x])
+
disabled, enabled = self.parse_values(values)
-replace_aliases = lambda x: objects.KEYWORDS.aliases.get(x, [x])
# expand keyword aliases to keyword lists
disabled = list(chain.from_iterable(map(replace_aliases, disabled)))
diff --git a/tests/checks/test_metadata.py b/tests/checks/test_metadata.py
index 6e0d310b..b194b726 100644
--- a/tes
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 4e39fe3b4a82e930c969baf67feec4ccb0cc8e38 Author: Arthur Zamarin gentoo org> AuthorDate: Fri Jan 2 10:00:33 2026 + Commit: Arthur Zamarin gentoo org> CommitDate: Fri Jan 2 10:00:33 2026 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4e39fe3b pyproject.toml: update snakeoil and pkgcore versions Signed-off-by: Arthur Zamarin gentoo.org> pyproject.toml | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 084f542e..4ab13310 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,8 +7,8 @@ requires = [ "pathspec", "tree-sitter~=0.25.0", "tree-sitter-bash~=0.23.1", - "snakeoil@git+https://github.com/pkgcore/snakeoil.git#master";, - "pkgcore@git+https://github.com/pkgcore/pkgcore.git#master";, + "snakeoil~=0.11.0", + "pkgcore~=0.12.31", ] build-backend = "py_build" backend-path = ["."] @@ -45,8 +45,8 @@ dependencies = [ "pathspec", "tree-sitter~=0.25.0", "tree-sitter-bash~=0.23.1", - "snakeoil@git+https://github.com/pkgcore/snakeoil.git#master";, - "pkgcore@git+https://github.com/pkgcore/pkgcore.git#master";, + "snakeoil~=0.11.0", + "pkgcore~=0.12.31", ] [project.optional-dependencies]
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: efa950dc665e998e7fb31c41678579d52ee2e657
Author: James Le Cuirot gentoo org>
AuthorDate: Mon Dec 22 18:16:30 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jan 2 08:57:01 2026 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=efa950dc
InheritsCheck: Whitelist branding.eclass from UnusedInherits
It can be used purely for variables recognised by external build tools
rather than the ebuild itself.
Resolves: https://github.com/pkgcore/pkgcheck/issues/765
Signed-off-by: James Le Cuirot gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/766
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/codingstyle.py | 10 +-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/pkgcheck/checks/codingstyle.py
b/src/pkgcheck/checks/codingstyle.py
index b2126429..6cd07148 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -817,6 +817,10 @@ class InheritsCheck(Check):
)
required_addons = (addons.eclass.EclassAddon,)
+# branding.eclass can be used purely for variables recognised by external
+# build tools rather than the ebuild itself.
+unused_whitelist = frozenset({"branding"})
+
def __init__(self, *args, eclass_addon):
super().__init__(*args)
self.eclass_cache = eclass_addon.eclasses
@@ -961,7 +965,11 @@ class InheritsCheck(Check):
)
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:
+elif (
+not self.eclass_cache[eclass].exported_function_names
+and exported_eclass_keys
+or eclass in self.unused_whitelist
+):
# 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: data/share/bash-completion/completions/
commit: fafa9c48ab0426855369788dfbb3a96556e8a347
Author: Arthur Zamarin gentoo org>
AuthorDate: Mon Dec 22 07:58:58 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Dec 22 07:58:58 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=fafa9c48
bash-completion: add some missing scan args
Signed-off-by: Arthur Zamarin gentoo.org>
data/share/bash-completion/completions/pkgcheck | 9 +++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/data/share/bash-completion/completions/pkgcheck
b/data/share/bash-completion/completions/pkgcheck
index c6213cae..1b8747d8 100644
--- a/data/share/bash-completion/completions/pkgcheck
+++ b/data/share/bash-completion/completions/pkgcheck
@@ -128,12 +128,17 @@ _pkgcheck() {
--cache-dir
--exit
+--stable-only
+--glsa-dir
+--stabletime
+
--net
-C --checksets
-s --scopes
-c --checks
-k --keywords
--timeout
+--user-agent
-a --arches
@@ -142,10 +147,10 @@ _pkgcheck() {
)
case ${prev} in
--[jt] | --jobs | --tasks)
+-[jt] | --jobs | --tasks | --timeout | --user-agent |
--stabletime)
COMPREPLY=()
;;
---cache-dir)
+--cache-dir | --glsa-dir)
_filedir -d
;;
-r | --repo)
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: data/share/bash-completion/completions/
commit: ff5145b989e3a61fa3db462ff81049a28e409566
Author: Arthur Zamarin gentoo org>
AuthorDate: Mon Dec 22 07:58:48 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Dec 22 07:58:48 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=ff5145b9
bash-completion: fix subcommand complete
Signed-off-by: Arthur Zamarin gentoo.org>
data/share/bash-completion/completions/pkgcheck | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/data/share/bash-completion/completions/pkgcheck
b/data/share/bash-completion/completions/pkgcheck
index 972fc1e5..c6213cae 100644
--- a/data/share/bash-completion/completions/pkgcheck
+++ b/data/share/bash-completion/completions/pkgcheck
@@ -51,7 +51,7 @@ _pkgcheck() {
done
if (( i == COMP_CWORD )); then
-COMPREPLY+=($(compgen -W "${subcommands}" -- "${cur}"))
+COMPREPLY+=($(compgen -W "${subcommands[*]}" -- "${cur}"))
return
fi
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 96aedaa70511e76f4cea82d219acfe99bd04be15 Author: Arthur Zamarin gentoo org> AuthorDate: Sat Dec 20 15:50:41 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Sat Dec 20 15:50:41 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=96aedaa7 pyproject.toml: fix [doc] dependencies Signed-off-by: Arthur Zamarin gentoo.org> pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fc08ddcd..084f542e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,6 @@ test = [ ] doc = [ "sphinx", - "snakeoil~=0.10.11", ] network = [ "requests",
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: be3e71097e6239c63a44badb1aaafdbe4902ea03 Author: Arthur Zamarin gentoo org> AuthorDate: Sat Dec 20 15:48:38 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Sat Dec 20 15:48:38 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=be3e7109 ci: add step for installing bash 5.3 Signed-off-by: Arthur Zamarin gentoo.org> .github/workflows/doc.yml | 3 +++ .github/workflows/test.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index b8fd7855..68c13348 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -21,6 +21,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 +- name: Install bash 5.3 + uses: pkgcore/gh-actions/bash-5.3@main + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 775a839e..1a772f19 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -110,6 +110,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 +- name: Install bash 5.3 + uses: pkgcore/gh-actions/bash-5.3@main + - name: Set up Python 3 uses: actions/setup-python@v5 with:
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: 9756d3d4466856cbe2e5da008290920a5621
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Dec 20 15:45:27 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Dec 20 15:45:27 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9756d3d4
ci: add step for installing bash 5.3
Signed-off-by: Arthur Zamarin gentoo.org>
.github/workflows/release.yml | 3 +++
.github/workflows/test.yml| 3 +++
2 files changed, 6 insertions(+)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index d36784d0..4c40b71f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -24,6 +24,9 @@ jobs:
continue-on-error: ${{ github.ref_type == 'branch' && github.ref_name !=
'release-test-full' }}
uses: pkgcore/gh-actions/reject-python-vcs-deps@main
+- name: Install bash 5.3
+ uses: pkgcore/gh-actions/bash-5.3@main
+
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 7098f0d1..775a839e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -51,6 +51,9 @@ jobs:
with:
artifact-id: ${{ inputs.release-artifact-id }}
+- name: Install bash 5.3
+ uses: pkgcore/gh-actions/bash-5.3@main
+
# experimental targets generally lack lxml wheels
- name: Install libxml2 and libxslt development packages
if: ${{ matrix.experimental && matrix.os != 'macos-latest' }}
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/scripts/
commit: 2d91176025789852df017bf838c318e3b80134ea
Author: Brian Harring gmail com>
AuthorDate: Sun Dec 14 23:39:40 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Dec 15 00:03:27 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=2d911760
clarify pkgcheck scan in it's --help
resolves #721
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/scripts/pkgcheck_scan.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pkgcheck/scripts/pkgcheck_scan.py
b/src/pkgcheck/scripts/pkgcheck_scan.py
index fe55ee6c..de22def6 100644
--- a/src/pkgcheck/scripts/pkgcheck_scan.py
+++ b/src/pkgcheck/scripts/pkgcheck_scan.py
@@ -50,7 +50,7 @@ scan.add_argument(
metavar="TARGET",
nargs="*",
action=arghparse.ParseNonblockingStdin,
-help="optional targets",
+help="if not given, scan the repo. If given, limit scans to pkgs matching
extended atom syntax. If no packaages match, no scans are ran",
)
main_options = scan.add_argument_group("main options")
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /, doc/
commit: 9e3fccf6e5de60bb0c9c965fbb889e99b82cfc55
Author: Brian Harring gmail com>
AuthorDate: Mon Dec 1 00:45:37 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Dec 1 00:45:37 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9e3fccf6
chore: pull in Makefile fixes
Signed-off-by: Brian Harring gmail.com>
Makefile | 19 ---
doc/build.sh | 39 +++
2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index 63b08eea..2efc1390 100644
--- a/Makefile
+++ b/Makefile
@@ -1,18 +1,31 @@
PYTHON ?= python
-SPHINX_BUILD ?= $(PYTHON) -m sphinx.cmd.build
.PHONY: man html
man html:
- $(SPHINX_BUILD) -a -b $@ doc build/sphinx/$@
+ doc/build.sh $@ "$$(pwd)/build/sphinx/$@"
+
+html: man
+
+.PHONY: docs
+docs: man html
.PHONY: sdist wheel
sdist wheel:
$(PYTHON) -m build --$@
+sdist: man
+
+.PHONY: release
+release: sdist wheel
+
.PHONY: clean
clean:
- $(RM) -r build doc/man/pkgcheck doc/generated dist
+ $(RM) -rf build doc/man/pkgcheck doc/generated dist
.PHONY: format
format:
$(PYTHON) -m ruff format
+
+.PHONY: dev-environment
+dev-environment:
+ $(PYTHON) -m pip install -e .[test,doc,formatter]
diff --git a/doc/build.sh b/doc/build.sh
new file mode 100755
index ..5199737b
--- /dev/null
+++ b/doc/build.sh
@@ -0,0 +1,39 @@
+#!/bin/bash -e
+base=$(dirname "$(dirname "$(readlink -f "$0")")")
+
+if [ ${#} -ne 2 ]; then
+echo "requires 2 arguments; the sphinx mode, and where to put the output."
+exit 1;
+fi
+mode="$1"
+output="$2"
+
+
+
+# the point of this script is to capture sphinx output for extension
+# failures, and also dump that log automatically.
+
+# force US; sphinx errors are localized, and we're abusing grep.
+export LANG=en_US.UTF-8
+
+# capture stderr
+t=$(mktemp)
+if python -m sphinx.cmd.build -a -b "$mode" "$base/doc" "$output" 2>$t; then
+exit $?
+fi
+
+# extract the traceback path
+dump=$(grep -A1 'traceback has been saved in' "$t" | tail -n1)
+cat < "$t"
+echo
+if [ -z "$dump" ]; then
+echo "FAILED auto extracting the traceback file. you'll have to do it
manually"
+else
+echo
+echo "contents of $dump"
+echo
+cat < "$dump"
+rm "$t"
+fi
+
+exit 2
\ No newline at end of file
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: c3ae2a7c22dd688bbc67736576e8e824f85468ae
Author: Brian Harring gmail com>
AuthorDate: Mon Dec 1 00:48:25 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Dec 1 00:52:21 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c3ae2a7c
chore: pull in the reusable test.yml changes
Signed-off-by: Brian Harring gmail.com>
.github/workflows/release.yml | 138 +-
.github/workflows/test.yml| 19 +-
2 files changed, 112 insertions(+), 45 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f866d9aa..d36784d0 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,86 +1,138 @@
+
name: release
on:
push:
-branches: [deploy]
+branches: [release-test-pypi, release-test-github, release-test-full]
tags: [v*]
workflow_dispatch:
+
jobs:
- build-and-deploy:
+ build:
runs-on: ubuntu-latest
-environment: release
-
-permissions:
- id-token: write # Used to authenticate to PyPI via OIDC
-
- contents: write # Used to authenticate github release publish
+outputs:
+ release-artifact-id: ${{ steps.upload-release.outputs.artifact-id }}
+ wheel-artifact-id: ${{ steps.upload-wheel.outputs.artifact-id }}
+ artifact-runner: ${{ github.job }}
steps:
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: Reject any VCS dependencies
- shell: python
- continue-on-error: ${{ github.ref_type == 'branch' }}
- run: |
-import re, tomllib
-manifest = tomllib.load(open('pyproject.toml', 'rb'))
-deps = manifest['build-system']['requires']
-deps.extend(manifest['project']['dependencies'])
-if rejects := list(filter(re.compile(r'@[^+]+').search, deps)):
- rejects = " \n".join(sorted(rejects))
- raise Exception(f'VCS dependencies were detected in
[build-system]:\n {rejects}')
+ continue-on-error: ${{ github.ref_type == 'branch' && github.ref_name !=
'release-test-full' }}
+ uses: pkgcore/gh-actions/reject-python-vcs-deps@main
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.13"
+cache: 'pip'
+cache-dependency-path: pyproject.toml
- name: Install dependencies
run: |
python -m pip install --upgrade pip
-pip install build ".[test,doc]"
+pip install build ".[doc]"
-- name: Test with pytest
- env:
-PY_COLORS: 1 # forcibly enable pytest colors
- run: pytest
-
-- name: Build sdist
+- name: Build the release
run: |
-git clean -fxd
-make man
-make sdist
-
-- name: Build wheel
- run: make wheel
+make release
- name: Output dist file info
run: |
sha512sum dist/*
+echo ::group::Release contents
tar -ztf dist/*.tar.gz | sort
+echo ::endgroup::
+echo ::group::All generated content in dist
+find .
+echo ::endgroup::
+
+- name: Upload wheel
+ id: upload-wheel
+ uses: actions/upload-artifact@v5
+ with:
+name: wheel-release
+path: dist/*.whl
+if-no-files-found: error
-- uses: actions/upload-artifact@v4
+- name: Upload release source
+ id: upload-release
+ uses: actions/upload-artifact@v5
with:
-name: results
-path: dist/*
+name: release-source
+path: dist/*.tar.gz
+if-no-files-found: error
+
+ test:
+needs: [build]
+uses: ./.github/workflows/test.yml
+with:
+ release-artifact-id: ${{ needs.build.outputs.release-artifact-id }}
+ disable-format-check: true
+
+ publish:
+if: github.ref_type == 'tag'
+needs: [build, test]
+environment: release
+permissions:
+ id-token: write # Used to authenticate to PyPI via OIDC
+ contents: write # release uploads
+runs-on: ubuntu-latest
-- name: publish
- uses: pypa/gh-action-pypi-publish@release/v1
- if: startsWith(github.ref, 'refs/tags/')
+steps:
+- &common_download_artifacts
+ name: Download artifacts
+ uses: actions/download-artifact@v5
+ with:
+merge-multiple: true # store both in the root, not in named directories
+artifact-ids: ${{ needs.build.outputs.release-artifact-id }},${{
needs.build.outputs.wheel-artifact-id }}
+
+- name: Publish github source
+ uses: softprops/action-gh-release@v2
+ with:
+files: '*.tar.*'
+fail_on_unmatched_files: true
+
+- name: Publish to PyPi server
+ uses: pypa/gh-action-pypi-publish@release/v1.13
+ with:
+packages-dir: .
-- name: Create GitHub release
- uses: softprops/action-gh-release@v1
- if: startsWith(github.ref, 'refs/tags/')
+ test-publish:
+
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: b403a79dac1a654096070b4ef5c9b6843ee265d2
Author: Brian Harring gmail com>
AuthorDate: Fri Nov 28 22:18:47 2025 +
Commit: Brian Harring gmail com>
CommitDate: Fri Nov 28 22:18:47 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b403a79d
chore: Tool.main override to pass args/kwargs down
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/cli.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/cli.py b/src/pkgcheck/cli.py
index 55e9f30a..4556158d 100644
--- a/src/pkgcheck/cli.py
+++ b/src/pkgcheck/cli.py
@@ -14,10 +14,10 @@ from . import const
class Tool(commandline.Tool):
-def main(self):
+def main(self, *args, **kwargs):
# suppress all pkgcore log messages
logging.getLogger("pkgcore").setLevel(100)
-return super().main()
+return super().main(*args, **kwargs)
class ConfigParser(configparser.ConfigParser):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/scripts/
commit: 4d2ad0d8ea4051ff3361637aea7397bfc0f073a6
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 20:17:16 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 20:17:16 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4d2ad0d8
chore: standardize access to the offending source
Signed-off-by: Brian Harring gmail.com>
tests/scripts/test_pkgcheck_scan.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/scripts/test_pkgcheck_scan.py
b/tests/scripts/test_pkgcheck_scan.py
index 218efff7..4462d8e5 100644
--- a/tests/scripts/test_pkgcheck_scan.py
+++ b/tests/scripts/test_pkgcheck_scan.py
@@ -621,7 +621,7 @@ class TestPkgcheckScan:
if not callable(custom_handler):
pytest.fail(f"{custom_handler_path} handler isn't
invokable")
-custom_handler.__source_path__ = custom_handler_path #
pyright: ignore[reportFunctionMemberAccess]
+custom_handler.__source_file__ = custom_handler_path #
pyright: ignore[reportFunctionMemberAccess]
except FileNotFoundError:
pass
@@ -721,7 +721,7 @@ class TestPkgcheckScan:
except Exception as e:
pytest.fail(
-f"handler {data.custom_filter.__source_path__!r} threw an
exception: {e!r}" # type: ignore
+f"handler {data.custom_filter.__source_file__!r} threw an
exception: {e!r}" # type: ignore
)
def assert_same(sources, results, verbose=False):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/scripts/, testdata/data/repos/eclass/EclassCheck/EclassBashSyntaxError/
commit: c4994d68dc02a69456434e180d4b4a6e440a6307
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 18:12:34 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 19:46:16 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c4994d68
feat: test_pkg_scan: output debugging info, allow custom hooks
First: output the source path of the expected result since it's pain
trying to debug this if you're an external user. This states exactly
what file caused it. For example:
Second: add the ability to use python code to filter out results. This
can be used in parallel to the normal mechanism, and there are checks
to try and block accidental suppression across the testdata.
Custom handlers can be added as /handler.py with a 'handler' functor
with the signature of typing.Callable[[Result], bool].
Third: fix https://github.com/pkgcore/pkgcheck/issues/760 since it's
causative. Between bash 5.2 and 5.3 the error output improved,
can't just store a literal error json. Instead a custom bit
of python can be written to do the enforcement, which is added
here.
Fourth: add as much sanity checks against the handlers as I can think
of. Being it's python code, addition of a random new handler can lead
to missing/unknowns- thus wire things in a way to try maximally to
identify the offender so debugging failures like this are less of a
heavy lift.
Close: pkgcore/pkgcheck#760
Signed-off-by: Brian Harring gmail.com>
.../EclassBashSyntaxError/expected.json| 1 -
.../EclassCheck/EclassBashSyntaxError/handler.py | 19 +++
tests/scripts/test_pkgcheck_scan.py| 155 +++--
3 files changed, 134 insertions(+), 41 deletions(-)
diff --git
a/testdata/data/repos/eclass/EclassCheck/EclassBashSyntaxError/expected.json
b/testdata/data/repos/eclass/EclassCheck/EclassBashSyntaxError/expected.json
deleted file mode 100644
index 526338b9..
--- a/testdata/data/repos/eclass/EclassCheck/EclassBashSyntaxError/expected.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__class__": "EclassBashSyntaxError", "eclass": "bad", "lineno": "12",
"error": "syntax error: unexpected end of file"}
diff --git
a/testdata/data/repos/eclass/EclassCheck/EclassBashSyntaxError/handler.py
b/testdata/data/repos/eclass/EclassCheck/EclassBashSyntaxError/handler.py
new file mode 100644
index ..8c05e139
--- /dev/null
+++ b/testdata/data/repos/eclass/EclassCheck/EclassBashSyntaxError/handler.py
@@ -0,0 +1,19 @@
+import copy
+
+# TODO: rip this out and just integrate json registries properly
+from pkgcheck.reporters import JsonStream
+
+old_bash_result = list(
+JsonStream.from_iter(
+[
+'{"__class__": "EclassBashSyntaxError", "eclass": "bad", "lineno":
"12", "error": "syntax error: unexpected end of file"}'
+]
+)
+)[0]
+
+new_bash_result = copy.deepcopy(old_bash_result)
+new_bash_result.error = "syntax error: unexpected end of file from `{' command
on line 11" # pyright: ignore[reportAttributeAccessIssue]
+
+
+def handler(result) -> bool:
+return result == old_bash_result or result == new_bash_result
diff --git a/tests/scripts/test_pkgcheck_scan.py
b/tests/scripts/test_pkgcheck_scan.py
index b282d3da..218efff7 100644
--- a/tests/scripts/test_pkgcheck_scan.py
+++ b/tests/scripts/test_pkgcheck_scan.py
@@ -1,4 +1,5 @@
-import contextlib
+import importlib
+import importlib.machinery
import io
import os
import pathlib
@@ -594,13 +595,37 @@ class TestPkgcheckScan:
@dataclass
class _expected_data_result:
-expected: typing.Iterable[Result]
-expected_verbose: typing.Iterable[Result]
+expected: dict[Result, pathlib.Path]
+expected_verbose: dict[Result, pathlib.Path]
+custom_filter: typing.Callable[[Result], bool] | None
-def _load_expected_data(self, path: str) -> _expected_data_result:
+def _load_expected_data(self, base: pathlib.Path) -> _expected_data_result:
"""Return the set of result objects from a given json stream file."""
-def boilerplate(path, allow_missing: bool) -> list[Result]:
+custom_handler = None
+try:
+with (custom_handler_path := base / "handler.py").open() as f:
+# We can't import since it's not a valid python directory
layout, nor do
+# want to pollute the namespace.
+module = importlib.machinery.SourceFileLoader(
+"handler", str(custom_handler_path)
+).load_module()
+if (
+custom_handler := typing.cast(
+typing.Callable[[Result], bool], getattr(module,
"handler")
+)
+) is None:
+pytest.fail(
+f"custom python handler {custom_handler_path!r} lacks
the necessary handle function or list of handlers"
+)
+
+if not callable(custom_
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/scripts/, src/pkgcheck/
commit: 6d5010db0ea3a1700cd34d760e3b687ddd0fd942
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 17:16:34 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 17:26:40 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=6d5010db
chore: simplify test_scan_repo
This is mostly so it's simpler to deal with since this
was opaque.
Additionally add a missing raise chain since I managed to flush
out that gap while mangling this code.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/reporters.py | 4 +-
tests/scripts/test_pkgcheck_scan.py | 109 ++--
2 files changed, 70 insertions(+), 43 deletions(-)
diff --git a/src/pkgcheck/reporters.py b/src/pkgcheck/reporters.py
index 6171cf75..0a6119cf 100644
--- a/src/pkgcheck/reporters.py
+++ b/src/pkgcheck/reporters.py
@@ -345,8 +345,8 @@ class JsonStream(StreamReporter):
yield cls._create(**data)
except (json.decoder.JSONDecodeError, UnicodeDecodeError,
DeserializationError) as e:
raise DeserializationError("failed loading") from e
-except (KeyError, InvalidResult):
-raise DeserializationError("unknown result")
+except (KeyError, InvalidResult) as e:
+raise DeserializationError("unknown result") from e
def _consume_reports_generator(self) -> T_process_report:
while True:
diff --git a/tests/scripts/test_pkgcheck_scan.py
b/tests/scripts/test_pkgcheck_scan.py
index ca8f37e5..b282d3da 100644
--- a/tests/scripts/test_pkgcheck_scan.py
+++ b/tests/scripts/test_pkgcheck_scan.py
@@ -1,21 +1,20 @@
+import contextlib
+import io
import os
+import pathlib
import shlex
import shutil
import subprocess
-import tempfile
import textwrap
+import typing
from collections import defaultdict
+from dataclasses import dataclass
from functools import partial
from io import StringIO
from operator import attrgetter
from unittest.mock import patch
import pytest
-from pkgcheck import __title__ as project
-from pkgcheck import base
-from pkgcheck import checks as checks_mod
-from pkgcheck import const, objects, reporters, scan
-from pkgcheck.scripts import run
from pkgcore import const as pkgcore_const
from pkgcore.ebuild import atom, restricts
from pkgcore.restrictions import packages
@@ -24,6 +23,12 @@ from snakeoil.fileutils import touch
from snakeoil.formatters import PlainTextFormatter
from snakeoil.osutils import pjoin
+from pkgcheck import __title__ as project
+from pkgcheck import base, const, objects, reporters, scan
+from pkgcheck import checks as checks_mod
+from pkgcheck.results import Result
+from pkgcheck.scripts import run
+
from ..misc import Profile
@@ -587,63 +592,85 @@ class TestPkgcheckScan:
assert len(results) == len(results_set)
return results_set
-def _get_results(self, path: str):
+@dataclass
+class _expected_data_result:
+expected: typing.Iterable[Result]
+expected_verbose: typing.Iterable[Result]
+
+def _load_expected_data(self, path: str) -> _expected_data_result:
"""Return the set of result objects from a given json stream file."""
-try:
-with (self.repos_data / path).open() as f:
-return set(reporters.JsonStream.from_iter(f))
-except FileNotFoundError:
-return set()
-def _render_results(self, results, **kwargs):
+def boilerplate(path, allow_missing: bool) -> list[Result]:
+try:
+with path.open() as f:
+data = list(reporters.JsonStream.from_iter(f))
+
+uniqued = set(data)
+duplicates = [
+x for x in data if (False, None) == (x in uniqued,
uniqued.discard(x))
+]
+assert [] == duplicates, f"duplicate results exist in
{path!r}"
+
+# Remove this after cleaning the scan/fix logic up to not
force duplicate
+# renders, and instead just work with a result stream
directly.
+assert self._render_results(data), f"failed rendering
results {data!r}"
+return data
+
+except FileNotFoundError:
+if not allow_missing:
+raise
+return []
+
+expected_path = self.repos_data / path / "expected.json"
+
+expected = boilerplate(expected_path, False)
+assert expected, f"regular results must always exist if the file
exists: {expected_path}"
+
+expected_verbose_path = self.repos_data / path /
"expected-verbose.json"
+expected_verbose = boilerplate(expected_verbose_path, True)
+
+return self._expected_data_result(expected,
expected_verbose=expected_verbose)
+
+def _render_results(self, results, **kwargs) -> str:
"""Render a given set of result objects into their related st
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/scripts/
commit: f51053dd142dd50a053a0721d53634e21da58261
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 15:50:41 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 15:51:42 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=f51053dd
Revert "WIP"
This was never supposed to have been pushed
This reverts commit e5f5f3d588c93317bf86953eb249fd04a71f6003.
Signed-off-by: Brian Harring gmail.com>
tests/scripts/test_pkgcheck_scan.py | 63 ++---
1 file changed, 17 insertions(+), 46 deletions(-)
diff --git a/tests/scripts/test_pkgcheck_scan.py
b/tests/scripts/test_pkgcheck_scan.py
index 152e1e6a..ca8f37e5 100644
--- a/tests/scripts/test_pkgcheck_scan.py
+++ b/tests/scripts/test_pkgcheck_scan.py
@@ -1,12 +1,9 @@
-import importlib
-import io
import os
import shlex
import shutil
import subprocess
import tempfile
import textwrap
-import typing
from collections import defaultdict
from functools import partial
from io import StringIO
@@ -14,6 +11,11 @@ from operator import attrgetter
from unittest.mock import patch
import pytest
+from pkgcheck import __title__ as project
+from pkgcheck import base
+from pkgcheck import checks as checks_mod
+from pkgcheck import const, objects, reporters, scan
+from pkgcheck.scripts import run
from pkgcore import const as pkgcore_const
from pkgcore.ebuild import atom, restricts
from pkgcore.restrictions import packages
@@ -22,12 +24,6 @@ from snakeoil.fileutils import touch
from snakeoil.formatters import PlainTextFormatter
from snakeoil.osutils import pjoin
-from pkgcheck import __title__ as project
-from pkgcheck import base, const, objects, reporters, scan
-from pkgcheck import checks as checks_mod
-from pkgcheck.results import Result
-from pkgcheck.scripts import run
-
from ..misc import Profile
@@ -591,45 +587,23 @@ class TestPkgcheckScan:
assert len(results) == len(results_set)
return results_set
-def _load_expected_results(
-self, path: str
-) -> tuple[typing.Callable[[typing.Set[Result]], bool] | None,
set[Result]]:
+def _get_results(self, path: str):
"""Return the set of result objects from a given json stream file."""
-explicit = []
-custom = None
-expected_path = self.repos_data / path / "expected.json"
-custom_path = self.repos_data / path / "custom.py"
try:
-with expected_path.open() as f:
-explicit = list(reporters.JsonStream.from_iter(f))
+with (self.repos_data / path).open() as f:
+return set(reporters.JsonStream.from_iter(f))
except FileNotFoundError:
-pass
-except Exception as e:
-raise Exception(f"failed loading {expected_path}") from e
-try:
-with custom_path.open() as f:
-# we have to use eval since the import pathway isn't valid
import lookup
-module = eval(f.read())
-custom = getattr(module, "handle")
-except FileNotFoundError:
-pass
-except Exception as e:
-raise Exception(f"failed loading {custom_path}") from e
-s_explicit = set(explicit)
-assert len(s_explicit) == len(explicit), f"results of {expected_path}
are not unique"
-assert custom is not None or len(explicit), (
-f"{(self.repos_data / path)!r} contains no expected.json nor
custom.py"
-)
-return custom, set(explicit)
+return set()
-def _render_results(self, results, **kwargs) -> str:
+def _render_results(self, results, **kwargs):
"""Render a given set of result objects into their related string
form."""
-# with tempfile.TemporaryFile() as f:
-with io.BytesIO() as f:
+with tempfile.TemporaryFile() as f:
with reporters.FancyReporter(out=PlainTextFormatter(f), **kwargs)
as reporter:
for result in sorted(results):
reporter.report(result)
-return f.getvalue().decode()
+f.seek(0)
+output = f.read().decode()
+return output
@pytest.mark.parametrize("repo", repos)
def test_scan_repo(self, repo, tmp_path_factory):
@@ -641,16 +615,13 @@ class TestPkgcheckScan:
for check, keywords in self._checks[repo].items():
for keyword in keywords:
# verify the expected results were seen during the repo scans
-custom_check, expected_results = self._load_expected_results(
-f"{repo}/{check}/{keyword}"
-)
-if custom_check:
-custom_check(scan_results)
+expected_results =
self._get_results(f"{repo}/{check}/{keyword}/expected.json")
+assert expected_results, "regular results must always exist"
assert self._render_results(exp
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/, tests/
commit: e186b078ec03bf5cf109eb2d7c45116f1890ab0a
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 12:48:40 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 15:49:35 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e186b078
chore: add callback/multiplexing reporters, cleanup reporter annotations
Additionally, split streaming reporters out as a subclass derivative.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/objects.py | 3 +-
src/pkgcheck/reporters.py | 122 +-
tests/test_reporters.py | 38 +++
3 files changed, 129 insertions(+), 34 deletions(-)
diff --git a/src/pkgcheck/objects.py b/src/pkgcheck/objects.py
index 0c2a03d2..8143e819 100644
--- a/src/pkgcheck/objects.py
+++ b/src/pkgcheck/objects.py
@@ -42,6 +42,7 @@ def _find_classes(module, matching_cls, skip=()): # pragma:
no cover
and issubclass(cls, matching_cls)
and cls.__name__[0] != "_"
and cls not in skip
+and not inspect.isabstract(cls)
):
yield cls
@@ -197,4 +198,4 @@ class _ChecksLazyDict(_LazyDict):
KEYWORDS = _KeywordsLazyDict("KEYWORDS", ("checks", "results.Result"))
CHECKS = _ChecksLazyDict("CHECKS", ("checks", "checks.Check"))
-REPORTERS = _LazyDict("REPORTERS", ("reporters", "reporters.Reporter"))
+REPORTERS = _LazyDict("REPORTERS", ("reporters", "reporters.StreamReporter"))
diff --git a/src/pkgcheck/reporters.py b/src/pkgcheck/reporters.py
index 50345617..6171cf75 100644
--- a/src/pkgcheck/reporters.py
+++ b/src/pkgcheck/reporters.py
@@ -1,6 +1,7 @@
"""Basic result reporters."""
import abc
+import contextlib
import csv
import json
import typing
@@ -18,43 +19,41 @@ T_process_report: typing.TypeAlias = typing.Generator[None,
Result, typing.NoRet
T_report_func: typing.TypeAlias = typing.Callable[[Result], None]
+class ReportFuncShim:
+"""Compatibility shim while migrating endusers away from using .report()"""
+
+__slots__ = ("report",)
+
+def __init__(self, report: T_report_func) -> None:
+self.report = report
+
+def __call__(self, result: Result) -> None:
+self.report(result)
+
+
class Reporter(abc.ABC, immutable.Simple):
"""Generic result reporter."""
-__slots__ = ("report", "_current_generator", "out")
+__slots__ = ("report", "_current_generator")
priority: int # used by the config system
_current_generator: T_process_report | None
-def __init__(self, out: snakeoil_Formatter):
-"""Initialize
-
-:type out: L{snakeoil.formatters.Formatter}
-"""
-self.out = out
+def __init__(self) -> None:
self._current_generator = None
@immutable.Simple.__allow_mutation_wrapper__
-def __enter__(self) -> T_report_func:
-self.out.flush()
+def __enter__(self) -> ReportFuncShim:
self._current_generator = self._consume_reports_generator()
# start the generator
next(self._current_generator)
-
-# make a class so there's no intermediate frame relaying for __call__.
Optimization.
-class reporter:
-__slots__ = ()
-report: T_report_func = staticmethod(self._current_generator.send)
-__call__: T_report_func =
staticmethod(self._current_generator.send)
-
-return reporter()
+return ReportFuncShim(self._current_generator.send)
@immutable.Simple.__allow_mutation_wrapper__
-def __exit__(self, *exc_info):
+def __exit__(self, typ, value, traceback):
# shut down the generator so it can do any finalization
self._current_generator.close() # pyright:
ignore[reportOptionalMemberAccess]
self._current_generator = None
-self.out.flush()
@abc.abstractmethod
def _consume_reports_generator(self) -> T_process_report:
@@ -67,7 +66,28 @@ class Reporter(abc.ABC, immutable.Simple):
"""
-class StrReporter(Reporter):
+class StreamReporter(Reporter):
+__slots__ = ("out",)
+out: snakeoil_Formatter
+
+def __init__(self, out: snakeoil_Formatter):
+"""Initialize
+
+:type out: L{snakeoil.formatters.Formatter}
+"""
+super().__init__()
+self.out = out
+
+def __enter__(self) -> ReportFuncShim:
+self.out.flush()
+return super().__enter__()
+
+def __exit__(self, typ, value, traceback) -> None:
+super().__exit__(typ, value, traceback)
+self.out.flush()
+
+
+class StrReporter(StreamReporter):
"""Simple string reporter, pkgcheck-0.1 behaviour.
Example::
@@ -96,7 +116,7 @@ class StrReporter(Reporter):
self.out.stream.flush()
-class FancyReporter(Reporter):
+class FancyReporter(StreamReporter):
"""Colored output grouped by result scope.
Example::
@@ -140,7 +160,7 @@ class FancyReporter(Reporter):
self.out.stream.flus
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/
commit: 48dbd5fbb42edb4ac35cf07148bde2386c694b8a Author: Brian Harring gmail com> AuthorDate: Mon Nov 24 14:28:25 2025 + Commit: Brian Harring gmail com> CommitDate: Mon Nov 24 15:49:35 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=48dbd5fb chore: rewrite reporter tests to simplify This also catches the "FormatReporter is mutating instances" issue, but a proper fix to that one is to make results immutable. Signed-off-by: Brian Harring gmail.com> tests/test_reporters.py | 155 +--- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/tests/test_reporters.py b/tests/test_reporters.py index b8e245ec..911a0c92 100644 --- a/tests/test_reporters.py +++ b/tests/test_reporters.py @@ -1,7 +1,6 @@ import json import sys import typing -from functools import partial from textwrap import dedent import pytest @@ -13,46 +12,46 @@ from pkgcheck.checks import codingstyle, git, metadata, metadata_xml, pkgdir, pr class BaseReporter: -reporter_cls = reporters.Reporter - [email protected](autouse=True) -def _setup(self): -self.log_warning = profiles.ProfileWarning(Exception("profile warning")) -self.log_error = profiles.ProfileError(Exception("profile error")) -pkg = FakePkg("dev-libs/foo-0") -self.commit_result = git.InvalidCommitMessage("no commit message", commit="8d86269bb4c7") -self.category_result = metadata_xml.CatMissingMetadataXml("metadata.xml", pkg=pkg) -self.package_result = pkgdir.InvalidPN(("bar", "baz"), pkg=pkg) -self.versioned_result = metadata.BadFilename(("0.tar.gz", "foo.tar.gz"), pkg=pkg) -self.line_result = codingstyle.ReadonlyVariable("P", line="P=6", lineno=7, pkg=pkg) -self.lines_result = codingstyle.EbuildUnquotedVariable("D", lines=(5, 7), pkg=pkg) - -def mk_reporter(self, **kwargs) -> reporters.Reporter: -out = PlainTextFormatter(sys.stdout) -return self.reporter_cls(out, **kwargs) - -add_report_output = None +reporter_cls: type[reporters.Reporter] +add_report_output: typing.ClassVar[str] +pkg = FakePkg("dev-libs/foo-0") + +results: typing.Final = ( +profiles.ProfileWarning(Exception("profile warning")), +profiles.ProfileError(Exception("profile error")), +git.InvalidCommitMessage("no commit message", commit="8d86269bb4c7"), +metadata_xml.CatMissingMetadataXml("metadata.xml", pkg=pkg), +pkgdir.InvalidPN(("bar", "baz"), pkg=pkg), +metadata.BadFilename(("0.tar.gz", "foo.tar.gz"), pkg=pkg), +codingstyle.ReadonlyVariable("P", line="P=6", lineno=7, pkg=pkg), +codingstyle.EbuildUnquotedVariable("D", lines=(5, 7), pkg=pkg), +) -def test_add_report(self, capsys): -with self.mk_reporter() as reporter: -reporter.report(self.commit_result) -reporter.report(self.log_warning) -reporter.report(self.category_result) -reporter.report(self.package_result) -reporter.report(self.versioned_result) -reporter.report(self.line_result) -reporter.report(self.lines_result) +def mk_reporter(self, *args, **kwargs) -> reporters.Reporter: +out = PlainTextFormatter(sys.stdout) +return self.reporter_cls(out, *args, **kwargs) + +def assert_add_report(self, capsys, reporter: reporters.Reporter, expected_out: str) -> None: +if reporter is None: +reporter = self.mk_reporter() +with reporter as report: +for result in self.results: +report(result) out, err = capsys.readouterr() assert not err -assert out == self.add_report_output +assert out == expected_out + +def test_add_report(self, capsys): +self.assert_add_report(capsys, self.mk_reporter(), self.add_report_output) class TestStrReporter(BaseReporter): reporter_cls = reporters.StrReporter add_report_output = dedent( """\ -commit 8d86269bb4c7: no commit message profile warning +profile error +commit 8d86269bb4c7: no commit message dev-libs: category is missing metadata.xml dev-libs/foo: invalid package names: [ bar, baz ] dev-libs/foo-0: bad filenames: [ 0.tar.gz, foo.tar.gz ] @@ -66,11 +65,12 @@ class TestFancyReporter(BaseReporter): reporter_cls = reporters.FancyReporter add_report_output = dedent( """\ -commit - InvalidCommitMessage: commit 8d86269bb4c7: no commit message - profiles ProfileWarning: profile warning + ProfileError: profile error + +commit + InvalidCommitMessage: commit 8d86269bb4c7: no commit message dev-libs CatMissingMetadataXml: category is missing metadata.xml @@ -86,1
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/scripts/
commit: e5f5f3d588c93317bf86953eb249fd04a71f6003
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 14:31:38 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 15:49:35 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e5f5f3d5
WIP
Signed-off-by: Brian Harring gmail.com>
tests/scripts/test_pkgcheck_scan.py | 63 +++--
1 file changed, 46 insertions(+), 17 deletions(-)
diff --git a/tests/scripts/test_pkgcheck_scan.py
b/tests/scripts/test_pkgcheck_scan.py
index ca8f37e5..152e1e6a 100644
--- a/tests/scripts/test_pkgcheck_scan.py
+++ b/tests/scripts/test_pkgcheck_scan.py
@@ -1,9 +1,12 @@
+import importlib
+import io
import os
import shlex
import shutil
import subprocess
import tempfile
import textwrap
+import typing
from collections import defaultdict
from functools import partial
from io import StringIO
@@ -11,11 +14,6 @@ from operator import attrgetter
from unittest.mock import patch
import pytest
-from pkgcheck import __title__ as project
-from pkgcheck import base
-from pkgcheck import checks as checks_mod
-from pkgcheck import const, objects, reporters, scan
-from pkgcheck.scripts import run
from pkgcore import const as pkgcore_const
from pkgcore.ebuild import atom, restricts
from pkgcore.restrictions import packages
@@ -24,6 +22,12 @@ from snakeoil.fileutils import touch
from snakeoil.formatters import PlainTextFormatter
from snakeoil.osutils import pjoin
+from pkgcheck import __title__ as project
+from pkgcheck import base, const, objects, reporters, scan
+from pkgcheck import checks as checks_mod
+from pkgcheck.results import Result
+from pkgcheck.scripts import run
+
from ..misc import Profile
@@ -587,23 +591,45 @@ class TestPkgcheckScan:
assert len(results) == len(results_set)
return results_set
-def _get_results(self, path: str):
+def _load_expected_results(
+self, path: str
+) -> tuple[typing.Callable[[typing.Set[Result]], bool] | None,
set[Result]]:
"""Return the set of result objects from a given json stream file."""
+explicit = []
+custom = None
+expected_path = self.repos_data / path / "expected.json"
+custom_path = self.repos_data / path / "custom.py"
try:
-with (self.repos_data / path).open() as f:
-return set(reporters.JsonStream.from_iter(f))
+with expected_path.open() as f:
+explicit = list(reporters.JsonStream.from_iter(f))
except FileNotFoundError:
-return set()
+pass
+except Exception as e:
+raise Exception(f"failed loading {expected_path}") from e
+try:
+with custom_path.open() as f:
+# we have to use eval since the import pathway isn't valid
import lookup
+module = eval(f.read())
+custom = getattr(module, "handle")
+except FileNotFoundError:
+pass
+except Exception as e:
+raise Exception(f"failed loading {custom_path}") from e
+s_explicit = set(explicit)
+assert len(s_explicit) == len(explicit), f"results of {expected_path}
are not unique"
+assert custom is not None or len(explicit), (
+f"{(self.repos_data / path)!r} contains no expected.json nor
custom.py"
+)
+return custom, set(explicit)
-def _render_results(self, results, **kwargs):
+def _render_results(self, results, **kwargs) -> str:
"""Render a given set of result objects into their related string
form."""
-with tempfile.TemporaryFile() as f:
+# with tempfile.TemporaryFile() as f:
+with io.BytesIO() as f:
with reporters.FancyReporter(out=PlainTextFormatter(f), **kwargs)
as reporter:
for result in sorted(results):
reporter.report(result)
-f.seek(0)
-output = f.read().decode()
-return output
+return f.getvalue().decode()
@pytest.mark.parametrize("repo", repos)
def test_scan_repo(self, repo, tmp_path_factory):
@@ -615,13 +641,16 @@ class TestPkgcheckScan:
for check, keywords in self._checks[repo].items():
for keyword in keywords:
# verify the expected results were seen during the repo scans
-expected_results =
self._get_results(f"{repo}/{check}/{keyword}/expected.json")
-assert expected_results, "regular results must always exist"
+custom_check, expected_results = self._load_expected_results(
+f"{repo}/{check}/{keyword}"
+)
+if custom_check:
+custom_check(scan_results)
assert self._render_results(expected_results), "failed
rendering results"
results.update(expected_results)
# wh
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: 4589289e7689d2cd79c89df0e0da5d41e1b9a5d3 Author: Brian Harring gmail com> AuthorDate: Mon Nov 24 14:25:22 2025 + Commit: Brian Harring gmail com> CommitDate: Mon Nov 24 15:49:35 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4589289e fix: FormatReporter was mutating results. Somewhere along the way in python land, vars turned into a view- not a copy. Thus the problem. Signed-off-by: Brian Harring gmail.com> src/pkgcheck/reporters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkgcheck/reporters.py b/src/pkgcheck/reporters.py index 0abb675b..50345617 100644 --- a/src/pkgcheck/reporters.py +++ b/src/pkgcheck/reporters.py @@ -283,7 +283,7 @@ class FormatReporter(Reporter): while True: result = yield -attrs = vars(result) +attrs = vars(result).copy() attrs.update((k, getattr(result, k)) for k in properties) s = formatter.format(self.format_str, **attrs) # output strings with at least one valid expansion or non-whitespace character
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 7bde46c48215db885e83c42c7881d7ae8f422361
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 15:48:45 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 15:48:45 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7bde46c4
chore: add PKGCHECK_DEBUG_SDIST=1 support working on generated files
I've just been shoving a return in there, and one of these days I
was going to forget to remove it. Thus do this instead.
Signed-off-by: Brian Harring gmail.com>
py_build.py | 5 +
1 file changed, 5 insertions(+)
diff --git a/py_build.py b/py_build.py
index 0a3917a4..a5c4cf89 100644
--- a/py_build.py
+++ b/py_build.py
@@ -115,6 +115,11 @@ def create_generated_files():
write_files(cleanup_files)
yield
finally:
+if os.environ.get("PKGCHECK_DEBUG_SDIST"):
+print(
+"WARNING: not wiping cleanup files since PKGCHECK_DEBUG_SDIST
is set in the environment"
+)
+return
for path in cleanup_files:
try:
path.unlink()
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: b83522144da3cfd9ddc460c2cb1b8c5e5be51540
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 15:12:50 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 15:42:11 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b8352214
chore: make building explicitly wipe objects to ensure it's regenerated
Signed-off-by: Brian Harring gmail.com>
py_build.py | 13 -
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/py_build.py b/py_build.py
index f211eb45..0a3917a4 100644
--- a/py_build.py
+++ b/py_build.py
@@ -45,8 +45,16 @@ def write_const(cleanup_files):
)
+def get_objects_path():
+return Path.cwd() / "src/pkgcheck/_objects.py"
+
+
+def wipe_objects_on_disk():
+get_objects_path().unlink(missing_ok=True)
+
+
def write_objects(cleanup_files):
-cleanup_files.append(path := Path.cwd() / "src/pkgcheck/_objects.py")
+cleanup_files.append(path := get_objects_path())
print(f"writing objects to {path}")
with sys_path():
@@ -96,6 +104,9 @@ def write_files(cleanup_files):
@contextmanager
def create_generated_files():
+# the objects registry isn't hot reloadable, and it's fragile for wiping
+# it if it already loaded the _objects_file. Thus just shoot it first
thing.
+wipe_objects_on_disk()
cleanup_files = []
try:
write_verinfo(cleanup_files)
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: 9dcd936b604248b157ec478ee4c5808027fd9c71 Author: Brian Harring gmail com> AuthorDate: Sun Nov 23 18:29:48 2025 + Commit: Brian Harring gmail com> CommitDate: Sun Nov 23 18:29:48 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9dcd936b chore: log the bash vesrion for the tests Signed-off-by: Brian Harring gmail.com> .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b74e6393..10ce8c20 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,6 +32,9 @@ jobs: fail-fast: false steps: +- name: Bash version + run: bash --version + - name: Checkout code uses: actions/checkout@v4
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 1ea8d014bf496af2c9b6f6a146aa9503a61452a6
Author: Brian Harring gmail com>
AuthorDate: Sun Nov 23 19:24:48 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sun Nov 23 19:24:48 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=1ea8d014
chore: cleanup py_build naming a bit
Signed-off-by: Brian Harring gmail.com>
py_build.py | 12 +++-
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/py_build.py b/py_build.py
index 73c9e895..dd3d8f91 100644
--- a/py_build.py
+++ b/py_build.py
@@ -108,13 +108,15 @@ def write_files(cleanup_files):
path.write_text("\n".join(getattr(objects, obj)) + "\n")
-def prepare_pkgcheck():
+@contextmanager
+def create_generated_files():
cleanup_files = []
try:
write_verinfo(cleanup_files)
write_const(cleanup_files)
write_objects(cleanup_files)
write_files(cleanup_files)
+yield
finally:
for path in cleanup_files:
try:
@@ -125,8 +127,8 @@ def prepare_pkgcheck():
def build_wheel(wheel_directory, config_settings=None,
metadata_directory=None):
"""Builds a wheel, places it in wheel_directory"""
-prepare_pkgcheck()
-return buildapi.build_wheel(wheel_directory, config_settings,
metadata_directory)
+with create_generated_files():
+return buildapi.build_wheel(wheel_directory, config_settings,
metadata_directory)
build_editable = buildapi.build_editable
@@ -134,5 +136,5 @@ build_editable = buildapi.build_editable
def build_sdist(sdist_directory, config_settings=True):
"""Builds an sdist, places it in sdist_directory"""
-prepare_pkgcheck()
-return buildapi.build_sdist(sdist_directory, config_settings)
+with create_generated_files():
+return buildapi.build_sdist(sdist_directory, config_settings)
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /, src/pkgcheck/
commit: 70da309dbd45011c4947546ea592d2b7e6a5505b
Author: Brian Harring gmail com>
AuthorDate: Mon Nov 24 08:36:45 2025 +
Commit: Brian Harring gmail com>
CommitDate: Mon Nov 24 08:39:01 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=70da309d
chore: cleanup generated files to be readable
Break this out to use full import paths (eliminating the
possibility of collision of names- checks.attrs and reporters.attrs for
example).
Additionally write this in a way a human can read it, rather than
single giant lines. For example, it now writes this:
```
REPORTERS = (
('CsvReporter', pkgcheck.reporters.CsvReporter),
('FancyReporter', pkgcheck.reporters.FancyReporter),
('FlycheckReporter', pkgcheck.reporters.FlycheckReporter),
('FormatReporter', pkgcheck.reporters.FormatReporter),
('JsonReporter', pkgcheck.reporters.JsonReporter),
('JsonStream', pkgcheck.reporters.JsonStream),
('StrReporter', pkgcheck.reporters.StrReporter),
('XmlReporter', pkgcheck.reporters.XmlReporter),
)
```
rather than this:
```
REPORTERS = (('CsvReporter', reporters.CsvReporter), ('FancyReporter',
reporters.FancyReporter), ('FlycheckReporter', reporters.FlycheckReporter),
('FormatReporter', reporters.FormatReporter), ('JsonReporter',
reporters.JsonReporter), ('JsonStream', reporters.JsonStream), ('StrReporter',
reporters.StrReporter), ('XmlReporter', reporters.XmlReporter))
```
Finally, use fchmod since it's the correct 'secure' approach,
and since it's my muscle memory now.
Signed-off-by: Brian Harring gmail.com>
py_build.py | 52 ++---
src/pkgcheck/objects.py | 6 +++---
2 files changed, 22 insertions(+), 36 deletions(-)
diff --git a/py_build.py b/py_build.py
index dd3d8f91..f211eb45 100644
--- a/py_build.py
+++ b/py_build.py
@@ -1,5 +1,5 @@
+import os
import sys
-from collections import defaultdict
from contextlib import contextmanager
from pathlib import Path
from textwrap import dedent
@@ -30,7 +30,7 @@ def write_const(cleanup_files):
cleanup_files.append(path := Path.cwd() / "src/pkgcheck/_const.py")
print(f"writing path constants to {path}")
with path.open("w") as f:
-path.chmod(0o644)
+os.fchmod(f.fileno(), 0o644)
f.write(
dedent(
"""\
@@ -49,41 +49,27 @@ def write_objects(cleanup_files):
cleanup_files.append(path := Path.cwd() / "src/pkgcheck/_objects.py")
print(f"writing objects to {path}")
-class _kls:
-def __init__(self, module):
-self.module = module
-
-def __repr__(self):
-return self.module
-
with sys_path():
from pkgcheck import objects
-modules = defaultdict(set)
-objs = defaultdict(list)
-for obj in ("KEYWORDS", "CHECKS", "REPORTERS"):
-for name, cls in getattr(objects, obj).items():
-parent, module = cls.__module__.rsplit(".", 1)
-modules[parent].add(module)
-objs[obj].append((name, _kls(f"{module}.{name}")))
+targets = ["CHECKS", "KEYWORDS", "REPORTERS"]
+with path.open("w") as f:
+os.fchmod(f.fileno(), 0o644)
+modules = set()
+for cls_type in targets:
+modules.update(cls.__module__ for cls in getattr(objects,
cls_type).values())
+for module in sorted(modules):
+f.write(f"import {module}\n")
-keywords = tuple(objs["KEYWORDS"])
-checks = tuple(objs["CHECKS"])
-reporters = tuple(objs["REPORTERS"])
+for cls_type in targets:
+f.write("\n")
-with path.open("w") as f:
-path.chmod(0o644)
-for k, v in sorted(modules.items()):
-f.write(f"from {k} import {', '.join(sorted(v))}\n")
-f.write(
-dedent(
-f"""\
-KEYWORDS = {keywords}
-CHECKS = {checks}
-REPORTERS = {reporters}
-"""
-)
-)
+registry = getattr(objects, cls_type)
+
+f.write(f"{cls_type} = (\n")
+for name, cls in sorted(registry.items(), key=lambda x: x[0]):
+f.write(f" ({name!r}, {cls.__module__}.{cls.__name__}),\n")
+f.write(")\n")
def write_files(cleanup_files):
@@ -105,7 +91,7 @@ def write_files(cleanup_files):
for obj in ("KEYWORDS", "CHECKS", "REPORTERS"):
print(f"Generating {obj.lower()} list")
cleanup_files.append(path := dst / obj.lower())
-path.write_text("\n".join(getattr(objects, obj)) + "\n")
+path.write_text("\n".join(sorted(getattr(objects, obj))) + "\n")
@contextmanager
diff --git a/src/pkgcheck/objects.py b/src/pkgcheck/objects.py
index 51f2bed2..0c2a03d2 100644
--- a/src/pkgcheck/objects.py
+++ b/src/pkgcheck/objects.py
@@ -99,13 +99,13 @@ class _LazyDict(Mapping):
return self._dict[key]
def keys(self):
-return iter(self
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: db2aa27efecb46321d48a9959e1d6e00ab9536ae
Author: Brian Harring gmail com>
AuthorDate: Sun Nov 23 17:29:32 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sun Nov 23 17:29:32 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=db2aa27e
fix: sdist wasn't including the generated tarball releases.
They exist on gentoo systems due to the install pathway triggering
'build_wheel', but the source should be in the tarball also.
Signed-off-by: Brian Harring gmail.com>
py_build.py | 27 +--
1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/py_build.py b/py_build.py
index 5199fdd1..73c9e895 100644
--- a/py_build.py
+++ b/py_build.py
@@ -1,6 +1,5 @@
import sys
from collections import defaultdict
-from functools import partial
from contextlib import contextmanager
from pathlib import Path
from textwrap import dedent
@@ -109,16 +108,13 @@ def write_files(cleanup_files):
path.write_text("\n".join(getattr(objects, obj)) + "\n")
-def prepare_pkgcheck(callback, only_version: bool):
+def prepare_pkgcheck():
cleanup_files = []
try:
write_verinfo(cleanup_files)
-if not only_version:
-write_const(cleanup_files)
-write_objects(cleanup_files)
-write_files(cleanup_files)
-
-return callback()
+write_const(cleanup_files)
+write_objects(cleanup_files)
+write_files(cleanup_files)
finally:
for path in cleanup_files:
try:
@@ -129,19 +125,14 @@ def prepare_pkgcheck(callback, only_version: bool):
def build_wheel(wheel_directory, config_settings=None,
metadata_directory=None):
"""Builds a wheel, places it in wheel_directory"""
-callback = partial(buildapi.build_wheel, wheel_directory, config_settings,
metadata_directory)
-return prepare_pkgcheck(callback, only_version=False)
+prepare_pkgcheck()
+return buildapi.build_wheel(wheel_directory, config_settings,
metadata_directory)
-def build_editable(wheel_directory, config_settings=None,
metadata_directory=None):
-"""Builds an "editable" wheel, places it in wheel_directory"""
-callback = partial(
-buildapi.build_editable, wheel_directory, config_settings,
metadata_directory
-)
-return prepare_pkgcheck(callback, only_version=True)
+build_editable = buildapi.build_editable
def build_sdist(sdist_directory, config_settings=True):
"""Builds an sdist, places it in sdist_directory"""
-callback = partial(buildapi.build_sdist, sdist_directory, config_settings)
-return prepare_pkgcheck(callback, only_version=True)
+prepare_pkgcheck()
+return buildapi.build_sdist(sdist_directory, config_settings)
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/, /
commit: ccc283a0beffaa5d25e0eaaeea635963b1a958c3
Author: Brian Harring gmail com>
AuthorDate: Sun Nov 23 16:28:42 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sun Nov 23 16:44:07 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=ccc283a0
chore: gut api.keywords, it's not used. Drop lazy-object-proxy dep
Just use objects.KEYWORDS instead.
Signed-off-by: Brian Harring gmail.com>
pyproject.toml | 2 --
src/pkgcheck/api.py | 22 ++
2 files changed, 2 insertions(+), 22 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index f32e0584..fc08ddcd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,7 +3,6 @@ requires = [
"flit_core >=3.8,<4",
# repeat all normal runtime dependencies here
"chardet",
- "lazy-object-proxy",
"lxml",
"pathspec",
"tree-sitter~=0.25.0",
@@ -42,7 +41,6 @@ dynamic = ["version"]
dependencies = [
"chardet",
- "lazy-object-proxy",
"lxml",
"pathspec",
"tree-sitter~=0.25.0",
diff --git a/src/pkgcheck/api.py b/src/pkgcheck/api.py
index c704f8c6..a98ccc66 100644
--- a/src/pkgcheck/api.py
+++ b/src/pkgcheck/api.py
@@ -1,12 +1,10 @@
"""Implements pkgcheck API to be exported."""
-from functools import partial
+__all__ = ("scan",)
+
-import lazy_object_proxy
from snakeoil.contexts import patch
-from snakeoil.mappings import AttrAccessible
-from . import objects
from .base import PkgcheckException
@@ -42,19 +40,3 @@ def scan(args=None, /, *, base_args=None):
with patch("argparse.ArgumentParser.exit", parser_exit):
options = pkgcheck.argparser.parse_args(base_args + ["scan"] + args)
return Pipeline(options)
-
-
-def _keywords():
-"""Proxy to delay module imports until keywords are requested."""
-
-class Keywords(AttrAccessible):
-"""Mapping of keyword names to related result classes.
-
-Result classes are also accessible via accessing their keyword
-name as a attribute.
-"""
-
-return Keywords(objects.KEYWORDS)
-
-
-keywords = lazy_object_proxy.Proxy(partial(_keywords))
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: b353835f522b646df1ccca8547ebe7bf5c5c2623
Author: Brian Harring gmail com>
AuthorDate: Sun Nov 23 16:57:06 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sun Nov 23 16:57:06 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b353835f
chore: suppress VCS check for test release runs
Signed-off-by: Brian Harring gmail.com>
.github/workflows/release.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 799ca3dc..f866d9aa 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -22,6 +22,7 @@ jobs:
- name: Reject any VCS dependencies
shell: python
+ continue-on-error: ${{ github.ref_type == 'branch' }}
run: |
import re, tomllib
manifest = tomllib.load(open('pyproject.toml', 'rb'))
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/, src/pkgcheck/
commit: a90e8deaf125a0a92754b49ae6e08c22cc08f33d
Author: Brian Harring gmail com>
AuthorDate: Sun Nov 23 16:21:43 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sun Nov 23 16:21:43 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=a90e8dea
chore: don't inject all Result classes into pkgcheck/__init__.py
Nothing uses this- I assume it's a historical hold over, but these
are accessible via object.KEYWORDS, so folks should use that registry.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/__init__.py | 21 ++---
tests/test_api.py| 14 +-
2 files changed, 3 insertions(+), 32 deletions(-)
diff --git a/src/pkgcheck/__init__.py b/src/pkgcheck/__init__.py
index 7b1ba8dd..301838af 100644
--- a/src/pkgcheck/__init__.py
+++ b/src/pkgcheck/__init__.py
@@ -1,24 +1,7 @@
-from importlib import import_module as _import
-
-from .api import keywords, scan
+from .api import scan
from .base import PkgcheckException
from .results import Result
-__all__ = ("keywords", "scan", "PkgcheckException", "Result")
+__all__ = ("scan", "PkgcheckException", "Result")
__title__ = "pkgcheck"
__version__ = "0.10.38"
-
-
-def __getattr__(name):
-"""Provide import access to keyword classes."""
-if name in keywords:
-return keywords[name]
-
-try:
-return _import("." + name, __name__)
-except ImportError:
-raise AttributeError(f"module {__name__} has no attribute {name}")
-
-
-def __dir__():
-return sorted(__all__ + tuple(keywords))
diff --git a/tests/test_api.py b/tests/test_api.py
index cf546ee5..3c3faa97 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -3,8 +3,8 @@ import os
import signal
import pytest
+
from pkgcheck import PkgcheckException, scan
-from pkgcheck import objects
class TestScanApi:
@@ -24,18 +24,6 @@ class TestScanApi:
def test_no_base_args(self, repo):
assert [] == list(scan(self.scan_args + ["-r", repo.location]))
-def test_keyword_import(self):
-"""Keyword classes are importable from the top-level module."""
-from pkgcheck import NonsolvableDeps, Result
-
-assert issubclass(NonsolvableDeps, Result)
-
-def test_module_attributes(self):
-"""All keyword class names are shown for the top-level module."""
-import pkgcheck
-
-assert set(objects.KEYWORDS) < set(dir(pkgcheck))
-
def test_sigint_handling(self, repo):
"""Verify SIGINT is properly handled by the parallelized pipeline."""
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/scripts/
commit: 9495a65c34c4dc03085199a579372c803d0b0831
Author: Brian Harring gmail com>
AuthorDate: Sat Nov 22 18:08:47 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sat Nov 22 19:06:59 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9495a65c
chore: annotate Tool for output at least
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/scripts/pkgcheck_cache.py | 3 ++-
src/pkgcheck/scripts/pkgcheck_ci.py | 2 +-
src/pkgcheck/scripts/pkgcheck_replay.py | 3 ++-
src/pkgcheck/scripts/pkgcheck_scan.py | 3 ++-
src/pkgcheck/scripts/pkgcheck_show.py | 4 ++--
5 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/pkgcheck/scripts/pkgcheck_cache.py
b/src/pkgcheck/scripts/pkgcheck_cache.py
index 5787c65e..da323a30 100644
--- a/src/pkgcheck/scripts/pkgcheck_cache.py
+++ b/src/pkgcheck/scripts/pkgcheck_cache.py
@@ -1,5 +1,6 @@
import os
+import snakeoil.formatters
from snakeoil.cli import arghparse
from snakeoil.osutils import pjoin
@@ -68,7 +69,7 @@ def _validate_cache_args(parser, namespace):
@cache.bind_main_func
-def _cache(options, out, err):
+def _cache(options, out: snakeoil.formatters.PlainTextFormatter, _err):
if options.remove_cache:
cache_obj = CachedAddon(options)
cache_obj.remove_caches()
diff --git a/src/pkgcheck/scripts/pkgcheck_ci.py
b/src/pkgcheck/scripts/pkgcheck_ci.py
index 1a15f640..36023e80 100644
--- a/src/pkgcheck/scripts/pkgcheck_ci.py
+++ b/src/pkgcheck/scripts/pkgcheck_ci.py
@@ -28,7 +28,7 @@ ci.add_argument(
@ci.bind_main_func
-def _ci(options, out, err):
+def _ci(options, out: PlainTextFormatter, _err):
pipe = scan(options.args)
with reporters.FancyReporter(out) as reporter:
diff --git a/src/pkgcheck/scripts/pkgcheck_replay.py
b/src/pkgcheck/scripts/pkgcheck_replay.py
index 37e0024e..88cef2a4 100644
--- a/src/pkgcheck/scripts/pkgcheck_replay.py
+++ b/src/pkgcheck/scripts/pkgcheck_replay.py
@@ -1,3 +1,4 @@
+import snakeoil.formatters
from snakeoil.cli import arghparse
from .. import reporters
@@ -25,7 +26,7 @@ replay.add_argument(
@replay.bind_main_func
-def _replay(options, out, err):
+def _replay(options, out: snakeoil.formatters.PlainTextFormatter, _err):
processed = 0
with options.reporter(out) as reporter:
diff --git a/src/pkgcheck/scripts/pkgcheck_scan.py
b/src/pkgcheck/scripts/pkgcheck_scan.py
index f8cf1006..fe55ee6c 100644
--- a/src/pkgcheck/scripts/pkgcheck_scan.py
+++ b/src/pkgcheck/scripts/pkgcheck_scan.py
@@ -4,6 +4,7 @@ import shlex
from contextlib import ExitStack
from unittest.mock import patch
+import snakeoil.formatters
from pkgcore import const as pkgcore_const
from pkgcore.repository import errors as repo_errors
from pkgcore.repository import multiplex
@@ -516,7 +517,7 @@ def _determine_restrictions(namespace, attr):
@scan.bind_main_func
-def _scan(options, out, err):
+def _scan(options, out: snakeoil.formatters.PlainTextFormatter, _err):
with ExitStack() as stack:
report = stack.enter_context(options.reporter(out))
for c in options.pop("contexts"):
diff --git a/src/pkgcheck/scripts/pkgcheck_show.py
b/src/pkgcheck/scripts/pkgcheck_show.py
index 4ea20e34..3a2335a7 100644
--- a/src/pkgcheck/scripts/pkgcheck_show.py
+++ b/src/pkgcheck/scripts/pkgcheck_show.py
@@ -3,7 +3,7 @@ from collections import defaultdict
from operator import attrgetter
from snakeoil.cli import arghparse
-from snakeoil.formatters import decorate_forced_wrapping
+from snakeoil.formatters import PlainTextFormatter, decorate_forced_wrapping
from .. import base, objects
from ..addons.caches import CachedAddon
@@ -176,7 +176,7 @@ def display_reporters(out, options):
@show.bind_main_func
-def _show(options, out, err):
+def _show(options, out: PlainTextFormatter, _err):
if options.checks:
display_checks(out, options)
elif options.scopes:
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/scripts/
commit: 9f0937f9f92496fa16a25e1ab8de1274bdcf1c71
Author: Brian Harring gmail com>
AuthorDate: Sat Nov 22 16:49:29 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sat Nov 22 18:19:28 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9f0937f9
chore: correct context protocol usage.
The returned obj from __enter__ is what has to
be used in a context, not the class/func/whatever invoked
to get it.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/scripts/pkgcheck_scan.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/scripts/pkgcheck_scan.py
b/src/pkgcheck/scripts/pkgcheck_scan.py
index 7e554aab..d25a83de 100644
--- a/src/pkgcheck/scripts/pkgcheck_scan.py
+++ b/src/pkgcheck/scripts/pkgcheck_scan.py
@@ -518,8 +518,8 @@ def _determine_restrictions(namespace, attr):
@scan.bind_main_func
def _scan(options, out, err):
with ExitStack() as stack:
-reporter = options.reporter(out)
-for c in options.pop("contexts") + [reporter]:
+reporter = stack.enter_context(options.reporter(out))
+for c in options.pop("contexts"):
stack.enter_context(c)
pipe = Pipeline(options)
for result in pipe:
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/, src/pkgcheck/scripts/
commit: b96561bcb32bc769b4d883efd92f3173606748cf
Author: Brian Harring gmail com>
AuthorDate: Sat Nov 22 16:51:07 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sat Nov 22 18:19:28 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b96561bc
refactor: Fix ontology of reporters and annotations.
The base is an ABC, thus make it one. In parallel the consuming
generator should *not* be assumed to be reusable between contexts,
instead the context should open up that consumer each time.
This code effects that change, while eliminating _start and _finish
since overloading __enter__ and __exit__ do the same thing. Plus it's
only shitty xml that needs that.
Beyond this, annotations are threaded in so folks writing checks will
be warned if they try reporting a non Result derivative.
Via the cleanup above, .report was removed from Reporter instances. Instead
a context object is returned with *strictly* the signature that should be
used, and additionally has a hardwired __call__ to the send in addition
to the .report().
I'll convert all checks to use the __call__ method in later commits.
That sort of flow is both clearer, and it also is faster (__call__ doesn't
require __dict__ or __slots__ lookup in the method tables- it's a hardwired
field in PyObject).
Finally, make this all immutable to keep folks from poking at shit they
shouldn't.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/reporters.py | 113 +-
src/pkgcheck/scripts/pkgcheck_scan.py | 4 +-
2 files changed, 71 insertions(+), 46 deletions(-)
diff --git a/src/pkgcheck/reporters.py b/src/pkgcheck/reporters.py
index 87e8d136..0abb675b 100644
--- a/src/pkgcheck/reporters.py
+++ b/src/pkgcheck/reporters.py
@@ -1,49 +1,70 @@
"""Basic result reporters."""
+import abc
import csv
import json
+import typing
from collections import defaultdict
from string import Formatter
from xml.sax.saxutils import escape as xml_escape
-from snakeoil.decorators import coroutine
+from snakeoil.formatters import Formatter as snakeoil_Formatter
+from snakeoil.klass import immutable
from . import base
from .results import BaseLinesResult, InvalidResult, Result
+T_process_report: typing.TypeAlias = typing.Generator[None, Result,
typing.NoReturn]
+T_report_func: typing.TypeAlias = typing.Callable[[Result], None]
-class Reporter:
+
+class Reporter(abc.ABC, immutable.Simple):
"""Generic result reporter."""
-def __init__(self, out):
+__slots__ = ("report", "_current_generator", "out")
+
+priority: int # used by the config system
+_current_generator: T_process_report | None
+
+def __init__(self, out: snakeoil_Formatter):
"""Initialize
:type out: L{snakeoil.formatters.Formatter}
"""
self.out = out
+self._current_generator = None
+
[email protected].__allow_mutation_wrapper__
+def __enter__(self) -> T_report_func:
+self.out.flush()
+self._current_generator = self._consume_reports_generator()
+# start the generator
+next(self._current_generator)
+
+# make a class so there's no intermediate frame relaying for __call__.
Optimization.
+class reporter:
+__slots__ = ()
+report: T_report_func = staticmethod(self._current_generator.send)
+__call__: T_report_func =
staticmethod(self._current_generator.send)
+
+return reporter()
+
[email protected].__allow_mutation_wrapper__
+def __exit__(self, *exc_info):
+# shut down the generator so it can do any finalization
+self._current_generator.close() # pyright:
ignore[reportOptionalMemberAccess]
+self._current_generator = None
+self.out.flush()
+
[email protected]
+def _consume_reports_generator(self) -> T_process_report:
+"""
+This must be a generator consuming from yield to then do something
with Results
-# initialize result processing coroutines
-self.report = self._process_report().send
-
-def __enter__(self):
-self._start()
-return self
-
-def __exit__(self, *excinfo):
-self._finish()
-# flush output buffer
-self.out.stream.flush()
-
-@coroutine
-def _process_report(self):
-"""Render and output a report result.."""
-raise NotImplementedError(self._process_report)
-
-def _start(self):
-"""Initialize reporter output."""
-
-def _finish(self):
-"""Finalize reporter output."""
+Whilst the pattern may seem odd, this is a generator since Reporters
have to typically
+keep state between Results- a generator simplifies this. Simpler
code, and faster
+since it's just resuming a generator frame.
+"""
class StrReporter(Reporter):
@@ -56,10 +77,11 @@ class StrReporter(Reporter):
sys-apps/portage-2.1-r2: no change in 75 days
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/
commit: be6860c6f142ce816e5e598a31af7d77ed601942
Author: Brian Harring gmail com>
AuthorDate: Sat Nov 22 16:47:35 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sat Nov 22 18:19:28 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=be6860c6
chore: correct usage of JsonStream class methods.
Signed-off-by: Brian Harring gmail.com>
tests/test_reporters.py | 35 ++-
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/tests/test_reporters.py b/tests/test_reporters.py
index 8ffc93cf..b8e245ec 100644
--- a/tests/test_reporters.py
+++ b/tests/test_reporters.py
@@ -1,14 +1,16 @@
import json
import sys
+import typing
from functools import partial
from textwrap import dedent
import pytest
-from pkgcheck import base, reporters
-from pkgcheck.checks import codingstyle, git, metadata, metadata_xml, pkgdir,
profiles
from pkgcore.test.misc import FakePkg
from snakeoil.formatters import PlainTextFormatter
+from pkgcheck import base, reporters
+from pkgcheck.checks import codingstyle, git, metadata, metadata_xml, pkgdir,
profiles
+
class BaseReporter:
reporter_cls = reporters.Reporter
@@ -25,7 +27,7 @@ class BaseReporter:
self.line_result = codingstyle.ReadonlyVariable("P", line="P=6",
lineno=7, pkg=pkg)
self.lines_result = codingstyle.EbuildUnquotedVariable("D", lines=(5,
7), pkg=pkg)
-def mk_reporter(self, **kwargs):
+def mk_reporter(self, **kwargs) -> reporters.Reporter:
out = PlainTextFormatter(sys.stdout)
return self.reporter_cls(out, **kwargs)
@@ -175,22 +177,21 @@ class TestJsonStream(BaseReporter):
reporter.report(result)
out, err = capsys.readouterr()
assert not err
-deserialized_result = next(reporter.from_iter([out]))
-assert str(deserialized_result) == str(result)
+deserialized_result = next(self.reporter_cls.from_iter([out]))
+assert str(deserialized_result) == str(result)
def test_deserialize_error(self):
-with self.mk_reporter() as reporter:
-# deserializing non-result objects raises exception
-obj = reporter.to_json(["result"])
-with pytest.raises(reporters.DeserializationError, match="failed
loading"):
-next(reporter.from_iter([obj]))
-
-# deserializing mangled JSON result objects raises exception
-obj = reporter.to_json(self.versioned_result)
-del obj["__class__"]
-json_obj = json.dumps(obj)
-with pytest.raises(reporters.DeserializationError, match="unknown
result"):
-next(reporter.from_iter([json_obj]))
+# deserializing non-result objects raises exception
+obj = self.reporter_cls.to_json(["result"])
+with pytest.raises(reporters.DeserializationError, match="failed
loading"):
+next(self.reporter_cls.from_iter([obj]))
+
+# deserializing mangled JSON result objects raises exception
+obj = self.reporter_cls.to_json(self.versioned_result)
+del obj["__class__"]
+json_obj = json.dumps(obj)
+with pytest.raises(reporters.DeserializationError, match="unknown
result"):
+next(self.reporter_cls.from_iter([json_obj]))
class TestFlycheckReporter(BaseReporter):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/, src/pkgcheck/checks/, src/pkgcheck/addons/
commit: e40b7253f505d3d6c48743ab539e89d308e725d6
Author: Brian Harring gmail com>
AuthorDate: Sat Nov 22 10:28:39 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sat Nov 22 18:19:28 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e40b7253
chore: minor code cleanup
Roughly:
* replace `raise NotImplemented` with abc.ABC. The latter should
be used- it just didn't exist at the time.
* if a generator is a single `yield from`, just return the thing
being consumed. Drop the intermediate frame and yield traversing
the frames.
* Add some annotations as I'm going for things that caught my eye.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/addons/git.py | 18 +++--
src/pkgcheck/checks/network.py | 13
src/pkgcheck/sources.py| 45 ++
3 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/src/pkgcheck/addons/git.py b/src/pkgcheck/addons/git.py
index 302c5bc1..2c8f1094 100644
--- a/src/pkgcheck/addons/git.py
+++ b/src/pkgcheck/addons/git.py
@@ -1,16 +1,18 @@
"""Git specific support and addon."""
+import abc
import argparse
import os
import re
import shlex
import subprocess
+import tempfile
+import typing
from collections import defaultdict, deque
from dataclasses import dataclass
from datetime import datetime
from functools import partial
from itertools import takewhile
-import tempfile
from pathspec import PathSpec
from pkgcore.ebuild import cpv
@@ -142,7 +144,10 @@ class GitLog:
return line.rstrip()
-class _ParseGitRepo:
+T = typing.TypeVar("T")
+
+
+class _ParseGitRepo(typing.Generic[T], abc.ABC):
"""Generic iterator for custom git log output parsing support."""
# git command to run on the targeted repo
@@ -169,8 +174,9 @@ class _ParseGitRepo:
def __iter__(self):
return self
-def __next__(self):
-raise NotImplementedError(self.__next__)
[email protected]
+def __next__(self) -> T:
+pass
@property
def changes(self):
@@ -201,7 +207,7 @@ class _ParseGitRepo:
continue
-class GitRepoCommits(_ParseGitRepo):
+class GitRepoCommits(_ParseGitRepo["GitCommit"]):
"""Parse git log output into an iterator of commit objects."""
_format = (
@@ -229,7 +235,7 @@ class GitRepoCommits(_ParseGitRepo):
return GitCommit(commit_hash, commit_time, author, committer, message,
ImmutableDict(pkgs))
-class GitRepoPkgs(_ParseGitRepo):
+class GitRepoPkgs(_ParseGitRepo["GitPkgChange"]):
"""Parse git log output into an iterator of package change objects."""
_format = (
diff --git a/src/pkgcheck/checks/network.py b/src/pkgcheck/checks/network.py
index b26603b1..fb5e2fd1 100644
--- a/src/pkgcheck/checks/network.py
+++ b/src/pkgcheck/checks/network.py
@@ -1,8 +1,10 @@
"""Various checks that require network support."""
+import abc
import re
import socket
import traceback
+import typing
import urllib.request
from functools import partial
@@ -96,7 +98,7 @@ class RequestError(_RequestException):
"""Wrapper for generic requests exception."""
-class _UrlCheck(NetworkCheck):
+class _UrlCheck(abc.ABC, NetworkCheck):
"""Generic URL verification check requiring network support."""
_source = sources.LatestVersionRepoSource
@@ -194,9 +196,12 @@ class _UrlCheck(NetworkCheck):
result = result._create(**attrs, pkg=pkg)
self.results_q.put([result])
-def _get_urls(self, pkg):
-"""Get URLs to verify for a given package."""
-raise NotImplementedError
[email protected]
+def _get_urls(self, pkg) -> typing.Iterable[tuple[str, str]]:
+"""Get URLs to verify for a given package.
+
+yields pairs of (key, url)
+"""
def _schedule_check(self, func, attr, url, executor, futures, **kwargs):
"""Schedule verification method to run in a separate thread against a
given URL.
diff --git a/src/pkgcheck/sources.py b/src/pkgcheck/sources.py
index 2d0832cd..b94f9758 100644
--- a/src/pkgcheck/sources.py
+++ b/src/pkgcheck/sources.py
@@ -1,6 +1,9 @@
"""Custom package sources used for feeding checks."""
+import abc
+import itertools
import os
+import typing
from collections import defaultdict, deque
from collections.abc import Set
from dataclasses import dataclass
@@ -14,9 +17,9 @@ from snakeoil import klass
from snakeoil.osutils import listdir_files, pjoin
from . import addons, base
-from .bash import ParseTree
from .addons.eclass import Eclass, EclassAddon
from .addons.profiles import ProfileAddon, ProfileNode
+from .bash import ParseTree
from .packages import FilteredPkg, RawCPV, WrappedPkg
@@ -31,10 +34,10 @@ class Source:
self.source = source
def __iter__(self):
-yield from self.source
+return iter(self.source)
def itermatch(self, restrict, **kwargs):
-yield fr
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: 651b2aa75d57bac71a045dc5f3533d736ee90552
Author: Brian Harring gmail com>
AuthorDate: Sat Nov 22 09:56:23 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sat Nov 22 18:19:27 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=651b2aa7
chore: mark Result as abstract and annotate desc
This is both for enforcement of implementation expectations,
and for IDE/mypy.
Signed-off-by: Brian Harring gmail.com>
src/pkgcheck/results.py | 6 --
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/results.py b/src/pkgcheck/results.py
index 23d639fc..51686b38 100644
--- a/src/pkgcheck/results.py
+++ b/src/pkgcheck/results.py
@@ -1,5 +1,6 @@
"""Base classes for check results."""
+import abc
from functools import total_ordering
from pkgcore.ebuild import cpv
@@ -15,7 +16,7 @@ class InvalidResult(Exception):
@total_ordering
-class Result:
+class Result(abc.ABC):
"""Generic report result returned from a check."""
# all results are shown by default
@@ -37,7 +38,8 @@ class Result:
return f"{self.name}: {self.desc}"
@property
-def desc(self):
[email protected]
+def desc(self) -> str:
"""Result description."""
@property
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: aa8ae9a99369ea6bc599db08b9ae658d835d0fb5 Author: Brian Harring gmail com> AuthorDate: Sat Nov 22 18:19:15 2025 + Commit: Brian Harring gmail com> CommitDate: Sat Nov 22 18:19:27 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=aa8ae9a9 chore: cut over to ToT deps from pkgcore/snakeoil during refactoring Signed-off-by: Brian Harring gmail.com> pyproject.toml | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 28185765..f32e0584 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,8 +8,8 @@ requires = [ "pathspec", "tree-sitter~=0.25.0", "tree-sitter-bash~=0.23.1", - "snakeoil~=0.10.11", - "pkgcore~=0.12.30", + "snakeoil@git+https://github.com/pkgcore/snakeoil.git#master";, + "pkgcore@git+https://github.com/pkgcore/pkgcore.git#master";, ] build-backend = "py_build" backend-path = ["."] @@ -47,8 +47,8 @@ dependencies = [ "pathspec", "tree-sitter~=0.25.0", "tree-sitter-bash~=0.23.1", - "snakeoil~=0.10.11", - "pkgcore~=0.12.30", + "snakeoil@git+https://github.com/pkgcore/snakeoil.git#master";, + "pkgcore@git+https://github.com/pkgcore/pkgcore.git#master";, ] [project.optional-dependencies]
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/network/profiles/, src/pkgcheck/checks/, ...
commit: 134c1679f2a1a367ae7ab166f08d18ee65bfaf08
Author: Michał Górny gentoo org>
AuthorDate: Wed Sep 3 15:40:16 2025 +
Commit: Michał Górny gentoo org>
CommitDate: Sat Nov 22 07:12:17 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=134c1679
network: Add PyPIAttestationAvailableCheck
Part-of: https://github.com/pkgcore/pkgcheck/pull/757
Closes: https://github.com/pkgcore/pkgcheck/pull/757
Signed-off-by: Michał Górny gentoo.org>
src/pkgcheck/checks/network.py | 123 +
.../PyPIAttestationAvailable/expected.json | 1 +
.../PyPIAttestationAvailable/Manifest | 1 +
.../PyPIAttestationAvailable-0.ebuild | 7 ++
.../PyPIAttestationAvailable/responses.py | 11 ++
testdata/repos/network/eclass/pypi.eclass | 1 +
testdata/repos/network/profiles/categories | 1 +
7 files changed, 145 insertions(+)
diff --git a/src/pkgcheck/checks/network.py b/src/pkgcheck/checks/network.py
index 6ac29d49..b26603b1 100644
--- a/src/pkgcheck/checks/network.py
+++ b/src/pkgcheck/checks/network.py
@@ -1,5 +1,6 @@
"""Various checks that require network support."""
+import re
import socket
import traceback
import urllib.request
@@ -337,3 +338,125 @@ class MetadataUrlCheck(_UrlCheck):
def schedule(self, pkgs, *args, **kwargs):
super().schedule(pkgs[-1], *args, **kwargs)
+
+
+class PyPIAttestationAvailable(results.VersionResult, results.Info):
+"""PyPI attestation can be used for the package."""
+
+def __init__(self, filename, **kwargs):
+super().__init__(**kwargs)
+self.filename = filename
+
+@property
+def desc(self):
+return (
+f"PyPI attestation is available for distfile {self.filename}. "
+"Consider adding PYPI_VERIFY_REPO."
+)
+
+
+class PyPIAttestationAvailableCheck(NetworkCheck):
+"""Check for available PyPI attestations."""
+
+required_addons = (addons.UseAddon,)
+
+_source = sources.LatestVersionRepoSource
+
+known_results = frozenset(
+{
+PyPIAttestationAvailable,
+SSLCertificateError,
+}
+)
+
+pypi_uri_re = re.compile(
+
r"^https://files\.pythonhosted\.org/packages/source/./(?P.+?)/"
+r"(?P[^/]+-(?P[^/]+)\.tar\.gz)$"
+)
+
+def __init__(self, *args, use_addon, **kwargs):
+super().__init__(*args, **kwargs)
+self.fetch_filter = use_addon.get_filter("fetchables")
+
+def _provenance_check(self, filename, url, *, pkg):
+"""Check provenance URLs."""
+result = None
+try:
+self.session.head(url, allow_redirects=False)
+except RequestError as e:
+pass
+except SSLError as e:
+result = SSLCertificateError(attr, url, str(e), pkg=pkg)
+else:
+result = PyPIAttestationAvailable(filename, pkg=pkg)
+return result
+
+def task_done(self, pkg, filename, future):
+"""Determine the result of a given URL verification task."""
+exc = future.exception()
+if exc is not None:
+# traceback can't be pickled so serialize it
+tb = traceback.format_exc()
+# return exceptions that occurred in threads
+self.results_q.put(tb)
+return
+
+result = future.result()
+if result is not None:
+if pkg is not None:
+# recreate result object with different pkg target and attr
+attrs = result._attrs.copy()
+attrs["filename"] = filename
+result = result._create(**attrs, pkg=pkg)
+self.results_q.put([result])
+
+def _schedule_check(self, filename, url, executor, futures, **kwargs):
+"""Schedule verification method to run in a separate thread against a
given URL.
+
+Note that this tries to avoid hitting the network for the same URL
+twice using a mapping from requested URLs to future objects, adding
+result-checking callbacks to the futures of existing URLs.
+"""
+future = futures.get(url)
+if future is None:
+future = executor.submit(self._provenance_check, filename, url,
**kwargs)
+future.add_done_callback(partial(self.task_done, None, None))
+futures[url] = future
+else:
+future.add_done_callback(partial(self.task_done, kwargs["pkg"],
filename))
+
+def _get_urls(self, pkg):
+# ignore conditionals
+fetchables, _ = self.fetch_filter(
+(fetchable,),
+pkg,
+pkg.generate_fetchables(
+allow_missing_checksums=True, ignore_unknown_mirrors=True,
skip_default_mirrors=True
+),
+)
+for f in fetchables.keys():
+for url in f.uri:
+if m := self.pypi_uri_re.match(url):
+
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: 0c59e0c298945f2542d4c6174edce47318af317e
Author: Brian Harring gmail com>
AuthorDate: Sun Nov 9 12:54:05 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sun Nov 9 12:54:05 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=0c59e0c2
chore: add more deps to the VCS release check
Signed-off-by: Brian Harring gmail.com>
.github/workflows/release.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 545cc4f2..799ca3dc 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -24,7 +24,9 @@ jobs:
shell: python
run: |
import re, tomllib
-deps = tomllib.load(open('pyproject.toml',
'rb'))['build-system']['requires']
+manifest = tomllib.load(open('pyproject.toml', 'rb'))
+deps = manifest['build-system']['requires']
+deps.extend(manifest['project']['dependencies'])
if rejects := list(filter(re.compile(r'@[^+]+').search, deps)):
rejects = " \n".join(sorted(rejects))
raise Exception(f'VCS dependencies were detected in
[build-system]:\n {rejects}')
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/
commit: a88b192af72bd8f3c5c9076b47fa51b2afe2f662
Author: Brian Harring gmail com>
AuthorDate: Sun Nov 9 12:41:58 2025 +
Commit: Brian Harring gmail com>
CommitDate: Sun Nov 9 12:41:58 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=a88b192a
chore: add protection to release blocking any vcs dep
Signed-off-by: Brian Harring gmail.com>
.github/workflows/release.yml | 9 +
1 file changed, 9 insertions(+)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 457312ab..545cc4f2 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -20,6 +20,15 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
+- name: Reject any VCS dependencies
+ shell: python
+ run: |
+import re, tomllib
+deps = tomllib.load(open('pyproject.toml',
'rb'))['build-system']['requires']
+if rejects := list(filter(re.compile(r'@[^+]+').search, deps)):
+ rejects = " \n".join(sorted(rejects))
+ raise Exception(f'VCS dependencies were detected in
[build-system]:\n {rejects}')
+
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/data/repos/profiledir/RepoProfilesCheck/SystemSetMissingKeywords/, ...
commit: 35bc26108e0bd4b99e4d621622634665122bf1a8
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Aug 1 15:16:44 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Aug 1 15:16:44 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=35bc2610
SystemSetMissingKeywords: check for missing keywords in system set packages
Happened not long ago, that sys-apps/kbd was missing stable ppc and
ppc64 keywords, which caused the stage3 build to fail for 3 months.
This is something we can check easily, so let's do it.
This commit adds a new check to the RepoProfilesCheck class that
verifies that all packages in the system set have matching keywords
to the arches' profiles system set.
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/profiles.py| 36 ++
.../SystemSetMissingKeywords/expected.json | 1 +
.../SystemSetMissingKeywords/fix.patch | 8 +
.../repos/profiledir/profiles/default/packages | 1 +
4 files changed, 46 insertions(+)
diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index faf3c310..f0d7cfa0 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -552,6 +552,20 @@ class ArchesOutOfSync(results.ProfilesResult,
results.Error):
return f"'profiles/arches.desc' is out of sync with 'arch.list',
arch{es}: {arches}"
+class SystemSetMissingKeywords(results.PackageResult, results.Error):
+"""System set is missing keywords for some arches."""
+
+def __init__(self, missing_arches, **kwargs):
+super().__init__(**kwargs)
+self.missing_arches = tuple(missing_arches)
+
+@property
+def desc(self):
+arches = ", ".join(self.missing_arches)
+s = pluralism(self.missing_arches, plural="es")
+return f"part of @system set, but is missing keywords for arch{s}:
{arches}"
+
+
def dir_parents(path):
"""Yield all directory path parents excluding the root directory.
@@ -588,6 +602,7 @@ class RepoProfilesCheck(RepoCheck):
BannedProfileEapi,
DeprecatedProfileEapi,
ArchesOutOfSync,
+SystemSetMissingKeywords,
}
)
@@ -602,6 +617,25 @@ class RepoProfilesCheck(RepoCheck):
self.repo = self.options.target_repo
self.profiles_dir = self.repo.config.profiles_base
self.non_profile_dirs = profile_addon.non_profile_dirs
+self.arch_profiles = profile_addon.arch_profiles
+
+def _check_system_set(self):
+system_packages: dict[atom_cls, set[str]] = defaultdict(set)
+stable_arches = self.options.target_repo.config.arches_desc["stable"]
+for arch, profiles in self.arch_profiles.items():
+is_stable = arch in stable_arches
+if not is_stable:
+arch = "~" + arch
+for profile, _ in profiles:
+for pkg in profile.system:
+system_packages[pkg].add(arch)
+for pkg in profile.profile_set:
+system_packages[pkg].add(arch)
+for atom, required_arches in system_packages.items():
+if pkgs := self.repo.match(atom):
+keywords = frozenset().union(*(pkg.keywords for pkg in pkgs))
+if missing_arches := required_arches - keywords:
+yield SystemSetMissingKeywords(sorted(missing_arches),
pkg=atom)
def finish(self):
if unknown_category_dirs := set(self.repo.category_dirs).difference(
@@ -674,3 +708,5 @@ class RepoProfilesCheck(RepoCheck):
if arches_desc :=
frozenset().union(*self.repo.config.arches_desc.values()):
if arches_mis_sync := self.repo.known_arches ^ arches_desc:
yield ArchesOutOfSync(sorted(arches_mis_sync))
+
+yield from self._check_system_set()
diff --git
a/testdata/data/repos/profiledir/RepoProfilesCheck/SystemSetMissingKeywords/expected.json
b/testdata/data/repos/profiledir/RepoProfilesCheck/SystemSetMissingKeywords/expected.json
new file mode 100644
index ..fc673293
--- /dev/null
+++
b/testdata/data/repos/profiledir/RepoProfilesCheck/SystemSetMissingKeywords/expected.json
@@ -0,0 +1 @@
+{"__class__": "SystemSetMissingKeywords", "category": "cat", "package":
"pkg1", "missing_arches": ["amd64"]}
diff --git
a/testdata/data/repos/profiledir/RepoProfilesCheck/SystemSetMissingKeywords/fix.patch
b/testdata/data/repos/profiledir/RepoProfilesCheck/SystemSetMissingKeywords/fix.patch
new file mode 100644
index ..df361a94
--- /dev/null
+++
b/testdata/data/repos/profiledir/RepoProfilesCheck/SystemSetMissingKeywords/fix.patch
@@ -0,0 +1,8 @@
+diff -Naur profiledir/cat/pkg1/pkg1-0.ebuild fixed/cat/pkg1/pkg1-0.ebuild
+--- profiledir/cat/pkg1/pkg1-0.ebuild
fixed/cat/pkg1/pkg1-0.ebuild
+@@ -3,3 +3,4 @@ HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+ LICENSE="BSD"
+ SLOT="0"
+ IU
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/PythonCheck/EPyTestPluginsSuggestion/, ...
commit: 13e1d6c5c154883093efa94eceddf757695cb75f
Author: Michał Górny gentoo org>
AuthorDate: Sat Jul 26 06:59:24 2025 +
Commit: Michał Górny gentoo org>
CommitDate: Sat Jul 26 10:06:57 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=13e1d6c5
PythonCheck: suggest opportunities for EPYTEST_PLUGINS
Closes: https://github.com/pkgcore/pkgcheck/pull/754
Acked-by: Arthur Zamarin gentoo.org>
Signed-off-by: Michał Górny gentoo.org>
src/pkgcheck/checks/python.py | 28 +-
.../EPyTestPluginsSuggestion/expected.json | 2 ++
.../PythonCheck/EPyTestPluginsSuggestion/fix.patch | 23 ++
.../ShadowedEPyTestTimeout/expected.json | 2 +-
.../PythonCheck/ShadowedEPyTestTimeout/fix.patch | 3 ++-
.../EPyTestPluginsSuggestion-0.ebuild} | 3 +--
.../EPyTestPluginsSuggestion-1.ebuild} | 8 +--
.../EPyTestPluginsSuggestion-2.ebuild} | 4 ++--
.../ShadowedEPyTestTimeout-0.ebuild| 3 ++-
9 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 9a451c11..2ba590ad 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -294,6 +294,18 @@ class
RedundantPyTestDisablePluginAutoload(results.LineResult, results.Warning):
)
+class EPyTestPluginsSuggestion(results.VersionResult, results.Info):
+"""``EPYTEST_PLUGINS`` can be used to control plugins
+
+The package could benefit from using ``EPYTEST_PLUGINS`` to specify
+pytest plugins to be loaded.
+"""
+
+@property
+def desc(self):
+return "EPYTEST_PLUGINS can be used to control pytest plugins loaded"
+
+
class PythonCheck(Check):
"""Python eclass checks.
@@ -318,6 +330,7 @@ class PythonCheck(Check):
MisplacedEPyTestVar,
ShadowedEPyTestTimeout,
RedundantPyTestDisablePluginAutoload,
+EPyTestPluginsSuggestion,
}
)
@@ -510,12 +523,15 @@ class PythonCheck(Check):
line = pkg.node_str(var_node)
found_pytest_disable_plugin_autoload.append((line, lineno))
-# EAPI 9+ defaults to disabled autoloading, in earlier EAPIs
EPYTEST_PLUGINS does that.
-if (
-str(pkg.eapi) not in ("7", "8") or have_epytest_plugins
-) and not have_epytest_plugin_autoload:
-for line, lineno in found_pytest_disable_plugin_autoload:
-yield RedundantPyTestDisablePluginAutoload(line=line,
lineno=lineno + 1, pkg=pkg)
+if not have_epytest_plugin_autoload:
+# EAPI 9+ defaults to disabled autoloading, in earlier EAPIs
EPYTEST_PLUGINS does that.
+if str(pkg.eapi) not in ("7", "8") or have_epytest_plugins:
+for line, lineno in found_pytest_disable_plugin_autoload:
+yield RedundantPyTestDisablePluginAutoload(
+line=line, lineno=lineno + 1, pkg=pkg
+)
+else:
+yield EPyTestPluginsSuggestion(pkg=pkg)
@staticmethod
def _prepare_deps(deps: str):
diff --git
a/testdata/data/repos/python/PythonCheck/EPyTestPluginsSuggestion/expected.json
b/testdata/data/repos/python/PythonCheck/EPyTestPluginsSuggestion/expected.json
new file mode 100644
index ..0613c386
--- /dev/null
+++
b/testdata/data/repos/python/PythonCheck/EPyTestPluginsSuggestion/expected.json
@@ -0,0 +1,2 @@
+{"__class__": "EPyTestPluginsSuggestion", "category": "PythonCheck",
"package": "EPyTestPluginsSuggestion", "version": "0"}
+{"__class__": "EPyTestPluginsSuggestion", "category": "PythonCheck",
"package": "EPyTestPluginsSuggestion", "version": "1"}
diff --git
a/testdata/data/repos/python/PythonCheck/EPyTestPluginsSuggestion/fix.patch
b/testdata/data/repos/python/PythonCheck/EPyTestPluginsSuggestion/fix.patch
new file mode 100644
index ..121f4726
--- /dev/null
+++ b/testdata/data/repos/python/PythonCheck/EPyTestPluginsSuggestion/fix.patch
@@ -0,0 +1,23 @@
+diff '--color=auto' -Naur
python/PythonCheck/EPyTestPluginsSuggestion/EPyTestPluginsSuggestion-0.ebuild
fixed/PythonCheck/EPyTestPluginsSuggestion/EPyTestPluginsSuggestion-0.ebuild
+---
python/PythonCheck/EPyTestPluginsSuggestion/EPyTestPluginsSuggestion-0.ebuild
2025-07-26 08:47:01.430511740 +0200
fixed/PythonCheck/EPyTestPluginsSuggestion/EPyTestPluginsSuggestion-0.ebuild
2025-07-26 08:53:08.525943176 +0200
+@@ -10,4 +10,5 @@
+ LICENSE="BSD"
+ SLOT="0"
+
++EPYTEST_PLUGINS=()
+ distutils_enable_tests pytest
+diff '--color=auto' -Naur
python/PythonCheck/EPyTestPluginsSuggestion/EPyTestPluginsSuggestion-1.ebuild
fixed/PythonCheck/EPyTestPluginsSuggestion/EPyTestPluginsSuggestion-1.ebuild
+---
python/PythonCheck/EPyTestPluginsSuggestion/EPyTestPluginsSuggestion-1.ebuild
2025-07-26 08:46:54.907116335 +0200
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...
commit: eb95e06748bf39b6a708cfc9ae9e87afb13da9f2
Author: Michał Górny gentoo org>
AuthorDate: Sat Jul 26 05:37:12 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Jul 26 06:13:55 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=eb95e067
PythonCheck: check for redundant PYTEST_DISABLE_PLUGIN_AUTOLOAD
Signed-off-by: Michał Górny gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/753
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/python.py | 38 ++
.../expected.json | 1 +
.../RedundantPyTestDisablePluginAutoload/fix.patch | 12 +++
.../RedundantPyTestDisablePluginAutoload-0.ebuild | 20
.../RedundantPyTestDisablePluginAutoload-1.ebuild | 23 +
.../RedundantPyTestDisablePluginAutoload-2.ebuild | 22 +
6 files changed, 116 insertions(+)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 281df257..9a451c11 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -279,6 +279,21 @@ class ShadowedEPyTestTimeout(results.LineResult,
results.Warning):
)
+class RedundantPyTestDisablePluginAutoload(results.LineResult,
results.Warning):
+"""Redundant ``PYTEST_DISABLE_PLUGIN_AUTOLOAD``
+
+The package uses ``EPYTEST_PLUGINS`` to disable plugin autoloading already,
+so ``PYTEST_DISABLE_PLUGIN_AUTOLOAD`` is redundant.
+"""
+
+@property
+def desc(self):
+return (
+f"line {self.lineno}: PYTEST_DISABLE_PLUGIN_AUTOLOAD is redundant,
"
+"autoloading disabled via EPYTEST_PLUGINS already"
+)
+
+
class PythonCheck(Check):
"""Python eclass checks.
@@ -302,6 +317,7 @@ class PythonCheck(Check):
PythonMissingSCMDependency,
MisplacedEPyTestVar,
ShadowedEPyTestTimeout,
+RedundantPyTestDisablePluginAutoload,
}
)
@@ -472,12 +488,34 @@ class PythonCheck(Check):
line = pkg.node_str(var_node)
yield MisplacedEPyTestVar(var_name, line=line,
lineno=lineno + 1, pkg=pkg)
+have_epytest_plugins = False
+have_epytest_plugin_autoload = False
+found_pytest_disable_plugin_autoload = []
+
for var_node in
bash.var_assign_query.captures(pkg.tree.root_node).get("assign", ()):
var_name = pkg.node_str(var_node.child_by_field_name("name"))
if var_name == "EPYTEST_TIMEOUT":
lineno, _ = var_node.start_point
line = pkg.node_str(var_node)
yield ShadowedEPyTestTimeout(line=line, lineno=lineno + 1,
pkg=pkg)
+elif var_name == "EPYTEST_PLUGINS":
+have_epytest_plugins = True
+elif var_name == "EPYTEST_PLUGIN_AUTOLOAD":
+if value_node := var_node.child_by_field_name("value"):
+value = pkg.node_str(value_node)
+if value not in ('""', "''"):
+have_epytest_plugin_autoload = True
+elif var_name == "PYTEST_DISABLE_PLUGIN_AUTOLOAD":
+lineno, _ = var_node.start_point
+line = pkg.node_str(var_node)
+found_pytest_disable_plugin_autoload.append((line, lineno))
+
+# EAPI 9+ defaults to disabled autoloading, in earlier EAPIs
EPYTEST_PLUGINS does that.
+if (
+str(pkg.eapi) not in ("7", "8") or have_epytest_plugins
+) and not have_epytest_plugin_autoload:
+for line, lineno in found_pytest_disable_plugin_autoload:
+yield RedundantPyTestDisablePluginAutoload(line=line,
lineno=lineno + 1, pkg=pkg)
@staticmethod
def _prepare_deps(deps: str):
diff --git
a/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/expected.json
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/expected.json
new file mode 100644
index ..3929a193
--- /dev/null
+++
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/expected.json
@@ -0,0 +1 @@
+{"__class__": "RedundantPyTestDisablePluginAutoload", "category":
"PythonCheck", "package": "RedundantPyTestDisablePluginAutoload", "version":
"0", "line": "PYTEST_DISABLE_PLUGIN_AUTOLOAD=1", "lineno": 18}
diff --git
a/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/fix.patch
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/fix.patch
new file mode 100644
index ..e6265c4b
--- /dev/null
+++
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/fix.patch
@@ -0,0 +1,12 @@
+diff '--color=auto' -Naur
python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
fixed/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTes
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: 3462a8194390c83424a38d1569b3c2c59d9008fa
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Jul 26 06:13:30 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Jul 26 06:13:30 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=3462a819
start work on 0.10.38
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pkgcheck/__init__.py b/src/pkgcheck/__init__.py
index 46f02ecd..7b1ba8dd 100644
--- a/src/pkgcheck/__init__.py
+++ b/src/pkgcheck/__init__.py
@@ -6,7 +6,7 @@ from .results import Result
__all__ = ("keywords", "scan", "PkgcheckException", "Result")
__title__ = "pkgcheck"
-__version__ = "0.10.37"
+__version__ = "0.10.38"
def __getattr__(name):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 61bd8d3e2b1020a77449a96bf56c3a7542310702 Author: Arthur Zamarin gentoo org> AuthorDate: Thu Jul 24 19:13:06 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Thu Jul 24 19:13:06 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=61bd8d3e new release 0.10.37 Signed-off-by: Arthur Zamarin gentoo.org> NEWS.rst | 36 1 file changed, 36 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 4948b250..2fc47215 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,42 @@ Release Notes = +- +pkgcheck 0.10.37 (2025-07-24) +- + +- Dockerfile: install ``Gentoo::PerlMod::Version`` for PerlCheck (Arthur Zamarin) + +- Replace ``p7zip`` with ``7zip`` as the required decompressor for ``.7z`` files + (Ophelia de Sica, #744) + +- bash: update support for tree-sitter 0.25 (Arthur Zamarin) + +**New Checks:** + +- MisplacedEPyTestVar: check for misplaced ``EPYTEST_*`` variables (Michał + Górny, #739, #747) + +- ShadowedEPyTestTimeout: detect ``EPYTEST_TIMEOUT`` overriding user values + (Michał Górny, #740, #747) + +- MasterPackageClobbered: check for master packages clobbered by packages with + the same name in overlays (Michał Górny, #745, #746) + +**Check Updates:** + +- DependencyCheck: extend missing revision checks to ``<=`` and ``>`` operators + (Michał Górny, #743) + +- DependencyCheck: provide replacement suggestions (Michał Górny, #743) + +- python: allow use of ``PYTHON_SINGLE_USEDEP`` in ``python_has_version`` + (Alfred Wingate, #749) + +- StableRequestCheck: ignore "old" non-stable slots (Arthur Zamarin, #750) + +- TooManyCrates: warn only for the ::gentoo repository (Arthur Zamarin, #752) + - pkgcheck 0.10.36 (2025-06-13) -
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: a8a0d3e3fbd85efdd503de8c8712d4c152061660
Author: Arthur Zamarin gentoo org>
AuthorDate: Thu Jul 24 18:22:39 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Thu Jul 24 18:22:39 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=a8a0d3e3
TooManyCrates: warn only for ::gentoo
Resolves: https://github.com/pkgcore/pkgcheck/issues/752
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/rust.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pkgcheck/checks/rust.py b/src/pkgcheck/checks/rust.py
index 346ba412..7228924c 100644
--- a/src/pkgcheck/checks/rust.py
+++ b/src/pkgcheck/checks/rust.py
@@ -69,7 +69,7 @@ class RustCheck(Check):
row, _ = val_node.start_point
val_str = pkg.node_str(val_node).strip("'\"")
crates = val_str.split()
-if len(crates) > 300:
+if len(crates) > 300 and self.options.gentoo_repo:
yield TooManyCrates(count=len(crates), pkg=pkg)
for lineno, line in enumerate(crates, start=row + 1):
for token in line.split():
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /, src/pkgcheck/bash/
commit: 034010da930d5ae9086c9be6e2ee160f4cf5dbe3
Author: Arthur Zamarin gentoo org>
AuthorDate: Mon Jul 21 17:53:24 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Jul 21 17:53:24 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=034010da
bash: update support to tree-sitter~=0.25
Also add backward compatible code for tree-sitter < 0.25.
Signed-off-by: Arthur Zamarin gentoo.org>
pyproject.toml| 4 ++--
src/pkgcheck/bash/__init__.py | 16 +---
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 40e0b757..28185765 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,7 @@ requires = [
"lazy-object-proxy",
"lxml",
"pathspec",
- "tree-sitter~=0.24.0",
+ "tree-sitter~=0.25.0",
"tree-sitter-bash~=0.23.1",
"snakeoil~=0.10.11",
"pkgcore~=0.12.30",
@@ -45,7 +45,7 @@ dependencies = [
"lazy-object-proxy",
"lxml",
"pathspec",
- "tree-sitter~=0.24.0",
+ "tree-sitter~=0.25.0",
"tree-sitter-bash~=0.23.1",
"snakeoil~=0.10.11",
"pkgcore~=0.12.30",
diff --git a/src/pkgcheck/bash/__init__.py b/src/pkgcheck/bash/__init__.py
index 8cbacea0..0b5486b4 100644
--- a/src/pkgcheck/bash/__init__.py
+++ b/src/pkgcheck/bash/__init__.py
@@ -6,7 +6,17 @@ import tree_sitter_bash
from tree_sitter import Language, Parser, Query
lang = Language(tree_sitter_bash.language())
-query = lang.query
+
+try:
+from tree_sitter import QueryCursor
+
+def query(query_str: str) -> "QueryCursor":
+return QueryCursor(Query(lang, query_str))
+except ImportError: # tree-sitter < 0.25
+QueryCursor = Query
+query = lang.query
+
+
parser = Parser(language=lang)
# various parse tree queries
@@ -29,14 +39,14 @@ class ParseTree:
"""Return the ebuild string associated with a given parse tree node."""
return self.data[node.start_byte : node.end_byte].decode("utf8")
-def global_query(self, query: Query):
+def global_query(self, query: QueryCursor):
"""Run a given parse tree query returning only those nodes in global
scope."""
for x in self.tree.root_node.children:
# skip nodes in function scope
if x.type != "function_definition":
yield from chain.from_iterable(query.captures(x).values())
-def func_query(self, query: Query):
+def func_query(self, query: QueryCursor):
"""Run a given parse tree query returning only those nodes in function
scope."""
for x in self.tree.root_node.children:
# only return nodes in function scope
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/PythonCheck/MisplacedEPyTestVar/, src/pkgcheck/checks/
commit: 5beaecdbd744b5166929341cd05164b201ac2dbf
Author: Michał Górny gentoo org>
AuthorDate: Mon Jul 21 02:54:18 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Jul 21 05:49:11 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=5beaecdb
Fix `MisplacedEPyTestVar` check with no `distutils_enable_tests`
Reported by @parona-source.
Signed-off-by: Michał Górny gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/751
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/python.py | 6 +++--
.../MisplacedEPyTestVar-1.ebuild | 29 ++
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 71a25f91..281df257 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -441,6 +441,7 @@ class PythonCheck(Check):
def check_epytest_vars(self, pkg):
"""Check for incorrect use of EPYTEST_* variables"""
# TODO: do we want to check for multiple det calls? Quite unlikely.
+det_lineno = None
for node in pkg.global_query(bash.cmd_query):
name = pkg.node_str(node.child_by_field_name("name"))
if name != "distutils_enable_tests":
@@ -454,8 +455,9 @@ class PythonCheck(Check):
break
elif argument != "\\":
return
-else:
-return
+
+if det_lineno is None:
+return
for var_name, var_node in self._get_all_global_assignments(pkg):
# While not all variables affect distutils_enable_tests, make it
diff --git
a/testdata/repos/python/PythonCheck/MisplacedEPyTestVar/MisplacedEPyTestVar-1.ebuild
b/testdata/repos/python/PythonCheck/MisplacedEPyTestVar/MisplacedEPyTestVar-1.ebuild
new file mode 100644
index ..0e30f6c4
--- /dev/null
+++
b/testdata/repos/python/PythonCheck/MisplacedEPyTestVar/MisplacedEPyTestVar-1.ebuild
@@ -0,0 +1,29 @@
+EAPI=8
+
+DISTUTILS_USE_PEP517=flit
+PYTHON_COMPAT=( python3_10 )
+
+inherit distutils-r1
+
+DESCRIPTION="Ebuild with misplaced EPYTEST vars"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+EPYTEST_PLUGIN_AUTOLOAD=1
+EPYTEST_PLUGINS=( foo bar baz )
+EPYTEST_XDIST=1
+: ${EPYTEST_TIMEOUT:=180}
+
+EPYTEST_DESELECT=(
+ tests/test_foo.py::test_foo
+)
+EPYTEST_IGNORE=(
+ tests/test_bar.py
+)
+
+python_test() {
+ : ${EPYTEST_TIMEOUT:=300}
+ local EPYTEST_PLUGINS=( "${EPYTEST_PLUGINS[@]}" more )
+ EPYTEST_XDIST= epytest
+}
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: d77661b7e3428e6c11150eee92c305517ed160ff
Author: Arthur Zamarin gentoo org>
AuthorDate: Sun Jul 20 16:54:15 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sun Jul 20 16:54:15 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d77661b7
StableRequestCheck: ignore "old" non-stable slots
if a slot has no stable packages, and all its packages are older than
the oldest stable package, then we can ignore it for the purposes of
stabilization requests.
Resolves: https://github.com/pkgcore/pkgcheck/issues/750
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/stablereq.py | 86 +++-
1 file changed, 50 insertions(+), 36 deletions(-)
diff --git a/src/pkgcheck/checks/stablereq.py b/src/pkgcheck/checks/stablereq.py
index be8e2c7f..4bb88a6d 100644
--- a/src/pkgcheck/checks/stablereq.py
+++ b/src/pkgcheck/checks/stablereq.py
@@ -64,40 +64,54 @@ class StableRequestCheck(GentooRepoCheck):
def feed(self, pkgset):
pkg_slotted = defaultdict(list)
-pkg_keywords = set()
+stable_pkg_keywords = set()
+stable_slots = set()
+oldest_stable = None
# ebuilds without keywords are ignored
-for pkg in (x for x in pkgset if x.keywords):
-pkg_slotted[pkg.slot].append(pkg)
-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)
-for pkg in reversed(pkgs):
-# stop if stable keywords are found
-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:
-# probably an uncommitted, local ebuild... skipping
-continue
-
-added = datetime.fromtimestamp(match.time)
-days_old = (self.today - added).days
-if days_old >= self.options.stable_time:
-pkg_stable_keywords = {x.lstrip("~") for x in
pkg.keywords}
-if stable_slot_keywords:
-keywords =
stable_slot_keywords.intersection(pkg_stable_keywords)
-else:
-keywords =
stable_pkg_keywords.intersection(pkg_stable_keywords)
-keywords = sorted("~" + x for x in keywords)
-yield StableRequest(slot, keywords, days_old, pkg=pkg)
-break
+for pkg in pkgset:
+if pkg.keywords:
+pkg_slotted[pkg.slot].append(pkg)
+stable_keywords = {x for x in pkg.keywords if x[0] not in
{"-", "~"}}
+if stable_keywords:
+stable_slots.add(pkg.slot)
+if oldest_stable is None:
+oldest_stable = pkg
+stable_pkg_keywords.update(stable_keywords)
+
+if not stable_pkg_keywords:
+return
+
+keyworded_pkg_keywords = {"~" + x for x in stable_pkg_keywords}
+for slot, pkgs in sorted(pkg_slotted.items()):
+if slot not in stable_slots and max(pkgs) < oldest_stable:
+# skip slots that are not stable and all their pkgs are older
than the oldest stable
+continue
+slot_keywords = set().union(*(pkg.keywords for pkg in pkgs))
+stable_slot_keywords =
slot_keywords.intersection(stable_pkg_keywords)
+
+for pkg in reversed(pkgs):
+# stop if stable keywords are found
+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:
+# probably an uncommitted, local ebuild... skipping
+continue
+
+added = datetime.fromtimestamp(match.time)
+days_old = (self.today - added).days
+if days_old >= self.options.stable_time:
+pkg_stable_keywords = {x.lstrip("~") for x in pkg.keyw
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/PythonCheck/PythonHasVersionUsage/, src/pkgcheck/checks/
commit: 7ea8eeba336ead2cb94f4394497f0414d2e3d71b
Author: Alfred Wingate protonmail com>
AuthorDate: Wed Jul 16 12:38:19 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sun Jul 20 16:17:09 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=7ea8eeba
python: Allow use of PYTHON_SINGLE_USEDEP in python_has_version
Signed-off-by: Alfred Wingate protonmail.com>
Closes: https://github.com/pkgcore/pkgcheck/pull/749
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/python.py | 12 +--
.../PythonHasVersionUsage-2.ebuild | 25 ++
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 39fbe55e..71a25f91 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -33,7 +33,7 @@ PYPI_WHEEL_URI_RE = re.compile(
re.escape(PYPI_URI_PREFIX) + r"(?P[^/]+)/[^/]/(?P[^/]+)/"
r"(?P[^/-]+)-(?P[^/-]+)-(?P=pytag)-(?P[^/]+)\.whl$"
)
-USE_FLAGS_PYTHON_USEDEP = re.compile(r"\[(.+,)?\$\{PYTHON_USEDEP\}(,.+)?\]$")
+USE_FLAGS_PYTHON_USEDEP =
re.compile(r"\[(.+,)?\$\{PYTHON_(SINGLE_)?USEDEP\}(,.+)?\]$")
PROJECT_SYMBOL_NORMALIZE_RE = re.compile(r"[-_.]+")
@@ -168,20 +168,18 @@ class PythonHasVersionUsage(results.LinesResult,
results.Style):
class PythonHasVersionMissingPythonUseDep(results.LineResult, results.Error):
"""Package calls ``python_has_version`` or ``has_version`` without
-``[${PYTHON_USEDEP}]`` suffix.
+``[${PYTHON_USEDEP}]`` or ``[${PYTHON_SINGLE_USEDEP}]`` suffix.
All calls to ``python_has_version`` or ``has_version`` inside
-``python_check_deps`` should contain ``[${PYTHON_USEDEP}]`` suffix for the
-dependency argument [#]_.
+``python_check_deps`` should contain ``[${PYTHON_USEDEP}]`` or
``[${PYTHON_SINGLE_USEDEP}]``
+suffix for the dependency argument [#]_.
.. [#] https://projects.gentoo.org/python/guide/any.html#dependencies
"""
@property
def desc(self):
-return (
-f"line: {self.lineno}: missing [${{PYTHON_USEDEP}}] suffix for
argument {self.line!r}"
-)
+return f"line: {self.lineno}: missing [${{PYTHON_USEDEP}}] or
[${{PYTHON_SINGLE_USEDEP}}] suffix for argument {self.line!r}"
class PythonAnyMismatchedUseHasVersionCheck(results.VersionResult,
results.Warning):
diff --git
a/testdata/repos/python/PythonCheck/PythonHasVersionUsage/PythonHasVersionUsage-2.ebuild
b/testdata/repos/python/PythonCheck/PythonHasVersionUsage/PythonHasVersionUsage-2.ebuild
new file mode 100644
index ..5da6ad03
--- /dev/null
+++
b/testdata/repos/python/PythonCheck/PythonHasVersionUsage/PythonHasVersionUsage-2.ebuild
@@ -0,0 +1,25 @@
+# Copyright 2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+PYTHON_COMPAT=( pypy3.11 python3_10 )
+
+inherit python-any-r1
+
+DESCRIPTION="Ebuild that uses has_version with PYTHON_SINGLE_USEDEP"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+
+LICENSE="BSD"
+SLOT="0"
+
+DEPEND="${PYTHON_DEPS}"
+BDEPEND="${PYTHON_DEPS}
+ $(python_gen_any_dep '
+ dev-util/babeltrace:2[python,${PYTHON_SINGLE_USEDEP}]
+ ')
+"
+
+python_check_deps() {
+ python_has_version -b
"dev-util/babeltrace:2[python,${PYTHON_SINGLE_USEDEP}]"
+}
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, ...
commit: d5f89e290c66a95a326a59b6103a2239dd08eedc
Author: Michał Górny gentoo org>
AuthorDate: Sat Jul 12 13:45:49 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Tue Jul 15 18:30:39 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d5f89e29
Add a check for clobbered packages in overlays
Add a check that reports if a given package clobbers a package from
the master repository. Since this only applies to some repositores
(e.g. ::guru), it is optional (disabled by default).
Closes: https://github.com/pkgcore/pkgcheck/issues/745
Co-authored-by: Arthur Zamarin gentoo.org>
Signed-off-by: Michał Górny gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/746
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/overlays.py| 36 +-
.../MasterPackageClobbered/expected.json | 1 +
.../MasterPackageClobbered-1.ebuild| 4 +++
.../MasterPackageClobberedMasked-1.ebuild | 4 +++
testdata/repos/overlay/profiles/categories | 1 +
.../MasterPackageClobbered-0.ebuild| 4 +++
.../MasterPackageClobberedMasked-0.ebuild | 4 +++
testdata/repos/overlayed/profiles/categories | 1 +
testdata/repos/overlayed/profiles/package.mask | 3 ++
9 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/src/pkgcheck/checks/overlays.py b/src/pkgcheck/checks/overlays.py
index cbe3d5b6..f44b2aa6 100644
--- a/src/pkgcheck/checks/overlays.py
+++ b/src/pkgcheck/checks/overlays.py
@@ -2,7 +2,7 @@ from snakeoil.sequences import iflatten_instance
from snakeoil.strings import pluralism
from .. import results, sources
-from . import MirrorsCheck, OptionalCheck, OverlayRepoCheck, RepoCheck
+from . import Check, MirrorsCheck, OptionalCheck, OverlayRepoCheck, RepoCheck
class UnusedInMastersLicenses(results.VersionResult, results.Warning):
@@ -132,3 +132,37 @@ class UnusedInMastersCheck(MirrorsCheck, OverlayRepoCheck,
RepoCheck, OptionalCh
non_local_use = pkg.iuse_stripped.difference(pkg.local_use.keys())
if flags := self.unused_master_flags.intersection(non_local_use):
yield UnusedInMastersGlobalUse(sorted(flags), pkg=pkg)
+
+
+class MasterPackageClobbered(results.PackageResult, results.Error):
+"""Package in master is clobbered by package in overlay.
+
+A repository (such as ``::guru``) that is supposed to only provide
+additional packages to its masters (``::gentoo``), provides a package
+that is found in its master, therefore potentially clobbering it.
+"""
+
+def __init__(self, repository: str, **kwarg):
+super().__init__(**kwarg)
+self.repository = repository
+
+@property
+def desc(self):
+return f"package from repository ::{self.repository} clobbered"
+
+
+class MasterPackageClobberedCheck(OverlayRepoCheck, OptionalCheck):
+"""Detect clobbering packages from master."""
+
+_source = sources.PackageRepoSource
+known_results = frozenset({MasterPackageClobbered})
+
+def feed(self, pkgset):
+pkg = pkgset[0]
+for repo in self.options.target_repo.masters:
+# Trigger only if at least one non-p.masked package matches,
+# to cover for packages being moved to subordinate repo.
+for master_pkg in repo.itermatch(pkg.unversioned_atom):
+if not repo.masked.match(master_pkg):
+yield MasterPackageClobbered(str(repo), pkg=pkg)
+break
diff --git
a/testdata/data/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobbered/expected.json
b/testdata/data/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobbered/expected.json
new file mode 100644
index ..25549996
--- /dev/null
+++
b/testdata/data/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobbered/expected.json
@@ -0,0 +1 @@
+{"__class__": "MasterPackageClobbered", "category":
"MasterPackageClobberedCheck", "package": "MasterPackageClobbered",
"repository": "overlayed"}
diff --git
a/testdata/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobbered/MasterPackageClobbered-1.ebuild
b/testdata/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobbered/MasterPackageClobbered-1.ebuild
new file mode 100644
index ..d89cba09
--- /dev/null
+++
b/testdata/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobbered/MasterPackageClobbered-1.ebuild
@@ -0,0 +1,4 @@
+DESCRIPTION="Ebuild clobbered by overlay"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
diff --git
a/testdata/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobberedMasked/MasterPackageClobberedMasked-1.ebuild
b/testdata/repos/overlay/MasterPackageClobberedCheck/MasterPackageClobberedMasked/MasterPackageClobberedMasked-1.ebuild
new file mode 100644
index ..d89cba09
--- /dev/null
+++
b/testdata/repos/overlay/MasterP
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 2c0530c090c8c6169b8164f9e795f772f48dbd1e
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Jul 12 19:23:42 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Tue Jul 15 18:08:23 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=2c0530c0
Dockerfile: install Gentoo::PerlMod::Version for PerlCheck
Signed-off-by: Arthur Zamarin gentoo.org>
Dockerfile | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Dockerfile b/Dockerfile
index 1c6c719f..bafd6060 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,9 @@
FROM python:3-slim
ARG PKGCHECK_VERSION
-RUN apt-get update && apt-get install -y git zstd && \
+RUN apt-get update && apt-get install -y --no-install-recommends git zstd
cpanminus make && \
+cpanm --quiet --notest Gentoo::PerlMod::Version && \
+apt remove --autoremove -y make cpanminus && \
rm -rf /var/lib/apt/lists/ /var/cache/apt /var/cache/dpkg && \
pip install pkgcheck==${PKGCHECK_VERSION} setuptools requests && \
pip cache purge
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/PythonCheck/MisplacedEPyTestVar/, ...
commit: 6806341926ca8490a09cc2d3726478c68858ec93
Author: Michał Górny gentoo org>
AuthorDate: Sat Jul 12 15:02:40 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Tue Jul 15 18:08:08 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=68063419
python: Add a check for misplaced `EPYTEST_*` variables
Add a check for `EPYTEST_*` variables being declared after calling
`distutils_enable_tests`, so they don't affect it. This catches only
global scope use, as it is valid to override them in function scope.
Since using `${var:=...}` assignment is also valid, hack a quick method
to handle them as well.
Closes: https://github.com/pkgcore/pkgcheck/issues/739
Signed-off-by: Michał Górny gentoo.org>
Part-of: https://github.com/pkgcore/pkgcheck/pull/747
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/bash/__init__.py | 1 +
src/pkgcheck/checks/python.py | 72 +-
.../PythonCheck/MisplacedEPyTestVar/expected.json | 4 ++
.../PythonCheck/MisplacedEPyTestVar/fix.patch | 19 ++
.../MisplacedEPyTestVar-0.ebuild | 31 ++
testdata/repos/python/eclass/distutils-r1.eclass | 2 +
6 files changed, 127 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/bash/__init__.py b/src/pkgcheck/bash/__init__.py
index 1b47881c..8cbacea0 100644
--- a/src/pkgcheck/bash/__init__.py
+++ b/src/pkgcheck/bash/__init__.py
@@ -13,6 +13,7 @@ parser = Parser(language=lang)
cmd_query = query("(command) @call")
func_query = query("(function_definition) @func")
var_assign_query = query("(variable_assignment) @assign")
+var_expansion_query = query("(expansion) @exp")
var_query = query("(variable_name) @var")
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index bc5c71bb..8249b3b8 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -247,6 +247,25 @@ class PythonMissingSCMDependency(results.VersionResult,
results.Warning):
)
+class MisplacedEPyTestVar(results.LineResult, results.Error):
+"""Invalid placement of ``EPYTEST_*`` variable
+
+``EPYTEST_*`` variables need to be set prior to ``distutils_enable_tests``
+to enable its functionality. The exception to that rule are local
overrides
+in ``python_test()`` -- we presume the author knows what they're doing.
+"""
+
+def __init__(self, variable, **kwargs):
+super().__init__(**kwargs)
+self.variable = variable
+
+@property
+def desc(self):
+return (
+f"line {self.lineno}: variable set after calling
distutils_enable_tests: {self.line!r}"
+)
+
+
class PythonCheck(Check):
"""Python eclass checks.
@@ -256,7 +275,7 @@ class PythonCheck(Check):
_source = sources.EbuildParseRepoSource
known_results = frozenset(
-[
+{
MissingPythonEclass,
PythonMissingRequiredUse,
PythonMissingDeps,
@@ -268,7 +287,8 @@ class PythonCheck(Check):
PythonAnyMismatchedUseHasVersionCheck,
PythonAnyMismatchedDepHasVersionCheck,
PythonMissingSCMDependency,
-]
+MisplacedEPyTestVar,
+}
)
has_version_known_flags = {
@@ -389,6 +409,53 @@ class PythonCheck(Check):
if not self.setuptools_scm.intersection(bdepends):
yield PythonMissingSCMDependency(pkg=pkg)
+def _get_all_global_assignments(self, pkg):
+"""Iterate over global plain and expansion assignments"""
+for node in pkg.global_query(bash.var_assign_query):
+name = pkg.node_str(node.child_by_field_name("name"))
+yield (name, node)
+
+# ${var:=value} expansions.
+for node in pkg.global_query(bash.var_expansion_query):
+if node.children[0].text != b"${":
+continue
+name = node.children[1].text
+if node.children[2].text not in (b"=", b":="):
+continue
+yield (name.decode(), node)
+
+def check_epytest_vars(self, pkg):
+"""Check for incorrect use of EPYTEST_* variables"""
+# TODO: do we want to check for multiple det calls? Quite unlikely.
+for node in pkg.global_query(bash.cmd_query):
+name = pkg.node_str(node.child_by_field_name("name"))
+if name != "distutils_enable_tests":
+continue
+for argument_node in node.children_by_field_name("argument"):
+argument = pkg.node_str(argument_node)
+# Check if the first argument is "pytest", but we need
+# to skip line continuations explicitly.
+if argument == "pytest":
+det_lineno, _ = node.start_point
+break
+elif argument != "\\":
+return
+else:
+return
+
+f
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/PythonCheck/ShadowedEPyTestTimeout/, src/pkgcheck/checks/, ...
commit: 8f841f52992c9013ea513e66ab3961ca5ac0fd60
Author: Michał Górny gentoo org>
AuthorDate: Sat Jul 12 15:30:30 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Tue Jul 15 18:08:08 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8f841f52
python: Detect `EPYTEST_TIMEOUT` overriding user value
Closes: https://github.com/pkgcore/pkgcheck/issues/740
Signed-off-by: Michał Górny gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/747
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/python.py | 23 ++
.../ShadowedEPyTestTimeout/expected.json | 1 +
.../PythonCheck/ShadowedEPyTestTimeout/fix.patch | 10 ++
.../ShadowedEPyTestTimeout-0.ebuild| 14 +
4 files changed, 48 insertions(+)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 8249b3b8..39fbe55e 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -266,6 +266,21 @@ class MisplacedEPyTestVar(results.LineResult,
results.Error):
)
+class ShadowedEPyTestTimeout(results.LineResult, results.Warning):
+"""``EPYTEST_TIMEOUT`` shadows user-specified value
+
+``EPYTEST_TIMEOUT`` should be set via ``${EPYTEST_TIMEOUT:=...}`` to permit
+using an environment variable to override it.
+"""
+
+@property
+def desc(self):
+return (
+f"line {self.lineno}: EPYTEST_TIMEOUT shadows user value, use "
+f"${{EPYTEST_TIMEOUT:=...}} instead: {self.line!r}"
+)
+
+
class PythonCheck(Check):
"""Python eclass checks.
@@ -288,6 +303,7 @@ class PythonCheck(Check):
PythonAnyMismatchedDepHasVersionCheck,
PythonMissingSCMDependency,
MisplacedEPyTestVar,
+ShadowedEPyTestTimeout,
}
)
@@ -456,6 +472,13 @@ class PythonCheck(Check):
line = pkg.node_str(var_node)
yield MisplacedEPyTestVar(var_name, line=line,
lineno=lineno + 1, pkg=pkg)
+for var_node in
bash.var_assign_query.captures(pkg.tree.root_node).get("assign", ()):
+var_name = pkg.node_str(var_node.child_by_field_name("name"))
+if var_name == "EPYTEST_TIMEOUT":
+lineno, _ = var_node.start_point
+line = pkg.node_str(var_node)
+yield ShadowedEPyTestTimeout(line=line, lineno=lineno + 1,
pkg=pkg)
+
@staticmethod
def _prepare_deps(deps: str):
try:
diff --git
a/testdata/data/repos/python/PythonCheck/ShadowedEPyTestTimeout/expected.json
b/testdata/data/repos/python/PythonCheck/ShadowedEPyTestTimeout/expected.json
new file mode 100644
index ..a0d98f8a
--- /dev/null
+++
b/testdata/data/repos/python/PythonCheck/ShadowedEPyTestTimeout/expected.json
@@ -0,0 +1 @@
+{"__class__": "ShadowedEPyTestTimeout", "category": "PythonCheck", "package":
"ShadowedEPyTestTimeout", "version": "0", "line": "EPYTEST_TIMEOUT=1200",
"lineno": 13}
diff --git
a/testdata/data/repos/python/PythonCheck/ShadowedEPyTestTimeout/fix.patch
b/testdata/data/repos/python/PythonCheck/ShadowedEPyTestTimeout/fix.patch
new file mode 100644
index ..83dea272
--- /dev/null
+++ b/testdata/data/repos/python/PythonCheck/ShadowedEPyTestTimeout/fix.patch
@@ -0,0 +1,10 @@
+diff '--color=auto' -Naur
python/PythonCheck/ShadowedEPyTestTimeout/ShadowedEPyTestTimeout-0.ebuild
fixed/PythonCheck/ShadowedEPyTestTimeout/ShadowedEPyTestTimeout-0.ebuild
+--- python/PythonCheck/ShadowedEPyTestTimeout/ShadowedEPyTestTimeout-0.ebuild
2025-07-12 17:27:01.027875233 +0200
fixed/PythonCheck/ShadowedEPyTestTimeout/ShadowedEPyTestTimeout-0.ebuild
2025-07-12 17:28:01.711247010 +0200
+@@ -10,5 +10,5 @@
+ LICENSE="BSD"
+ SLOT="0"
+
+-EPYTEST_TIMEOUT=1200
++: ${EPYTEST_TIMEOUT:=1200}
+ distutils_enable_tests pytest
diff --git
a/testdata/repos/python/PythonCheck/ShadowedEPyTestTimeout/ShadowedEPyTestTimeout-0.ebuild
b/testdata/repos/python/PythonCheck/ShadowedEPyTestTimeout/ShadowedEPyTestTimeout-0.ebuild
new file mode 100644
index ..c87fee5a
--- /dev/null
+++
b/testdata/repos/python/PythonCheck/ShadowedEPyTestTimeout/ShadowedEPyTestTimeout-0.ebuild
@@ -0,0 +1,14 @@
+EAPI=8
+
+DISTUTILS_USE_PEP517=flit
+PYTHON_COMPAT=( python3_10 )
+
+inherit distutils-r1
+
+DESCRIPTION="Ebuild with misplaced EPYTEST vars"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+EPYTEST_TIMEOUT=1200
+distutils_enable_tests pytest
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/checks/, src/pkgcheck/checks/
commit: c1a730bbc60ea0d0dc7dcd8c8af3199bafc02220
Author: Ophelia Beatrice de Sica gmail com>
AuthorDate: Fri Jul 11 19:37:30 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jul 11 19:43:51 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c1a730bb
Replace p7zip with 7zip for .7z files
P7zip was a fork of 7zip from a time when 7zip was windows only.
Since then 7zip got official Linux support and work on p7zip stopped.
At this point p7zip is old and outdated and may or may not be vulnerable.
(See notice on the official Gentoo wiki)
Last year I filed a bug about this on the Gentoo bug tracker
which is currently being worked on.
I think it is somewhat counter productive to tell people to require p7zip
when there is active work to replace it.
See-also: https://wiki.gentoo.org/index.php?title=P7zip&oldid=1306559
Bug: https://bugs.gentoo.org/942397
Signed-off-by: Ophelia de Sica gmail.com>
Closes: https://github.com/pkgcore/pkgcheck/pull/744
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/metadata.py | 2 +-
tests/checks/test_metadata.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 2020eaec..1ca5ad77 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -1747,7 +1747,7 @@ class MissingUnpackerDepCheck(Check):
non_system_unpackers = ImmutableDict(
{
".zip": frozenset(["app-arch/unzip"]),
-".7z": frozenset(["app-arch/p7zip"]),
+".7z": frozenset(["app-arch/7zip"]),
".rar": frozenset(["app-arch/rar", "app-arch/unrar"]),
".lha": frozenset(["app-arch/lha"]),
".lzh": frozenset(["app-arch/lha"]),
diff --git a/tests/checks/test_metadata.py b/tests/checks/test_metadata.py
index 5e336633..b34704a2 100644
--- a/tests/checks/test_metadata.py
+++ b/tests/checks/test_metadata.py
@@ -1378,4 +1378,4 @@ class TestMissingUnpackerDepCheck(use_based(),
misc.ReportTestCase):
)
assert isinstance(r, metadata.MissingUnpackerDep)
assert r.filenames == (f"diffball-2.7.1.7z",)
-assert r.unpackers == ("app-arch/p7zip",)
+assert r.unpackers == ("app-arch/7zip",)
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: 35d74e5a39dc50ed066ca129917b40ea9fe99ce6
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jul 11 19:43:27 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jul 11 19:43:27 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=35d74e5a
fix formatting
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/metadata.py | 6 --
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 53bfdf2e..2020eaec 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -767,7 +767,7 @@ class MissingPackageRevision(results.VersionResult,
results.Warning):
def desc(self):
return (
f'"{self.op}" operator used without package revision:
{self.dep}="{self.atom}"; '
-f'did you mean either of: {self.suggestions}?'
+f"did you mean either of: {self.suggestions}?"
)
@@ -977,7 +977,9 @@ class DependencyCheck(Check):
else:
repl1 = self._make_replacement_atom(atom, atom.op,
"-r")
-yield MissingPackageRevision(attr, atom.op, str(atom),
[repl0, repl1], pkg=pkg)
+yield MissingPackageRevision(
+attr, atom.op, str(atom), [repl0, repl1], pkg=pkg
+)
if isinstance(atom, transitive_use_atom) and atom.use is
not None:
for useflag in atom.use:
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/, ...
commit: f850924100957202b8593a3251a874993d858a63
Author: Michał Górny gentoo org>
AuthorDate: Fri Jul 11 19:08:11 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jul 11 19:26:04 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=f8509241
DependencyCheck: include replacement suggestions
Signed-off-by: Michał Górny gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/743
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/metadata.py| 23 +++---
.../MissingPackageRevision/expected.json | 12 +--
2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index 429c774f..53bfdf2e 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -756,15 +756,19 @@ class MissingPackageRevision(results.VersionResult,
results.Warning):
operators.
"""
-def __init__(self, dep, op, atom, **kwargs):
+def __init__(self, dep: str, op: str, atom: str, suggestions: list[str],
**kwargs):
super().__init__(**kwargs)
self.dep = dep.upper()
self.op = op
self.atom = atom
+self.suggestions = tuple(suggestions)
@property
def desc(self):
-return f'"{self.op}" operator used without package revision:
{self.dep}="{self.atom}"'
+return (
+f'"{self.op}" operator used without package revision:
{self.dep}="{self.atom}"; '
+f'did you mean either of: {self.suggestions}?'
+)
class MissingUseDepDefault(results.VersionResult, results.Warning):
@@ -910,6 +914,13 @@ class DependencyCheck(Check):
return missing_use_deps
return {}
+def _make_replacement_atom(self, orig: atom_cls, op: str, rev: str) -> str:
+"""Make a replacement atom string from orig, with op & rev replaced"""
+s = f"{op}{orig.key}-{orig.version}{rev}"
+if orig.blocks:
+s = ("!!" if orig.blocks_strongly else "!") + s
+return s
+
def feed(self, pkg):
deprecated = defaultdict(set)
@@ -960,7 +971,13 @@ class DependencyCheck(Check):
# these operators are most likely to mean "the whole
version" rather than r0
# blockers also matched intentionally
if atom.op in ("=", "<=", ">") and not atom.revision:
-yield MissingPackageRevision(attr, atom.op, str(atom),
pkg=pkg)
+repl0 = self._make_replacement_atom(atom, atom.op,
"-r0")
+if atom.op == "=":
+repl1 = self._make_replacement_atom(atom, "~", "")
+else:
+repl1 = self._make_replacement_atom(atom, atom.op,
"-r")
+
+yield MissingPackageRevision(attr, atom.op, str(atom),
[repl0, repl1], pkg=pkg)
if isinstance(atom, transitive_use_atom) and atom.use is
not None:
for useflag in atom.use:
diff --git
a/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
b/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
index 96124dea..86ca3797 100644
---
a/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
+++
b/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
@@ -1,6 +1,6 @@
-{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "0", "dep": "RDEPEND", "op":
"=", "atom": "=stub/stub5-1"}
-{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "1", "dep": "DEPEND", "op":
"<=", "atom": "<=stub/stub5-1"}
-{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "2", "dep": "BDEPEND", "op":
">", "atom": ">stub/stub5-0"}
-{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "0-r1", "dep": "RDEPEND", "op":
"=", "atom": "!=stub/stub5-0"}
-{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "1-r1", "dep": "RDEPEND", "op":
"<=", "atom": "!<=stub/stub5-0"}
-{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "2-r1", "dep": "RDEPEND", "op":
">", "atom": "!>stub/stub5-2"}
+{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "0", "dep": "RDEPEND", "op":
"=", "atom": "=stub/stub5-1", "suggestions": ["=stub/stub5-1-r0",
"~stub/stub5-1"]}
+{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRe
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/, testdata/repos/standalone/stub/stub5/, ...
commit: 8b0c541f4f0d62c4eeac440b3fdfcde1848ac829
Author: Michał Górny gentoo org>
AuthorDate: Wed Jul 9 07:39:55 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jul 11 19:26:02 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8b0c541f
DependencyCheck: extend missing revision checks to `<=` and `>`
Extend missing package revision in dependency check to `<=` and `>`
operators. They are similar to `=` in that it only match specific
revision, while people often expect them to match the whole version.
While at it, extend tests to checking blockers too.
Signed-off-by: Michał Górny gentoo.org>
Part-of: https://github.com/pkgcore/pkgcheck/pull/743
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/metadata.py| 27 +-
.../MissingPackageRevision/expected.json | 7 ++-
.../MissingPackageRevision/fix.patch | 57 +++---
...0.ebuild => MissingPackageRevision-0-r1.ebuild} | 3 +-
.../MissingPackageRevision-0.ebuild| 3 +-
...0.ebuild => MissingPackageRevision-1-r1.ebuild} | 3 +-
...on-0.ebuild => MissingPackageRevision-1.ebuild} | 3 +-
...0.ebuild => MissingPackageRevision-2-r1.ebuild} | 3 +-
...on-0.ebuild => MissingPackageRevision-2.ebuild} | 3 +-
.../repos/standalone/stub/stub5/stub5-1.ebuild | 4 ++
10 files changed, 89 insertions(+), 24 deletions(-)
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index f20d20e2..429c774f 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -745,23 +745,26 @@ class MissingSlotDepCheck(Check):
class MissingPackageRevision(results.VersionResult, results.Warning):
"""Missing package revision in =cat/pkg dependencies.
-The dependency string uses the ``=`` operator without specifying a
revision.
-This means that only ``-r0`` of the dependency will be matched, and newer
-revisions of the same ebuild will not be accepted.
-
-If any revision of the package is acceptable, the ``~`` operator should be
-used instead of ``=``. If only the initial revision of the dependency is
-allowed, ``-r0`` should be appended in order to make the intent explicit.
+The dependency string uses the ``=``, ``<=`` or ``>`` operator without
+specifying a revision. These operators are frequently misused,
+with assumptions they apply to all revisions of the given version,
+while they do only apply to ``-r0``.
+
+If applying the operator to ``-r0`` only is intentional, then ``-r0``
+should be appended to make it explicit. Otheriwse, ``~`` can be used
+instead of ``=``, and ``-r`` or next version can be used for other
+operators.
"""
-def __init__(self, dep, atom, **kwargs):
+def __init__(self, dep, op, atom, **kwargs):
super().__init__(**kwargs)
self.dep = dep.upper()
+self.op = op
self.atom = atom
@property
def desc(self):
-return f'"=" operator used without package revision:
{self.dep}="{self.atom}"'
+return f'"{self.op}" operator used without package revision:
{self.dep}="{self.atom}"'
class MissingUseDepDefault(results.VersionResult, results.Warning):
@@ -954,8 +957,10 @@ class DependencyCheck(Check):
pkgs = (x.cpvstr for x in sorted(atoms))
yield MissingUseDepDefault(attr, str(atom), use,
pkgs, pkg=pkg)
-if atom.op == "=" and not atom.revision:
-yield MissingPackageRevision(attr, str(atom), pkg=pkg)
+# these operators are most likely to mean "the whole
version" rather than r0
+# blockers also matched intentionally
+if atom.op in ("=", "<=", ">") and not atom.revision:
+yield MissingPackageRevision(attr, atom.op, str(atom),
pkg=pkg)
if isinstance(atom, transitive_use_atom) and atom.use is
not None:
for useflag in atom.use:
diff --git
a/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
b/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
index 12d3f28c..96124dea 100644
---
a/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
+++
b/testdata/data/repos/standalone/DependencyCheck/MissingPackageRevision/expected.json
@@ -1 +1,6 @@
-{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "0", "dep": "RDEPEND", "atom":
"=stub/stub1-0"}
+{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevision", "version": "0", "dep": "RDEPEND", "op":
"=", "atom": "=stub/stub5-1"}
+{"__class__": "MissingPackageRevision", "category": "DependencyCheck",
"package": "MissingPackageRevisi
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: 96bda21f71d8d4b364d556f1bae1569c28f825f3
Author: Arthur Zamarin gentoo org>
AuthorDate: Thu Jul 10 18:30:08 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Thu Jul 10 18:30:08 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=96bda21f
start work on 0.10.37
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pkgcheck/__init__.py b/src/pkgcheck/__init__.py
index ba76bf12..46f02ecd 100644
--- a/src/pkgcheck/__init__.py
+++ b/src/pkgcheck/__init__.py
@@ -6,7 +6,7 @@ from .results import Result
__all__ = ("keywords", "scan", "PkgcheckException", "Result")
__title__ = "pkgcheck"
-__version__ = "0.10.36"
+__version__ = "0.10.37"
def __getattr__(name):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: d591876c5a899dbbf3fa56a1529cd815563688d7 Author: Arthur Zamarin gentoo org> AuthorDate: Fri Jun 13 00:40:30 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Fri Jun 13 00:40:45 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d591876c new release 0.10.36 Signed-off-by: Arthur Zamarin gentoo.org> NEWS.rst | 6 ++ 1 file changed, 6 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 80e368b9..4948b250 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,12 @@ Release Notes = +- +pkgcheck 0.10.36 (2025-06-13) +- + +- fix Dockerfile to include zstd (Arthur Zamarin) + - pkgcheck 0.10.35 (2025-06-12) -
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: 559b80756e80dc5cf78901d31869e9f7f378
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jun 13 00:37:05 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jun 13 00:37:12 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=559b8075
start work on 0.10.36
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pkgcheck/__init__.py b/src/pkgcheck/__init__.py
index 4d0cc809..ba76bf12 100644
--- a/src/pkgcheck/__init__.py
+++ b/src/pkgcheck/__init__.py
@@ -6,7 +6,7 @@ from .results import Result
__all__ = ("keywords", "scan", "PkgcheckException", "Result")
__title__ = "pkgcheck"
-__version__ = "0.10.35"
+__version__ = "0.10.36"
def __getattr__(name):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: cbdb08bd73eb919ee3a723eacbfe202d250012d1 Author: Arthur Zamarin gentoo org> AuthorDate: Fri Jun 13 00:37:30 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Fri Jun 13 00:37:30 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=cbdb08bd pyproject: fix minimal dependencies Signed-off-by: Arthur Zamarin gentoo.org> pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 03b496ff..40e0b757 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ requires = [ "lxml", "pathspec", "tree-sitter~=0.24.0", - "tree-sitter-bash~=0.23.0", + "tree-sitter-bash~=0.23.1", "snakeoil~=0.10.11", "pkgcore~=0.12.30", ] @@ -46,7 +46,7 @@ dependencies = [ "lxml", "pathspec", "tree-sitter~=0.24.0", - "tree-sitter-bash~=0.23.0", + "tree-sitter-bash~=0.23.1", "snakeoil~=0.10.11", "pkgcore~=0.12.30", ]
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: d48b8d4322b0e53aaac14a28116e61d91d4d5f82
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Jun 13 00:35:57 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Jun 13 00:37:12 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=d48b8d43
Dockerfile: add missing zstd dependency
Signed-off-by: Arthur Zamarin gentoo.org>
Dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dockerfile b/Dockerfile
index 00909bd4..1c6c719f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
FROM python:3-slim
ARG PKGCHECK_VERSION
-RUN apt-get update && apt-get install -y git && \
+RUN apt-get update && apt-get install -y git zstd && \
rm -rf /var/lib/apt/lists/ /var/cache/apt /var/cache/dpkg && \
pip install pkgcheck==${PKGCHECK_VERSION} setuptools requests && \
pip cache purge
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: f43a9a2430cdf288ab22a5c28c154007e1084071 Author: Arthur Zamarin gentoo org> AuthorDate: Thu Jun 12 17:22:00 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Thu Jun 12 17:22:00 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=f43a9a24 new release 0.10.35 Signed-off-by: Arthur Zamarin gentoo.org> NEWS.rst | 17 + 1 file changed, 17 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 8ff8fe29..80e368b9 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,23 @@ Release Notes = +- +pkgcheck 0.10.35 (2025-06-12) +- + +- caches: support compression of the profiles cache file, reducing its size + from 192MB to 4MB (Arthur Zamarin) + +- Fix compatibility with Python 3.14 (Michał Górny, #738) + +**Check Updates:** + +- BadPackageUpdate: fix issues when not running under the ``profiles/`` + directory (Arthur Zamarin) + +- VisibilityCheck: check for masked dependencies in master repos (Anna + CyberTailor, #736) + - pkgcheck 0.10.34 (2025-04-04) -
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 1a2cdafc550a37d6736cfed4e7e2e5d450449f31 Author: Arthur Zamarin gentoo org> AuthorDate: Thu Jun 12 16:01:07 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Thu Jun 12 16:01:07 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=1a2cdafc pyproject: cap tree-sitter deps If we leave it to pypi python packages, they can get out of sync, and become not complient one to another (like tree-sitter-bash-0.25.0 and tree-sitter-0.24.0). It doesn't occur in ::gentoo, because we source compile tree-sitter-0.24.0 with dev-libs/tree-sitter-0.25.0 and it works. Signed-off-by: Arthur Zamarin gentoo.org> pyproject.toml | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 49788d4a..03b496ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,8 @@ requires = [ "lazy-object-proxy", "lxml", "pathspec", - "tree-sitter>=0.23.0", - "tree-sitter-bash>=0.21.0", + "tree-sitter~=0.24.0", + "tree-sitter-bash~=0.23.0", "snakeoil~=0.10.11", "pkgcore~=0.12.30", ] @@ -45,8 +45,8 @@ dependencies = [ "lazy-object-proxy", "lxml", "pathspec", - "tree-sitter>=0.23.0", - "tree-sitter-bash>=0.21.0", + "tree-sitter~=0.24.0", + "tree-sitter-bash~=0.23.0", "snakeoil~=0.10.11", "pkgcore~=0.12.30", ]
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: tests/scripts/
commit: 46a37bb18a13f1ec68273d00524c73e5b91823a0
Author: Michał Górny gentoo org>
AuthorDate: Sat May 31 14:21:10 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Jun 2 13:16:25 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=46a37bb1
tests: Wrap partial() in staticmethod(), in attributes for py3.14
Wrap `partial()` uses in class attributes in `staticmethod()`,
as required for them to work correctly in Python 3.14.
> functools.partial is now a method descriptor. Wrap it in staticmethod()
> if you want to preserve the old behavior.
(https://docs.python.org/3.14/whatsnew/3.14.html#changes-in-the-python-api)
Signed-off-by: Michał Górny gentoo.org>
Part-of: https://github.com/pkgcore/pkgcheck/pull/738
Closes: https://github.com/pkgcore/pkgcheck/pull/738
Signed-off-by: Arthur Zamarin gentoo.org>
tests/scripts/test_pkgcheck.py | 4 ++--
tests/scripts/test_pkgcheck_cache.py | 2 +-
tests/scripts/test_pkgcheck_ci.py| 2 +-
tests/scripts/test_pkgcheck_show.py | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/scripts/test_pkgcheck.py b/tests/scripts/test_pkgcheck.py
index 21b52424..a5ac7743 100644
--- a/tests/scripts/test_pkgcheck.py
+++ b/tests/scripts/test_pkgcheck.py
@@ -9,7 +9,7 @@ from pkgcheck.scripts import run
def test_script_run(capsys):
"""Test regular code path for running scripts."""
-script = partial(run, project)
+script = staticmethod(partial(run, project))
with patch(f"{project}.scripts.import_module") as import_module:
import_module.side_effect = ImportError("baz module doesn't exist")
@@ -40,7 +40,7 @@ def test_script_run(capsys):
class TestPkgcheck:
-script = partial(run, project)
+script = staticmethod(partial(run, project))
def test_version(self, capsys):
with patch("sys.argv", [project, "--version"]):
diff --git a/tests/scripts/test_pkgcheck_cache.py
b/tests/scripts/test_pkgcheck_cache.py
index 09c75028..9e0b7e43 100644
--- a/tests/scripts/test_pkgcheck_cache.py
+++ b/tests/scripts/test_pkgcheck_cache.py
@@ -8,7 +8,7 @@ from pkgcheck.scripts import run
class TestPkgcheckCache:
-script = partial(run, project)
+script = staticmethod(partial(run, project))
@pytest.fixture(autouse=True)
def _setup(self, testconfig, tmp_path):
diff --git a/tests/scripts/test_pkgcheck_ci.py
b/tests/scripts/test_pkgcheck_ci.py
index 6530c0f0..9c32f31c 100644
--- a/tests/scripts/test_pkgcheck_ci.py
+++ b/tests/scripts/test_pkgcheck_ci.py
@@ -9,7 +9,7 @@ from pkgcore.ebuild.cpv import VersionedCPV
class TestPkgcheckCi:
-script = partial(run, "pkgcheck")
+script = staticmethod(partial(run, "pkgcheck"))
@pytest.fixture(autouse=True)
def _setup(self, testconfig, tmp_path):
diff --git a/tests/scripts/test_pkgcheck_show.py
b/tests/scripts/test_pkgcheck_show.py
index 26677059..cc48e67a 100644
--- a/tests/scripts/test_pkgcheck_show.py
+++ b/tests/scripts/test_pkgcheck_show.py
@@ -10,7 +10,7 @@ from pkgcheck.scripts import run
class TestPkgcheckShow:
-script = partial(run, project)
+script = staticmethod(partial(run, project))
@pytest.fixture(autouse=True)
def _setup(self, testconfig):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/overlayed/stub/masked/, ...
commit: 14884614fb8419028fdd8b63c8d6bb2aa01c1dd4
Author: @CyberTailor <@CyberTailor>
AuthorDate: Fri May 23 21:00:13 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Jun 2 13:34:05 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=14884614
VisibilityCheck: check deps masked in master repo(s)
There's a logical error in f884cf16ade6cda385dcc0c3216830816ebc589a,
which resulted in "profiles/package.mask" of master repos ignored
completely.
Because of this bug, only overlay's masks and per-profile masks were
respected.
To fix this, add "repo.pkg_masks" back to the visibility filter.
Signed-off-by: Anna @CyberTailor sysrq.in>
Part-of: https://github.com/pkgcore/pkgcheck/pull/736
Closes: https://github.com/pkgcore/pkgcheck/pull/736
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/addons/profiles.py| 2 +-
.../VisibilityCheck/NonsolvableDepsInStable/expected-verbose.json | 2 ++
.../overlay/VisibilityCheck/NonsolvableDepsInStable/expected.json | 1 +
.../NonsolvableDepsInStable/NonsolvableDepsInStable-0.ebuild | 7 +++
testdata/repos/overlay/profiles/categories | 1 +
testdata/repos/overlayed/profiles/package.mask | 1 +
testdata/repos/overlayed/stub/masked/masked-0.ebuild | 5 +
7 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/src/pkgcheck/addons/profiles.py b/src/pkgcheck/addons/profiles.py
index ec4e8e8e..e5a3ec37 100644
--- a/src/pkgcheck/addons/profiles.py
+++ b/src/pkgcheck/addons/profiles.py
@@ -359,7 +359,7 @@ class ProfileAddon(caches.CachedAddon):
# stable cache is usable for unstable, but not vice
versa.
# unstable insoluble is usable for stable, but not
vice versa
vfilter = domain.generate_filter(
-self.target_repo.pkg_masks | masks, unmasks
+self.target_repo.pkg_masks | repo.pkg_masks |
masks, unmasks
)
self.profile_filters.setdefault(stable_key, []).append(
ProfileData(
diff --git
a/testdata/data/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/expected-verbose.json
b/testdata/data/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/expected-verbose.json
new file mode 100644
index ..4960bc7f
--- /dev/null
+++
b/testdata/data/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/expected-verbose.json
@@ -0,0 +1,2 @@
+{"__class__": "NonsolvableDepsInStable", "category": "VisibilityCheck",
"package": "NonsolvableDepsInStable", "version": "0", "attr": "depend",
"keyword": "amd64", "profile": "default", "deps": ["stub/masked"],
"profile_status": "stable", "profile_deprecated": false, "num_profiles": null}
+{"__class__": "NonsolvableDepsInStable", "category": "VisibilityCheck",
"package": "NonsolvableDepsInStable", "version": "0", "attr": "depend",
"keyword": "~amd64", "profile": "default", "deps": ["stub/masked"],
"profile_status": "stable", "profile_deprecated": false, "num_profiles": null}
diff --git
a/testdata/data/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/expected.json
b/testdata/data/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/expected.json
new file mode 100644
index ..cec289c2
--- /dev/null
+++
b/testdata/data/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/expected.json
@@ -0,0 +1 @@
+{"__class__": "NonsolvableDepsInStable", "category": "VisibilityCheck",
"package": "NonsolvableDepsInStable", "version": "0", "attr": "depend",
"keyword": "amd64", "profile": "default", "deps": ["stub/masked"],
"profile_status": "stable", "profile_deprecated": false, "num_profiles": 2}
diff --git
a/testdata/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/NonsolvableDepsInStable-0.ebuild
b/testdata/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/NonsolvableDepsInStable-0.ebuild
new file mode 100644
index ..348f0a7e
--- /dev/null
+++
b/testdata/repos/overlay/VisibilityCheck/NonsolvableDepsInStable/NonsolvableDepsInStable-0.ebuild
@@ -0,0 +1,7 @@
+EAPI=7
+DESCRIPTION="Ebuild with masked nonsolvable dep in master repo"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+KEYWORDS="amd64"
+DEPEND="stub/masked"
diff --git a/testdata/repos/overlay/profiles/categories
b/testdata/repos/overlay/profiles/categories
index 367e18ec..6dbed601 100644
--- a/testdata/repos/overlay/profiles/categories
+++ b/testdata/repos/overlay/profiles/categories
@@ -1 +1,2 @@
UnusedInMastersCheck
+VisibilityCheck
diff --git a/testdata/repos/overlayed/profiles/package.mask
b/testdata/repos/overlayed/profiles/package.mask
new file mode 100644
index ..e6ebacc1
--- /dev/null
+++ b/testdata/repos/overlayed/profiles/package.mask
@@ -0,0 +1 @@
+stub/masked
diff --git a/testdata/repos/overlayed/stub/masked/masked-0.ebu
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/standalone/BadCommandsCheck/BannedEapiCommand/, ...
commit: e44c31cffbedc5a53c6b408515f25f8d808e00b1
Author: Arthur Zamarin gentoo org>
AuthorDate: Mon Jun 2 13:24:22 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Jun 2 13:24:22 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=e44c31cf
BannedEapiCommand: add test for EAPI=9 banned commands
Signed-off-by: Arthur Zamarin gentoo.org>
.../BadCommandsCheck/BannedEapiCommand/expected.json | 2 ++
.../BadCommandsCheck/BannedEapiCommand/fix.patch | 14 ++
.../BannedEapiCommand/BannedEapiCommand-3.ebuild | 15 +++
3 files changed, 31 insertions(+)
diff --git
a/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/expected.json
b/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/expected.json
index d441021b..36b765e4 100644
---
a/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/expected.json
+++
b/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/expected.json
@@ -3,3 +3,5 @@
{"__class__": "BannedEapiCommand", "category": "BadCommandsCheck", "package":
"BannedEapiCommand", "version": "1", "line": "best_version --host-root
stub/stub1:2", "lineno": 12, "command": "best_version --host-root", "eapi": "7"}
{"__class__": "BannedEapiCommand", "category": "BadCommandsCheck", "package":
"BannedEapiCommand", "version": "2", "line": "usermod -s /bin/bash uucp",
"lineno": 9, "command": "usermod", "eapi": "6"}
{"__class__": "BannedEapiCommand", "category": "BadCommandsCheck", "package":
"BannedEapiCommand", "version": "2", "line": "usermod -s /bin/false uucp",
"lineno": 13, "command": "usermod", "eapi": "6"}
+{"__class__": "BannedEapiCommand", "category": "BadCommandsCheck", "package":
"BannedEapiCommand", "version": "3", "line": "assert \"failed\"", "lineno": 10,
"command": "assert", "eapi": "9"}
+{"__class__": "BannedEapiCommand", "category": "BadCommandsCheck", "package":
"BannedEapiCommand", "version": "3", "line": "domo foo.po", "lineno": 14,
"command": "domo", "eapi": "9"}
diff --git
a/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/fix.patch
b/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/fix.patch
index a0950afe..bfe6f82f 100644
---
a/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/fix.patch
+++
b/testdata/data/repos/standalone/BadCommandsCheck/BannedEapiCommand/fix.patch
@@ -39,3 +39,17 @@ diff -Naur
standalone/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-2.ebu
-pkg_postrm() {
- usermod -s /bin/false uucp || die
-}
+diff -Naur
standalone/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-3.ebuild
fixed/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-3.ebuild
+--- standalone/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-3.ebuild
fixed/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-3.ebuild
+@@ -7,9 +7,5 @@ SLOT="0"
+
+ src_unpack() {
+ tar -xzf foo.tar.gz 3 | hexdump -C
+- assert "failed"
+-}
+-
+-src_install() {
+- domo foo.po
++ pipestatus || die "failed"
+ }
diff --git
a/testdata/repos/standalone/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-3.ebuild
b/testdata/repos/standalone/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-3.ebuild
new file mode 100644
index ..fb28bd7d
--- /dev/null
+++
b/testdata/repos/standalone/BadCommandsCheck/BannedEapiCommand/BannedEapiCommand-3.ebuild
@@ -0,0 +1,15 @@
+EAPI=9
+
+DESCRIPTION="Ebuild using banned commands"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+src_unpack() {
+ tar -xzf foo.tar.gz 3 | hexdump -C
+ assert "failed"
+}
+
+src_install() {
+ domo foo.po
+}
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: .github/workflows/, /
commit: 130900996ad677aaa687382c98d3e79bcf7178ed
Author: Arthur Zamarin gentoo org>
AuthorDate: Mon Jun 2 13:16:03 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Mon Jun 2 13:16:03 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=13090099
update minimal python & deps
Signed-off-by: Arthur Zamarin gentoo.org>
.github/workflows/doc.yml | 4 ++--
.github/workflows/release.yml | 4 ++--
.github/workflows/test.yml| 8
README.rst| 2 +-
pyproject.toml| 14 ++
tox.ini | 2 +-
6 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml
index 2ca20e41..b8fd7855 100644
--- a/.github/workflows/doc.yml
+++ b/.github/workflows/doc.yml
@@ -21,10 +21,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
-- name: Set up Python 3.11
+- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
-python-version: '3.11'
+python-version: '3.13'
- name: Install dependencies
run: |
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b8be4db0..457312ab 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -20,10 +20,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
-- name: Set up Python 3.11
+- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
-python-version: "3.11"
+python-version: "3.13"
- name: Install dependencies
run: |
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4db1dcca..b74e6393 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -13,20 +13,20 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
-python-version: ['3.10', '3.11', '3.12']
+python-version: ['3.11', '3.12', '3.13']
deps: [newest-deps]
experimental: [false]
include:
- os: ubuntu-latest
-python-version: '3.13-dev'
+python-version: '3.14-dev'
deps: newest-deps
experimental: true
- os: ubuntu-latest
-python-version: '3.11'
+python-version: '3.13'
deps: minimal-deps
experimental: false
- os: macos-latest
-python-version: '3.11'
+python-version: '3.13'
deps: newest-deps
experimental: true
fail-fast: false
diff --git a/README.rst b/README.rst
index 47015de0..7905a572 100644
--- a/README.rst
+++ b/README.rst
@@ -69,7 +69,7 @@ environments just execute **tox** in the root directory of a
repo or unpacked
tarball. Otherwise, for a specific python version execute something similar to
the following::
-tox -e py311
+tox -e py313
Adding new checks
=
diff --git a/pyproject.toml b/pyproject.toml
index 5f2e94f7..49788d4a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,8 +8,8 @@ requires = [
"pathspec",
"tree-sitter>=0.23.0",
"tree-sitter-bash>=0.21.0",
- "snakeoil~=0.10.8",
- "pkgcore~=0.12.25",
+ "snakeoil~=0.10.11",
+ "pkgcore~=0.12.30",
]
build-backend = "py_build"
backend-path = ["."]
@@ -19,7 +19,7 @@ name = "pkgcheck"
description = "pkgcore-based QA utility for ebuild repos"
readme = "README.rst"
license = {file = "LICENSE"}
-requires-python = "~=3.10"
+requires-python = "~=3.11"
# alphabetical by surname.
authors = [
{name = "Michał Górny", email = "[email protected]"},
@@ -33,7 +33,6 @@ maintainers = [
]
classifiers = [
"License :: OSI Approved :: BSD License",
- "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
@@ -48,8 +47,8 @@ dependencies = [
"pathspec",
"tree-sitter>=0.23.0",
"tree-sitter-bash>=0.21.0",
- "snakeoil~=0.10.8",
- "pkgcore~=0.12.25",
+ "snakeoil~=0.10.11",
+ "pkgcore~=0.12.30",
]
[project.optional-dependencies]
@@ -60,8 +59,7 @@ test = [
]
doc = [
"sphinx",
- "tomli; python_version < '3.11'",
- "snakeoil~=0.10.4",
+ "snakeoil~=0.10.11",
]
network = [
"requests",
diff --git a/tox.ini b/tox.ini
index d71b88ce..8506efcf 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py3{10,11,12}
+envlist = py3{11,12,13,14}
skip_missing_interpreters = True
isolated_build = True
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: f942207e55dcca60b156638e0f516b58d0fd5f00 Author: Arthur Zamarin gentoo org> AuthorDate: Sat May 31 10:59:02 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Sat May 31 10:59:02 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=f942207e git-blame-ignore-revs: ignore ruff format Signed-off-by: Arthur Zamarin gentoo.org> .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 2f7c35b1..ec1a7c92 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,3 +1,5 @@ +# Reformat the repository with ruff +0bec745861d8ed839fed6f88f8cee7329e05342e # Reformat the repository with black-24 fb4dc9bbf2b51732aa4a254d8ba18c0235f8d70c # Reformat the repository with black-23
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/scripts/, src/pkgcheck/checks/, .github/workflows/, src/pkgcheck/, ...
commit: df472e75e8ad3425705f77dd29cb98a178448092
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat May 31 10:57:46 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat May 31 10:58:29 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=df472e75
use ruff as formatter
Signed-off-by: Arthur Zamarin gentoo.org>
.github/workflows/test.yml | 4 +-
Makefile| 2 +-
pyproject.toml | 4 +
src/pkgcheck/addons/git.py | 2 +-
src/pkgcheck/checks/acct.py | 2 +-
src/pkgcheck/checks/codingstyle.py | 5 +-
src/pkgcheck/checks/metadata.py | 20 ++--
src/pkgcheck/checks/profiles.py | 3 +-
src/pkgcheck/checks/python.py | 4 +-
src/pkgcheck/checks/visibility.py | 5 +-
src/pkgcheck/feeds.py | 2 +-
src/pkgcheck/reporters.py | 8 +-
src/pkgcheck/scripts/argparsers.py | 2 +-
tests/checks/test_codingstyle.py| 8 +-
tests/checks/test_metadata.py | 4 +-
tests/checks/test_python.py | 214 +---
tests/checks/test_whitespace.py | 6 +-
tests/scripts/test_pkgcheck_scan.py | 6 +-
18 files changed, 118 insertions(+), 183 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 150ff0f0..4db1dcca 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -108,4 +108,6 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
-- uses: psf/black@stable
+- uses: astral-sh/ruff-action@v3
+ with:
+args: "format --check --diff"
diff --git a/Makefile b/Makefile
index 1d48fcb2..63b08eea 100644
--- a/Makefile
+++ b/Makefile
@@ -15,4 +15,4 @@ clean:
.PHONY: format
format:
- $(PYTHON) -m black .
+ $(PYTHON) -m ruff format
diff --git a/pyproject.toml b/pyproject.toml
index 4e7d2d82..5f2e94f7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -89,6 +89,10 @@ exclude = [
"doc/api/", "doc/generated/", "doc/_build/",
]
+[tool.ruff]
+line-length = 100
+target-version = "py311"
+
[tool.black]
line-length = 100
diff --git a/src/pkgcheck/addons/git.py b/src/pkgcheck/addons/git.py
index e3de52c0..302c5bc1 100644
--- a/src/pkgcheck/addons/git.py
+++ b/src/pkgcheck/addons/git.py
@@ -646,7 +646,7 @@ class GitAddon(caches.CachedAddon):
# skip cache usage when not running on the default branch
if branch != default_branch:
logger.debug(
-"skipping %s git repo cache update on " "non-default
branch %r",
+"skipping %s git repo cache update on non-default
branch %r",
repo,
branch,
)
diff --git a/src/pkgcheck/checks/acct.py b/src/pkgcheck/checks/acct.py
index 30953c89..47015953 100644
--- a/src/pkgcheck/checks/acct.py
+++ b/src/pkgcheck/checks/acct.py
@@ -55,7 +55,7 @@ class OutsideRangeAccountIdentifier(results.VersionResult,
results.Error):
@property
def desc(self):
-return f"{self.kind} id {self.identifier} outside permitted " f"static
allocation range"
+return f"{self.kind} id {self.identifier} outside permitted static
allocation range"
class AcctCheck(GentooRepoCheck, RepoCheck):
diff --git a/src/pkgcheck/checks/codingstyle.py
b/src/pkgcheck/checks/codingstyle.py
index d5473616..b2126429 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -356,10 +356,7 @@ class DeprecatedInsinto(results.LineResult,
results.Warning):
@property
def desc(self):
-return (
-f"deprecated insinto usage (use {self.cmd} instead), "
-f"line {self.lineno}: {self.line}"
-)
+return f"deprecated insinto usage (use {self.cmd} instead), line
{self.lineno}: {self.line}"
class InsintoCheck(Check):
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index e375ba1f..f20d20e2 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -77,9 +77,7 @@ class MissingLicenseRestricts(results.VersionResult,
results.Warning):
@property
def desc(self):
restrictions = " ".join(self.restrictions)
-return (
-f"{self.license_group} license {self.license!r} " f'requires
RESTRICT="{restrictions}"'
-)
+return f'{self.license_group} license {self.license!r} requires
RESTRICT="{restrictions}"'
class UnnecessaryLicense(results.VersionResult, results.Warning):
@@ -374,8 +372,7 @@ class RequiredUseDefaults(results.VersionResult,
results.Warning):
num_profiles = ""
# collapsed version
return (
-f"profile: {self.profile!r}{num_profiles} "
-f"failed REQUIRED_USE: {self.required_use}"
+f"profile: {self.profile
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/addons/
commit: b471c5cb82debe479b2021d7adfffe9e228ac896
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri May 2 09:52:35 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri May 2 10:03:31 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b471c5cb
caches: support compression of cache files
profiles.pickle has become quite fat on disk, getting to 185MB in size.
More information on the source of issue can be found in the issue linked
below, but I've decided to use "zstd -T0" (with default compression level)
to compress the cache files. This should help with the size of the
cache files, and the performance hit should be negligible.
I've measured the time it takes to load the cache files before and after
this change, and the difference is nil. The time is mostly the cost of
pickle.load, and the compression/decompression is negligible in comparison.
I'm still somewhat concerned about my usage of subprocess.Popen, but I
think it's fine.
Resolves: https://github.com/pkgcore/pkgcheck/issues/735
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/addons/caches.py | 30 --
src/pkgcheck/addons/profiles.py | 2 +-
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/pkgcheck/addons/caches.py b/src/pkgcheck/addons/caches.py
index 9cd13e58..a6c94b73 100644
--- a/src/pkgcheck/addons/caches.py
+++ b/src/pkgcheck/addons/caches.py
@@ -5,6 +5,7 @@ import os
import pathlib
import pickle
import shutil
+import subprocess
from collections import UserDict
from dataclasses import dataclass
from hashlib import blake2b
@@ -79,11 +80,21 @@ class CachedAddon(Addon):
dirname = f"{repo.repo_id.lstrip(os.sep)}-{token}"
return pjoin(self.options.cache_dir, "repos", dirname, self.cache.file)
-def load_cache(self, path, fallback=None):
+def load_cache(self, path: str, fallback=None):
cache = fallback
try:
-with open(path, "rb") as f:
-cache = pickle.load(f)
+if path.endswith(".zst"):
+if not os.path.exists(path):
+raise FileNotFoundError(path)
+with subprocess.Popen(("zstd", "-qdcf", path),
stdout=subprocess.PIPE) as proc:
+if proc.poll():
+raise PkgcheckUserException(
+f"failed decompressing {self.cache.type} cache:
{path!r}"
+)
+cache = pickle.load(proc.stdout)
+else:
+with open(path, "rb") as f:
+cache = pickle.load(f)
if cache.version != self.cache.version:
logger.debug("forcing %s cache regen due to outdated version",
self.cache.type)
os.remove(path)
@@ -98,11 +109,18 @@ class CachedAddon(Addon):
cache = fallback
return cache
-def save_cache(self, data, path):
+def save_cache(self, data, path: str):
try:
os.makedirs(os.path.dirname(path), exist_ok=True)
-with AtomicWriteFile(path, binary=True) as f:
-pickle.dump(data, f, protocol=-1)
+if path.endswith(".zst"):
+with subprocess.Popen(("zstd", "-T0", "-fqo", path),
stdin=subprocess.PIPE) as proc:
+pickle.dump(data, proc.stdin, protocol=-1)
+if os.path.exists(path[:-4]):
+logger.warning("removing old %s cache file",
self.cache.type)
+os.remove(path[:-4])
+else:
+with AtomicWriteFile(path, binary=True) as f:
+pickle.dump(data, f, protocol=-1)
except IOError as e:
msg = f"failed dumping {self.cache.type} cache: {path!r}:
{e.strerror}"
raise PkgcheckUserException(msg)
diff --git a/src/pkgcheck/addons/profiles.py b/src/pkgcheck/addons/profiles.py
index f9a6862e..ec4e8e8e 100644
--- a/src/pkgcheck/addons/profiles.py
+++ b/src/pkgcheck/addons/profiles.py
@@ -119,7 +119,7 @@ class ProfileAddon(caches.CachedAddon):
non_profile_dirs = frozenset(["desc", "updates"])
# cache registry
-cache = caches.CacheData(type="profiles", file="profiles.pickle",
version=2)
+cache = caches.CacheData(type="profiles", file="profiles.pickle.zst",
version=3)
@classmethod
def mangle_argparser(cls, parser):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: c8c1d3a1339ab5e575d330dbc248ffd59c8907e2
Author: Arthur Zamarin gentoo org>
AuthorDate: Wed Apr 9 18:01:30 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Wed Apr 9 18:01:30 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=c8c1d3a1
BadPackageUpdate: fix when ran as only check
Fixes: be92740c59c7dc0309c4e05f2f73ebdf339e2376
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/repo_metadata.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/pkgcheck/checks/repo_metadata.py
b/src/pkgcheck/checks/repo_metadata.py
index 8225abbf..32f6b70d 100644
--- a/src/pkgcheck/checks/repo_metadata.py
+++ b/src/pkgcheck/checks/repo_metadata.py
@@ -105,7 +105,8 @@ class PackageUpdatesCheck(RepoCheck):
base.LogMap("pkgcore.log.logger.error", BadPackageUpdate),
)
-del self.repo.config.__dict__["_updates"] # clear cache for immutable
dict
+if hasattr(self.repo.config, "_updates"):
+del self.repo.config.__dict__["_updates"] # clear cache for
immutable dict
# convert log warnings/errors into reports
with base.LogReports(*logmap) as log_reports:
repo_updates = self.repo.config.updates
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/data/repos/visibility/PackageUpdatesCheck/BadPackageUpdate/, ...
commit: be92740c59c7dc0309c4e05f2f73ebdf339e2376
Author: Arthur Zamarin gentoo org>
AuthorDate: Tue Apr 8 18:17:38 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Tue Apr 8 18:17:38 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=be92740c
BadPackageUpdate: fix when not run inside profiles/ dir
When we weren't inside profiles/ dir, we were running the VisibilityCheck
check. This check was collecting repo.config.updates. This one is cached,
resulting in the value not being recomputed when time comes for
PackageUpdatesCheck to run. This commit fixes this by making sure we
invalidate the cache.
Sadly the object we're using to store config is Immutable, resulting in
a very ugly hack to invalidate the cache, by using the __dict__ attribute
of the object. This is not a good practice, but it works.
Reported-by: Eli Schwartz gentoo.org>
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/repo_metadata.py | 1 +
.../repos/visibility/PackageUpdatesCheck/BadPackageUpdate/expected.json | 1 +
.../repos/visibility/PackageUpdatesCheck/OldPackageUpdate/expected.json | 1 +
testdata/repos/visibility/profiles/updates/1Q-2024 | 1 +
4 files changed, 4 insertions(+)
diff --git a/src/pkgcheck/checks/repo_metadata.py
b/src/pkgcheck/checks/repo_metadata.py
index 0e1c7f84..8225abbf 100644
--- a/src/pkgcheck/checks/repo_metadata.py
+++ b/src/pkgcheck/checks/repo_metadata.py
@@ -105,6 +105,7 @@ class PackageUpdatesCheck(RepoCheck):
base.LogMap("pkgcore.log.logger.error", BadPackageUpdate),
)
+del self.repo.config.__dict__["_updates"] # clear cache for immutable
dict
# convert log warnings/errors into reports
with base.LogReports(*logmap) as log_reports:
repo_updates = self.repo.config.updates
diff --git
a/testdata/data/repos/visibility/PackageUpdatesCheck/BadPackageUpdate/expected.json
b/testdata/data/repos/visibility/PackageUpdatesCheck/BadPackageUpdate/expected.json
new file mode 100644
index ..6af54b91
--- /dev/null
+++
b/testdata/data/repos/visibility/PackageUpdatesCheck/BadPackageUpdate/expected.json
@@ -0,0 +1 @@
+{"__class__": "BadPackageUpdate", "msg": "file '1Q-2024': 'move
<=stub/old-name-1.2.3.4 stub/stable' on line 3: atom <=stub/old-name-1.2.3.4
must be versionless"}
diff --git
a/testdata/data/repos/visibility/PackageUpdatesCheck/OldPackageUpdate/expected.json
b/testdata/data/repos/visibility/PackageUpdatesCheck/OldPackageUpdate/expected.json
new file mode 100644
index ..4ec693cb
--- /dev/null
+++
b/testdata/data/repos/visibility/PackageUpdatesCheck/OldPackageUpdate/expected.json
@@ -0,0 +1 @@
+{"__class__": "OldPackageUpdate", "pkg": "stub/random-pkgname", "updates":
["move", "VisibilityCheck/OldPackageName", "stub/random-pkgname"]}
diff --git a/testdata/repos/visibility/profiles/updates/1Q-2024
b/testdata/repos/visibility/profiles/updates/1Q-2024
index dfb9b553..0570b222 100644
--- a/testdata/repos/visibility/profiles/updates/1Q-2024
+++ b/testdata/repos/visibility/profiles/updates/1Q-2024
@@ -1,2 +1,3 @@
move stub/old-name stub/stable
move VisibilityCheck/OldPackageName stub/random-pkgname
+move <=stub/old-name-1.2.3.4 stub/stable
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/
commit: 0abdd4515ada790696c9527ed9e0781f929da877
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Apr 4 19:18:42 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Apr 4 19:18:42 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=0abdd451
start work on 0.10.35
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pkgcheck/__init__.py b/src/pkgcheck/__init__.py
index cba1c1e5..4d0cc809 100644
--- a/src/pkgcheck/__init__.py
+++ b/src/pkgcheck/__init__.py
@@ -6,7 +6,7 @@ from .results import Result
__all__ = ("keywords", "scan", "PkgcheckException", "Result")
__title__ = "pkgcheck"
-__version__ = "0.10.34"
+__version__ = "0.10.35"
def __getattr__(name):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: /
commit: 8561609ea40069db3e4772873480279ecbd37d1a Author: Arthur Zamarin gentoo org> AuthorDate: Fri Apr 4 19:08:05 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Fri Apr 4 19:08:05 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8561609e new release 0.10.34 Signed-off-by: Arthur Zamarin gentoo.org> NEWS.rst | 40 1 file changed, 40 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 8f5c64dd..8ff8fe29 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,46 @@ Release Notes = +- +pkgcheck 0.10.34 (2025-04-04) +- + +**New Checks:** + +- NonConsistentTarUsage: detect ``tar`` invocations missing the ``-f`` argument + (Arthur Zamarin, #709) + +- TooManyCrates: flag packages with more than 300 CRATES (Arthur Zamarin) + +**Check Updates:** + +- OutdatedBlocker: extend the threshold for outdated blockers from 2 years to 4 + years (Sam James) + +- DeprecatedInsinto: add support for paths related to shell completion and + systemd (Arthur Zamarin) + +- DirectStableKeywords: exclude ``sec-keys/*`` and ``virtual/*`` categories + from this check (Arthur Zamarin, #719) + +- RequiredUseDefaults: skip all USE flags prefixed with ``cpu_flags_`` (Arthur + Zamarin) + +- git: suggest clearing the pkgcheck cache when encountering a ``git log`` + error (Martin Mokry, #729) + +- PythonCompatUpdate: ignore ``*t`` (freethreading) Python targets + (Arthur Zamarin, Michał Górny, #711, #732) + +- DeadUrl: prevent crashes when servers return invalid UTF-8 data (Arthur + Zamarin) + +- PathVariablesCheck: expand the list of names checked for path variable issues + (Arthur Zamarin) + +- MissingRemoteId: exclude URIs used for fetching ``-crates`` or ``-deps`` + tarballs from this check (Arthur Zamarin) + - pkgcheck 0.10.33 (2024-12-04) -
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: 18abe5874888fe4c923545b70cc43ca96f57776a
Author: Arthur Zamarin gentoo org>
AuthorDate: Fri Mar 28 16:40:04 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Fri Mar 28 16:40:04 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=18abe587
MissingRemoteId: don't report for -crates or -deps
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/metadata_xml.py | 14 --
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/pkgcheck/checks/metadata_xml.py
b/src/pkgcheck/checks/metadata_xml.py
index cfba70c8..49bd3cfb 100644
--- a/src/pkgcheck/checks/metadata_xml.py
+++ b/src/pkgcheck/checks/metadata_xml.py
@@ -675,6 +675,16 @@ class MissingRemoteIdCheck(Check):
(remote_type, re.compile(regex)) for remote_type, regex in
self.remotes_map
)
+@staticmethod
+def __filter_url(url: str) -> bool:
+if url.endswith((".patch", ".diff")):
+return False
+if "-crates.tar" in url:
+return False
+if "-deps.tar" in url:
+return False
+return True
+
def feed(self, pkgset):
remotes = {u.type: (None, None) for u in pkgset[0].upstreams}
for pkg in sorted(pkgset, reverse=True):
@@ -686,10 +696,10 @@ class MissingRemoteIdCheck(Check):
),
(fetchable, Conditional),
)
-all_urls = set(
+all_urls: set[str] = set(
chain.from_iterable(f.uri for f in fetchables if isinstance(f,
fetchable))
)
-urls = {url for url in all_urls if not url.endswith((".patch",
".diff"))}
+urls = set(filter(self.__filter_url, all_urls))
urls = sorted(urls.union(pkg.homepage), key=len)
for remote_type, regex in self.remotes_map:
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/PythonCompatCheck/PythonCompatUpdate/, ...
commit: beee75e768792dde4c558419375a72210203a608
Author: Michał Górny gentoo org>
AuthorDate: Wed Mar 19 06:52:30 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Wed Mar 19 15:39:14 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=beee75e7
python: Fix misfired PythonCompatUpdate when newest PYTHON_COMPAT is *t
Signed-off-by: Michał Górny gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/732
Fixes: b86872a25614ca16177ca161638d8a0837cbda37
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/python.py | 2 +-
.../PythonCompatUpdate/PythonCompatUpdate-4.ebuild| 11 +++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index a075fba6..5969f136 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -658,7 +658,7 @@ class PythonCompatCheck(Check):
all_targets = (
f"python{x.slot.replace('.', '_')}"
for x in deps
-if x.key == "dev-lang/python" and x.slot is not None
+if x.key == "dev-lang/python" and x.slot is not None and not
x.slot.endswith("t")
)
latest_target = max(all_targets, key=self.sorter)
except ValueError:
diff --git
a/testdata/repos/python/PythonCompatCheck/PythonCompatUpdate/PythonCompatUpdate-4.ebuild
b/testdata/repos/python/PythonCompatCheck/PythonCompatUpdate/PythonCompatUpdate-4.ebuild
new file mode 100644
index ..a57c1d47
--- /dev/null
+++
b/testdata/repos/python/PythonCompatCheck/PythonCompatUpdate/PythonCompatUpdate-4.ebuild
@@ -0,0 +1,11 @@
+EAPI=7
+PYTHON_COMPAT=( python3_{7..10} python3_13t pypy3 pypy3_11 )
+
+inherit python-any-r1
+
+DESCRIPTION="Ebuild with potential PYTHON_COMPAT updates"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+DEPEND="${PYTHON_DEPS}"
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: b67acd43a296495f50bc6ce147ac45490ad6bc87
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Mar 8 16:21:10 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Mar 8 16:21:10 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b67acd43
PathVariablesCheck: add some more names
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/codingstyle.py | 8 +++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/pkgcheck/checks/codingstyle.py
b/src/pkgcheck/checks/codingstyle.py
index b49ffced..d5473616 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -190,7 +190,7 @@ class PathVariablesCheck(Check):
"""Scan ebuild for path variables with various issues."""
_source = sources.EbuildFileRepoSource
-known_results = frozenset([MissingSlash, UnnecessarySlashStrip,
DoublePrefixInPath])
+known_results = frozenset({MissingSlash, UnnecessarySlashStrip,
DoublePrefixInPath})
prefixed_dir_functions = (
"insinto",
"exeinto",
@@ -225,13 +225,19 @@ class PathVariablesCheck(Check):
# qmake-utils.eclass
"qt4_get_bindir",
"qt5_get_bindir",
+"qt6_get_bindir",
# s6.eclass
"s6_get_servicedir",
+# shell-completion.eclass
+"get_fishcompdir",
+"get_zshcompdir",
# systemd.eclass
"systemd_get_systemunitdir",
"systemd_get_userunitdir",
"systemd_get_utildir",
"systemd_get_systemgeneratordir",
+"systemd_get_systempresetdir",
+"systemd_get_sleepdir",
)
prefixed_rhs_variables = (
# catch silly ${ED}${EPREFIX} mistake ;-)
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: 03552ba817ef8851f763cd8274bbaf154cb60d8b Author: Arthur Zamarin gentoo org> AuthorDate: Sat Mar 1 19:14:23 2025 + Commit: Arthur Zamarin gentoo org> CommitDate: Sat Mar 1 19:14:23 2025 + URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=03552ba8 DeadUrl: don't crash if nvalid utf-8 data is returned by the server It was crashing for the URL: ftp://ftp.wspse.de/pub/linux/wspse/mp3c-0.31.tar.bz2 Signed-off-by: Arthur Zamarin gentoo.org> src/pkgcheck/checks/network.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkgcheck/checks/network.py b/src/pkgcheck/checks/network.py index 64e54280..6ac29d49 100644 --- a/src/pkgcheck/checks/network.py +++ b/src/pkgcheck/checks/network.py @@ -170,6 +170,8 @@ class _UrlCheck(NetworkCheck): result = DeadUrl(attr, url, str(e.reason), pkg=pkg) except socket.timeout as e: result = DeadUrl(attr, url, str(e), pkg=pkg) +except UnicodeDecodeError: +... # ignore ftp:// URLs that return binary data return result def task_done(self, pkg, attr, future):
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: f444cf692ecbd913d1c226438a200ff5e9f8a999
Author: Arthur Zamarin gentoo org>
AuthorDate: Thu Feb 27 19:27:33 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Thu Feb 27 19:27:33 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=f444cf69
TooManyCrates: new check for >300 CRATES
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/rust.py | 24 +++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/pkgcheck/checks/rust.py b/src/pkgcheck/checks/rust.py
index 7a5cbdad..346ba412 100644
--- a/src/pkgcheck/checks/rust.py
+++ b/src/pkgcheck/checks/rust.py
@@ -31,6 +31,24 @@ class SuboptimalCratesURICall(results.LineResult,
results.Warning):
return f"line: {self.lineno}: calling {self.line!r} is suboptimal, use
'${{CARGO_CRATE_URIS}}' for global CRATES instead"
+class TooManyCrates(results.VersionResult, results.Warning):
+"""Too many crates in ``CRATES`` variable.
+
+The ``CRATES`` variable is a space-separated list of crates. When it has
+more than 300 crates, it can cause performance issues for metadata
+generation and package manager handling. It is recommended to use a crates
+tarball instead.
+"""
+
+def __init__(self, count: int, **kwargs):
+super().__init__(**kwargs)
+self.count = count
+
+@property
+def desc(self):
+return f"CRATES variable has {self.count} crates, consider using
crates tarball instead"
+
+
class RustCheck(Check):
"""Checks for rust related issues."""
@@ -39,6 +57,7 @@ class RustCheck(Check):
{
SuboptimalCratesSeparator,
SuboptimalCratesURICall,
+TooManyCrates,
}
)
@@ -49,7 +68,10 @@ class RustCheck(Check):
val_node = node.children[-1]
row, _ = val_node.start_point
val_str = pkg.node_str(val_node).strip("'\"")
-for lineno, line in enumerate(val_str.splitlines(), start=row
+ 1):
+crates = val_str.split()
+if len(crates) > 300:
+yield TooManyCrates(count=len(crates), pkg=pkg)
+for lineno, line in enumerate(crates, start=row + 1):
for token in line.split():
if "@" not in token:
yield SuboptimalCratesSeparator(
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/dev-lang/pypy/, ...
commit: 649d63647eb4cd6d6d715d6c6b2eef738b2cc1c8
Author: Arthur Zamarin gentoo org>
AuthorDate: Thu Feb 27 17:21:54 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Thu Feb 27 17:21:54 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=649d6364
PythonCompatUpdate: also report for pypy3.* targets if has pypy3
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/python.py | 38 --
.../PythonCheck/DistutilsNonPEP517Build/fix.patch | 2 +-
.../PythonCompatUpdate/expected.json | 1 +
.../PythonCompatCheck/PythonCompatUpdate/fix.patch | 33 ---
.../DistutilsNonPEP517Build-0.ebuild | 2 +-
.../PythonAnyMismatchedDepHasVersionCheck-0.ebuild | 2 +-
.../PythonAnyMismatchedDepHasVersionCheck-1.ebuild | 2 +-
.../PythonAnyMismatchedUseHasVersionCheck-0.ebuild | 2 +-
.../PythonAnyMismatchedUseHasVersionCheck-1.ebuild | 2 +-
.../PythonAnyMismatchedUseHasVersionCheck-2.ebuild | 2 +-
.../PythonHasVersionMissingPythonUseDep-0.ebuild | 2 +-
.../PythonHasVersionUsage-0.ebuild | 2 +-
.../PythonHasVersionUsage-1.ebuild | 2 +-
.../PythonMissingDeps/PythonMissingDeps-0.ebuild | 2 +-
.../PythonMissingDeps/PythonMissingDeps-1.ebuild | 2 +-
.../PythonMissingDeps/PythonMissingDeps-2.ebuild | 2 +-
.../PythonCompatUpdate-3.ebuild} | 7 ++--
.../python/dev-lang/pypy/pypy-3.11.7.3.18.ebuild | 6
testdata/repos/python/eclass/python-any-r1.eclass | 7 +++-
testdata/repos/python/eclass/python-r1.eclass | 7 +++-
.../repos/python/eclass/python-single-r1.eclass| 7 +++-
.../repos/python/profiles/desc/python_targets.desc | 1 +
22 files changed, 92 insertions(+), 41 deletions(-)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 755272f0..a075fba6 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -599,12 +599,16 @@ class PythonCompatCheck(Check):
# determine available PYTHON_TARGET use flags
targets = []
+pypy_targets = []
for target, _desc in repo.use_expand_desc.get(IUSE_PREFIX[:-1], ()):
target = target.removeprefix(IUSE_PREFIX)
if target.startswith("python"):
targets.append(target)
+elif target.startswith("pypy"):
+pypy_targets.append(target)
targets = (x for x in targets if not x.endswith("t"))
multi_targets = tuple(sorted(targets, key=self.sorter))
+self.pypy_targets = tuple(sorted(pypy_targets, key=self.sorter))
# determine available PYTHON_SINGLE_TARGET use flags
targets = []
@@ -651,15 +655,13 @@ class PythonCompatCheck(Check):
try:
# determine the latest supported python version
-latest_target = sorted(
-(
-f"python{x.slot.replace('.', '_')}"
-for x in deps
-if x.key == "dev-lang/python" and x.slot is not None
-),
-key=self.sorter,
-)[-1]
-except IndexError:
+all_targets = (
+f"python{x.slot.replace('.', '_')}"
+for x in deps
+if x.key == "dev-lang/python" and x.slot is not None
+)
+latest_target = max(all_targets, key=self.sorter)
+except ValueError:
# should be flagged by PythonMissingDeps
return
@@ -670,6 +672,18 @@ class PythonCompatCheck(Check):
# determine python impls to target
targets = set(takewhile(lambda x: x != latest_target,
reversed(available_targets)))
+try:
+# determine the latest supported pypy version
+all_targets = (
+"pypy3" if x.slot == "3.10" else f"pypy{x.slot.replace('.',
'_')}"
+for x in deps
+if x.key == "dev-lang/pypy" and x.slot is not None
+)
+latest_pypy = max(all_targets, key=self.sorter)
+targets.update(takewhile(lambda x: x != latest_pypy,
reversed(self.pypy_targets)))
+except ValueError:
+...
+
if targets:
try:
# determine if deps support missing python targets
@@ -677,7 +691,11 @@ class PythonCompatCheck(Check):
# TODO: use query caching for repo matching?
latest = sorted(self.options.search_repo.match(dep))[-1]
targets.intersection_update(
-f"python{x.rsplit('python', 1)[-1]}"
+(
+f"pypy{x.rsplit('pypy', 1)[-1]}"
+if "pypy" in x
+else f"python{x.rsplit('python', 1)[-1]}"
+)
for x in latest.iuse_stripped
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/python/profiles/desc/, src/pkgcheck/checks/
commit: b86872a25614ca16177ca161638d8a0837cbda37
Author: Arthur Zamarin gentoo org>
AuthorDate: Thu Feb 27 16:39:06 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Thu Feb 27 16:39:06 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=b86872a2
PythonCompatUpdate: ignore *t targets (freethreading)
Resolves: https://github.com/pkgcore/pkgcheck/issues/711
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/python.py | 14 +-
testdata/repos/python/profiles/desc/python_targets.desc | 1 +
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 392241b2..755272f0 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -577,7 +577,7 @@ class PythonCompatCheck(Check):
``python-any-r1``.
"""
-known_results = frozenset([PythonCompatUpdate])
+known_results = frozenset({PythonCompatUpdate})
whitelist_backports = frozenset(
{
@@ -600,15 +600,19 @@ class PythonCompatCheck(Check):
# determine available PYTHON_TARGET use flags
targets = []
for target, _desc in repo.use_expand_desc.get(IUSE_PREFIX[:-1], ()):
-if target[len(IUSE_PREFIX) :].startswith("python"):
-targets.append(target[len(IUSE_PREFIX) :])
+target = target.removeprefix(IUSE_PREFIX)
+if target.startswith("python"):
+targets.append(target)
+targets = (x for x in targets if not x.endswith("t"))
multi_targets = tuple(sorted(targets, key=self.sorter))
# determine available PYTHON_SINGLE_TARGET use flags
targets = []
for target, _desc in repo.use_expand_desc.get(IUSE_PREFIX_S[:-1], ()):
-if target[len(IUSE_PREFIX_S) :].startswith("python"):
-targets.append(target[len(IUSE_PREFIX_S) :])
+target = target.removeprefix(IUSE_PREFIX_S)
+if target.startswith("python"):
+targets.append(target)
+targets = (x for x in targets if not x.endswith("t"))
single_targets = tuple(sorted(targets, key=self.sorter))
self.params = {
diff --git a/testdata/repos/python/profiles/desc/python_targets.desc
b/testdata/repos/python/profiles/desc/python_targets.desc
index 8e55f2da..3f87ee55 100644
--- a/testdata/repos/python/profiles/desc/python_targets.desc
+++ b/testdata/repos/python/profiles/desc/python_targets.desc
@@ -4,4 +4,5 @@ python3_7 - Build with Python 3.7
python3_8 - Build with Python 3.8
python3_9 - Build with Python 3.9
python3_10 - Build with Python 3.10
+python3_13t - Build with Python 3.13 freethreading
pypy3 - Build for PyPy3 only
[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: src/pkgcheck/checks/
commit: 8b934057b7cd08365ef395be8599840f183bf2e8
Author: Arthur Zamarin gentoo org>
AuthorDate: Sat Feb 22 08:29:58 2025 +
Commit: Arthur Zamarin gentoo org>
CommitDate: Sat Feb 22 08:29:58 2025 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=8b934057
RequiredUseDefaults: skip all USE flags with prefix "cpu_flags_"
Signed-off-by: Arthur Zamarin gentoo.org>
src/pkgcheck/checks/metadata.py | 10 +-
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py
index c81c5b09..e375ba1f 100644
--- a/src/pkgcheck/checks/metadata.py
+++ b/src/pkgcheck/checks/metadata.py
@@ -436,21 +436,21 @@ class RequiredUseCheck(Check):
src = FakeConfigurable(pkg, profile)
for node in pkg.required_use.evaluate_depset(src.use):
if not node.match(src.use):
-failures[node].append((src.use, profile.key,
profile.name))
+use_flag = str(node)
+if not use_flag.startswith("cpu_flags_"):
+failures[use_flag].append((src.use,
profile.key, profile.name))
if self.options.verbosity > 0:
# report all failures with profile info in verbose mode
for node, profile_info in failures.items():
for use, keyword, profile in profile_info:
-yield RequiredUseDefaults(str(node), sorted(use), keyword,
profile, pkg=pkg)
+yield RequiredUseDefaults(node, sorted(use), keyword,
profile, pkg=pkg)
else:
# only report one failure per REQUIRED_USE node in regular mode
for node, profile_info in failures.items():
num_profiles = len(profile_info)
_use, _keyword, profile = profile_info[0]
-yield RequiredUseDefaults(
-str(node), profile=profile, num_profiles=num_profiles,
pkg=pkg
-)
+yield RequiredUseDefaults(node, profile=profile,
num_profiles=num_profiles, pkg=pkg)
class UnusedLocalUse(results.PackageResult, results.Warning):
