1 |
The @changed-deps set is useful, but it has limitations similar to the |
2 |
@installed set (see bug #387059), which can make it unsuitable for use |
3 |
when updating the whole system. Therefore, implement two new options |
4 |
that are analogous to --newuse and --binpkg-respect-use, called |
5 |
--changed-deps and --binpkg-changed-deps. |
6 |
|
7 |
The rationale for having a separate --binpkg-* option is the same in |
8 |
both cases: depending on the situation, people may want different |
9 |
behavior for binary packages. For example, just like |
10 |
---binpkg-respect-use is automatically enabled if the user has not |
11 |
specified --usepkgonly, so is --binpkg-changed-deps (though the user |
12 |
can explicitly override the automatic behavior). In both cases, |
13 |
inconsistencies in dependencies are automatically avoided, increasing |
14 |
the probability of a successful dependency calculation. |
15 |
|
16 |
X-Gentoo-Bug: 282927 |
17 |
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=282927 |
18 |
--- |
19 |
man/emerge.1 | 22 +++- |
20 |
pym/_emerge/create_depgraph_params.py | 16 +++ |
21 |
pym/_emerge/depgraph.py | 138 ++++++++++++++++++++++-- |
22 |
pym/_emerge/main.py | 26 +++++ |
23 |
pym/portage/dep/_slot_operator.py | 13 +++ |
24 |
pym/portage/tests/resolver/test_changed_deps.py | 120 +++++++++++++++++++++ |
25 |
6 files changed, 323 insertions(+), 12 deletions(-) |
26 |
create mode 100644 pym/portage/tests/resolver/test_changed_deps.py |
27 |
|
28 |
diff --git a/man/emerge.1 b/man/emerge.1 |
29 |
index faa1f33..7eb30a5 100644 |
30 |
--- a/man/emerge.1 |
31 |
+++ b/man/emerge.1 |
32 |
@@ -386,9 +386,20 @@ Specifies an integer number of times to backtrack if |
33 |
dependency calculation fails due to a conflict or an |
34 |
unsatisfied dependency (default: \'10\'). |
35 |
.TP |
36 |
+.BR "\-\-binpkg\-changed\-deps [ y | n ]" |
37 |
+Tells emerge to ignore binary packages for which the corresponding |
38 |
+ebuild dependencies have changed since the packages were built. |
39 |
+In order to help avoid issues with resolving inconsistent dependencies, |
40 |
+this option is automatically enabled unless the \fB\-\-usepkgonly\fR |
41 |
+option is enabled. Behavior with respect to changed build\-time |
42 |
+dependencies is controlled by the \fB\-\-with\-bdeps\fR option. |
43 |
+.TP |
44 |
.BR "\-\-binpkg\-respect\-use [ y | n ]" |
45 |
-Tells emerge to ignore binary packages if their use flags |
46 |
-don't match the current configuration. (default: \'n\') |
47 |
+Tells emerge to ignore binary packages if their USE flags |
48 |
+don't match the current configuration. In order to help avoid issues |
49 |
+with resolving inconsistent USE flag settings, this option is |
50 |
+automatically enabled unless the \fB\-\-usepkgonly\fR option |
51 |
+is enabled. |
52 |
.TP |
53 |
.BR "\-\-buildpkg [ y | n ] (\-b short option)" |
54 |
Tells emerge to build binary packages for all ebuilds processed in |
55 |
@@ -410,6 +421,13 @@ Creates binary packages for all ebuilds processed without actually |
56 |
merging the packages. This comes with the caveat that all build-time |
57 |
dependencies must already be emerged on the system. |
58 |
.TP |
59 |
+.BR "\-\-changed\-deps [ y | n ]" |
60 |
+Tells emerge to replace installed packages for which the corresponding |
61 |
+ebuild dependencies have changed since the packages were built. This |
62 |
+option also implies the \fB\-\-selective\fR option. Behavior with |
63 |
+respect to changed build\-time dependencies is controlled by the |
64 |
+\fB\-\-with\-bdeps\fR option. |
65 |
+.TP |
66 |
.BR "\-\-changed\-use " (\fB\-U\fR) |
67 |
Tells emerge to include installed packages where USE flags have |
68 |
changed since installation. This option also implies the |
69 |
diff --git a/pym/_emerge/create_depgraph_params.py b/pym/_emerge/create_depgraph_params.py |
70 |
index 6f74de7..11e20f4 100644 |
71 |
--- a/pym/_emerge/create_depgraph_params.py |
72 |
+++ b/pym/_emerge/create_depgraph_params.py |
73 |
@@ -22,6 +22,8 @@ def create_depgraph_params(myopts, myaction): |
74 |
# ignore_built_slot_operator_deps: ignore the slot/sub-slot := operator parts |
75 |
# of dependencies that have been recorded when packages where built |
76 |
# with_test_deps: pull in test deps for packages matched by arguments |
77 |
+ # changed_deps: rebuild installed packages with outdated deps |
78 |
+ # binpkg_changed_deps: reject binary packages with outdated deps |
79 |
myparams = {"recurse" : True} |
80 |
|
81 |
bdeps = myopts.get("--with-bdeps") |
82 |
@@ -51,6 +53,7 @@ def create_depgraph_params(myopts, myaction): |
83 |
"--newuse" in myopts or \ |
84 |
"--reinstall" in myopts or \ |
85 |
"--noreplace" in myopts or \ |
86 |
+ myopts.get("--changed-deps", "n") != "n" or \ |
87 |
myopts.get("--selective", "n") != "n": |
88 |
myparams["selective"] = True |
89 |
|
90 |
@@ -99,6 +102,19 @@ def create_depgraph_params(myopts, myaction): |
91 |
# have been specified. |
92 |
myparams['binpkg_respect_use'] = 'auto' |
93 |
|
94 |
+ binpkg_changed_deps = myopts.get('--binpkg-changed-deps') |
95 |
+ if binpkg_changed_deps is not None: |
96 |
+ myparams['binpkg_changed_deps'] = binpkg_changed_deps |
97 |
+ elif '--usepkgonly' not in myopts: |
98 |
+ # In order to avoid dependency resolution issues due to changed |
99 |
+ # dependencies, enable this automatically, as long as it doesn't |
100 |
+ # strongly conflict with other options that have been specified. |
101 |
+ myparams['binpkg_changed_deps'] = 'auto' |
102 |
+ |
103 |
+ changed_deps = myopts.get('--changed-deps') |
104 |
+ if changed_deps is not None: |
105 |
+ myparams['changed_deps'] = changed_deps |
106 |
+ |
107 |
if myopts.get("--selective") == "n": |
108 |
# --selective=n can be used to remove selective |
109 |
# behavior that may have been implied by some |
110 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
111 |
index 28abea4..fae117d 100644 |
112 |
--- a/pym/_emerge/depgraph.py |
113 |
+++ b/pym/_emerge/depgraph.py |
114 |
@@ -24,7 +24,8 @@ from portage.dbapi._similar_name_search import similar_name_search |
115 |
from portage.dep import Atom, best_match_to_list, extract_affecting_use, \ |
116 |
check_required_use, human_readable_required_use, match_from_list, \ |
117 |
_repo_separator |
118 |
-from portage.dep._slot_operator import ignore_built_slot_operator_deps |
119 |
+from portage.dep._slot_operator import (ignore_built_slot_operator_deps, |
120 |
+ strip_slots) |
121 |
from portage.eapi import eapi_has_strong_blocks, eapi_has_required_use, \ |
122 |
_get_eapi_attrs |
123 |
from portage.exception import (InvalidAtom, InvalidData, InvalidDependString, |
124 |
@@ -794,14 +795,12 @@ class depgraph(object): |
125 |
match the user's config. |
126 |
""" |
127 |
if not self._dynamic_config.ignored_binaries \ |
128 |
- or '--quiet' in self._frozen_config.myopts \ |
129 |
- or self._dynamic_config.myparams.get( |
130 |
- "binpkg_respect_use") in ("y", "n"): |
131 |
+ or '--quiet' in self._frozen_config.myopts: |
132 |
return |
133 |
|
134 |
- for pkg in list(self._dynamic_config.ignored_binaries): |
135 |
+ ignored_binaries = {} |
136 |
|
137 |
- selected_pkg = list() |
138 |
+ for pkg in list(self._dynamic_config.ignored_binaries): |
139 |
|
140 |
for selected_pkg in self._dynamic_config._package_tracker.match( |
141 |
pkg.root, pkg.slot_atom): |
142 |
@@ -819,15 +818,38 @@ class depgraph(object): |
143 |
self._dynamic_config.ignored_binaries.pop(pkg) |
144 |
break |
145 |
|
146 |
- if not self._dynamic_config.ignored_binaries: |
147 |
+ else: |
148 |
+ for reason, info in self._dynamic_config.\ |
149 |
+ ignored_binaries[pkg].items(): |
150 |
+ ignored_binaries.setdefault(reason, {})[pkg] = info |
151 |
+ |
152 |
+ if self._dynamic_config.myparams.get( |
153 |
+ "binpkg_respect_use") in ("y", "n"): |
154 |
+ ignored_binaries.pop("respect_use", None) |
155 |
+ |
156 |
+ if self._dynamic_config.myparams.get( |
157 |
+ "binpkg_changed_deps") in ("y", "n"): |
158 |
+ ignored_binaries.pop("changed_deps", None) |
159 |
+ |
160 |
+ if not ignored_binaries: |
161 |
return |
162 |
|
163 |
self._show_merge_list() |
164 |
|
165 |
+ if ignored_binaries.get("respect_use"): |
166 |
+ self._show_ignored_binaries_respect_use( |
167 |
+ ignored_binaries["respect_use"]) |
168 |
+ |
169 |
+ if ignored_binaries.get("changed_deps"): |
170 |
+ self._show_ignored_binaries_changed_deps( |
171 |
+ ignored_binaries["changed_deps"]) |
172 |
+ |
173 |
+ def _show_ignored_binaries_respect_use(self, respect_use): |
174 |
+ |
175 |
writemsg("\n!!! The following binary packages have been ignored " + \ |
176 |
"due to non matching USE:\n\n", noiselevel=-1) |
177 |
|
178 |
- for pkg, flags in self._dynamic_config.ignored_binaries.items(): |
179 |
+ for pkg, flags in respect_use.items(): |
180 |
flag_display = [] |
181 |
for flag in sorted(flags): |
182 |
if flag not in pkg.use.enabled: |
183 |
@@ -852,6 +874,30 @@ class depgraph(object): |
184 |
line = colorize("INFORM", line) |
185 |
writemsg(line + "\n", noiselevel=-1) |
186 |
|
187 |
+ def _show_ignored_binaries_changed_deps(self, changed_deps): |
188 |
+ |
189 |
+ writemsg("\n!!! The following binary packages have been " |
190 |
+ "ignored due to changed dependencies:\n\n", |
191 |
+ noiselevel=-1) |
192 |
+ |
193 |
+ for pkg in changed_deps: |
194 |
+ msg = " %s%s%s" % (pkg.cpv, _repo_separator, pkg.repo) |
195 |
+ if pkg.root_config.settings["ROOT"] != "/": |
196 |
+ msg += " for %s" % pkg.root |
197 |
+ writemsg("%s\n" % msg, noiselevel=-1) |
198 |
+ |
199 |
+ msg = [ |
200 |
+ "", |
201 |
+ "NOTE: The --binpkg-changed-deps=n option will prevent emerge", |
202 |
+ " from ignoring these binary packages if possible.", |
203 |
+ " Using --binpkg-changed-deps=y will silence this warning." |
204 |
+ ] |
205 |
+ |
206 |
+ for line in msg: |
207 |
+ if line: |
208 |
+ line = colorize("INFORM", line) |
209 |
+ writemsg(line + "\n", noiselevel=-1) |
210 |
+ |
211 |
def _get_missed_updates(self): |
212 |
|
213 |
# In order to minimize noise, show only the highest |
214 |
@@ -2173,6 +2219,52 @@ class depgraph(object): |
215 |
return flags |
216 |
return None |
217 |
|
218 |
+ def _changed_deps(self, pkg): |
219 |
+ |
220 |
+ ebuild = None |
221 |
+ try: |
222 |
+ ebuild = self._pkg(pkg.cpv, "ebuild", |
223 |
+ pkg.root_config, myrepo=pkg.repo) |
224 |
+ except PackageNotFound: |
225 |
+ # Use first available instance of the same version. |
226 |
+ for ebuild in self._iter_match_pkgs( |
227 |
+ pkg.root_config, "ebuild", Atom("=" + pkg.cpv)): |
228 |
+ break |
229 |
+ |
230 |
+ if ebuild is None: |
231 |
+ changed = False |
232 |
+ else: |
233 |
+ if self._dynamic_config.myparams.get("bdeps", "n") == "y": |
234 |
+ depvars = Package._dep_keys |
235 |
+ else: |
236 |
+ depvars = Package._runtime_keys |
237 |
+ |
238 |
+ # Use _raw_metadata, in order to avoid interaction |
239 |
+ # with --dynamic-deps. |
240 |
+ try: |
241 |
+ built_deps = [] |
242 |
+ for k in depvars: |
243 |
+ dep_struct = portage.dep.use_reduce( |
244 |
+ pkg._raw_metadata[k], uselist=pkg.use.enabled, |
245 |
+ eapi=pkg.eapi, token_class=Atom) |
246 |
+ strip_slots(dep_struct) |
247 |
+ built_deps.append(dep_struct) |
248 |
+ except InvalidDependString: |
249 |
+ changed = True |
250 |
+ else: |
251 |
+ unbuilt_deps = [] |
252 |
+ for k in depvars: |
253 |
+ dep_struct = portage.dep.use_reduce( |
254 |
+ ebuild._raw_metadata[k], |
255 |
+ uselist=pkg.use.enabled, |
256 |
+ eapi=ebuild.eapi, token_class=Atom) |
257 |
+ strip_slots(dep_struct) |
258 |
+ unbuilt_deps.append(dep_struct) |
259 |
+ |
260 |
+ changed = built_deps != unbuilt_deps |
261 |
+ |
262 |
+ return changed |
263 |
+ |
264 |
def _create_graph(self, allow_unsatisfied=False): |
265 |
dep_stack = self._dynamic_config._dep_stack |
266 |
dep_disjunctive_stack = self._dynamic_config._dep_disjunctive_stack |
267 |
@@ -4595,8 +4687,14 @@ class depgraph(object): |
268 |
mreasons = ["need to rebuild from source"] |
269 |
elif pkg.installed and root_slot in self._rebuild.reinstall_list: |
270 |
mreasons = ["need to rebuild from source"] |
271 |
- elif pkg.built and not mreasons: |
272 |
+ elif (pkg.built and not mreasons and |
273 |
+ self._dynamic_config.ignored_binaries.get( |
274 |
+ pkg, {}).get("respect_use")): |
275 |
mreasons = ["use flag configuration mismatch"] |
276 |
+ elif (pkg.built and not mreasons and |
277 |
+ self._dynamic_config.ignored_binaries.get( |
278 |
+ pkg, {}).get("changed_deps")): |
279 |
+ mreasons = ["changed deps"] |
280 |
masked_packages.append( |
281 |
(root_config, pkgsettings, cpv, repo, metadata, mreasons)) |
282 |
|
283 |
@@ -5693,6 +5791,12 @@ class depgraph(object): |
284 |
# reject the built package if necessary. |
285 |
reinstall_use = ("--newuse" in self._frozen_config.myopts or \ |
286 |
"--reinstall" in self._frozen_config.myopts) |
287 |
+ changed_deps = ( |
288 |
+ self._dynamic_config.myparams.get( |
289 |
+ "changed_deps", "n") != "n") |
290 |
+ binpkg_changed_deps = ( |
291 |
+ self._dynamic_config.myparams.get( |
292 |
+ "binpkg_changed_deps", "n") != "n") |
293 |
respect_use = self._dynamic_config.myparams.get("binpkg_respect_use") in ("y", "auto") |
294 |
if built and not useoldpkg and \ |
295 |
(not installed or matched_packages) and \ |
296 |
@@ -5719,8 +5823,22 @@ class depgraph(object): |
297 |
forced_flags, old_use, iuses, now_use, cur_iuse) |
298 |
if reinstall_for_flags: |
299 |
if not pkg.installed: |
300 |
- self._dynamic_config.ignored_binaries.setdefault(pkg, set()).update(reinstall_for_flags) |
301 |
+ self._dynamic_config.\ |
302 |
+ ignored_binaries.setdefault( |
303 |
+ pkg, {}).setdefault( |
304 |
+ "respect_use", set()).update( |
305 |
+ reinstall_for_flags) |
306 |
break |
307 |
+ |
308 |
+ if (((installed and changed_deps) or |
309 |
+ (not installed and binpkg_changed_deps)) and |
310 |
+ self._changed_deps(pkg)): |
311 |
+ if not installed: |
312 |
+ self._dynamic_config.\ |
313 |
+ ignored_binaries.setdefault( |
314 |
+ pkg, {})["changed_deps"] = True |
315 |
+ break |
316 |
+ |
317 |
# Compare current config to installed package |
318 |
# and do not reinstall if possible. |
319 |
if not installed and not useoldpkg and cpv in vardb.match(atom): |
320 |
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py |
321 |
index 7c707f9..ecbbdb0 100644 |
322 |
--- a/pym/_emerge/main.py |
323 |
+++ b/pym/_emerge/main.py |
324 |
@@ -129,7 +129,9 @@ def insert_optional_args(args): |
325 |
'--autounmask-keep-masks': y_or_n, |
326 |
'--autounmask-unrestricted-atoms' : y_or_n, |
327 |
'--autounmask-write' : y_or_n, |
328 |
+ '--binpkg-changed-deps' : y_or_n, |
329 |
'--buildpkg' : y_or_n, |
330 |
+ '--changed-deps' : y_or_n, |
331 |
'--complete-graph' : y_or_n, |
332 |
'--deep' : valid_integers, |
333 |
'--depclean-lib-check' : y_or_n, |
334 |
@@ -353,6 +355,12 @@ def parse_opts(tmpcmdline, silent=False): |
335 |
"action" : "store" |
336 |
}, |
337 |
|
338 |
+ "--binpkg-changed-deps": { |
339 |
+ "help" : ("reject binary packages with outdated " |
340 |
+ "dependencies"), |
341 |
+ "choices" : true_y_or_n |
342 |
+ }, |
343 |
+ |
344 |
"--buildpkg": { |
345 |
"shortopt" : "-b", |
346 |
"help" : "build binary packages", |
347 |
@@ -367,6 +375,12 @@ def parse_opts(tmpcmdline, silent=False): |
348 |
"action" : "append" |
349 |
}, |
350 |
|
351 |
+ "--changed-deps": { |
352 |
+ "help" : ("replace installed packages with " |
353 |
+ "outdated dependencies"), |
354 |
+ "choices" : true_y_or_n |
355 |
+ }, |
356 |
+ |
357 |
"--config-root": { |
358 |
"help":"specify the location for portage configuration files", |
359 |
"action":"store" |
360 |
@@ -722,6 +736,12 @@ def parse_opts(tmpcmdline, silent=False): |
361 |
if myoptions.autounmask_write in true_y: |
362 |
myoptions.autounmask_write = True |
363 |
|
364 |
+ if myoptions.binpkg_changed_deps is not None: |
365 |
+ if myoptions.binpkg_changed_deps in true_y: |
366 |
+ myoptions.binpkg_changed_deps = 'y' |
367 |
+ else: |
368 |
+ myoptions.binpkg_changed_deps = 'n' |
369 |
+ |
370 |
if myoptions.buildpkg in true_y: |
371 |
myoptions.buildpkg = True |
372 |
|
373 |
@@ -731,6 +751,12 @@ def parse_opts(tmpcmdline, silent=False): |
374 |
parser.error("Invalid Atom(s) in --buildpkg-exclude parameter: '%s'\n" % \ |
375 |
(",".join(bad_atoms),)) |
376 |
|
377 |
+ if myoptions.changed_deps is not None: |
378 |
+ if myoptions.changed_deps in true_y: |
379 |
+ myoptions.changed_deps = 'y' |
380 |
+ else: |
381 |
+ myoptions.changed_deps = 'n' |
382 |
+ |
383 |
if myoptions.changed_use is not False: |
384 |
myoptions.reinstall = "changed-use" |
385 |
myoptions.changed_use = False |
386 |
diff --git a/pym/portage/dep/_slot_operator.py b/pym/portage/dep/_slot_operator.py |
387 |
index 8b67fc5..8ce570d 100644 |
388 |
--- a/pym/portage/dep/_slot_operator.py |
389 |
+++ b/pym/portage/dep/_slot_operator.py |
390 |
@@ -8,6 +8,19 @@ from portage.eapi import _get_eapi_attrs |
391 |
from portage.exception import InvalidData |
392 |
from _emerge.Package import Package |
393 |
|
394 |
+def strip_slots(dep_struct): |
395 |
+ """ |
396 |
+ Search dep_struct for any slot := operators and remove the |
397 |
+ slot/sub-slot part, while preserving the operator. The result |
398 |
+ is suitable for --changed-deps comparisons. |
399 |
+ """ |
400 |
+ for i, x in enumerate(dep_struct): |
401 |
+ if isinstance(x, list): |
402 |
+ strip_slots(x) |
403 |
+ elif (isinstance(x, Atom) and |
404 |
+ x.slot_operator == "=" and x.slot is not None): |
405 |
+ dep_struct[i] = x.with_slot("=") |
406 |
+ |
407 |
def find_built_slot_operator_atoms(pkg): |
408 |
atoms = {} |
409 |
for k in Package._dep_keys: |
410 |
diff --git a/pym/portage/tests/resolver/test_changed_deps.py b/pym/portage/tests/resolver/test_changed_deps.py |
411 |
new file mode 100644 |
412 |
index 0000000..2421c53 |
413 |
--- /dev/null |
414 |
+++ b/pym/portage/tests/resolver/test_changed_deps.py |
415 |
@@ -0,0 +1,120 @@ |
416 |
+# Copyright 2014 Gentoo Foundation |
417 |
+# Distributed under the terms of the GNU General Public License v2 |
418 |
+ |
419 |
+from portage.tests import TestCase |
420 |
+from portage.tests.resolver.ResolverPlayground import ( |
421 |
+ ResolverPlayground, ResolverPlaygroundTestCase) |
422 |
+ |
423 |
+class ChangedDepsTestCase(TestCase): |
424 |
+ |
425 |
+ def testChangedDeps(self): |
426 |
+ |
427 |
+ ebuilds = { |
428 |
+ "app-misc/A-0": { |
429 |
+ "DEPEND": "app-misc/B", |
430 |
+ "RDEPEND": "app-misc/B", |
431 |
+ }, |
432 |
+ "app-misc/B-0": { |
433 |
+ } |
434 |
+ } |
435 |
+ |
436 |
+ binpkgs = { |
437 |
+ "app-misc/A-0": {}, |
438 |
+ } |
439 |
+ |
440 |
+ installed = { |
441 |
+ "app-misc/A-0": {}, |
442 |
+ } |
443 |
+ |
444 |
+ world= ( |
445 |
+ "app-misc/A", |
446 |
+ ) |
447 |
+ |
448 |
+ test_cases = ( |
449 |
+ |
450 |
+ # --dynamic-deps=n causes the original deps to be respected |
451 |
+ ResolverPlaygroundTestCase( |
452 |
+ ["@world"], |
453 |
+ success = True, |
454 |
+ options = { |
455 |
+ "--update": True, |
456 |
+ "--deep": True, |
457 |
+ "--dynamic-deps": "n", |
458 |
+ "--usepkg": True, |
459 |
+ }, |
460 |
+ mergelist = [] |
461 |
+ ), |
462 |
+ |
463 |
+ # --dynamic-deps causes app-misc/B to get pulled in |
464 |
+ ResolverPlaygroundTestCase( |
465 |
+ ["@world"], |
466 |
+ success = True, |
467 |
+ options = { |
468 |
+ "--update": True, |
469 |
+ "--deep": True, |
470 |
+ "--usepkg": True, |
471 |
+ }, |
472 |
+ mergelist = ["app-misc/B-0"] |
473 |
+ ), |
474 |
+ |
475 |
+ # --changed-deps causes app-misc/A to be rebuilt |
476 |
+ ResolverPlaygroundTestCase( |
477 |
+ ["@world"], |
478 |
+ success = True, |
479 |
+ options = { |
480 |
+ "--update": True, |
481 |
+ "--deep": True, |
482 |
+ "--changed-deps": "y", |
483 |
+ "--usepkg": True, |
484 |
+ }, |
485 |
+ mergelist = ["app-misc/B-0", "app-misc/A-0"] |
486 |
+ ), |
487 |
+ |
488 |
+ # --usepkgonly prevents automatic --binpkg-changed-deps |
489 |
+ ResolverPlaygroundTestCase( |
490 |
+ ["app-misc/A"], |
491 |
+ success = True, |
492 |
+ options = { |
493 |
+ "--changed-deps": "y", |
494 |
+ "--usepkgonly": True, |
495 |
+ }, |
496 |
+ mergelist = ["[binary]app-misc/A-0"] |
497 |
+ ), |
498 |
+ |
499 |
+ # Test automatic --binpkg-changed-deps, which cases the |
500 |
+ # binpkg with stale deps to be ignored (with warning |
501 |
+ # message) |
502 |
+ ResolverPlaygroundTestCase( |
503 |
+ ["app-misc/A"], |
504 |
+ success = True, |
505 |
+ options = { |
506 |
+ "--usepkg": True, |
507 |
+ }, |
508 |
+ mergelist = ["app-misc/B-0", "app-misc/A-0"] |
509 |
+ ), |
510 |
+ ) |
511 |
+ test_cases = ( |
512 |
+ |
513 |
+ # Forcibly disable --binpkg-changed-deps, which causes |
514 |
+ # --changed-deps to be overridden by --binpkg-changed-deps |
515 |
+ ResolverPlaygroundTestCase( |
516 |
+ ["app-misc/A"], |
517 |
+ success = True, |
518 |
+ options = { |
519 |
+ "--binpkg-changed-deps": "n", |
520 |
+ "--changed-deps": "y", |
521 |
+ "--usepkg": True, |
522 |
+ }, |
523 |
+ mergelist = ["[binary]app-misc/A-0"] |
524 |
+ ), |
525 |
+ ) |
526 |
+ |
527 |
+ playground = ResolverPlayground(debug=False, ebuilds=ebuilds, |
528 |
+ binpkgs=binpkgs, installed=installed, world=world) |
529 |
+ try: |
530 |
+ for test_case in test_cases: |
531 |
+ playground.run_TestCase(test_case) |
532 |
+ self.assertEqual(test_case.test_success, |
533 |
+ True, test_case.fail_msg) |
534 |
+ finally: |
535 |
+ playground.cleanup() |
536 |
-- |
537 |
2.0.5 |