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

2023-01-19 Thread Arthur Zamarin
commit: 72ec9a3d5ee68be6158566ce51ef3ab62ae23832
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Thu Jan 19 21:48:07 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Fri Jan 20 06:46:02 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=72ec9a3d

ArchesMisSync: check for arch.list <-> arches.desc missync

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

 src/pkgcheck/checks/profiles.py   | 19 +++
 .../RepoProfilesCheck/ArchesOutOfSync/expected.json   |  1 +
 .../RepoProfilesCheck/ArchesOutOfSync/fix.sh  |  2 ++
 testdata/repos/profiledir/profiles/arches.desc|  2 ++
 4 files changed, 24 insertions(+)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 625a05d6..a0b8c618 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -498,6 +498,20 @@ class NonexistentCategories(results.ProfilesResult, 
results.Warning):
 return f"nonexistent profiles/categories entr{ies}: {categories}"
 
 
+class ArchesOutOfSync(results.ProfilesResult, results.Error):
+"""``profiles/arches.desc`` is out of sync with ``arch.list``."""
+
+def __init__(self, arches):
+super().__init__()
+self.arches = tuple(arches)
+
+@property
+def desc(self):
+es = pluralism(self.arches, plural="es")
+arches = ", ".join(self.arches)
+return f"'profiles/arches.desc' is out of sync with 'arch.list', 
arch{es}: {arches}"
+
+
 def dir_parents(path):
 """Yield all directory path parents excluding the root directory.
 
@@ -533,6 +547,7 @@ class RepoProfilesCheck(RepoCheck):
 ProfileWarning,
 BannedProfileEapi,
 DeprecatedProfileEapi,
+ArchesOutOfSync,
 ]
 )
 
@@ -614,3 +629,7 @@ class RepoProfilesCheck(RepoCheck):
 
 if unused_profile_dirs := available_profile_dirs - seen_profile_dirs:
 yield UnusedProfileDirs(sorted(unused_profile_dirs))
+
+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))

diff --git 
a/testdata/data/repos/profiledir/RepoProfilesCheck/ArchesOutOfSync/expected.json
 
b/testdata/data/repos/profiledir/RepoProfilesCheck/ArchesOutOfSync/expected.json
new file mode 100644
index ..9e51e311
--- /dev/null
+++ 
b/testdata/data/repos/profiledir/RepoProfilesCheck/ArchesOutOfSync/expected.json
@@ -0,0 +1 @@
+{"__class__": "ArchesOutOfSync", "arches": ["unknown_arch"]}

diff --git 
a/testdata/data/repos/profiledir/RepoProfilesCheck/ArchesOutOfSync/fix.sh 
b/testdata/data/repos/profiledir/RepoProfilesCheck/ArchesOutOfSync/fix.sh
new file mode 100755
index ..d7c5432e
--- /dev/null
+++ b/testdata/data/repos/profiledir/RepoProfilesCheck/ArchesOutOfSync/fix.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+sed -i '/^unknown_arch/d' profiles/arch.list

diff --git a/testdata/repos/profiledir/profiles/arches.desc 
b/testdata/repos/profiledir/profiles/arches.desc
new file mode 100644
index ..d6266385
--- /dev/null
+++ b/testdata/repos/profiledir/profiles/arches.desc
@@ -0,0 +1,2 @@
+amd64 stable
+x86 testing



[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/profiledir/profiles/unknown_use/, ...

2023-01-17 Thread Arthur Zamarin
commit: 75664ae7e124d21b43245e6f6fcfbcd8a588950f
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Jan 15 21:02:52 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Mon Jan 16 20:00:20 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=75664ae7

ProfilesCheck: check for unknown USE_EXPAND_* in make.defaults

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

 src/pkgcheck/checks/profiles.py| 29 --
 .../UnknownProfileUseExpand/expected.json  |  2 ++
 .../UnknownProfileUseExpand/fix.patch  | 26 +++
 .../profiledir/profiles/desc/python_targets.desc   |  2 ++
 .../profiledir/profiles/unknown_use/make.defaults  |  7 ++
 5 files changed, 58 insertions(+), 8 deletions(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 6d113519..7929a10c 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -2,6 +2,7 @@
 
 import os
 from collections import defaultdict
+from typing import Iterable
 
 from pkgcore.ebuild import misc
 from pkgcore.ebuild import profiles as profiles_mod
@@ -96,16 +97,17 @@ class UnknownProfilePackageKeywords(results.ProfilesResult, 
results.Warning):
 class UnknownProfileUseExpand(results.ProfilesResult, results.Warning):
 """Profile includes nonexistent USE_EXPAND group(s)."""
 
-def __init__(self, path, groups):
+def __init__(self, path: str, var: str, groups: Iterable[str]):
 super().__init__()
 self.path = path
+self.var = var
 self.groups = tuple(groups)
 
 @property
 def desc(self):
 s = pluralism(self.groups)
 groups = ", ".join(self.groups)
-return f"{self.path!r}: unknown USE_EXPAND group{s}: {groups}"
+return f"{self.path!r}: unknown USE_EXPAND group{s} in {self.var!r}: 
{groups}"
 
 
 class UnknownProfileArch(results.ProfilesResult, results.Warning):
@@ -181,7 +183,10 @@ class ProfilesCheck(Check):
 self.keywords = keywords_addon
 self.search_repo = self.options.search_repo
 self.profiles_dir = repo.config.profiles_base
-self.use_expand_groups = frozenset(x.upper() for x in 
repo.config.use_expand_desc)
+self.use_expand_groups = {
+use.upper(): frozenset({val.removeprefix(f"{use}_") for val, _desc 
in vals})
+for use, vals in repo.config.use_expand_desc.items()
+}
 
 local_iuse = {use for _pkg, (use, _desc) in repo.config.use_local_desc}
 self.available_iuse = frozenset(
@@ -289,7 +294,7 @@ class ProfilesCheck(Check):
 yield UnknownProfilePackage(pjoin(node.name, filename), a)
 
 @verify_files(("make.defaults", "make_defaults"))
-def _make_defaults(self, filename: str, node, vals: dict[str, str]):
+def _make_defaults(self, filename: str, node: sources.ProfileNode, vals: 
dict[str, str]):
 if use_flags := {
 use.removeprefix("-")
 for use_group in ("USE", "IUSE_IMPLICIT")
@@ -297,14 +302,22 @@ class ProfilesCheck(Check):
 }:
 if unknown := use_flags - self.available_iuse:
 yield UnknownProfileUse(pjoin(node.name, filename), 
sorted(unknown))
-if defined := set(vals.get("USE_EXPAND", "").split()):
-if unknown := defined - self.use_expand_groups:
-yield UnknownProfileUseExpand(pjoin(node.name, filename), 
sorted(unknown))
+implicit_use_expands = set(vals.get("USE_EXPAND_IMPLICIT", "").split())
+for use_group in (
+"USE_EXPAND",
+"USE_EXPAND_HIDDEN",
+"USE_EXPAND_UNPREFIXED",
+):
+values = {use.removeprefix("-") for use in vals.get(use_group, 
"").split()}
+if unknown := values - self.use_expand_groups.keys() - 
implicit_use_expands:
+yield UnknownProfileUseExpand(
+pjoin(node.name, filename), use_group, sorted(unknown)
+)
 if arch := vals.get("ARCH", None):
 if arch not in self.keywords.arches:
 yield UnknownProfileArch(pjoin(node.name, filename), arch)
 
-def feed(self, profile):
+def feed(self, profile: sources.Profile):
 for f in profile.files.intersection(self.known_files):
 attr, func = self.known_files[f]
 with base.LogReports(*_logmap) as log_reports:

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/expected.json
 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/expected.json
new file mode 100644
index ..5817a2e1
--- /dev/null
+++ 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/expected.json
@@ -0,0 +1,2 @@
+{"__class__": "UnknownProfileUseExpand", "path": "unknown_use/make.defaults", 
"var": "USE_EXPAND", "groups": 

[gentoo-commits] proj/pkgcore/pkgcheck:master commit in: testdata/repos/profiledir/profiles/unknown_arch/, src/pkgcheck/addons/, ...

2023-01-17 Thread Arthur Zamarin
commit: 826c474777a1f0ff1c1051dbbf7196116e5a8cc9
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sun Jan 15 18:51:16 2023 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Sun Jan 15 18:51:25 2023 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=826c4747

ProfilesCheck: check for unknown ARCH in make.defaults

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

 src/pkgcheck/addons/__init__.py|  2 +-
 src/pkgcheck/checks/profiles.py| 25 ++
 .../ProfilesCheck/UnknownProfileArch/expected.json |  1 +
 .../ProfilesCheck/UnknownProfileArch/fix.patch |  6 ++
 testdata/repos/profiledir/profiles/profiles.desc   |  1 +
 .../repos/profiledir/profiles/unknown_arch/eapi|  1 +
 .../profiledir/profiles/unknown_arch/make.defaults |  1 +
 tests/scripts/test_pkgcheck_scan.py|  2 +-
 8 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/pkgcheck/addons/__init__.py b/src/pkgcheck/addons/__init__.py
index 5a5be2d0..56678669 100644
--- a/src/pkgcheck/addons/__init__.py
+++ b/src/pkgcheck/addons/__init__.py
@@ -89,7 +89,7 @@ class KeywordsAddon(base.Addon):
 def __init__(self, *args):
 super().__init__(*args)
 special = {"-*"}
-self.arches = self.options.target_repo.known_arches
+self.arches: frozenset[str] = self.options.target_repo.known_arches
 unstable = {"~" + x for x in self.arches}
 disabled = {"-" + x for x in chain(self.arches, unstable)}
 self.valid = special | self.arches | unstable | disabled

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index 8673ed7d..00d7c069 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -108,6 +108,19 @@ class UnknownProfileUseExpand(results.ProfilesResult, 
results.Warning):
 return f"{self.path!r}: unknown USE_EXPAND group{s}: {groups}"
 
 
+class UnknownProfileArch(results.ProfilesResult, results.Warning):
+"""Profile includes unknown ARCH."""
+
+def __init__(self, path: str, arch: str):
+super().__init__()
+self.path = path
+self.arch = arch
+
+@property
+def desc(self):
+return f"{self.path!r}: unknown ARCH {self.arch!r}"
+
+
 class ProfileWarning(results.ProfilesResult, results.LogWarning):
 """Badly formatted data in various profile files."""
 
@@ -146,22 +159,23 @@ class ProfilesCheck(Check):
 _source = sources.ProfilesRepoSource
 required_addons = (addons.UseAddon, addons.KeywordsAddon)
 known_results = frozenset(
-[
+{
 UnknownProfilePackage,
 UnmatchedProfilePackageUnmask,
 UnknownProfilePackageUse,
 UnknownProfileUse,
 UnknownProfilePackageKeywords,
 UnknownProfileUseExpand,
+UnknownProfileArch,
 ProfileWarning,
 ProfileError,
-]
+}
 )
 
 # mapping between known files and verification methods
 known_files = {}
 
-def __init__(self, *args, use_addon, keywords_addon):
+def __init__(self, *args, use_addon: addons.UseAddon, keywords_addon: 
addons.KeywordsAddon):
 super().__init__(*args)
 repo = self.options.target_repo
 self.keywords = keywords_addon
@@ -275,10 +289,13 @@ class ProfilesCheck(Check):
 yield UnknownProfilePackage(pjoin(node.name, filename), a)
 
 @verify_files(("make.defaults", "make_defaults"))
-def _make_defaults(self, filename, node, vals):
+def _make_defaults(self, filename: str, node, vals: dict[str, str]):
 if defined := set(vals.get("USE_EXPAND", "").split()):
 if unknown := defined - self.use_expand_groups:
 yield UnknownProfileUseExpand(pjoin(node.name, filename), 
sorted(unknown))
+if arch := vals.get("ARCH", None):
+if arch not in self.keywords.arches:
+yield UnknownProfileArch(pjoin(node.name, filename), arch)
 
 def feed(self, profile):
 for f in profile.files.intersection(self.known_files):

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileArch/expected.json 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileArch/expected.json
new file mode 100644
index ..17c7329f
--- /dev/null
+++ 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileArch/expected.json
@@ -0,0 +1 @@
+{"__class__": "UnknownProfileArch", "path": "unknown_arch/make.defaults", 
"arch": "unknown"}

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileArch/fix.patch 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileArch/fix.patch
new file mode 100644
index ..87aa24a0
--- /dev/null
+++ b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileArch/fix.patch
@@ -0,0 +1,6 @@
+diff -Naur 

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

2022-10-04 Thread Arthur Zamarin
commit: 03df2f52b71ec03e84047409b4564ae27b7c4a46
Author: Arthur Zamarin  gentoo  org>
AuthorDate: Sat Oct  1 14:10:02 2022 +
Commit: Arthur Zamarin  gentoo  org>
CommitDate: Tue Oct  4 10:43:06 2022 +
URL:
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=03df2f52

ProfilesCheck: new check for UnmatchedProfilePackageUnmask

Add missing check from repoman, for unmatched unmask of atom in
`package.mask` files. This checks for any unmask of package, which isn't
masked in parent profiles.

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

 src/pkgcheck/checks/profiles.py| 49 --
 .../UnmatchedProfilePackageUnmask/expected.json|  1 +
 .../UnmatchedProfilePackageUnmask/fix.patch|  7 
 testdata/repos/profiledir/profiles/profiles.desc   |  1 +
 .../profiledir/profiles/unmatched_unmasks/eapi |  1 +
 .../profiles/unmatched_unmasks/package.mask|  2 +
 .../profiledir/profiles/unmatched_unmasks/parent   |  1 +
 7 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/src/pkgcheck/checks/profiles.py b/src/pkgcheck/checks/profiles.py
index d825730f..73e2898e 100644
--- a/src/pkgcheck/checks/profiles.py
+++ b/src/pkgcheck/checks/profiles.py
@@ -28,6 +28,23 @@ class UnknownProfilePackage(results.ProfilesResult, 
results.Warning):
 return f'{self.path!r}: unknown package: {self.atom!r}'
 
 
+class UnmatchedProfilePackageUnmask(results.ProfilesResult, results.Warning):
+"""The profile's files include a package.unmask (or similar) entry which
+negates a non-existent mask, i.e. it undoes a mask which doesn't exist in
+the parent profile.
+
+No atoms matching this entry were found in the parent profile to unmask."""
+
+def __init__(self, path, atom):
+super().__init__()
+self.path = path
+self.atom = str(atom)
+
+@property
+def desc(self):
+return f'{self.path!r}: unmask of not masked package: {self.atom!r}'
+
+
 class UnknownProfilePackageUse(results.ProfilesResult, results.Warning):
 """Profile files include entries with USE flags that aren't used on any 
