commit:     de599e61198012a5c7a6bda37e864609bc8d5754
Author:     Brian Harring <ferringb <AT> gmail <DOT> com>
AuthorDate: Sun Dec 25 22:50:50 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=de599e61

Force stable sorting of /etc/portage/* files loading.

Specifically, alphanumeric sorting; a '00' should always be
parsed before an '01' or 'a'.

The ordering must be stable so that globals- in a 00 file- can
be overridden per package via other files.  If there is no stable
ordering forced on how the order of files read, then this isn't supported.

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

 src/pkgcore/ebuild/domain.py |  3 ++-
 tests/ebuild/test_domain.py  | 56 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/src/pkgcore/ebuild/domain.py b/src/pkgcore/ebuild/domain.py
index 4e33e0fc9..7e76f1112 100644
--- a/src/pkgcore/ebuild/domain.py
+++ b/src/pkgcore/ebuild/domain.py
@@ -132,7 +132,8 @@ def generate_filter(masks, unmasks, *extra):
 def _read_config_file(path):
     """Read all the data files under a given path."""
     try:
-        for fs_obj in iter_scan(path, follow_symlinks=True):
+        # sort based on location by default; this is to ensure 00 is before 
01, and before a
+        for fs_obj in sorted(iter_scan(path, follow_symlinks=True)):
             if not fs_obj.is_reg or "/." in fs_obj.location:
                 continue
             for lineno, line in iter_read_bash(

diff --git a/tests/ebuild/test_domain.py b/tests/ebuild/test_domain.py
new file mode 100644
index 000000000..6629cfb9a
--- /dev/null
+++ b/tests/ebuild/test_domain.py
@@ -0,0 +1,56 @@
+from unittest import mock
+
+import pytest
+
+from pkgcore.ebuild import domain as domain_mod
+from pkgcore.ebuild import profiles
+from pkgcore.fs.livefs import iter_scan
+from pkgcore.restrictions import packages
+
+from .test_profiles import profile_mixin
+
+
+class TestDomain:
+    @pytest.fixture(autouse=True, scope="function")
+    def _setup(self, tmp_path_factory):
+        self.confdir = tmp_path_factory.mktemp("conf")
+        self.rootdir = tmp_path_factory.mktemp("root")
+        self.pmixin = profile_mixin()
+        self.profile_base = tmp_path_factory.mktemp("profiles")
+        self.profile1 = self.profile_base / "profile1"
+        self.pmixin.mk_profile(self.profile_base, str(self.profile1))
+
+    def mk_domain(self):
+        return domain_mod.domain(
+            profiles.OnDiskProfile(str(self.profile_base), "profile1"),
+            [],
+            [],
+            ROOT=self.rootdir,
+            config_dir=self.confdir,
+        )
+
+    def test_sorting(self):
+        """assert that configuration files are read in alphanum ordering"""
+        cdir = self.confdir / "package.use"
+        cdir.mkdir()
+
+        # assert the base state; no files, no content.
+        assert () == self.mk_domain().pkg_use
+
+        open(cdir / "00", "w").write("*/* X")
+        open(cdir / "01", "w").write("*/* -X Y")
+
+        # Force the returned ordering to be reversed; this is to assert that
+        # the domain forces a sort.
+        orig_func = iter_scan
+
+        def rev_iter_scan(*args, **kwargs):
+            return iter(sorted(orig_func(*args, **kwargs), reverse=True))
+
+        with mock.patch(
+            "pkgcore.fs.livefs.iter_scan", side_effect=rev_iter_scan
+        ), mock.patch("pkgcore.ebuild.domain.iter_scan", 
side_effect=rev_iter_scan):
+            assert (
+                (packages.AlwaysTrue, ((), ("X",))),
+                (packages.AlwaysTrue, (("X",), ("Y",))),
+            ) == self.mk_domain().pkg_use

Reply via email to