1 |
On Fri, 17 Mar 2017 01:18:19 -0700 |
2 |
Zac Medico <zmedico@g.o> wrote: |
3 |
|
4 |
> Fix check_reverse_dependencies to ignore direct circular dependencies, |
5 |
> since these dependencies tend to prevent updates of packages. This |
6 |
> solves a missed update from llvm:0 to llvm:4 when clang is not in the |
7 |
> world file, as demonstrated by the included test case. |
8 |
> |
9 |
> X-Gentoo-bug: 612874 |
10 |
> X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=612874 |
11 |
> --- |
12 |
> pym/_emerge/depgraph.py | 31 |
13 |
> ++++++++++++----- .../resolver/test_slot_operator_exclusive_slots.py |
14 |
> | 39 ++++++++++++++++++++++ |
15 |
> pym/portage/util/digraph.py | 6 ++++ 3 files |
16 |
> changed, 68 insertions(+), 8 deletions(-) |
17 |
> |
18 |
> diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
19 |
> index f4145d0..e94b96c 100644 |
20 |
> --- a/pym/_emerge/depgraph.py |
21 |
> +++ b/pym/_emerge/depgraph.py |
22 |
> @@ -1844,14 +1844,29 @@ class depgraph(object): |
23 |
> if (not |
24 |
> self._too_deep(parent.depth) and not |
25 |
> self._frozen_config.excluded_pkgs. findAtomForPackage(parent, |
26 |
> - |
27 |
> modified_use=self._pkg_use_enabled(parent)) and |
28 |
> - |
29 |
> (self._upgrade_available(parent) or |
30 |
> - (parent.installed |
31 |
> and self._in_blocker_conflict(parent)))): |
32 |
> - # This parent may be |
33 |
> irrelevant, since an |
34 |
> - # update is |
35 |
> available (see bug 584626), or |
36 |
> - # it could be |
37 |
> uninstalled in order to solve |
38 |
> - # a blocker conflict |
39 |
> (bug 612772). |
40 |
> - continue |
41 |
> + |
42 |
> modified_use=self._pkg_use_enabled(parent))): |
43 |
> + # Check for common |
44 |
> reasons that the parent's |
45 |
> + # dependency might |
46 |
> be irrelevant. |
47 |
> + if |
48 |
> self._upgrade_available(parent): |
49 |
> + # This |
50 |
> parent could be replaced by |
51 |
> + # an upgrade |
52 |
> (bug 584626). |
53 |
> + continue |
54 |
> + if parent.installed |
55 |
> and self._in_blocker_conflict(parent): |
56 |
> + # This |
57 |
> parent could be uninstalled in order |
58 |
> + # to solve a |
59 |
> blocker conflict (bug 612772). |
60 |
> + continue |
61 |
> + if |
62 |
> self._dynamic_config.digraph.has_edge(parent, |
63 |
> + |
64 |
> existing_pkg): |
65 |
> + # There is a |
66 |
> direct circular dependency between |
67 |
> + # parent and |
68 |
> existing_pkg. This type of |
69 |
> + # |
70 |
> relationship tends to prevent updates |
71 |
> + # of |
72 |
> packages (bug 612874). Since candidate_pkg |
73 |
> + # is |
74 |
> available, we risk a missed update if we |
75 |
> + # don't try |
76 |
> to eliminate this parent from the |
77 |
> + # graph. |
78 |
> Therefore, we give candidate_pkg a |
79 |
> + # chance, |
80 |
> and assume that it will be masked |
81 |
> + # by |
82 |
> backtracking if necessary. |
83 |
> + continue |
84 |
> |
85 |
> atom_set = |
86 |
> InternalPackageSet(initial_atoms=(atom,), allow_repo=True) |
87 |
> diff --git |
88 |
> a/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py |
89 |
> b/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py |
90 |
> index 2ab379c..689ed31 100644 --- |
91 |
> a/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py |
92 |
> +++ |
93 |
> b/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py @@ |
94 |
> -107,3 +107,42 @@ class SlotOperatorExclusiveSlotsTestCase(TestCase): |
95 |
> test_case.fail_msg) finally: playground.cleanup() + |
96 |
> + |
97 |
> + world = ["media-libs/mesa"] |
98 |
> + |
99 |
> + test_cases = ( |
100 |
> + |
101 |
> + # Test bug #612874, where a direct circular |
102 |
> dependency |
103 |
> + # between llvm-3.9.1 and clang-3.9.1-r100 |
104 |
> causes a |
105 |
> + # missed update from llvm:0 to llvm:4. Since |
106 |
> llvm:4 does |
107 |
> + # not have a dependency on clang, the |
108 |
> upgrade from llvm:0 |
109 |
> + # to llvm:4 makes the installed |
110 |
> sys-devel/clang-3.9.1-r100 |
111 |
> + # instance eligible for removal by emerge |
112 |
> --depclean, which |
113 |
> + # explains why clang does not appear in the |
114 |
> mergelist. |
115 |
> + ResolverPlaygroundTestCase( |
116 |
> + ["@world"], |
117 |
> + options = {"--update": True, |
118 |
> "--deep": True}, |
119 |
> + success = True, |
120 |
> + ambiguous_merge_order = True, |
121 |
> + mergelist = [ |
122 |
> + 'sys-devel/llvm-4.0.0', |
123 |
> + ( |
124 |
> + 'media-libs/mesa-17.0.1', |
125 |
> + '[uninstall]sys-devel/llvm-3.9.1', |
126 |
> + '!sys-devel/llvm:0', |
127 |
> + ) |
128 |
> + ], |
129 |
> + ), |
130 |
> + |
131 |
> + ) |
132 |
> + |
133 |
> + playground = ResolverPlayground(ebuilds=ebuilds, |
134 |
> + installed=installed, world=world) |
135 |
> + try: |
136 |
> + for test_case in test_cases: |
137 |
> + playground.run_TestCase(test_case) |
138 |
> + |
139 |
> self.assertEqual(test_case.test_success, True, |
140 |
> + test_case.fail_msg) |
141 |
> + finally: |
142 |
> + playground.cleanup() |
143 |
> diff --git a/pym/portage/util/digraph.py b/pym/portage/util/digraph.py |
144 |
> index 4a9cb43..b6be0c9 100644 |
145 |
> --- a/pym/portage/util/digraph.py |
146 |
> +++ b/pym/portage/util/digraph.py |
147 |
> @@ -93,6 +93,12 @@ class digraph(object): |
148 |
> del self.nodes[node] |
149 |
> self.order = order |
150 |
> |
151 |
> + def has_edge(self, child, parent): |
152 |
> + """ |
153 |
> + Return True if the given edge exists. |
154 |
> + """ |
155 |
> + return child in self.nodes[parent][0] |
156 |
> + |
157 |
> def remove_edge(self, child, parent): |
158 |
> """ |
159 |
> Remove edge in the direction from child to parent. |
160 |
> Note that it is |
161 |
|
162 |
|
163 |
Looks good |
164 |
|
165 |
-- |
166 |
Brian Dolbec <dolsen> |