matching packages."""
 
@@ -129,7 +146,8 @@ class ProfilesCheck(Check):
 _source = sources.ProfilesRepoSource
 required_addons = (addons.UseAddon, addons.KeywordsAddon)
 known_results = frozenset([
-UnknownProfilePackage, UnknownProfilePackageUse, UnknownProfileUse,
+UnknownProfilePackage, UnmatchedProfilePackageUnmask,
+UnknownProfilePackageUse, UnknownProfileUse,
 UnknownProfilePackageKeywords, UnknownProfileUseExpand,
 ProfileWarning, ProfileError,
 ])
@@ -145,11 +163,19 @@ class ProfilesCheck(Check):
 self.profiles_dir = repo.config.profiles_base
 self.use_expand_groups = frozenset(x.upper() for x in 
repo.config.use_expand_desc)
 
-local_iuse = {use for pkg, (use, desc) in repo.config.use_local_desc}
+local_iuse = {use for _pkg, (use, _desc) in repo.config.use_local_desc}
 self.available_iuse = frozenset(
 local_iuse | use_addon.global_iuse |
 use_addon.global_iuse_expand | use_addon.global_iuse_implicit)
 
+@staticmethod
+def traverse_parents_tree(profile):
+def _traverse(node):
+for parent in node.parents:
+yield parent
+yield from _traverse(parent)
+return set(_traverse(profile))
+
 @verify_files(('parent', 'parents'),
   ('eapi', 'eapi'))
 def _pull_attr(self, *args):
@@ -160,7 +186,7 @@ class ProfilesCheck(Check):
 def _deprecated(self, filename, node, vals):
 # make sure replacement profile exists
 if vals is not None:
-replacement, msg = vals
+replacement, _msg = vals
 try:
 addons.profiles.ProfileNode(pjoin(self.profiles_dir, 
replacement))
 except profiles_mod.ProfileError:
@@ -195,7 +221,6 @@ class ProfilesCheck(Check):
 pjoin(node.name, filename), unknown_enabled)
 
 @verify_files(('packages', 'packages'),
-  ('package.mask', 'masks'),
   ('package.unmask', 'unmasks'),
   ('package.deprecated', 'pkg_deprecated'))
 def _pkg_atoms(self, filename, node, vals):
@@ -203,6 +228,22 @@ class ProfilesCheck(Check):
 if not self.search_repo.match(x):
 yield UnknownProfilePackage(pjoin(node.name, filename), x)
 
+@verify_files(('package.mask', 'masks'),)
+def _pkg_masks(self, filename, node, vals):
+all_parents = self.traverse_parents_tree(node)
+all_masked = set().union(*(masked[1]
+for p in all_parents if (masked := p.masks)))
+
+unmasked, masked = vals
+for x in masked:
+if not self.search_repo.match(x):
+yield UnknownProfilePackage(pjoin(node.name,