Gentoo Archives: gentoo-portage-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-portage-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-portage-dev] [PATCH v2] Replace implicit {FEATURES->USE}=test forcing with USE default
Date: Tue, 31 Jul 2018 10:45:30
Message-Id: 20180731103117.2126-1-mgorny@gentoo.org
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

Replies