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] Replace implicit {FEATURES->USE}=test forcing with USE default
Date: Mon, 30 Jul 2018 20:44:38
Message-Id: 20180730204426.4261-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 | 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