commit:     35bc26108e0bd4b99e4d621622634665122bf1a8
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Fri Aug  1 15:16:44 2025 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  1 15:16:44 2025 +0000
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 <arthurzam <AT> 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 00000000..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 00000000..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"
+ IUSE="used"
++KEYWORDS="amd64"

diff --git a/testdata/repos/profiledir/profiles/default/packages 
b/testdata/repos/profiledir/profiles/default/packages
new file mode 100644
index 00000000..9bd2f97e
--- /dev/null
+++ b/testdata/repos/profiledir/profiles/default/packages
@@ -0,0 +1 @@
+*cat/pkg1

Reply via email to