commit:     bb09a2d4db4cd0f85f8ae8ceaddc05ae2585aba3
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat Sep 10 06:22:39 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Sep 28 23:56:08 2022 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=bb09a2d4

portage: sets: VariableSet: parse *DEPEND in includes/excludes

VariableSet takes a metadata variable and checks
its contents based on 'includes' or 'excludes'
from the set definition.

Unfortunately, until now, it didn't parse/expand the chosen variable
and would only match it literally (it'd also not check effective
metadata, just what's listed in the ebuild -- no *DEPEND
from an eclass, for example).

If variable is *DEPEND, actually parse includes/excludes
so we can effecitvely match say, includes="dev-lang/go"
against ">=dev-lang/go-1.18" in an ebuild.

Bug: https://bugs.gentoo.org/827974
Bug: https://bugs.gentoo.org/865115
Signed-off-by: Sam James <sam <AT> gentoo.org>

 lib/portage/_sets/dbapi.py | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/lib/portage/_sets/dbapi.py b/lib/portage/_sets/dbapi.py
index 4a837522f..5e7b00e08 100644
--- a/lib/portage/_sets/dbapi.py
+++ b/lib/portage/_sets/dbapi.py
@@ -168,14 +168,31 @@ class VariableSet(EverythingSet):
             return False
         (values,) = self._metadatadb.aux_get(ebuild, [self._variable])
         values = values.split()
+
+        if "DEPEND" in self._variable:
+            include_atoms = []
+            for include in self._includes:
+                include_atoms.append(Atom(include))
+
+            for x in use_reduce(values, token_class=Atom):
+                if not isinstance(x, Atom):
+                    continue
+
+                for include_atom in include_atoms:
+                    if include_atom.match(x):
+                        return True
+
+            return False
+
         if self._includes and not self._includes.intersection(values):
             return False
+
         if self._excludes and self._excludes.intersection(values):
             return False
+
         return True
 
     def singleBuilder(cls, options, settings, trees):
-
         variable = options.get("variable")
         if variable is None:
             raise SetConfigError(_("missing required attribute: 'variable'"))

Reply via email to