Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] Handle binary package IUSE_IMPLICIT divergence (bug 640318)
Date: Mon, 11 Dec 2017 01:54:39
Message-Id: 20171211015136.104030-1-zmedico@gentoo.org
1 Since profile IUSE_IMPLICIT settings may diverge from those
2 that a binary package was built with, consider members of
3 built USE settings to be members of IUSE_EFFECTIVE. Only do
4 this for EAPIs that support IUSE_EFFECTIVE, since built USE
5 settings for earlier EAPIs may contain a large number of
6 irrelevant flags.
7
8 Note that the binary package may be remote, so it's only
9 possible to rely on metadata that is available in the remote
10 Packages file, and the IUSE_IMPLICIT header in the Packages
11 file is vulnerable to mutation.
12
13 Bug: https://bugs.gentoo.org/640318
14 ---
15 pym/_emerge/Package.py | 32 +++++++++++++++++++++++++++++++
16 pym/portage/dbapi/__init__.py | 5 +++++
17 pym/portage/package/ebuild/config.py | 6 ++++++
18 pym/portage/tests/dbapi/test_fakedbapi.py | 20 +++++++++++++++++++
19 4 files changed, 63 insertions(+)
20
21 diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py
22 index 2c1a116ea..e1943175d 100644
23 --- a/pym/_emerge/Package.py
24 +++ b/pym/_emerge/Package.py
25 @@ -3,6 +3,7 @@
26
27 from __future__ import unicode_literals
28
29 +import functools
30 import sys
31 from itertools import chain
32 import warnings
33 @@ -82,6 +83,10 @@ class Package(Task):
34
35 if eapi_attrs.iuse_effective:
36 implicit_match = self.root_config.settings._iuse_effective_match
37 + if self.built:
38 + implicit_match = functools.partial(
39 + self._built_iuse_effective_match,
40 + implicit_match, frozenset(self._metadata['USE'].split()))
41 else:
42 implicit_match = self.root_config.settings._iuse_implicit_match
43 usealiases = self.root_config.settings._use_manager.getUseAliases(self)
44 @@ -109,6 +114,33 @@ class Package(Task):
45 type_name=self.type_name)
46 self._hash_value = hash(self._hash_key)
47
48 + @staticmethod
49 + def _built_iuse_effective_match(prof_effective_match, built_use, flag):
50 + """
51 + For built packages, it is desirable for the built USE setting to be
52 + independent of the profile's current IUSE_IMPLICIT state, since the
53 + profile's IUSE_IMPLICT setting may have diverged. Therefore, any
54 + member the built USE is setting considered to be a valid member of
55 + IUSE_EFFECTIVE. Note that the binary package may be remote, so it's
56 + only possible to rely on metadata that is available in the remote
57 + Packages file, and the IUSE_IMPLICIT header in the Packages file is
58 + vulnerable to mutation (see bug 640318).
59 +
60 + This function is only used for EAPIs that support IUSE_EFFECTIVE,
61 + since built USE settings for earlier EAPIs may contain a large
62 + number of irrelevant flags.
63 +
64 + @param prof_effective_match: function to match IUSE_EFFECTIVE
65 + values for the current profile
66 + @type prof_effective_match: callable
67 + @param built_use: built USE setting
68 + @type built_use: frozenset
69 + @return: True if flag is a valid USE value which may
70 + be specified in USE dependencies, False otherwise.
71 + @rtype: bool
72 + """
73 + return flag in built_use or prof_effective_match(flag)
74 +
75 @property
76 def eapi(self):
77 return self._metadata["EAPI"]
78 diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py
79 index 95053840d..2574b63df 100644
80 --- a/pym/portage/dbapi/__init__.py
81 +++ b/pym/portage/dbapi/__init__.py
82 @@ -5,6 +5,7 @@ from __future__ import unicode_literals
83
84 __all__ = ["dbapi"]
85
86 +import functools
87 import re
88
89 import portage
90 @@ -219,6 +220,10 @@ class dbapi(object):
91 eapi_attrs = _get_eapi_attrs(metadata["EAPI"])
92 if eapi_attrs.iuse_effective:
93 iuse_implicit_match = self.settings._iuse_effective_match
94 + if not self._use_mutable:
95 + iuse_implicit_match = functools.partial(
96 + Package._built_iuse_effective_match,
97 + iuse_implicit_match, frozenset(metadata["USE"].split()))
98 else:
99 iuse_implicit_match = self.settings._iuse_implicit_match
100 usealiases = self.settings._use_manager.getUseAliases(pkg)
101 diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
102 index cd2b009aa..d0225a311 100644
103 --- a/pym/portage/package/ebuild/config.py
104 +++ b/pym/portage/package/ebuild/config.py
105 @@ -1693,6 +1693,12 @@ class config(object):
106 iuse_implicit_match = self._iuse_effective_match
107 portage_iuse = set(self._iuse_effective)
108 portage_iuse.update(explicit_iuse)
109 + if built_use is not None:
110 + # When the binary package was built, the profile may have
111 + # had different IUSE_IMPLICIT settings, so any member of
112 + # the built USE setting is considered to be a member of
113 + # IUSE_EFFECTIVE (see bug 640318).
114 + portage_iuse.update(built_use)
115 self.configdict["pkg"]["IUSE_EFFECTIVE"] = \
116 " ".join(sorted(portage_iuse))
117 else:
118 diff --git a/pym/portage/tests/dbapi/test_fakedbapi.py b/pym/portage/tests/dbapi/test_fakedbapi.py
119 index e4f5dd771..19ea9cd00 100644
120 --- a/pym/portage/tests/dbapi/test_fakedbapi.py
121 +++ b/pym/portage/tests/dbapi/test_fakedbapi.py
122 @@ -14,6 +14,20 @@ class TestFakedbapi(TestCase):
123
124 def testFakedbapi(self):
125 packages = (
126 + ("app-misc/foo-1", {
127 + "EAPI" : "2", # does not support IUSE_EFFECTIVE
128 + "IUSE" : "",
129 + "repository" : "gentoo",
130 + "SLOT" : "1",
131 + "USE" : "missing-iuse",
132 + }),
133 + ("app-misc/foo-2", {
134 + "EAPI" : "5", # supports IUSE_EFFECTIVE
135 + "IUSE" : "",
136 + "repository" : "gentoo",
137 + "SLOT" : "2",
138 + "USE" : "missing-iuse",
139 + }),
140 ("sys-apps/portage-2.1.10", {
141 "EAPI" : "2",
142 "IUSE" : "ipc doc",
143 @@ -29,6 +43,12 @@ class TestFakedbapi(TestCase):
144 )
145
146 match_tests = (
147 + # The missing-iuse match is only intended to work for binary
148 + # packages with EAPIs that support IUSE_EFFECTIVE (bug 640318).
149 + ("app-misc/foo[missing-iuse]", ["app-misc/foo-2"]),
150 + ("app-misc/foo[-missing-iuse]", []),
151 + ("app-misc/foo", ["app-misc/foo-1", "app-misc/foo-2"]),
152 +
153 ("sys-apps/portage:0[ipc]", ["sys-apps/portage-2.1.10"]),
154 ("sys-apps/portage:0[-ipc]", []),
155 ("sys-apps/portage:0[doc]", []),
156 --
157 2.13.6