public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: Sebastian Luther <SebastianLuther@gmx.de>
To: gentoo-portage-dev@lists.gentoo.org
Subject: [gentoo-portage-dev] [PATCH 08/10] Some small output fixes for the slot conflict handler
Date: Wed, 29 Jan 2014 16:33:12 +0100	[thread overview]
Message-ID: <1391009594-22750-9-git-send-email-SebastianLuther@gmx.de> (raw)
In-Reply-To: <1391009594-22750-1-git-send-email-SebastianLuther@gmx.de>

* unmatched atom printing now uses ^^ markers
* unmatched atom printing properly supports sub-slots
* Fix spurious "no parents" message caused by AtomArg parents
---
 pym/_emerge/resolver/slot_collision.py | 119 ++++++++++++++++++++++++++-------
 1 file changed, 96 insertions(+), 23 deletions(-)

diff --git a/pym/_emerge/resolver/slot_collision.py b/pym/_emerge/resolver/slot_collision.py
index ca3fb74..c5936ad 100644
--- a/pym/_emerge/resolver/slot_collision.py
+++ b/pym/_emerge/resolver/slot_collision.py
@@ -1,4 +1,4 @@
-# Copyright 2010-2013 Gentoo Foundation
+# Copyright 2010-2014 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from __future__ import print_function, unicode_literals
@@ -273,12 +273,14 @@ class slot_conflict_handler(object):
 					for ppkg, atom in parent_atoms:
 						atom_set = InternalPackageSet(initial_atoms=(atom,))
 						atom_without_use_set = InternalPackageSet(initial_atoms=(atom.without_use,))
+						atom_without_use_and_slot_set = InternalPackageSet(initial_atoms=(
+							atom.without_use.without_slot,))
 
 						for other_pkg in pkgs:
 							if other_pkg == pkg:
 								continue
 
