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 | 52 +++++---- |
14 |
.../tests/resolver/test_features_test_use.py | 108 +++++++++++------- |
15 |
man/make.conf.5 | 6 +- |
16 |
5 files changed, 102 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..37c5c6656 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,24 @@ 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.append("test") |
113 |
+ |
114 |
+ feature_use = " ".join(feature_use) |
115 |
+ if feature_use != self.configdict["features"].get("USE", ""): |
116 |
+ self.configdict["features"]["USE"] = feature_use |
117 |
+ # TODO: can we avoid that? |
118 |
+ self.reset(keeping_pkg=1) |
119 |
+ has_changed = True |
120 |
+ |
121 |
env_configdict = self.configdict['env'] |
122 |
|
123 |
# Ensure that "pkg" values are always preferred over "env" values. |
124 |
@@ -1677,11 +1701,8 @@ class config(object): |
125 |
# package has different IUSE. |
126 |
use = set(self["USE"].split()) |
127 |
unfiltered_use = frozenset(use) |
128 |
- if explicit_iuse is None: |
129 |
- explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split()) |
130 |
|
131 |
if eapi_attrs.iuse_effective: |
132 |
- iuse_implicit_match = self._iuse_effective_match |
133 |
portage_iuse = set(self._iuse_effective) |
134 |
portage_iuse.update(explicit_iuse) |
135 |
if built_use is not None: |
136 |
@@ -1693,7 +1714,6 @@ class config(object): |
137 |
self.configdict["pkg"]["IUSE_EFFECTIVE"] = \ |
138 |
" ".join(sorted(portage_iuse)) |
139 |
else: |
140 |
- iuse_implicit_match = self._iuse_implicit_match |
141 |
portage_iuse = self._get_implicit_iuse() |
142 |
portage_iuse.update(explicit_iuse) |
143 |
|
144 |
@@ -1729,21 +1749,17 @@ class config(object): |
145 |
self.get("EBUILD_FORCE_TEST") == "1" |
146 |
|
147 |
if "test" in explicit_iuse or iuse_implicit_match("test"): |
148 |
- if "test" not in self.features: |
149 |
- use.discard("test") |
150 |
- elif restrict_test or \ |
151 |
+ if "test" in self.features: |
152 |
+ if ebuild_force_test and "test" in self.usemask: |
153 |
+ self.usemask = \ |
154 |
+ frozenset(x for x in self.usemask if x != "test") |
155 |
+ if restrict_test or \ |
156 |
("test" in self.usemask and not ebuild_force_test): |
157 |
# "test" is in IUSE and USE=test is masked, so execution |
158 |
# of src_test() probably is not reliable. Therefore, |
159 |
# temporarily disable FEATURES=test just for this package. |
160 |
self["FEATURES"] = " ".join(x for x in self.features \ |
161 |
if x != "test") |
162 |
- use.discard("test") |
163 |
- else: |
164 |
- use.add("test") |
165 |
- if ebuild_force_test and "test" in self.usemask: |
166 |
- self.usemask = \ |
167 |
- frozenset(x for x in self.usemask if x != "test") |
168 |
|
169 |
if eapi_attrs.feature_flag_targetroot and \ |
170 |
("targetroot" in explicit_iuse or iuse_implicit_match("targetroot")): |
171 |
@@ -1900,12 +1916,6 @@ class config(object): |
172 |
iuse_implicit.add("build") |
173 |
iuse_implicit.add("bootstrap") |
174 |
|
175 |
- # Controlled by FEATURES=test. Make this implicit, so handling |
176 |
- # of FEATURES=test is consistent regardless of explicit IUSE. |
177 |
- # Users may use use.mask/package.use.mask to control |
178 |
- # FEATURES=test for all ebuilds, regardless of explicit IUSE. |
179 |
- iuse_implicit.add("test") |
180 |
- |
181 |
return iuse_implicit |
182 |
|
183 |
def _getUseMask(self, pkg, stable=None): |
184 |
diff --git a/lib/portage/tests/resolver/test_features_test_use.py b/lib/portage/tests/resolver/test_features_test_use.py |
185 |
index bdd179d7a..da7172c17 100644 |
186 |
--- a/lib/portage/tests/resolver/test_features_test_use.py |
187 |
+++ b/lib/portage/tests/resolver/test_features_test_use.py |
188 |
@@ -1,68 +1,88 @@ |
189 |
-# Copyright 2012 Gentoo Foundation |
190 |
+# Copyright 2012-2018 Gentoo Foundation |
191 |
# Distributed under the terms of the GNU General Public License v2 |
192 |
|
193 |
from portage.tests import TestCase |
194 |
from portage.tests.resolver.ResolverPlayground import (ResolverPlayground, |
195 |
ResolverPlaygroundTestCase) |
196 |
|
197 |
-class FeaturesTestUse(TestCase): |
198 |
|
199 |
- def testFeaturesTestUse(self): |
200 |
- ebuilds = { |
201 |
- "dev-libs/A-1" : { |
202 |
- "IUSE": "test" |
203 |
- }, |
204 |
- "dev-libs/B-1" : { |
205 |
- "IUSE": "test foo" |
206 |
- }, |
207 |
- } |
208 |
+class TestDepend(TestCase): |
209 |
+ ebuilds = { |
210 |
+ "dev-libs/A-1" : { |
211 |
+ "IUSE": "test", |
212 |
+ "DEPEND": "test? ( dev-libs/B )", |
213 |
+ }, |
214 |
+ "dev-libs/B-1" : { |
215 |
+ }, |
216 |
+ } |
217 |
|
218 |
- installed = { |
219 |
- "dev-libs/A-1" : { |
220 |
- "USE": "", |
221 |
- "IUSE": "test" |
222 |
- }, |
223 |
- "dev-libs/B-1" : { |
224 |
- "USE": "foo", |
225 |
- "IUSE": "test foo" |
226 |
- }, |
227 |
- } |
228 |
+ installed = { |
229 |
+ "dev-libs/A-1" : { |
230 |
+ "USE": "", |
231 |
+ "IUSE": "test", |
232 |
+ "DEPEND": "test? ( dev-libs/B )", |
233 |
+ }, |
234 |
+ } |
235 |
|
236 |
+ def test_default_use_test(self): |
237 |
+ """ |
238 |
+ Test that FEATURES=test enables USE=test by default. |
239 |
+ """ |
240 |
user_config = { |
241 |
- "make.conf" : ("FEATURES=test", "USE=\"-test -foo\"") |
242 |
+ "make.conf" : ("FEATURES=test", "USE=\"\"") |
243 |
} |
244 |
- |
245 |
- test_cases = ( |
246 |
- |
247 |
- # USE=test state should not trigger --newuse rebuilds, as |
248 |
- # specified in bug #373209, comment #3. |
249 |
- ResolverPlaygroundTestCase( |
250 |
+ test_case = ResolverPlaygroundTestCase( |
251 |
["dev-libs/A"], |
252 |
- options = {"--newuse": True, "--selective": True}, |
253 |
+ options = {}, |
254 |
success = True, |
255 |
- mergelist = []), |
256 |
+ mergelist = ["dev-libs/B-1", "dev-libs/A-1"]) |
257 |
+ |
258 |
+ playground = ResolverPlayground(ebuilds=self.ebuilds, |
259 |
+ user_config=user_config, debug=False) |
260 |
+ try: |
261 |
+ playground.run_TestCase(test_case) |
262 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
263 |
+ finally: |
264 |
+ playground.cleanup() |
265 |
|
266 |
- # USE=-test -> USE=test, with USE=test forced by FEATURES=test |
267 |
- ResolverPlaygroundTestCase( |
268 |
+ def test_no_forced_use_test(self): |
269 |
+ """ |
270 |
+ Test that FEATURES=test no longer forces USE=test. |
271 |
+ """ |
272 |
+ user_config = { |
273 |
+ "make.conf" : ("FEATURES=test", "USE=\"-test\"") |
274 |
+ } |
275 |
+ test_case = ResolverPlaygroundTestCase( |
276 |
["dev-libs/A"], |
277 |
options = {}, |
278 |
success = True, |
279 |
- mergelist = ["dev-libs/A-1"]), |
280 |
+ mergelist = ["dev-libs/A-1"]) |
281 |
+ |
282 |
+ playground = ResolverPlayground(ebuilds=self.ebuilds, |
283 |
+ user_config=user_config, debug=False) |
284 |
+ try: |
285 |
+ playground.run_TestCase(test_case) |
286 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
287 |
+ finally: |
288 |
+ playground.cleanup() |
289 |
|
290 |
- # USE=foo -> USE=-foo, with USE=test forced by FEATURES=test |
291 |
- ResolverPlaygroundTestCase( |
292 |
- ["dev-libs/B"], |
293 |
+ def test_newuse(self): |
294 |
+ """ |
295 |
+ Test that --newuse now detects USE=test changes. |
296 |
+ """ |
297 |
+ user_config = { |
298 |
+ "make.conf" : ("FEATURES=test", "USE=\"\"") |
299 |
+ } |
300 |
+ test_case = ResolverPlaygroundTestCase( |
301 |
+ ["dev-libs/A"], |
302 |
options = {"--newuse": True, "--selective": True}, |
303 |
success = True, |
304 |
- mergelist = ["dev-libs/B-1"]), |
305 |
- ) |
306 |
+ mergelist = ["dev-libs/B-1", "dev-libs/A-1"]) |
307 |
|
308 |
- playground = ResolverPlayground(ebuilds=ebuilds, |
309 |
- installed=installed, user_config=user_config, debug=False) |
310 |
+ playground = ResolverPlayground(ebuilds=self.ebuilds, |
311 |
+ user_config=user_config, debug=False) |
312 |
try: |
313 |
- for test_case in test_cases: |
314 |
- playground.run_TestCase(test_case) |
315 |
- self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
316 |
+ playground.run_TestCase(test_case) |
317 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
318 |
finally: |
319 |
playground.cleanup() |
320 |
- |
321 |
diff --git a/man/make.conf.5 b/man/make.conf.5 |
322 |
index cb0f00237..a4e33923c 100644 |
323 |
--- a/man/make.conf.5 |
324 |
+++ b/man/make.conf.5 |
325 |
@@ -1138,7 +1138,7 @@ This variable contains options that control the build behavior of several |
326 |
packages. More information in \fBebuild\fR(5). Possible USE values |
327 |
can be found in \fI/usr/portage/profiles/use.desc\fR. |
328 |
.TP |
329 |
-\fBUSE_ORDER\fR = \fI"env:pkg:conf:defaults:pkginternal:repo:env.d"\fR |
330 |
+\fBUSE_ORDER\fR = \fI"env:pkg:conf:defaults:pkginternal:features:repo:env.d"\fR |
331 |
Determines the precedence of layers in the incremental stacking of the USE |
332 |
variable. Precedence decreases from left to right such that env overrides |
333 |
pkg, pkg overrides conf, and so forth. |
334 |
@@ -1167,6 +1167,10 @@ USE from make.defaults and package.use in the profile |
335 |
.B pkginternal |
336 |
USE from \fBebuild\fR(5) IUSE defaults |
337 |
.TP |
338 |
+.B features |
339 |
+Flags implied by FEATURES. Currently includes USE=\fBtest\fR |
340 |
+for FEATURES=\fBtest\fR. |
341 |
+.TP |
342 |
.B repo |
343 |
USE from make.defaults and package.use in the repo's profiles/ top dir |
344 |
(e.g. /usr/portage/profiles/package.use) (see \fBportage\fR(5)) |
345 |
-- |
346 |
2.18.0 |