diff options
author | Sebastian Luther <SebastianLuther@gmx.de> | 2010-06-01 08:04:58 +0200 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2010-08-12 01:17:24 -0700 |
commit | bc19b9ddb0c540d083ccb4c616eab4e6e33d3bab (patch) | |
tree | ecc4a8e764fdfdf308460b92c2fe15333095cd79 /pym/_emerge/depgraph.py | |
parent | 4150715da2ae6efdf64a786980357768748500fa (diff) | |
download | portage-bc19b9ddb0c540d083ccb4c616eab4e6e33d3bab.tar.gz portage-bc19b9ddb0c540d083ccb4c616eab4e6e33d3bab.tar.bz2 portage-bc19b9ddb0c540d083ccb4c616eab4e6e33d3bab.zip |
Add new slot collision handler in _emerge/resolver/slot_collision.py
Diffstat (limited to 'pym/_emerge/depgraph.py')
-rw-r--r-- | pym/_emerge/depgraph.py | 193 |
1 files changed, 7 insertions, 186 deletions
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 324691f71..5b075f378 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -55,6 +55,8 @@ from _emerge.SetArg import SetArg from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice from _emerge.UnmergeDepPriority import UnmergeDepPriority +from _emerge.resolver.slot_collision import slot_conflict_handler + if sys.hexversion >= 0x3000000: basestring = str long = int @@ -468,103 +470,12 @@ class depgraph(object): self._show_merge_list() - msg = [] - msg.append("\n!!! Multiple package instances within a single " + \ - "package slot have been pulled\n") - msg.append("!!! into the dependency graph, resulting" + \ - " in a slot conflict:\n\n") - indent = " " - # Max number of parents shown, to avoid flooding the display. - max_parents = 3 - explanation_columns = 70 - explanations = 0 - for (slot_atom, root), slot_nodes \ - in self._dynamic_config._slot_collision_info.items(): - msg.append(str(slot_atom)) - if root != '/': - msg.append(" for %s" % (root,)) - msg.append("\n\n") + handler = slot_conflict_handler(self._dynamic_config._slot_collision_info, \ + self._dynamic_config._parent_atoms, self._frozen_config.myopts) + handler.print_conflict() + has_explanation = handler.print_explanation() - for node in slot_nodes: - msg.append(indent) - msg.append(str(node)) - parent_atoms = self._dynamic_config._parent_atoms.get(node) - if parent_atoms: - pruned_list = set() - for pkg, atom in parent_atoms: - num_matched_slot_atoms = 0 - atom_set = InternalPackageSet(initial_atoms=(atom,)) - for other_node in slot_nodes: - if other_node == node: - continue - if atom_set.findAtomForPackage(other_node): - num_matched_slot_atoms += 1 - if num_matched_slot_atoms < len(slot_nodes) - 1: - pruned_list.add((pkg, atom)) - if len(pruned_list) >= max_parents: - break - - # If this package was pulled in by conflict atoms then - # show those alone since those are the most interesting. - if not pruned_list: - # When generating the pruned list, prefer instances - # of DependencyArg over instances of Package. - for parent_atom in parent_atoms: - if len(pruned_list) >= max_parents: - break - parent, atom = parent_atom - if isinstance(parent, DependencyArg): - pruned_list.add(parent_atom) - # Prefer Packages instances that themselves have been - # pulled into collision slots. - for parent_atom in parent_atoms: - if len(pruned_list) >= max_parents: - break - parent, atom = parent_atom - if isinstance(parent, Package) and \ - (parent.slot_atom, parent.root) \ - in self._dynamic_config._slot_collision_info: - pruned_list.add(parent_atom) - for parent_atom in parent_atoms: - if len(pruned_list) >= max_parents: - break - pruned_list.add(parent_atom) - omitted_parents = len(parent_atoms) - len(pruned_list) - parent_atoms = pruned_list - msg.append(" pulled in by\n") - for parent_atom in parent_atoms: - parent, atom = parent_atom - msg.append(2*indent) - if isinstance(parent, - (PackageArg, AtomArg)): - # For PackageArg and AtomArg types, it's - # redundant to display the atom attribute. - msg.append(str(parent)) - else: - # Display the specific atom from SetArg or - # Package types. - msg.append("%s required by %s" % (atom.unevaluated_atom, parent)) - msg.append("\n") - if omitted_parents: - msg.append(2*indent) - msg.append("(and %d more)\n" % omitted_parents) - else: - msg.append(" (no parents)\n") - msg.append("\n") - explanation = self._slot_conflict_explanation(slot_nodes) - if explanation: - explanations += 1 - msg.append(indent + "Explanation:\n\n") - for line in textwrap.wrap(explanation, explanation_columns): - msg.append(2*indent + line + "\n") - msg.append("\n") - msg.append("\n") - sys.stderr.write("".join(msg)) - sys.stderr.flush() - - explanations_for_all = explanations == len(self._dynamic_config._slot_collision_info) - - if explanations_for_all or "--quiet" in self._frozen_config.myopts: + if has_explanation or "--quiet" in self._frozen_config.myopts: return msg = [] @@ -597,96 +508,6 @@ class depgraph(object): writemsg(line + '\n', noiselevel=-1) writemsg('\n', noiselevel=-1) - def _slot_conflict_explanation(self, slot_nodes): - """ - When a slot conflict occurs due to USE deps, there are a few - different cases to consider: - - 1) New USE are correctly set but --newuse wasn't requested so an - installed package with incorrect USE happened to get pulled - into graph before the new one. - - 2) New USE are incorrectly set but an installed package has correct - USE so it got pulled into the graph, and a new instance also got - pulled in due to --newuse or an upgrade. - - 3) Multiple USE deps exist that can't be satisfied simultaneously, - and multiple package instances got pulled into the same slot to - satisfy the conflicting deps. - - Currently, explanations and suggested courses of action are generated - for cases 1 and 2. Case 3 is too complex to give a useful suggestion. - """ - - if len(slot_nodes) != 2: - # Suggestions are only implemented for - # conflicts between two packages. - return None - - all_conflict_atoms = self._dynamic_config._slot_conflict_parent_atoms - matched_node = None - matched_atoms = None - unmatched_node = None - for node in slot_nodes: - parent_atoms = self._dynamic_config._parent_atoms.get(node) - if not parent_atoms: - # Normally, there are always parent atoms. If there are - # none then something unexpected is happening and there's - # currently no suggestion for this case. - return None - conflict_atoms = all_conflict_atoms.intersection(parent_atoms) - for parent_atom in conflict_atoms: - parent, atom = parent_atom - if not atom.use: - # Suggestions are currently only implemented for cases - # in which all conflict atoms have USE deps. - return None - if conflict_atoms: - if matched_node is not None: - # If conflict atoms match multiple nodes - # then there's no suggestion. - return None - matched_node = node - matched_atoms = conflict_atoms - else: - if unmatched_node is not None: - # Neither node is matched by conflict atoms, and - # there is no suggestion for this case. - return None - unmatched_node = node - - if matched_node is None or unmatched_node is None: - # This shouldn't happen. - return None - - if unmatched_node.installed and not matched_node.installed and \ - unmatched_node.cpv == matched_node.cpv: - # If the conflicting packages are the same version then - # --newuse should be all that's needed. If they are different - # versions then there's some other problem. - return "New USE are correctly set, but --newuse wasn't" + \ - " requested, so an installed package with incorrect USE " + \ - "happened to get pulled into the dependency graph. " + \ - "In order to solve " + \ - "this, either specify the --newuse option or explicitly " + \ - " reinstall '%s'." % matched_node.slot_atom - - if matched_node.installed and not unmatched_node.installed: - atoms = sorted(set(atom for parent, atom in matched_atoms)) - explanation = ("New USE for '%s' are incorrectly set. " + \ - "In order to solve this, adjust USE to satisfy '%s'") % \ - (matched_node.slot_atom, atoms[0]) - if len(atoms) > 1: - for atom in atoms[1:-1]: - explanation += ", '%s'" % (atom,) - if len(atoms) > 2: - explanation += "," - explanation += " and '%s'" % (atoms[-1],) - explanation += "." - return explanation - - return None - def _process_slot_conflicts(self): """ Process slot conflict data to identify specific atoms which |