Gentoo Archives: gentoo-commits

From: Zac Medico <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: pym/_emerge/
Date: Sun, 17 Jun 2012 03:07:03
Message-Id: 1339902396.8838c798d771af7f5356cacf37e10d9f55ac6519.zmedico@gentoo
1 commit: 8838c798d771af7f5356cacf37e10d9f55ac6519
2 Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
3 AuthorDate: Sun Jun 17 03:06:36 2012 +0000
4 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
5 CommitDate: Sun Jun 17 03:06:36 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=8838c798
7
8 depgraph: split out _handle_slot_conflict method
9
10 ---
11 pym/_emerge/depgraph.py | 245 ++++++++++++++++++++++++-----------------------
12 1 files changed, 125 insertions(+), 120 deletions(-)
13
14 diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
15 index 276a749..ec9434b 100644
16 --- a/pym/_emerge/depgraph.py
17 +++ b/pym/_emerge/depgraph.py
18 @@ -833,6 +833,128 @@ class depgraph(object):
19 else:
20 self._dynamic_config._slot_conflict_parent_atoms.add(parent_atom)
21
22 + def _handle_slot_conflict(self, existing_node, pkg, dep, arg_atoms):
23 +
24 + debug = "--debug" in self._frozen_config.myopts
25 + self._add_slot_conflict(pkg)
26 +
27 + if dep.atom is not None and dep.parent is not None:
28 + self._add_parent_atom(pkg, (dep.parent, dep.atom))
29 +
30 + if arg_atoms:
31 + for parent_atom in arg_atoms:
32 + parent, atom = parent_atom
33 + self._add_parent_atom(pkg, parent_atom)
34 +
35 + # The existing node should not already be in
36 + # runtime_pkg_mask, since that would trigger an
37 + # infinite backtracking loop.
38 + if self._dynamic_config._allow_backtracking and \
39 + existing_node in self._dynamic_config._runtime_pkg_mask:
40 + if debug:
41 + writemsg_level(
42 + "!!! backtracking loop detected: %s %s\n" % \
43 + (existing_node,
44 + self._dynamic_config._runtime_pkg_mask[existing_node]),
45 + level=logging.DEBUG, noiselevel=-1)
46 + elif self._dynamic_config._allow_backtracking and \
47 + not self._accept_blocker_conflicts() and \
48 + not self.need_restart():
49 +
50 + self._process_slot_conflicts()
51 +
52 + backtrack_data = []
53 + fallback_data = []
54 + all_parents = set()
55 + # The ordering of backtrack_data can make
56 + # a difference here, because both mask actions may lead
57 + # to valid, but different, solutions and the one with
58 + # 'existing_node' masked is usually the better one. Because
59 + # of that, we choose an order such that
60 + # the backtracker will first explore the choice with
61 + # existing_node masked. The backtracker reverses the
62 + # order, so the order it uses is the reverse of the
63 + # order shown here. See bug #339606.
64 + for to_be_selected, to_be_masked in (existing_node, pkg), (pkg, existing_node):
65 + # For missed update messages, find out which
66 + # atoms matched to_be_selected that did not
67 + # match to_be_masked.
68 + parent_atoms = \
69 + self._dynamic_config._parent_atoms.get(to_be_selected, set())
70 + if parent_atoms:
71 + conflict_atoms = self._dynamic_config._slot_conflict_parent_atoms.intersection(parent_atoms)
72 + if conflict_atoms:
73 + parent_atoms = conflict_atoms
74 +
75 + all_parents.update(parent_atoms)
76 +
77 + all_match = True
78 + for parent, atom in parent_atoms:
79 + i = InternalPackageSet(initial_atoms=(atom,),
80 + allow_repo=True)
81 + if not i.findAtomForPackage(to_be_masked):
82 + all_match = False
83 + break
84 +
85 + fallback_data.append((to_be_masked, parent_atoms))
86 +
87 + if all_match:
88 + # 'to_be_masked' does not violate any parent atom, which means
89 + # there is no point in masking it.
90 + pass
91 + else:
92 + backtrack_data.append((to_be_masked, parent_atoms))
93 +
94 + if not backtrack_data:
95 + # This shouldn't happen, but fall back to the old
96 + # behavior if this gets triggered somehow.
97 + backtrack_data = fallback_data
98 +
99 + if len(backtrack_data) > 1:
100 + # NOTE: Generally, we prefer to mask the higher
101 + # version since this solves common cases in which a
102 + # lower version is needed so that all dependencies
103 + # will be satisfied (bug #337178). However, if
104 + # existing_node happens to be installed then we
105 + # mask that since this is a common case that is
106 + # triggered when --update is not enabled.
107 + if existing_node.installed:
108 + pass
109 + elif pkg > existing_node:
110 + backtrack_data.reverse()
111 +
112 + to_be_masked = backtrack_data[-1][0]
113 +
114 + self._dynamic_config._backtrack_infos["slot conflict"] = backtrack_data
115 + self._dynamic_config._need_restart = True
116 + if debug:
117 + msg = []
118 + msg.append("")
119 + msg.append("")
120 + msg.append("backtracking due to slot conflict:")
121 + if backtrack_data is fallback_data:
122 + msg.append("!!! backtrack_data fallback")
123 + msg.append(" first package: %s" % existing_node)
124 + msg.append(" second package: %s" % pkg)
125 + msg.append(" package to mask: %s" % to_be_masked)
126 + msg.append(" slot: %s" % pkg.slot_atom)
127 + msg.append(" parents: %s" % ", ".join( \
128 + "(%s, '%s')" % (ppkg, atom) for ppkg, atom in all_parents))
129 + msg.append("")
130 + writemsg_level("".join("%s\n" % l for l in msg),
131 + noiselevel=-1, level=logging.DEBUG)
132 + return False
133 +
134 + if debug:
135 + writemsg_level(
136 + "%s%s %s\n" % ("Slot Conflict:".ljust(15),
137 + existing_node, pkg_use_display(existing_node,
138 + self._frozen_config.myopts,
139 + modified_use=self._pkg_use_enabled(existing_node))),
140 + level=logging.DEBUG, noiselevel=-1)
141 +
142 + return True
143 +
144 def _reinstall_for_flags(self, pkg, forced_flags,
145 orig_use, orig_iuse, cur_use, cur_iuse):
146 """Return a set of flags that trigger reinstallation, or None if there
147 @@ -1152,128 +1274,11 @@ class depgraph(object):
148 return 1
149 else:
150 # A slot conflict has occurred.
151 - # The existing node should not already be in
152 - # runtime_pkg_mask, since that would trigger an
153 - # infinite backtracking loop.
154 - if self._dynamic_config._allow_backtracking and \
155 - existing_node in \
156 - self._dynamic_config._runtime_pkg_mask:
157 - if "--debug" in self._frozen_config.myopts:
158 - writemsg(
159 - "!!! backtracking loop detected: %s %s\n" % \
160 - (existing_node,
161 - self._dynamic_config._runtime_pkg_mask[
162 - existing_node]), noiselevel=-1)
163 - elif self._dynamic_config._allow_backtracking and \
164 - not self._accept_blocker_conflicts() and \
165 - not self.need_restart():
166 -
167 - self._add_slot_conflict(pkg)
168 - if dep.atom is not None and dep.parent is not None:
169 - self._add_parent_atom(pkg, (dep.parent, dep.atom))
170 -
171 - if arg_atoms:
172 - for parent_atom in arg_atoms:
173 - parent, atom = parent_atom
174 - self._add_parent_atom(pkg, parent_atom)
175 - self._process_slot_conflicts()
176 -
177 - backtrack_data = []
178 - fallback_data = []
179 - all_parents = set()
180 - # The ordering of backtrack_data can make
181 - # a difference here, because both mask actions may lead
182 - # to valid, but different, solutions and the one with
183 - # 'existing_node' masked is usually the better one. Because
184 - # of that, we choose an order such that
185 - # the backtracker will first explore the choice with
186 - # existing_node masked. The backtracker reverses the
187 - # order, so the order it uses is the reverse of the
188 - # order shown here. See bug #339606.
189 - for to_be_selected, to_be_masked in (existing_node, pkg), (pkg, existing_node):
190 - # For missed update messages, find out which
191 - # atoms matched to_be_selected that did not
192 - # match to_be_masked.
193 - parent_atoms = \
194 - self._dynamic_config._parent_atoms.get(to_be_selected, set())
195 - if parent_atoms:
196 - conflict_atoms = self._dynamic_config._slot_conflict_parent_atoms.intersection(parent_atoms)
197 - if conflict_atoms:
198 - parent_atoms = conflict_atoms
199 -
200 - all_parents.update(parent_atoms)
201 -
202 - all_match = True
203 - for parent, atom in parent_atoms:
204 - i = InternalPackageSet(initial_atoms=(atom,),
205 - allow_repo=True)
206 - if not i.findAtomForPackage(to_be_masked):
207 - all_match = False
208 - break
209 -
210 - fallback_data.append((to_be_masked, parent_atoms))
211 -
212 - if all_match:
213 - # 'to_be_masked' does not violate any parent atom, which means
214 - # there is no point in masking it.
215 - pass
216 - else:
217 - backtrack_data.append((to_be_masked, parent_atoms))
218 -
219 - if not backtrack_data:
220 - # This shouldn't happen, but fall back to the old
221 - # behavior if this gets triggered somehow.
222 - backtrack_data = fallback_data
223 -
224 - if len(backtrack_data) > 1:
225 - # NOTE: Generally, we prefer to mask the higher
226 - # version since this solves common cases in which a
227 - # lower version is needed so that all dependencies
228 - # will be satisfied (bug #337178). However, if
229 - # existing_node happens to be installed then we
230 - # mask that since this is a common case that is
231 - # triggered when --update is not enabled.
232 - if existing_node.installed:
233 - pass
234 - elif pkg > existing_node:
235 - backtrack_data.reverse()
236 -
237 - to_be_masked = backtrack_data[-1][0]
238 -
239 - self._dynamic_config._backtrack_infos["slot conflict"] = backtrack_data
240 - self._dynamic_config._need_restart = True
241 - if "--debug" in self._frozen_config.myopts:
242 - msg = []
243 - msg.append("")
244 - msg.append("")
245 - msg.append("backtracking due to slot conflict:")
246 - if backtrack_data is fallback_data:
247 - msg.append("!!! backtrack_data fallback")
248 - msg.append(" first package: %s" % existing_node)
249 - msg.append(" second package: %s" % pkg)
250 - msg.append(" package to mask: %s" % to_be_masked)
251 - msg.append(" slot: %s" % pkg.slot_atom)
252 - msg.append(" parents: %s" % ", ".join( \
253 - "(%s, '%s')" % (ppkg, atom) for ppkg, atom in all_parents))
254 - msg.append("")
255 - writemsg_level("".join("%s\n" % l for l in msg),
256 - noiselevel=-1, level=logging.DEBUG)
257 - return 0
258 -
259 - # A slot collision has occurred. Sometimes this coincides
260 - # with unresolvable blockers, so the slot collision will be
261 - # shown later if there are no unresolvable blockers.
262 - self._add_slot_conflict(pkg)
263 + if not self._handle_slot_conflict(
264 + existing_node, pkg, dep, arg_atoms):
265 + return False
266 slot_collision = True
267
268 - if debug:
269 - writemsg_level(
270 - "%s%s %s\n" % ("Slot Conflict:".ljust(15),
271 - existing_node, pkg_use_display(existing_node,
272 - self._frozen_config.myopts,
273 - modified_use=self._pkg_use_enabled(existing_node))),
274 - level=logging.DEBUG, noiselevel=-1)
275 -
276 if slot_collision:
277 # Now add this node to the graph so that self.display()
278 # can show use flags and --tree portage.output. This node is