commit:     75664ae7e124d21b43245e6f6fcfbcd8a588950f
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 15 21:02:52 2023 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Mon Jan 16 20:00:20 2023 +0000
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 <arthurzam <AT> 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 00000000..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": ["PYTHON_SINGLE_TARGET"]}
+{"__class__": "UnknownProfileUseExpand", "path": "unknown_use/make.defaults", 
"var": "USE_EXPAND_UNPREFIXED", "groups": ["LUA_TARGETS"]}

diff --git 
a/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/fix.patch
 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/fix.patch
new file mode 100644
index 00000000..f3932558
--- /dev/null
+++ 
b/testdata/data/repos/profiledir/ProfilesCheck/UnknownProfileUseExpand/fix.patch
@@ -0,0 +1,26 @@
+diff -Naur profiledir/profiles/desc/python_single_target.desc 
fixed/profiles/desc/python_single_target.desc
+new file mode 100644
+index 00000000..dcf7e163
+--- /dev/null
++++ fixed/profiles/desc/python_single_target.desc
+@@ -0,0 +1,3 @@
++python3_10 - Build for Python 3.10 only
++python3_11 - Build for Python 3.11 only
++
+diff -Naur profiledir/profiles/unknown_use/make.defaults 
fixed/profiles/unknown_use/make.defaults
+diff --git a/testdata/repos/profiledir/profiles/unknown_use/make.defaults 
b/testdata/repos/profiledir/profiles/unknown_use/make.defaults
+index 6d789215..2c98efd3 100644
+--- profiledir/profiles/unknown_use/make.defaults
++++ fixed/profiles/unknown_use/make.defaults
+@@ -1,9 +1,8 @@
+ USE="defaults_use used"
+ IUSE_IMPLICIT="defaults_iuse_implicit used"
+ USE_EXPAND_IMPLICIT="ARCH ELIBC"
+-USE_EXPAND="PYTHON_TARGETS PYTHON_SINGLE_TARGET"
+-USE_EXPAND_UNPREFIXED="ARCH LUA_TARGETS PYTHON_TARGETS"
++USE_EXPAND="PYTHON_TARGETS"
++USE_EXPAND_UNPREFIXED="ARCH PYTHON_TARGETS"
+ USE_EXPAND_VALUES_ARCH="amd64 x86"
+-USE_EXPAND_VALUES_LUA_TARGETS="lua5_1"
+ USE_EXPAND_VALUES_PYTHON_TARGETS="python3_9 python3_10"
+ PYTHON_TARGETS="python3_9 python3_10"

diff --git a/testdata/repos/profiledir/profiles/desc/python_targets.desc 
b/testdata/repos/profiledir/profiles/desc/python_targets.desc
new file mode 100644
index 00000000..75237297
--- /dev/null
+++ b/testdata/repos/profiledir/profiles/desc/python_targets.desc
@@ -0,0 +1,2 @@
+python3_10 - Build with Python 3.10
+python3_11 - Build with Python 3.11

diff --git a/testdata/repos/profiledir/profiles/unknown_use/make.defaults 
b/testdata/repos/profiledir/profiles/unknown_use/make.defaults
index 4699667b..9bcb7cb9 100644
--- a/testdata/repos/profiledir/profiles/unknown_use/make.defaults
+++ b/testdata/repos/profiledir/profiles/unknown_use/make.defaults
@@ -1,2 +1,9 @@
 USE="defaults_use used"
 IUSE_IMPLICIT="defaults_iuse_implicit used"
+USE_EXPAND_IMPLICIT="ARCH ELIBC"
+USE_EXPAND="PYTHON_TARGETS PYTHON_SINGLE_TARGET"
+USE_EXPAND_UNPREFIXED="ARCH LUA_TARGETS PYTHON_TARGETS"
+USE_EXPAND_VALUES_ARCH="amd64 x86"
+USE_EXPAND_VALUES_LUA_TARGETS="lua5_1"
+USE_EXPAND_VALUES_PYTHON_TARGETS="python3_9 python3_10"
+PYTHON_TARGETS="python3_9 python3_10"

Reply via email to