-							if not atom_without_use_set.findAtomForPackage(other_pkg, \
+							if not atom_without_use_and_slot_set.findAtomForPackage(other_pkg, \
 								modified_use=_pkg_use_enabled(other_pkg)):
 								if atom.operator is not None:
 									# The version range does not match.
@@ -295,9 +297,11 @@ class slot_conflict_handler(object):
 									atoms.add((ppkg, atom, other_pkg))
 									num_all_specific_atoms += 1
 									collision_reasons[key] = atoms
-								else:
-									# The sub_slot does not match.
-									key = ("sub-slot", atom.sub_slot)
+
+							elif not atom_without_use_set.findAtomForPackage(other_pkg, \
+								modified_use=_pkg_use_enabled(other_pkg)):
+									# The slot and/or sub_slot does not match.
+									key = ("slot", (atom.slot, atom.sub_slot, atom.slot_operator))
 									atoms = collision_reasons.get(key, set())
 									atoms.add((ppkg, atom, other_pkg))
 									num_all_specific_atoms += 1
@@ -342,6 +346,11 @@ class slot_conflict_handler(object):
 										atoms.add((ppkg, atom, other_pkg))
 										collision_reasons[("use", flag)] = atoms
 									num_all_specific_atoms += 1
+							elif isinstance(ppkg, AtomArg) and other_pkg.installed:
+								parent_atoms = collision_reasons.get(("AtomArg", None), set())
+								parent_atoms.add((ppkg, atom))
+								collision_reasons[("AtomArg", None)] = parent_atoms
+								num_all_specific_atoms += 1
 
 					msg.append(" pulled in by\n")
 
@@ -372,9 +381,11 @@ class slot_conflict_handler(object):
 							if not verboseconflicts:
 								selected_for_display.update(
 										best_matches.values())
-						elif type == "sub-slot":
+						elif type == "slot":
 							for ppkg, atom, other_pkg in parents:
 								selected_for_display.add((ppkg, atom))
+								if not verboseconflicts:
+									break
 						elif type == "use":
 							#Prefer atoms with unconditional use deps over, because it's
 							#not possible to change them on the parent, which means there
@@ -416,21 +427,50 @@ class slot_conflict_handler(object):
 								# If the list is long, people can simply
 								# use a pager.
 								selected_for_display.add((ppkg, atom))
+						elif type == "AtomArg":
+							for ppkg, atom in parents:
+								selected_for_display.add((ppkg, atom))
 
-					def highlight_violations(atom, version, use=[]):
+					def highlight_violations(atom, version, use, slot_violated):
 						"""Colorize parts of an atom"""
 						atom_str = "%s" % (atom,)
+						colored_idx = set()
 						if version:
 							op = atom.operator
 							ver = None
 							if atom.cp != atom.cpv:
 								ver = cpv_getversion(atom.cpv)
 							slot = atom.slot
+							sub_slot = atom.sub_slot
+							slot_operator = atom.slot_operator
 
 							if op == "=*":
 								op = "="
 								ver += "*"
 
+							slot_str = ""
+							if slot:
+								slot_str = ":" + slot
+							if sub_slot:
+								slot_str += "/" + sub_slot
+							if slot_operator:
+								slot_str += slot_operator
+
+							# Compute color_idx before adding the color codes
+							# as these change the indices of the letters.
+							if op is not None:
+								colored_idx.update(range(len(op)))
+
+							if ver is not None:
+								start = atom_str.rfind(ver)
+								end = start + len(ver)
+								colored_idx.update(range(start, end))
+
+							if slot_str:
+								ii = atom_str.find(slot_str)
+								colored_idx.update(range(ii, ii + len(slot_str)))
+
+
 							if op is not None:
 								atom_str = atom_str.replace(op, colorize("BAD", op), 1)
 
@@ -440,25 +480,48 @@ class slot_conflict_handler(object):
 								atom_str = atom_str[:start] + \
 									colorize("BAD", ver) + \
 									atom_str[end:]
+
+							if slot_str:
+								atom_str = atom_str.replace(slot_str, colorize("BAD", slot_str), 1)
+
+						elif slot_violated:
+							slot = atom.slot
+							sub_slot = atom.sub_slot
+							slot_operator = atom.slot_operator
+
+							slot_str = ""
 							if slot:
-								atom_str = atom_str.replace(":" + slot, colorize("BAD", ":" + slot))
+								slot_str = ":" + slot
+							if sub_slot:
+								slot_str += "/" + sub_slot
+							if slot_operator:
+								slot_str += slot_operator
+
+							if slot_str:
+								ii = atom_str.find(slot_str)
+								colored_idx.update(range(ii, ii + len(slot_str)))
+								atom_str = atom_str.replace(slot_str, colorize("BAD", slot_str), 1)
 						
 						if use and atom.use.tokens:
 							use_part_start = atom_str.find("[")
 							use_part_end = atom_str.find("]")
 							
 							new_tokens = []
+							# Compute start index in non-colored atom.
+							ii = str(atom).find("[") +  1
 							for token in atom.use.tokens:
 								if token.lstrip("-!").rstrip("=?") in use:
 									new_tokens.append(colorize("BAD", token))
+									colored_idx.update(range(ii, ii + len(token)))
 								else:
 									new_tokens.append(token)
+								ii += 1 + len(token)
 
 							atom_str = atom_str[:use_part_start] \
 								+ "[%s]" % (",".join(new_tokens),) + \
 								atom_str[use_part_end+1:]
 						
-						return atom_str
+						return atom_str, colored_idx
 
 					# Show unconditional use deps first, since those
 					# are more problematic than the conditional kind.
@@ -469,37 +532,48 @@ class slot_conflict_handler(object):
 								ordered_list.append(parent_atom)
 					for parent_atom in ordered_list:
 						parent, atom = parent_atom
-						msg.append(2*indent)
-						if isinstance(parent,
-							(PackageArg, AtomArg)):
-							# For PackageArg and AtomArg types, it's
+						if isinstance(parent, PackageArg):
+							# For PackageArg it's
 							# redundant to display the atom attribute.
-							msg.append("%s" % (parent,))
+							msg.append("%s\n" % (parent,))
+						elif isinstance(parent, AtomArg):
+							msg.append("%s (Argument)\n" % (atom,))
 						else:
 							# Display the specific atom from SetArg or
 							# Package types.
 							version_violated = False
-							sub_slot_violated = False
+							slot_violated = False
 							use = []
 							for (type, sub_type), parents in collision_reasons.items():
 								for x in parents:
 									if parent == x[0] and atom == x[1]:
 										if type == "version":
 											version_violated = True
-										elif type == "sub-slot":
-											sub_slot_violated = True
+										elif type == "slot":
+											slot_violated = True
 										elif type == "use":
 											use.append(sub_type)
 										break
 
-							atom_str = highlight_violations(atom.unevaluated_atom, version_violated, use)
+							atom_str, colored_idx = highlight_violations(atom.unevaluated_atom,
+								version_violated, use, slot_violated)
 
-							if version_violated or sub_slot_violated:
+							if version_violated or slot_violated:
 								self.is_a_version_conflict = True
 
-							msg.append("%s required by %s" % (atom_str, parent))
-						msg.append("\n")
-					
+							cur_line = "%s required by %s\n" % (atom_str, parent)
+							marker_line = ""
+							for ii in range(len(cur_line)):
+								if ii in colored_idx:
+									marker_line += "^"
+								else:
+									marker_line += " "
+							marker_line += "\n"
+							msg.append(2*indent)
+							msg.append(cur_line)
+							msg.append(2*indent)
+							msg.append(marker_line)
+
 					if not selected_for_display:
 						msg.append(2*indent)
 						msg.append("(no parents that aren't satisfied by other packages in this slot)\n")
@@ -519,7 +593,6 @@ class slot_conflict_handler(object):
 
 	def get_explanation(self):
 		msg = ""
-		_pkg_use_enabled = self.depgraph._pkg_use_enabled
 
 		if self.is_a_version_conflict:
 			return None
-- 
1.8.3.2



  parent reply	other threads:[~2014-01-29 15:34 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-29 15:33 [gentoo-portage-dev] [PATCH 00/10] First steps to get rid of backtracking Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 01/10] Add resolver/package_tracker Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 02/10] Replace _slot_pkg_map and some tree dbapiS with _package_tracker Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 03/10] Replace mydbapi " Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 04/10] Replace _slot_collision_info " Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 05/10] Replace _slot_collision_nodes " Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 06/10] Package.__str__: show slot/sub-slot Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 07/10] format_unmatched_atom: Pretty printing for unmatched atoms Sebastian Luther
2014-01-29 15:33 ` Sebastian Luther [this message]
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 09/10] Add digraph.discard Sebastian Luther
2014-01-29 15:33 ` [gentoo-portage-dev] [PATCH 10/10] Solve some slot conflicts without backtracking Sebastian Luther
2014-02-02 20:41 ` [gentoo-portage-dev] [PATCH 00/10] First steps to get rid of backtracking Brian Dolbec
2014-02-02 21:04   ` Sebastian Luther

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1391009594-22750-9-git-send-email-SebastianLuther@gmx.de \
    --to=sebastianluther@gmx.de \
    --cc=gentoo-portage-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox