1 |
Use an explicit USE_ORDER entry to control mapping FEATURES=test into |
2 |
default-enabled USE=test, rather than forcing/masking it depending |
3 |
on the state of FEATURES. |
4 |
|
5 |
This makes it possible for users to enable (or disable) USE=test |
6 |
independently of FEATURES. An example use case is installing test |
7 |
dependencies and building test cases without actually running tests |
8 |
at a particular moment which is something I've been doing quite |
9 |
frequently with LLVM. |
10 |
--- |
11 |
cnf/make.globals | 2 +- |
12 |
lib/portage/eapi.py | 2 +- |
13 |
lib/portage/package/ebuild/config.py | 51 +++++---- |
14 |
.../tests/resolver/test_features_test_use.py | 108 +++++++++++------- |
15 |
man/make.conf.5 | 6 +- |
16 |
5 files changed, 101 insertions(+), 68 deletions(-) |
17 |
|
18 |
diff --git a/cnf/make.globals b/cnf/make.globals |
19 |
index 08a37a534..04a708af8 100644 |
20 |
--- a/cnf/make.globals |
21 |
+++ b/cnf/make.globals |
22 |
@@ -107,7 +107,7 @@ CONFIG_PROTECT="/etc" |
23 |
CONFIG_PROTECT_MASK="/etc/env.d" |
24 |
|
25 |
# Disable auto-use |
26 |
-USE_ORDER="env:pkg:conf:defaults:pkginternal:repo:env.d" |
27 |
+USE_ORDER="env:pkg:conf:defaults:pkginternal:features:repo:env.d" |
28 |
|
29 |
# Mode bits for ${WORKDIR} (see ebuild.5). |
30 |
PORTAGE_WORKDIR_MODE="0700" |
31 |
diff --git a/lib/portage/eapi.py b/lib/portage/eapi.py |
32 |
index 158d58243..5e12e976d 100644 |
33 |
--- a/lib/portage/eapi.py |
34 |
+++ b/lib/portage/eapi.py |
35 |
@@ -170,7 +170,7 @@ def _get_eapi_attrs(eapi): |
36 |
exports_EBUILD_PHASE_FUNC = (eapi is None or eapi_exports_EBUILD_PHASE_FUNC(eapi)), |
37 |
exports_PORTDIR = (eapi is None or eapi_exports_PORTDIR(eapi)), |
38 |
exports_ECLASSDIR = (eapi is not None and eapi_exports_ECLASSDIR(eapi)), |
39 |
- feature_flag_test = True, |
40 |
+ feature_flag_test = False, |
41 |
feature_flag_targetroot = (eapi is not None and eapi_has_targetroot(eapi)), |
42 |
hdepend = (eapi is not None and eapi_has_hdepend(eapi)), |
43 |
iuse_defaults = (eapi is None or eapi_has_iuse_defaults(eapi)), |
44 |
diff --git a/lib/portage/package/ebuild/config.py b/lib/portage/package/ebuild/config.py |
45 |
index 320d9f6c0..e253b680b 100644 |
46 |
--- a/lib/portage/package/ebuild/config.py |
47 |
+++ b/lib/portage/package/ebuild/config.py |
48 |
@@ -294,6 +294,7 @@ class config(object): |
49 |
self.configlist = [ |
50 |
self.configdict['env.d'], |
51 |
self.configdict['repo'], |
52 |
+ self.configdict['features'], |
53 |
self.configdict['pkginternal'], |
54 |
self.configdict['globals'], |
55 |
self.configdict['defaults'], |
56 |
@@ -461,13 +462,16 @@ class config(object): |
57 |
# back up our incremental variables: |
58 |
self.configdict={} |
59 |
self._use_expand_dict = {} |
60 |
- # configlist will contain: [ env.d, globals, defaults, conf, pkg, backupenv, env ] |
61 |
+ # configlist will contain: [ env.d, globals, features, defaults, conf, pkg, backupenv, env ] |
62 |
self.configlist.append({}) |
63 |
self.configdict["env.d"] = self.configlist[-1] |
64 |
|
65 |
self.configlist.append({}) |
66 |
self.configdict["repo"] = self.configlist[-1] |
67 |
|
68 |
+ self.configlist.append({}) |
69 |
+ self.configdict["features"] = self.configlist[-1] |
70 |
+ |
71 |
self.configlist.append({}) |
72 |
self.configdict["pkginternal"] = self.configlist[-1] |
73 |
|
74 |
@@ -868,7 +872,7 @@ class config(object): |
75 |
# reasonable defaults; this is important as without USE_ORDER, |
76 |
# USE will always be "" (nothing set)! |
77 |
if "USE_ORDER" not in self: |
78 |
- self["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:repo:env.d" |
79 |
+ self["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:features:repo:env.d" |
80 |
self.backup_changes("USE_ORDER") |
81 |
|
82 |
if "CBUILD" not in self and "CHOST" in self: |
83 |
@@ -1292,6 +1296,7 @@ class config(object): |
84 |
del self._penv[:] |
85 |
self.configdict["pkg"].clear() |
86 |
self.configdict["pkginternal"].clear() |
87 |
+ self.configdict["features"].clear() |
88 |
self.configdict["repo"].clear() |
89 |
self.configdict["defaults"]["USE"] = \ |
90 |
" ".join(self.make_defaults_use) |
91 |
@@ -1452,6 +1457,7 @@ class config(object): |
92 |
cp = cpv_getkey(mycpv) |
93 |
cpv_slot = self.mycpv |
94 |
pkginternaluse = "" |
95 |
+ feature_use = "" |
96 |
iuse = "" |
97 |
pkg_configdict = self.configdict["pkg"] |
98 |
previous_iuse = pkg_configdict.get("IUSE") |
99 |
@@ -1650,6 +1656,23 @@ class config(object): |
100 |
if has_changed: |
101 |
self.reset(keeping_pkg=1) |
102 |
|
103 |
+ if explicit_iuse is None: |
104 |
+ explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split()) |
105 |
+ if eapi_attrs.iuse_effective: |
106 |
+ iuse_implicit_match = self._iuse_effective_match |
107 |
+ else: |
108 |
+ iuse_implicit_match = self._iuse_implicit_match |
109 |
+ |
110 |
+ if "test" in explicit_iuse or iuse_implicit_match("test"): |
111 |
+ if "test" in self.features: |
112 |
+ feature_use += "test" |
113 |
+ |
114 |
+ if feature_use != self.configdict["features"].get("USE", ""): |
115 |
+ self.configdict["features"]["USE"] = feature_use |
116 |
+ # TODO: can we avoid that? |
117 |
+ self.reset(keeping_pkg=1) |
118 |
+ has_changed = True |
119 |
+ |
120 |
env_configdict = self.configdict['env'] |
121 |
|
122 |
# Ensure that "pkg" values are always preferred over "env" values. |
123 |
@@ -1677,11 +1700,8 @@ class config(object): |
124 |
# package has different IUSE. |
125 |
use = set(self["USE"].split()) |
126 |
unfiltered_use = frozenset(use) |
127 |
- if explicit_iuse is None: |
128 |
- explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split()) |
129 |
|
130 |
if eapi_attrs.iuse_effective: |
131 |
- iuse_implicit_match = self._iuse_effective_match |
132 |
portage_iuse = set(self._iuse_effective) |
133 |
portage_iuse.update(explicit_iuse) |
134 |
if built_use is not None: |
135 |
@@ -1693,7 +1713,6 @@ class config(object): |
136 |
self.configdict["pkg"]["IUSE_EFFECTIVE"] = \ |
137 |
" ".join(sorted(portage_iuse)) |
138 |
else: |
139 |
- iuse_implicit_match = self._iuse_implicit_match |
140 |
portage_iuse = self._get_implicit_iuse() |
141 |
portage_iuse.update(explicit_iuse) |
142 |
|
143 |
@@ -1729,21 +1748,17 @@ class config(object): |
144 |
self.get("EBUILD_FORCE_TEST") == "1" |
145 |
|
146 |
if "test" in explicit_iuse or iuse_implicit_match("test"): |
147 |
- if "test" not in self.features: |
148 |
- use.discard("test") |
149 |
- elif restrict_test or \ |
150 |
+ if "test" in self.features: |
151 |
+ if ebuild_force_test and "test" in self.usemask: |
152 |
+ self.usemask = \ |
153 |
+ frozenset(x for x in self.usemask if x != "test") |
154 |
+ if restrict_test or \ |
155 |
("test" in self.usemask and not ebuild_force_test): |
156 |
# "test" is in IUSE and USE=test is masked, so execution |
157 |
# of src_test() probably is not reliable. Therefore, |
158 |
# temporarily disable FEATURES=test just for this package. |
159 |
self["FEATURES"] = " ".join(x for x in self.features \ |
160 |
if x != "test") |
161 |
- use.discard("test") |
162 |
- else: |
163 |
- use.add("test") |
164 |
- if ebuild_force_test and "test" in self.usemask: |
165 |
- self.usemask = \ |
166 |
- frozenset(x for x in self.usemask if x != "test") |
167 |
|
168 |
if eapi_attrs.feature_flag_targetroot and \ |
169 |
("targetroot" in explicit_iuse or iuse_implicit_match("targetroot")): |
170 |
@@ -1900,12 +1915,6 @@ class config(object): |
171 |
iuse_implicit.add("build") |
172 |
iuse_implicit.add("bootstrap") |
173 |
|
174 |
- # Controlled by FEATURES=test. Make this implicit, so handling |
175 |
- # of FEATURES=test is consistent regardless of explicit IUSE. |
176 |
- # Users may use use.mask/package.use.mask to control |
177 |
- # FEATURES=test for all ebuilds, regardless of explicit IUSE. |
178 |
- iuse_implicit.add("test") |
179 |
- |
180 |
return iuse_implicit |
181 |
|
182 |
def _getUseMask(self, pkg, stable=None): |
183 |
diff --git a/lib/portage/tests/resolver/test_features_test_use.py b/lib/portage/tests/resolver/test_features_test_use.py |
184 |
index bdd179d7a..da7172c17 100644 |
185 |
--- a/lib/portage/tests/resolver/test_features_test_use.py |
186 |
+++ b/lib/portage/tests/resolver/test_features_test_use.py |
187 |
@@ -1,68 +1,88 @@ |
188 |
-# Copyright 2012 Gentoo Foundation |
189 |
+# Copyright 2012-2018 Gentoo Foundation |
190 |
# Distributed under the terms of the GNU General Public License v2 |
191 |
|
192 |
from portage.tests import TestCase |
193 |
from portage.tests.resolver.ResolverPlayground import (ResolverPlayground, |
194 |
ResolverPlaygroundTestCase) |
195 |
|
196 |
-class FeaturesTestUse(TestCase): |
197 |
|
198 |
- def testFeaturesTestUse(self): |
199 |
- ebuilds = { |
200 |
- "dev-libs/A-1" : { |
201 |
- "IUSE": "test" |
202 |
- }, |
203 |
- "dev-libs/B-1" : { |
204 |
- "IUSE": "test foo" |
205 |
- }, |
206 |
- } |
207 |
+class TestDepend(TestCase): |
208 |
+ ebuilds = { |
209 |
+ "dev-libs/A-1" : { |
210 |
+ "IUSE": "test", |
211 |
+ "DEPEND": "test? ( dev-libs/B )", |
212 |
+ }, |
213 |
+ "dev-libs/B-1" : { |
214 |
+ }, |
215 |
+ } |
216 |
|
217 |
- installed = { |
218 |
- "dev-libs/A-1" : { |
219 |
- "USE": "", |
220 |
- "IUSE": "test" |
221 |
- }, |
222 |
- "dev-libs/B-1" : { |
223 |
- "USE": "foo", |
224 |
- "IUSE": "test foo" |
225 |
- }, |
226 |
- } |
227 |
+ installed = { |
228 |
+ "dev-libs/A-1" : { |
229 |
+ "USE": "", |
230 |
+ "IUSE": "test", |
231 |
+ "DEPEND": "test? ( dev-libs/B )", |
232 |
+ }, |
233 |
+ } |
234 |
|
235 |
+ def test_default_use_test(self): |
236 |
+ """ |
237 |
+ Test that FEATURES=test enables USE=test by default. |
238 |
+ """ |
239 |
user_config = { |
240 |
- "make.conf" : ("FEATURES=test", "USE=\"-test -foo\"") |
241 |
+ "make.conf" : ("FEATURES=test", "USE=\"\"") |
242 |
} |
243 |
- |
244 |
- test_cases = ( |
245 |
- |
246 |
- # USE=test state should not trigger --newuse rebuilds, as |
247 |
- # specified in bug #373209, comment #3. |
248 |
- ResolverPlaygroundTestCase( |
249 |
+ test_case = ResolverPlaygroundTestCase( |
250 |
["dev-libs/A"], |
251 |
- options = {"--newuse": True, "--selective": True}, |
252 |
+ options = {}, |
253 |
success = True, |
254 |
- mergelist = []), |
255 |
+ mergelist = ["dev-libs/B-1", "dev-libs/A-1"]) |
256 |
+ |
257 |
+ playground = ResolverPlayground(ebuilds=self.ebuilds, |
258 |
+ user_config=user_config, debug=False) |
259 |
+ try: |
260 |
+ playground.run_TestCase(test_case) |
261 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
262 |
+ finally: |
263 |
+ playground.cleanup() |
264 |
|
265 |
- # USE=-test -> USE=test, with USE=test forced by FEATURES=test |
266 |
- ResolverPlaygroundTestCase( |
267 |
+ def test_no_forced_use_test(self): |
268 |
+ """ |
269 |
+ Test that FEATURES=test no longer forces USE=test. |
270 |
+ """ |
271 |
+ user_config = { |
272 |
+ "make.conf" : ("FEATURES=test", "USE=\"-test\"") |
273 |
+ } |
274 |
+ test_case = ResolverPlaygroundTestCase( |
275 |
["dev-libs/A"], |
276 |
options = {}, |
277 |
success = True, |
278 |
- mergelist = ["dev-libs/A-1"]), |
279 |
+ mergelist = ["dev-libs/A-1"]) |
280 |
+ |
281 |
+ playground = ResolverPlayground(ebuilds=self.ebuilds, |
282 |
+ user_config=user_config, debug=False) |
283 |
+ try: |
284 |
+ playground.run_TestCase(test_case) |
285 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
286 |
+ finally: |
287 |
+ playground.cleanup() |
288 |
|
289 |
- # USE=foo -> USE=-foo, with USE=test forced by FEATURES=test |
290 |
- ResolverPlaygroundTestCase( |
291 |
- ["dev-libs/B"], |
292 |
+ def test_newuse(self): |
293 |
+ """ |
294 |
+ Test that --newuse now detects USE=test changes. |
295 |
+ """ |
296 |
+ user_config = { |
297 |
+ "make.conf" : ("FEATURES=test", "USE=\"\"") |
298 |
+ } |
299 |
+ test_case = ResolverPlaygroundTestCase( |
300 |
+ ["dev-libs/A"], |
301 |
options = {"--newuse": True, "--selective": True}, |
302 |
success = True, |
303 |
- mergelist = ["dev-libs/B-1"]), |
304 |
- ) |
305 |
+ mergelist = ["dev-libs/B-1", "dev-libs/A-1"]) |
306 |
|
307 |
- playground = ResolverPlayground(ebuilds=ebuilds, |
308 |
- installed=installed, user_config=user_config, debug=False) |
309 |
+ playground = ResolverPlayground(ebuilds=self.ebuilds, |
310 |
+ user_config=user_config, debug=False) |
311 |
try: |
312 |
- for test_case in test_cases: |
313 |
- playground.run_TestCase(test_case) |
314 |
- self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
315 |
+ playground.run_TestCase(test_case) |
316 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
317 |
finally: |
318 |
playground.cleanup() |
319 |
- |
320 |
diff --git a/man/make.conf.5 b/man/make.conf.5 |
321 |
index cb0f00237..a4e33923c 100644 |
322 |
--- a/man/make.conf.5 |
323 |
+++ b/man/make.conf.5 |
324 |
@@ -1138,7 +1138,7 @@ This variable contains options that control the build behavior of several |
325 |
packages. More information in \fBebuild\fR(5). Possible USE values |
326 |
can be found in \fI/usr/portage/profiles/use.desc\fR. |
327 |
.TP |
328 |
-\fBUSE_ORDER\fR = \fI"env:pkg:conf:defaults:pkginternal:repo:env.d"\fR |
329 |
+\fBUSE_ORDER\fR = \fI"env:pkg:conf:defaults:pkginternal:features:repo:env.d"\fR |
330 |
Determines the precedence of layers in the incremental stacking of the USE |
331 |
variable. Precedence decreases from left to right such that env overrides |
332 |
pkg, pkg overrides conf, and so forth. |
333 |
@@ -1167,6 +1167,10 @@ USE from make.defaults and package.use in the profile |
334 |
.B pkginternal |
335 |
USE from \fBebuild\fR(5) IUSE defaults |
336 |
.TP |
337 |
+.B features |
338 |
+Flags implied by FEATURES. Currently includes USE=\fBtest\fR |
339 |
+for FEATURES=\fBtest\fR. |
340 |
+.TP |
341 |
.B repo |
342 |
USE from make.defaults and package.use in the repo's profiles/ top dir |
343 |
(e.g. /usr/portage/profiles/package.use) (see \fBportage\fR(5)) |
344 |
-- |
345 |
2.18.0 |