1 |
commit: f76b983e95d022d6f377e3efd599dd8efbd30b3d |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Aug 29 07:38:12 2012 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Aug 29 07:38:12 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=f76b983e |
7 |
|
8 |
EAPI 5: Profile IUSE injection |
9 |
|
10 |
See bug #176467 and the PMS patch: |
11 |
http://git.overlays.gentoo.org/gitweb/?p=proj/pms.git;a=commit;h=d9040ab3482af5f790368bac5d053bf1cd760ba8 |
12 |
|
13 |
--- |
14 |
pym/_emerge/Package.py | 13 +++-- |
15 |
pym/portage/const.py | 4 +- |
16 |
pym/portage/dbapi/__init__.py | 9 +++- |
17 |
pym/portage/dbapi/_expand_new_virt.py | 10 +++- |
18 |
pym/portage/eapi.py | 6 ++- |
19 |
pym/portage/package/ebuild/config.py | 93 ++++++++++++++++++++++++++++++-- |
20 |
pym/portage/package/ebuild/doebuild.py | 8 ++- |
21 |
7 files changed, 125 insertions(+), 18 deletions(-) |
22 |
|
23 |
diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py |
24 |
index 0da374a..ce51a8b 100644 |
25 |
--- a/pym/_emerge/Package.py |
26 |
+++ b/pym/_emerge/Package.py |
27 |
@@ -64,6 +64,13 @@ class Package(Task): |
28 |
self.slot_abi = self.cpv.slot_abi |
29 |
# sync metadata with validated repo (may be UNKNOWN_REPO) |
30 |
self.metadata['repository'] = self.cpv.repo |
31 |
+ |
32 |
+ if eapi_attrs.iuse_effective: |
33 |
+ implicit_match = self.root_config.settings._iuse_effective_match |
34 |
+ else: |
35 |
+ implicit_match = self.root_config.settings._iuse_implicit_match |
36 |
+ self.iuse = self._iuse(self.metadata["IUSE"].split(), implicit_match) |
37 |
+ |
38 |
if (self.iuse.enabled or self.iuse.disabled) and \ |
39 |
not eapi_attrs.iuse_defaults: |
40 |
if not self.installed: |
41 |
@@ -615,7 +622,7 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): |
42 |
|
43 |
__slots__ = ("_pkg",) |
44 |
_wrapped_keys = frozenset( |
45 |
- ["COUNTER", "INHERITED", "IUSE", "USE", "_mtime_"]) |
46 |
+ ["COUNTER", "INHERITED", "USE", "_mtime_"]) |
47 |
_use_conditional_keys = frozenset( |
48 |
['LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',]) |
49 |
|
50 |
@@ -684,10 +691,6 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): |
51 |
v = frozenset(v.split()) |
52 |
self._pkg.inherited = v |
53 |
|
54 |
- def _set_iuse(self, k, v): |
55 |
- self._pkg.iuse = self._pkg._iuse( |
56 |
- v.split(), self._pkg.root_config.settings._iuse_implicit_match) |
57 |
- |
58 |
def _set_counter(self, k, v): |
59 |
if isinstance(v, basestring): |
60 |
try: |
61 |
|
62 |
diff --git a/pym/portage/const.py b/pym/portage/const.py |
63 |
index c2049f8..6dffc5d 100644 |
64 |
--- a/pym/portage/const.py |
65 |
+++ b/pym/portage/const.py |
66 |
@@ -79,8 +79,10 @@ OS_HEADERS_PACKAGE_ATOM = "virtual/os-headers" |
67 |
INCREMENTALS = ("USE", "USE_EXPAND", "USE_EXPAND_HIDDEN", |
68 |
"FEATURES", "ACCEPT_KEYWORDS", |
69 |
"CONFIG_PROTECT_MASK", "CONFIG_PROTECT", |
70 |
+ "IUSE_IMPLICIT", |
71 |
"PRELINK_PATH", "PRELINK_PATH_MASK", |
72 |
- "PROFILE_ONLY_VARIABLES") |
73 |
+ "PROFILE_ONLY_VARIABLES", |
74 |
+ "USE_EXPAND_IMPLICIT", "USE_EXPAND_UNPREFIXED") |
75 |
EBUILD_PHASES = ("pretend", "setup", "unpack", "prepare", "configure", |
76 |
"compile", "test", "install", |
77 |
"package", "preinst", "postinst","prerm", "postrm", |
78 |
|
79 |
diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py |
80 |
index 97b4255..f326e68 100644 |
81 |
--- a/pym/portage/dbapi/__init__.py |
82 |
+++ b/pym/portage/dbapi/__init__.py |
83 |
@@ -16,6 +16,7 @@ portage.proxy.lazyimport.lazyimport(globals(), |
84 |
|
85 |
from portage import os |
86 |
from portage import auxdbkeys |
87 |
+from portage.eapi import _get_eapi_attrs |
88 |
from portage.exception import InvalidData |
89 |
from portage.localization import _ |
90 |
|
91 |
@@ -181,7 +182,7 @@ class dbapi(object): |
92 |
2) Check enabled/disabled flag states. |
93 |
""" |
94 |
|
95 |
- aux_keys = ["IUSE", "KEYWORDS", "SLOT", "USE", "repository"] |
96 |
+ aux_keys = ["EAPI", "IUSE", "KEYWORDS", "SLOT", "USE", "repository"] |
97 |
for cpv in cpv_iter: |
98 |
try: |
99 |
metadata = dict(zip(aux_keys, |
100 |
@@ -195,7 +196,11 @@ class dbapi(object): |
101 |
yield cpv |
102 |
|
103 |
def _match_use(self, atom, cpv, metadata): |
104 |
- iuse_implicit_match = self.settings._iuse_implicit_match |
105 |
+ eapi_attrs = _get_eapi_attrs(metadata["EAPI"]) |
106 |
+ if eapi_attrs.iuse_effective: |
107 |
+ iuse_implicit_match = self.settings._iuse_effective_match |
108 |
+ else: |
109 |
+ iuse_implicit_match = self.settings._iuse_implicit_match |
110 |
iuse = frozenset(x.lstrip('+-') for x in metadata["IUSE"].split()) |
111 |
|
112 |
for x in atom.unevaluated_atom.use.required: |
113 |
|
114 |
diff --git a/pym/portage/dbapi/_expand_new_virt.py b/pym/portage/dbapi/_expand_new_virt.py |
115 |
index d379b4c..95b2c28 100644 |
116 |
--- a/pym/portage/dbapi/_expand_new_virt.py |
117 |
+++ b/pym/portage/dbapi/_expand_new_virt.py |
118 |
@@ -1,8 +1,9 @@ |
119 |
-# Copyright 2011 Gentoo Foundation |
120 |
+# Copyright 2011-2012 Gentoo Foundation |
121 |
# Distributed under the terms of the GNU General Public License v2 |
122 |
|
123 |
import portage |
124 |
from portage.dep import Atom, _get_useflag_re |
125 |
+from portage.eapi import _get_eapi_attrs |
126 |
|
127 |
def expand_new_virt(vardb, atom): |
128 |
""" |
129 |
@@ -44,6 +45,7 @@ def expand_new_virt(vardb, atom): |
130 |
yield atom |
131 |
continue |
132 |
|
133 |
+ eapi_attrs = _get_eapi_attrs(eapi) |
134 |
# Validate IUSE and IUSE, for early detection of vardb corruption. |
135 |
useflag_re = _get_useflag_re(eapi) |
136 |
valid_iuse = [] |
137 |
@@ -54,7 +56,11 @@ def expand_new_virt(vardb, atom): |
138 |
valid_iuse.append(x) |
139 |
valid_iuse = frozenset(valid_iuse) |
140 |
|
141 |
- iuse_implicit_match = vardb.settings._iuse_implicit_match |
142 |
+ if eapi_attrs.iuse_effective: |
143 |
+ iuse_implicit_match = vardb.settings._iuse_effective_match |
144 |
+ else: |
145 |
+ iuse_implicit_match = vardb.settings._iuse_implicit_match |
146 |
+ |
147 |
valid_use = [] |
148 |
for x in use.split(): |
149 |
if x in valid_iuse or iuse_implicit_match(x): |
150 |
|
151 |
diff --git a/pym/portage/eapi.py b/pym/portage/eapi.py |
152 |
index b701d02..00ce2a5 100644 |
153 |
--- a/pym/portage/eapi.py |
154 |
+++ b/pym/portage/eapi.py |
155 |
@@ -8,6 +8,9 @@ from portage import eapi_is_supported |
156 |
def eapi_has_iuse_defaults(eapi): |
157 |
return eapi != "0" |
158 |
|
159 |
+def eapi_has_iuse_effective(eapi): |
160 |
+ return eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi") |
161 |
+ |
162 |
def eapi_has_slot_deps(eapi): |
163 |
return eapi != "0" |
164 |
|
165 |
@@ -72,7 +75,7 @@ def eapi_allows_dots_in_use_flags(eapi): |
166 |
return eapi in ("4-python",) |
167 |
|
168 |
_eapi_attrs = collections.namedtuple('_eapi_attrs', |
169 |
- 'dots_in_PN dots_in_use_flags iuse_defaults ' |
170 |
+ 'dots_in_PN dots_in_use_flags iuse_defaults iuse_effective ' |
171 |
'repo_deps required_use required_use_at_most_one_of slot_abi slot_deps ' |
172 |
'src_uri_arrows strong_blocks use_deps use_dep_defaults') |
173 |
|
174 |
@@ -98,6 +101,7 @@ def _get_eapi_attrs(eapi): |
175 |
dots_in_PN = (eapi is None or eapi_allows_dots_in_PN(eapi)), |
176 |
dots_in_use_flags = (eapi is None or eapi_allows_dots_in_use_flags(eapi)), |
177 |
iuse_defaults = (eapi is None or eapi_has_iuse_defaults(eapi)), |
178 |
+ iuse_effective = (eapi is not None and eapi_has_iuse_effective(eapi)), |
179 |
repo_deps = (eapi is None or eapi_has_repo_deps(eapi)), |
180 |
required_use = (eapi is None or eapi_has_required_use(eapi)), |
181 |
required_use_at_most_one_of = (eapi is None or eapi_has_required_use_at_most_one_of(eapi)), |
182 |
|
183 |
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py |
184 |
index 871831f..6a9ed08 100644 |
185 |
--- a/pym/portage/package/ebuild/config.py |
186 |
+++ b/pym/portage/package/ebuild/config.py |
187 |
@@ -32,7 +32,7 @@ from portage.dbapi.porttree import portdbapi |
188 |
from portage.dbapi.vartree import vartree |
189 |
from portage.dep import Atom, isvalidatom, match_from_list, use_reduce, _repo_separator, _slot_separator |
190 |
from portage.eapi import eapi_exports_AA, eapi_exports_merge_type, \ |
191 |
- eapi_supports_prefix, eapi_exports_replace_vars |
192 |
+ eapi_supports_prefix, eapi_exports_replace_vars, _get_eapi_attrs |
193 |
from portage.env.loaders import KeyValuePairFileLoader |
194 |
from portage.exception import InvalidDependString, PortageException |
195 |
from portage.localization import _ |
196 |
@@ -215,6 +215,7 @@ class config(object): |
197 |
self.profiles = clone.profiles |
198 |
self.packages = clone.packages |
199 |
self.repositories = clone.repositories |
200 |
+ self._iuse_effective = clone._iuse_effective |
201 |
self._iuse_implicit_match = clone._iuse_implicit_match |
202 |
self._non_user_variables = clone._non_user_variables |
203 |
self._env_d_blacklist = clone._env_d_blacklist |
204 |
@@ -793,6 +794,7 @@ class config(object): |
205 |
if bsd_chflags: |
206 |
self.features.add('chflags') |
207 |
|
208 |
+ self._iuse_effective = self._calc_iuse_effective() |
209 |
self._iuse_implicit_match = _iuse_implicit_match_cache(self) |
210 |
|
211 |
self._validate_commands() |
212 |
@@ -1251,6 +1253,7 @@ class config(object): |
213 |
pkg_configdict["CATEGORY"] = cat |
214 |
pkg_configdict["PF"] = pf |
215 |
repository = None |
216 |
+ eapi = None |
217 |
if mydb: |
218 |
if not hasattr(mydb, "aux_get"): |
219 |
for k in aux_keys: |
220 |
@@ -1277,6 +1280,7 @@ class config(object): |
221 |
# Empty USE means this dbapi instance does not contain |
222 |
# built packages. |
223 |
built_use = None |
224 |
+ eapi = pkg_configdict['EAPI'] |
225 |
|
226 |
repository = pkg_configdict.pop("repository", None) |
227 |
if repository is not None: |
228 |
@@ -1295,6 +1299,9 @@ class config(object): |
229 |
elif x.startswith("-"): |
230 |
pkginternaluse.append(x) |
231 |
pkginternaluse = " ".join(pkginternaluse) |
232 |
+ |
233 |
+ eapi_attrs = _get_eapi_attrs(eapi) |
234 |
+ |
235 |
if pkginternaluse != self.configdict["pkginternal"].get("USE", ""): |
236 |
self.configdict["pkginternal"]["USE"] = pkginternaluse |
237 |
has_changed = True |
238 |
@@ -1434,9 +1441,17 @@ class config(object): |
239 |
use = set(self["USE"].split()) |
240 |
if explicit_iuse is None: |
241 |
explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split()) |
242 |
- iuse_implicit_match = self._iuse_implicit_match |
243 |
- portage_iuse = self._get_implicit_iuse() |
244 |
- portage_iuse.update(explicit_iuse) |
245 |
+ |
246 |
+ if eapi_attrs.iuse_effective: |
247 |
+ iuse_implicit_match = self._iuse_effective_match |
248 |
+ portage_iuse = set(self._iuse_effective) |
249 |
+ portage_iuse.update(explicit_iuse) |
250 |
+ self.configdict["pkg"]["IUSE_EFFECTIVE"] = \ |
251 |
+ " ".join(sorted(portage_iuse)) |
252 |
+ else: |
253 |
+ iuse_implicit_match = self._iuse_implicit_match |
254 |
+ portage_iuse = self._get_implicit_iuse() |
255 |
+ portage_iuse.update(explicit_iuse) |
256 |
|
257 |
# PORTAGE_IUSE is not always needed so it's lazily evaluated. |
258 |
self.configdict["env"].addLazySingleton( |
259 |
@@ -1501,6 +1516,14 @@ class config(object): |
260 |
self.configdict['env'].addLazySingleton(k, |
261 |
lazy_use_expand.__getitem__, k) |
262 |
|
263 |
+ for k in self.get("USE_EXPAND_UNPREFIXED", "").split(): |
264 |
+ var_split = self.get(k, '').split() |
265 |
+ var_split = [ x for x in var_split if x in use ] |
266 |
+ if var_split: |
267 |
+ self.configlist[-1][k] = ' '.join(var_split) |
268 |
+ elif k in self: |
269 |
+ self.configlist[-1][k] = '' |
270 |
+ |
271 |
# Filtered for the ebuild environment. Store this in a separate |
272 |
# attribute since we still want to be able to see global USE |
273 |
# settings for things like emerge --info. |
274 |
@@ -1545,9 +1568,42 @@ class config(object): |
275 |
else: |
276 |
container[k] = v |
277 |
|
278 |
+ def _iuse_effective_match(self, flag): |
279 |
+ return flag in self._iuse_effective |
280 |
+ |
281 |
+ def _calc_iuse_effective(self): |
282 |
+ """ |
283 |
+ Beginning with EAPI 5, IUSE_EFFECTIVE is defined by PMS. |
284 |
+ """ |
285 |
+ iuse_effective = [] |
286 |
+ iuse_effective.extend(self.get("IUSE_IMPLICIT", "").split()) |
287 |
+ |
288 |
+ # USE_EXPAND_IMPLICIT should contain things like ARCH, ELIBC, |
289 |
+ # KERNEL, and USERLAND. |
290 |
+ use_expand_implicit = frozenset( |
291 |
+ self.get("USE_EXPAND_IMPLICIT", "").split()) |
292 |
+ |
293 |
+ # USE_EXPAND_UNPREFIXED should contain at least ARCH, and |
294 |
+ # USE_EXPAND_VALUES_ARCH should contain all valid ARCH flags. |
295 |
+ for v in self.get("USE_EXPAND_UNPREFIXED", "").split(): |
296 |
+ if v not in use_expand_implicit: |
297 |
+ continue |
298 |
+ iuse_effective.extend( |
299 |
+ self.get("USE_EXPAND_VALUES_" + v, "").split()) |
300 |
+ |
301 |
+ use_expand = frozenset(self.get("USE_EXPAND", "").split()) |
302 |
+ for v in use_expand_implicit: |
303 |
+ if v not in use_expand: |
304 |
+ continue |
305 |
+ lower_v = v.lower() |
306 |
+ for x in self.get("USE_EXPAND_VALUES_" + v, "").split(): |
307 |
+ iuse_effective.append(lower_v + "_" + x) |
308 |
+ |
309 |
+ return frozenset(iuse_effective) |
310 |
+ |
311 |
def _get_implicit_iuse(self): |
312 |
""" |
313 |
- Some flags are considered to |
314 |
+ Prior to EAPI 5, these flags are considered to |
315 |
be implicit members of IUSE: |
316 |
* Flags derived from ARCH |
317 |
* Flags derived from USE_EXPAND_HIDDEN variables |
318 |
@@ -2005,6 +2061,8 @@ class config(object): |
319 |
if v is not None: |
320 |
use_expand_dict[k] = v |
321 |
|
322 |
+ use_expand_unprefixed = self.get("USE_EXPAND_UNPREFIXED", "").split() |
323 |
+ |
324 |
# In order to best accomodate the long-standing practice of |
325 |
# setting default USE_EXPAND variables in the profile's |
326 |
# make.defaults, we translate these variables into their |
327 |
@@ -2018,6 +2076,12 @@ class config(object): |
328 |
continue |
329 |
use = cfg.get("USE", "") |
330 |
expand_use = [] |
331 |
+ |
332 |
+ for k in use_expand_unprefixed: |
333 |
+ v = cfg.get(k) |
334 |
+ if v is not None: |
335 |
+ expand_use.extend(v.split()) |
336 |
+ |
337 |
for k in use_expand_dict: |
338 |
v = cfg.get(k) |
339 |
if v is None: |
340 |
@@ -2055,6 +2119,17 @@ class config(object): |
341 |
iuse = [x.lstrip("+-") for x in iuse.split()] |
342 |
myflags = set() |
343 |
for curdb in self.uvlist: |
344 |
+ |
345 |
+ for k in use_expand_unprefixed: |
346 |
+ v = curdb.get(k) |
347 |
+ if v is None: |
348 |
+ continue |
349 |
+ for x in v.split(): |
350 |
+ if x[:1] == "-": |
351 |
+ myflags.discard(x[1:]) |
352 |
+ else: |
353 |
+ myflags.add(x) |
354 |
+ |
355 |
cur_use_expand = [x for x in use_expand if x in curdb] |
356 |
mysplit = curdb.get("USE", "").split() |
357 |
if not mysplit and not cur_use_expand: |
358 |
@@ -2171,6 +2246,14 @@ class config(object): |
359 |
elif k in self: |
360 |
self.configlist[-1][k] = '' |
361 |
|
362 |
+ for k in use_expand_unprefixed: |
363 |
+ var_split = self.get(k, '').split() |
364 |
+ var_split = [ x for x in var_split if x in myflags ] |
365 |
+ if var_split: |
366 |
+ self.configlist[-1][k] = ' '.join(var_split) |
367 |
+ elif k in self: |
368 |
+ self.configlist[-1][k] = '' |
369 |
+ |
370 |
@property |
371 |
def virts_p(self): |
372 |
warnings.warn("portage config.virts_p attribute " + \ |
373 |
|
374 |
diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py |
375 |
index 6e7e63c..3ba8ebd 100644 |
376 |
--- a/pym/portage/package/ebuild/doebuild.py |
377 |
+++ b/pym/portage/package/ebuild/doebuild.py |
378 |
@@ -1638,8 +1638,12 @@ def _post_src_install_write_metadata(settings): |
379 |
|
380 |
build_info_dir = os.path.join(settings['PORTAGE_BUILDDIR'], 'build-info') |
381 |
|
382 |
- for k in ('IUSE',): |
383 |
- v = settings.get(k) |
384 |
+ metadata_keys = ['IUSE'] |
385 |
+ if eapi_attrs.iuse_effective: |
386 |
+ metadata_keys.append('IUSE_EFFECTIVE') |
387 |
+ |
388 |
+ for k in metadata_keys: |
389 |
+ v = settings.configdict['pkg'].get(k) |
390 |
if v is not None: |
391 |
write_atomic(os.path.join(build_info_dir, k), v + '\n') |