1 |
For emerge --usepkgonly mode, it's useful to be able to operate without |
2 |
dependence on a local ebuild repository and profile. Therefore, |
3 |
merge Packages header settings from the binary package database |
4 |
(including binhost(s) if enabled) into the profile configuration, |
5 |
in order to propagate implicit IUSE and USE_EXPAND settings for use |
6 |
with binary and installed packages. Values are appended, so the result |
7 |
is a union of elements. |
8 |
|
9 |
Also use ARCH from the binary package database if it's not defined by |
10 |
the profile, since ARCH is used for validation by emerge's profile_check |
11 |
function, and also for KEYWORDS logic in the _getmaskingstatus function. |
12 |
|
13 |
All changes are currently confined to --usepkgonly mode, since this is |
14 |
the mode where it is needed the most, and this ensures that behavior of |
15 |
source-based builds is completely unaffected. |
16 |
|
17 |
The changes only affect dependency calculations (where implicit IUSE |
18 |
plays a role) and the user interface (display of USE_EXPAND flags). |
19 |
The bash execution environment for binary and installed packages is |
20 |
completely unaffected, since that environment relies on variables loaded |
21 |
from environment.bz2 files. |
22 |
|
23 |
Bug: https://bugs.gentoo.org/640318 |
24 |
--- |
25 |
pym/_emerge/actions.py | 48 +++++++++++++++++-------- |
26 |
pym/_emerge/main.py | 4 --- |
27 |
pym/portage/dbapi/bintree.py | 56 ++++++++++++++++++++++++++++++ |
28 |
pym/portage/package/ebuild/config.py | 7 ++-- |
29 |
pym/portage/package/ebuild/profile_iuse.py | 32 +++++++++++++++++ |
30 |
5 files changed, 127 insertions(+), 20 deletions(-) |
31 |
create mode 100644 pym/portage/package/ebuild/profile_iuse.py |
32 |
|
33 |
diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py |
34 |
index 347ef5fbc..b90aa8cb0 100644 |
35 |
--- a/pym/_emerge/actions.py |
36 |
+++ b/pym/_emerge/actions.py |
37 |
@@ -78,6 +78,7 @@ from _emerge.depgraph import backtrack_depgraph, depgraph, resume_depgraph |
38 |
from _emerge.DepPrioritySatisfiedRange import DepPrioritySatisfiedRange |
39 |
from _emerge.emergelog import emergelog |
40 |
from _emerge.is_valid_package_atom import is_valid_package_atom |
41 |
+from _emerge.main import profile_check |
42 |
from _emerge.MetadataRegen import MetadataRegen |
43 |
from _emerge.Package import Package |
44 |
from _emerge.ProgressHandler import ProgressHandler |
45 |
@@ -2209,9 +2210,21 @@ def action_uninstall(settings, trees, ldpath_mtimes, |
46 |
return rval |
47 |
|
48 |
def adjust_configs(myopts, trees): |
49 |
- for myroot in trees: |
50 |
+ for myroot, mytrees in trees.items(): |
51 |
mysettings = trees[myroot]["vartree"].settings |
52 |
mysettings.unlock() |
53 |
+ |
54 |
+ # For --usepkgonly mode, propagate settings from the binary package |
55 |
+ # database, so that it's possible to operate without dependence on |
56 |
+ # a local ebuild repository and profile. |
57 |
+ if ('--usepkgonly' in myopts and |
58 |
+ mytrees['bintree']._propagate_config(mysettings)): |
59 |
+ # Also propagate changes to the portdbapi doebuild_settings |
60 |
+ # attribute which is used by Package instances for USE |
61 |
+ # calculations (in support of --binpkg-respect-use). |
62 |
+ mytrees['porttree'].dbapi.doebuild_settings = \ |
63 |
+ portage.config(clone=mysettings) |
64 |
+ |
65 |
adjust_config(myopts, mysettings) |
66 |
mysettings.lock() |
67 |
|
68 |
@@ -2868,7 +2881,27 @@ def run_action(emerge_config): |
69 |
"--usepkg", "--usepkgonly"): |
70 |
emerge_config.opts.pop(opt, None) |
71 |
|
72 |
+ # Populate the bintree with current --getbinpkg setting. |
73 |
+ # This needs to happen before: |
74 |
+ # * expand_set_arguments, in case any sets use the bintree |
75 |
+ # * adjust_configs and profile_check, in order to propagate settings |
76 |
+ # implicit IUSE and USE_EXPAND settings from the binhost(s) |
77 |
+ if (emerge_config.action in ('search', None) and |
78 |
+ '--usepkg' in emerge_config.opts): |
79 |
+ for mytrees in emerge_config.trees.values(): |
80 |
+ try: |
81 |
+ mytrees['bintree'].populate( |
82 |
+ getbinpkgs='--getbinpkg' in emerge_config.opts) |
83 |
+ except ParseError as e: |
84 |
+ writemsg('\n\n!!!%s.\nSee make.conf(5) for more info.\n' |
85 |
+ % (e,), noiselevel=-1) |
86 |
+ return 1 |
87 |
+ |
88 |
adjust_configs(emerge_config.opts, emerge_config.trees) |
89 |
+ |
90 |
+ if profile_check(emerge_config.trees, emerge_config.action) != os.EX_OK: |
91 |
+ return 1 |
92 |
+ |
93 |
apply_priorities(emerge_config.target_config.settings) |
94 |
|
95 |
if ("--autounmask-continue" in emerge_config.opts and |
96 |
@@ -2919,19 +2952,6 @@ def run_action(emerge_config): |
97 |
# Freeze the portdbapi for performance (memoize all xmatch results). |
98 |
mydb.freeze() |
99 |
|
100 |
- if emerge_config.action in ('search', None) and \ |
101 |
- "--usepkg" in emerge_config.opts: |
102 |
- # Populate the bintree with current --getbinpkg setting. |
103 |
- # This needs to happen before expand_set_arguments(), in case |
104 |
- # any sets use the bintree. |
105 |
- try: |
106 |
- mytrees["bintree"].populate( |
107 |
- getbinpkgs="--getbinpkg" in emerge_config.opts) |
108 |
- except ParseError as e: |
109 |
- writemsg("\n\n!!!%s.\nSee make.conf(5) for more info.\n" |
110 |
- % e, noiselevel=-1) |
111 |
- return 1 |
112 |
- |
113 |
del mytrees, mydb |
114 |
|
115 |
for x in emerge_config.args: |
116 |
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py |
117 |
index 4aa9585fa..226387495 100644 |
118 |
--- a/pym/_emerge/main.py |
119 |
+++ b/pym/_emerge/main.py |
120 |
@@ -1269,10 +1269,6 @@ def emerge_main(args=None): |
121 |
except locale.Error as e: |
122 |
writemsg_level("setlocale: %s\n" % e, level=logging.WARN) |
123 |
|
124 |
- rval = profile_check(emerge_config.trees, emerge_config.action) |
125 |
- if rval != os.EX_OK: |
126 |
- return rval |
127 |
- |
128 |
tmpcmdline = [] |
129 |
if "--ignore-default-opts" not in myopts: |
130 |
tmpcmdline.extend(portage.util.shlex_split( |
131 |
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py |
132 |
index a963c578e..269a7b226 100644 |
133 |
--- a/pym/portage/dbapi/bintree.py |
134 |
+++ b/pym/portage/dbapi/bintree.py |
135 |
@@ -29,6 +29,7 @@ from portage.dep import Atom, use_reduce, paren_enclose |
136 |
from portage.exception import AlarmSignal, InvalidData, InvalidPackageName, \ |
137 |
ParseError, PermissionDenied, PortageException |
138 |
from portage.localization import _ |
139 |
+from portage.package.ebuild.profile_iuse import iter_iuse_vars |
140 |
from portage import _movefile |
141 |
from portage import os |
142 |
from portage import _encodings |
143 |
@@ -322,6 +323,7 @@ class binarytree(object): |
144 |
self._pkgindex_use_evaluated_keys = \ |
145 |
("BDEPEND", "DEPEND", "HDEPEND", "LICENSE", "RDEPEND", |
146 |
"PDEPEND", "PROPERTIES", "RESTRICT") |
147 |
+ self._pkgindex_header = None |
148 |
self._pkgindex_header_keys = set([ |
149 |
"ACCEPT_KEYWORDS", "ACCEPT_LICENSE", |
150 |
"ACCEPT_PROPERTIES", "ACCEPT_RESTRICT", "CBUILD", |
151 |
@@ -805,6 +807,10 @@ class binarytree(object): |
152 |
pkgindex.packages.extend(iter(metadata.values())) |
153 |
self._update_pkgindex_header(pkgindex.header) |
154 |
|
155 |
+ self._pkgindex_header = {} |
156 |
+ self._merge_pkgindex_header(pkgindex.header, |
157 |
+ self._pkgindex_header) |
158 |
+ |
159 |
return pkgindex if update_pkgindex else None |
160 |
|
161 |
def _populate_remote(self, getbinpkg_refresh=True): |
162 |
@@ -1041,6 +1047,8 @@ class binarytree(object): |
163 |
self.dbapi.cpv_inject(cpv) |
164 |
|
165 |
self._remote_has_index = True |
166 |
+ self._merge_pkgindex_header(pkgindex.header, |
167 |
+ self._pkgindex_header) |
168 |
|
169 |
def inject(self, cpv, filename=None): |
170 |
"""Add a freshly built package to the database. This updates |
171 |
@@ -1292,6 +1300,54 @@ class binarytree(object): |
172 |
inherited_keys=self._pkgindex_inherited_keys, |
173 |
translated_keys=self._pkgindex_translated_keys) |
174 |
|
175 |
+ @staticmethod |
176 |
+ def _merge_pkgindex_header(src, dest): |
177 |
+ """ |
178 |
+ Merge Packages header settings from src to dest, in order to |
179 |
+ propagate implicit IUSE and USE_EXPAND settings for use with |
180 |
+ binary and installed packages. Values are appended, so the |
181 |
+ result is a union of elements from src and dest. |
182 |
+ |
183 |
+ Pull in ARCH if it's not defined, since it's used for validation |
184 |
+ by emerge's profile_check function, and also for KEYWORDS logic |
185 |
+ in the _getmaskingstatus function. |
186 |
+ |
187 |
+ @param src: source mapping (read only) |
188 |
+ @type src: Mapping |
189 |
+ @param dest: destination mapping |
190 |
+ @type dest: MutableMapping |
191 |
+ """ |
192 |
+ for k, v in iter_iuse_vars(src): |
193 |
+ v_before = dest.get(k) |
194 |
+ if v_before is not None: |
195 |
+ v = v_before + ' ' + v |
196 |
+ dest[k] = v |
197 |
+ |
198 |
+ if 'ARCH' not in dest and 'ARCH' in src: |
199 |
+ dest['ARCH'] = src['ARCH'] |
200 |
+ |
201 |
+ def _propagate_config(self, config): |
202 |
+ """ |
203 |
+ Propagate implicit IUSE and USE_EXPAND settings from the binary |
204 |
+ package database to a config instance. If settings are not |
205 |
+ available to propagate, then this will do nothing and return |
206 |
+ False. |
207 |
+ |
208 |
+ @param config: config instance |
209 |
+ @type config: portage.config |
210 |
+ @rtype: bool |
211 |
+ @return: True if settings successfully propagated, False if settings |
212 |
+ were not available to propagate. |
213 |
+ """ |
214 |
+ if self._pkgindex_header is None: |
215 |
+ return False |
216 |
+ |
217 |
+ self._merge_pkgindex_header(self._pkgindex_header, |
218 |
+ config.configdict['defaults']) |
219 |
+ config.regenerate() |
220 |
+ config._init_iuse() |
221 |
+ return True |
222 |
+ |
223 |
def _update_pkgindex_header(self, header): |
224 |
""" |
225 |
Add useful settings to the Packages file header, for use by |
226 |
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py |
227 |
index a32892e94..071385684 100644 |
228 |
--- a/pym/portage/package/ebuild/config.py |
229 |
+++ b/pym/portage/package/ebuild/config.py |
230 |
@@ -943,8 +943,7 @@ class config(object): |
231 |
if bsd_chflags: |
232 |
self.features.add('chflags') |
233 |
|
234 |
- self._iuse_effective = self._calc_iuse_effective() |
235 |
- self._iuse_implicit_match = _iuse_implicit_match_cache(self) |
236 |
+ self._init_iuse() |
237 |
|
238 |
self._validate_commands() |
239 |
|
240 |
@@ -961,6 +960,10 @@ class config(object): |
241 |
if mycpv: |
242 |
self.setcpv(mycpv) |
243 |
|
244 |
+ def _init_iuse(self): |
245 |
+ self._iuse_effective = self._calc_iuse_effective() |
246 |
+ self._iuse_implicit_match = _iuse_implicit_match_cache(self) |
247 |
+ |
248 |
@property |
249 |
def mygcfg(self): |
250 |
warnings.warn("portage.config.mygcfg is deprecated", stacklevel=3) |
251 |
diff --git a/pym/portage/package/ebuild/profile_iuse.py b/pym/portage/package/ebuild/profile_iuse.py |
252 |
new file mode 100644 |
253 |
index 000000000..d3f201e54 |
254 |
--- /dev/null |
255 |
+++ b/pym/portage/package/ebuild/profile_iuse.py |
256 |
@@ -0,0 +1,32 @@ |
257 |
+# Copyright 2018 Gentoo Foundation |
258 |
+# Distributed under the terms of the GNU General Public License v2 |
259 |
+ |
260 |
+__all__ = ( |
261 |
+ 'iter_iuse_vars', |
262 |
+) |
263 |
+ |
264 |
+ |
265 |
+def iter_iuse_vars(env): |
266 |
+ """ |
267 |
+ Iterate over (key, value) pairs of profile variables that contribute |
268 |
+ to implicit IUSE for EAPI 5 and later. |
269 |
+ |
270 |
+ @param env: Ebuild environment |
271 |
+ @type env: Mapping |
272 |
+ @rtype: iterator |
273 |
+ @return: iterator over (key, value) pairs of profile variables |
274 |
+ """ |
275 |
+ |
276 |
+ for k in ('IUSE_IMPLICIT', 'USE_EXPAND_IMPLICIT', 'USE_EXPAND_UNPREFIXED', 'USE_EXPAND'): |
277 |
+ v = env.get(k) |
278 |
+ if v is not None: |
279 |
+ yield (k, v) |
280 |
+ |
281 |
+ use_expand_implicit = frozenset(env.get('USE_EXPAND_IMPLICIT', '').split()) |
282 |
+ |
283 |
+ for v in env.get('USE_EXPAND_UNPREFIXED', '').split() + env.get('USE_EXPAND', '').split(): |
284 |
+ if v in use_expand_implicit: |
285 |
+ k = 'USE_EXPAND_VALUES_' + v |
286 |
+ v = env.get(k) |
287 |
+ if v is not None: |
288 |
+ yield (k, v) |
289 |
-- |
290 |
2.13.6 |