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