1 |
commit: 0c00530c92ecca3499c7d98fedae41a9ab559d17 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Nov 24 09:14:41 2015 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Nov 24 16:43:58 2015 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=0c00530c |
7 |
|
8 |
depgraph: autounmask for conditional USE deps (bug 566704) |
9 |
|
10 |
For parents with unsatisfied conditional dependencies, translate |
11 |
USE change suggestions into autounmask changes. |
12 |
|
13 |
X-Gentoo-Bug: 566704 |
14 |
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=566704 |
15 |
Acked-by: Alexander Berntsen <bernalex <AT> gentoo.org> |
16 |
|
17 |
pym/_emerge/depgraph.py | 35 +++++++++++++++++- |
18 |
.../tests/resolver/test_autounmask_parent.py | 43 ++++++++++++++++++++++ |
19 |
2 files changed, 77 insertions(+), 1 deletion(-) |
20 |
|
21 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
22 |
index 57040ab..f659b0a 100644 |
23 |
--- a/pym/_emerge/depgraph.py |
24 |
+++ b/pym/_emerge/depgraph.py |
25 |
@@ -4075,6 +4075,7 @@ class depgraph(object): |
26 |
# Now that the root packages have been added to the graph, |
27 |
# process the dependencies. |
28 |
if not self._create_graph(): |
29 |
+ self._apply_parent_use_changes() |
30 |
return 0, myfavorites |
31 |
|
32 |
try: |
33 |
@@ -4162,6 +4163,24 @@ class depgraph(object): |
34 |
# We're true here unless we are missing binaries. |
35 |
return (True, myfavorites) |
36 |
|
37 |
+ def _apply_parent_use_changes(self): |
38 |
+ """ |
39 |
+ For parents with unsatisfied conditional dependencies, translate |
40 |
+ USE change suggestions into autounmask changes. |
41 |
+ """ |
42 |
+ if (self._dynamic_config._unsatisfied_deps_for_display and |
43 |
+ self._dynamic_config._autounmask): |
44 |
+ remaining_items = [] |
45 |
+ for item in self._dynamic_config._unsatisfied_deps_for_display: |
46 |
+ pargs, kwargs = item |
47 |
+ kwargs = kwargs.copy() |
48 |
+ kwargs['collect_use_changes'] = True |
49 |
+ if not self._show_unsatisfied_dep(*pargs, |
50 |
+ **portage._native_kwargs(kwargs)): |
51 |
+ remaining_items.append(item) |
52 |
+ if len(remaining_items) != len(self._dynamic_config._unsatisfied_deps_for_display): |
53 |
+ self._dynamic_config._unsatisfied_deps_for_display = remaining_items |
54 |
+ |
55 |
def _set_args(self, args): |
56 |
""" |
57 |
Create the "__non_set_args__" package set from atoms and packages given as |
58 |
@@ -4718,7 +4737,8 @@ class depgraph(object): |
59 |
|
60 |
|
61 |
def _show_unsatisfied_dep(self, root, atom, myparent=None, arg=None, |
62 |
- check_backtrack=False, check_autounmask_breakage=False, show_req_use=None): |
63 |
+ check_backtrack=False, check_autounmask_breakage=False, show_req_use=None, |
64 |
+ collect_use_changes=False): |
65 |
""" |
66 |
When check_backtrack=True, no output is produced and |
67 |
the method either returns or raises _backtrack_mask if |
68 |
@@ -4962,15 +4982,28 @@ class depgraph(object): |
69 |
"defined by %s: '%s'" % (myparent.cpv, \ |
70 |
human_readable_required_use(required_use)) |
71 |
|
72 |
+ target_use = {} |
73 |
for flag in involved_flags: |
74 |
if flag in self._pkg_use_enabled(myparent): |
75 |
+ target_use[flag] = False |
76 |
changes.append(colorize("blue", "-" + flag)) |
77 |
else: |
78 |
+ target_use[flag] = True |
79 |
changes.append(colorize("red", "+" + flag)) |
80 |
+ |
81 |
+ if collect_use_changes and not required_use_warning: |
82 |
+ previous_changes = self._dynamic_config._needed_use_config_changes.get(myparent) |
83 |
+ self._pkg_use_enabled(myparent, target_use=target_use) |
84 |
+ if previous_changes is not self._dynamic_config._needed_use_config_changes.get(myparent): |
85 |
+ return True |
86 |
+ |
87 |
mreasons.append("Change USE: %s" % " ".join(changes) + required_use_warning) |
88 |
if (myparent, mreasons) not in missing_use_reasons: |
89 |
missing_use_reasons.append((myparent, mreasons)) |
90 |
|
91 |
+ if collect_use_changes: |
92 |
+ return False |
93 |
+ |
94 |
unmasked_use_reasons = [(pkg, mreasons) for (pkg, mreasons) \ |
95 |
in missing_use_reasons if pkg not in masked_pkg_instances] |
96 |
|
97 |
|
98 |
diff --git a/pym/portage/tests/resolver/test_autounmask_parent.py b/pym/portage/tests/resolver/test_autounmask_parent.py |
99 |
new file mode 100644 |
100 |
index 0000000..042acab |
101 |
--- /dev/null |
102 |
+++ b/pym/portage/tests/resolver/test_autounmask_parent.py |
103 |
@@ -0,0 +1,43 @@ |
104 |
+# Copyright 2015 Gentoo Foundation |
105 |
+# Distributed under the terms of the GNU General Public License v2 |
106 |
+ |
107 |
+from portage.tests import TestCase |
108 |
+from portage.tests.resolver.ResolverPlayground import ( |
109 |
+ ResolverPlayground, |
110 |
+ ResolverPlaygroundTestCase, |
111 |
+) |
112 |
+ |
113 |
+class AutounmaskParentTestCase(TestCase): |
114 |
+ |
115 |
+ def testAutounmaskParentUse(self): |
116 |
+ |
117 |
+ ebuilds = { |
118 |
+ "dev-libs/B-1": { |
119 |
+ "EAPI": "5", |
120 |
+ "DEPEND": "dev-libs/D[foo(-)?,bar(-)?]", |
121 |
+ "IUSE": "+bar +foo", |
122 |
+ }, |
123 |
+ "dev-libs/D-1": {}, |
124 |
+ } |
125 |
+ |
126 |
+ test_cases = ( |
127 |
+ # Test bug 566704 |
128 |
+ ResolverPlaygroundTestCase( |
129 |
+ ["=dev-libs/B-1"], |
130 |
+ options={"--autounmask": True}, |
131 |
+ success=False, |
132 |
+ use_changes={ |
133 |
+ "dev-libs/B-1": { |
134 |
+ "foo": False, |
135 |
+ "bar": False, |
136 |
+ } |
137 |
+ }), |
138 |
+ ) |
139 |
+ |
140 |
+ playground = ResolverPlayground(ebuilds=ebuilds) |
141 |
+ try: |
142 |
+ for test_case in test_cases: |
143 |
+ playground.run_TestCase(test_case) |
144 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
145 |
+ finally: |
146 |
+ playground.cleanup() |