public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Arthur Zamarin" <arthurzam@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/pkgcore/pkgcore:master commit in: tests/ebuild/, src/pkgcore/ebuild/
Date: Mon, 26 Dec 2022 17:28:04 +0000 (UTC)	[thread overview]
Message-ID: <1672075644.6bcdbd769bfa8ebf78e31887e4fd54eaf1c47032.arthurzam@gentoo> (raw)

commit:     6bcdbd769bfa8ebf78e31887e4fd54eaf1c47032
Author:     Brian Harring <ferringb <AT> gmail <DOT> com>
AuthorDate: Sun Dec 25 23:23:15 2022 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Mon Dec 26 17:27:24 2022 +0000
URL:        https://gitweb.gentoo.org/proj/pkgcore/pkgcore.git/commit/?id=6bcdbd76

Add USE_EXPAND expansion awareness for /etc/portage/package.use/* files.

Specifically, if you have:
`*/* PYTHON_TARGETS: -python2_7 python3_9`

Pkgcore was treating `PYTHON_TARGETS:` as a use flag.  That's obviously
wrong, and the parsing should be tightened there.

Closes: https://github.com/pkgcore/pkgcore/issues/384
Signed-off-by: Brian Harring <ferringb <AT> gmail.com>
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcore/ebuild/domain.py | 44 ++++++++++++++++++++++++++++++++++++++------
 tests/ebuild/test_domain.py  | 28 ++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/src/pkgcore/ebuild/domain.py b/src/pkgcore/ebuild/domain.py
index 7e76f1112..6f86f7d14 100644
--- a/src/pkgcore/ebuild/domain.py
+++ b/src/pkgcore/ebuild/domain.py
@@ -66,15 +66,47 @@ def package_masks(iterable):
             logger.warning(f"{path!r}, line {lineno}: parsing error: {e}")
 
 
-def package_keywords_splitter(iterable):
+def restriction_payload_splitter(iterable, post_process=lambda x: x):
     for line, lineno, path in iterable:
         v = line.split()
         try:
-            yield parse_match(v[0]), tuple(v[1:]), line, lineno, path
+            # TODO: expand this invocation to allow threading token level validation down.
+            # things like "is this a valid use flag?"
+            yield parse_match(v[0]), tuple(post_process(v[1:])), line, lineno, path
         except ParseError as e:
             logger.warning(f"{path!r}, line {lineno}: parsing error: {e}")
 
 
+def package_use_splitter(iterable):
+    """Parse package.use user configuration files
+
+    Basic syntax is <query> (?:-?use_f )* (?:USE_EXPAND: (?:flags)*)
+    IE, a restriction to match, use flags to turn on.  If a 'flag' ends in ':'
+    then it's considered a USE_EXPAND directive, and all that follow are values of that
+    USE_EXPAND target and should be expanded into their normalized/long form.
+    """
+
+    def f(tokens: list[str]):
+        i = iter(tokens)
+        for idx, x in enumerate(i):
+            if x.endswith(":"):
+                # we encountered `USE_EXPAND:` , thus all following tokens
+                # are values of that.
+                x = x.lower()[:-1]
+                l = tokens[0:idx]
+                for flag in i:
+                    if flag.startswith("-"):
+                        flag = f"-{x}_{flag[1:]}"
+                    else:
+                        flag = f"{x}_{flag}"
+                    l.append(flag)
+                return l
+        # if we made it here, there's no USE_EXPAND; thus just return the original sequence
+        return tokens
+
+    return restriction_payload_splitter(iterable, post_process=f)
+
+
 def package_env_splitter(basedir, iterable):
     for line, lineno, path in iterable:
         val = line.split()
@@ -396,25 +428,25 @@ class domain(config_domain):
         return tuple(x[0] for x in data)
 
     # TODO: deprecated, remove in 0.11
-    @load_property("package.keywords", parse_func=package_keywords_splitter)
+    @load_property("package.keywords", parse_func=restriction_payload_splitter)
     def pkg_keywords(self, data, debug=False):
         if debug:
             return tuple(data)
         return tuple((x[0], stable_unique(x[1])) for x in data)
 
-    @load_property("package.accept_keywords", parse_func=package_keywords_splitter)
+    @load_property("package.accept_keywords", parse_func=restriction_payload_splitter)
     def pkg_accept_keywords(self, data, debug=False):
         if debug:
             return tuple(data)
         return tuple((x[0], stable_unique(x[1])) for x in data)
 
-    @load_property("package.license", parse_func=package_keywords_splitter)
+    @load_property("package.license", parse_func=restriction_payload_splitter)
     def pkg_licenses(self, data, debug=False):
         if debug:
             return tuple(data)
         return tuple((x[0], stable_unique(x[1])) for x in data)
 
-    @load_property("package.use", parse_func=package_keywords_splitter)
+    @load_property("package.use", parse_func=package_use_splitter)
     def pkg_use(self, data, debug=False):
         if debug:
             return tuple(data)

diff --git a/tests/ebuild/test_domain.py b/tests/ebuild/test_domain.py
index 6629cfb9a..87c3d489f 100644
--- a/tests/ebuild/test_domain.py
+++ b/tests/ebuild/test_domain.py
@@ -1,3 +1,4 @@
+import textwrap
 from unittest import mock
 
 import pytest
@@ -54,3 +55,30 @@ class TestDomain:
                 (packages.AlwaysTrue, ((), ("X",))),
                 (packages.AlwaysTrue, (("X",), ("Y",))),
             ) == self.mk_domain().pkg_use
+
+    def test_use_expand_syntax(self):
+        puse = self.confdir / "package.use"
+        puse.mkdir()
+        open(puse / "a", "w").write(
+            textwrap.dedent(
+                """
+                */* x_y1
+                # unrelated is there to verify that it's unaffected by the USE_EXPAND
+                */* unrelated X: -y1 y2
+                """
+            )
+        )
+
+        assert (
+            (packages.AlwaysTrue, ((), ("x_y1",))),
+            (
+                packages.AlwaysTrue,
+                (
+                    ("x_y1",),
+                    (
+                        "unrelated",
+                        "x_y2",
+                    ),
+                ),
+            ),
+        ) == self.mk_domain().pkg_use


             reply	other threads:[~2022-12-26 17:28 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-26 17:28 Arthur Zamarin [this message]
  -- strict thread matches above, loose matches on Subject: below --
2022-12-26 17:28 [gentoo-commits] proj/pkgcore/pkgcore:master commit in: tests/ebuild/, src/pkgcore/ebuild/ Arthur Zamarin
2022-12-26 17:28 Arthur Zamarin
2022-12-26 17:28 Arthur Zamarin
2023-01-02 20:03 Arthur Zamarin
2023-01-17 20:50 Arthur Zamarin
2023-02-02 19:58 Arthur Zamarin
2023-08-29 17:37 Arthur Zamarin
2023-10-23 17:35 Arthur Zamarin
2023-12-28  5:27 Arthur Zamarin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1672075644.6bcdbd769bfa8ebf78e31887e4fd54eaf1c47032.arthurzam@gentoo \
    --to=arthurzam@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox