1 |
commit: f9473424cb810bc946ff5a63fcce1e9ebfa86bf9 |
2 |
Author: Sebastian Luther <SebastianLuther <AT> gmx <DOT> de> |
3 |
AuthorDate: Mon Jan 27 23:00:49 2014 +0000 |
4 |
Commit: Sebastian Luther <SebastianLuther <AT> gmx <DOT> de > |
5 |
CommitDate: Wed Feb 5 19:39:21 2014 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=f9473424 |
7 |
|
8 |
Some small output fixes for the slot conflict handler |
9 |
|
10 |
* unmatched atom printing now uses ^^ markers |
11 |
* unmatched atom printing properly supports sub-slots |
12 |
* Fix spurious "no parents" message caused by AtomArg parents |
13 |
|
14 |
--- |
15 |
pym/_emerge/resolver/slot_collision.py | 119 ++++++++++++++++++++++++++------- |
16 |
1 file changed, 96 insertions(+), 23 deletions(-) |
17 |
|
18 |
diff --git a/pym/_emerge/resolver/slot_collision.py b/pym/_emerge/resolver/slot_collision.py |
19 |
index ca3fb74..c5936ad 100644 |
20 |
--- a/pym/_emerge/resolver/slot_collision.py |
21 |
+++ b/pym/_emerge/resolver/slot_collision.py |
22 |
@@ -1,4 +1,4 @@ |
23 |
-# Copyright 2010-2013 Gentoo Foundation |
24 |
+# Copyright 2010-2014 Gentoo Foundation |
25 |
# Distributed under the terms of the GNU General Public License v2 |
26 |
|
27 |
from __future__ import print_function, unicode_literals |
28 |
@@ -273,12 +273,14 @@ class slot_conflict_handler(object): |
29 |
for ppkg, atom in parent_atoms: |
30 |
atom_set = InternalPackageSet(initial_atoms=(atom,)) |
31 |
atom_without_use_set = InternalPackageSet(initial_atoms=(atom.without_use,)) |
32 |
+ atom_without_use_and_slot_set = InternalPackageSet(initial_atoms=( |
33 |
+ atom.without_use.without_slot,)) |
34 |
|
35 |
for other_pkg in pkgs: |
36 |
if other_pkg == pkg: |
37 |
continue |
38 |
|
39 |
- if not atom_without_use_set.findAtomForPackage(other_pkg, \ |
40 |
+ if not atom_without_use_and_slot_set.findAtomForPackage(other_pkg, \ |
41 |
modified_use=_pkg_use_enabled(other_pkg)): |
42 |
if atom.operator is not None: |
43 |
# The version range does not match. |
44 |
@@ -295,9 +297,11 @@ class slot_conflict_handler(object): |
45 |
atoms.add((ppkg, atom, other_pkg)) |
46 |
num_all_specific_atoms += 1 |
47 |
collision_reasons[key] = atoms |
48 |
- else: |
49 |
- # The sub_slot does not match. |
50 |
- key = ("sub-slot", atom.sub_slot) |
51 |
+ |
52 |
+ elif not atom_without_use_set.findAtomForPackage(other_pkg, \ |
53 |
+ modified_use=_pkg_use_enabled(other_pkg)): |
54 |
+ # The slot and/or sub_slot does not match. |
55 |
+ key = ("slot", (atom.slot, atom.sub_slot, atom.slot_operator)) |
56 |
atoms = collision_reasons.get(key, set()) |
57 |
atoms.add((ppkg, atom, other_pkg)) |
58 |
num_all_specific_atoms += 1 |
59 |
@@ -342,6 +346,11 @@ class slot_conflict_handler(object): |
60 |
atoms.add((ppkg, atom, other_pkg)) |
61 |
collision_reasons[("use", flag)] = atoms |
62 |
num_all_specific_atoms += 1 |
63 |
+ elif isinstance(ppkg, AtomArg) and other_pkg.installed: |
64 |
+ parent_atoms = collision_reasons.get(("AtomArg", None), set()) |
65 |
+ parent_atoms.add((ppkg, atom)) |
66 |
+ collision_reasons[("AtomArg", None)] = parent_atoms |
67 |
+ num_all_specific_atoms += 1 |
68 |
|
69 |
msg.append(" pulled in by\n") |
70 |
|
71 |
@@ -372,9 +381,11 @@ class slot_conflict_handler(object): |
72 |
if not verboseconflicts: |
73 |
selected_for_display.update( |
74 |
best_matches.values()) |
75 |
- elif type == "sub-slot": |
76 |
+ elif type == "slot": |
77 |
for ppkg, atom, other_pkg in parents: |
78 |
selected_for_display.add((ppkg, atom)) |
79 |
+ if not verboseconflicts: |
80 |
+ break |
81 |
elif type == "use": |
82 |
#Prefer atoms with unconditional use deps over, because it's |
83 |
#not possible to change them on the parent, which means there |
84 |
@@ -416,21 +427,50 @@ class slot_conflict_handler(object): |
85 |
# If the list is long, people can simply |
86 |
# use a pager. |
87 |
selected_for_display.add((ppkg, atom)) |
88 |
+ elif type == "AtomArg": |
89 |
+ for ppkg, atom in parents: |
90 |
+ selected_for_display.add((ppkg, atom)) |
91 |
|
92 |
- def highlight_violations(atom, version, use=[]): |
93 |
+ def highlight_violations(atom, version, use, slot_violated): |
94 |
"""Colorize parts of an atom""" |
95 |
atom_str = "%s" % (atom,) |
96 |
+ colored_idx = set() |
97 |
if version: |
98 |
op = atom.operator |
99 |
ver = None |
100 |
if atom.cp != atom.cpv: |
101 |
ver = cpv_getversion(atom.cpv) |
102 |
slot = atom.slot |
103 |
+ sub_slot = atom.sub_slot |
104 |
+ slot_operator = atom.slot_operator |
105 |
|
106 |
if op == "=*": |
107 |
op = "=" |
108 |
ver += "*" |
109 |
|
110 |
+ slot_str = "" |
111 |
+ if slot: |
112 |
+ slot_str = ":" + slot |
113 |
+ if sub_slot: |
114 |
+ slot_str += "/" + sub_slot |
115 |
+ if slot_operator: |
116 |
+ slot_str += slot_operator |
117 |
+ |
118 |
+ # Compute color_idx before adding the color codes |
119 |
+ # as these change the indices of the letters. |
120 |
+ if op is not None: |
121 |
+ colored_idx.update(range(len(op))) |
122 |
+ |
123 |
+ if ver is not None: |
124 |
+ start = atom_str.rfind(ver) |
125 |
+ end = start + len(ver) |
126 |
+ colored_idx.update(range(start, end)) |
127 |
+ |
128 |
+ if slot_str: |
129 |
+ ii = atom_str.find(slot_str) |
130 |
+ colored_idx.update(range(ii, ii + len(slot_str))) |
131 |
+ |
132 |
+ |
133 |
if op is not None: |
134 |
atom_str = atom_str.replace(op, colorize("BAD", op), 1) |
135 |
|
136 |
@@ -440,25 +480,48 @@ class slot_conflict_handler(object): |
137 |
atom_str = atom_str[:start] + \ |
138 |
colorize("BAD", ver) + \ |
139 |
atom_str[end:] |
140 |
+ |
141 |
+ if slot_str: |
142 |
+ atom_str = atom_str.replace(slot_str, colorize("BAD", slot_str), 1) |
143 |
+ |
144 |
+ elif slot_violated: |
145 |
+ slot = atom.slot |
146 |
+ sub_slot = atom.sub_slot |
147 |
+ slot_operator = atom.slot_operator |
148 |
+ |
149 |
+ slot_str = "" |
150 |
if slot: |
151 |
- atom_str = atom_str.replace(":" + slot, colorize("BAD", ":" + slot)) |
152 |
+ slot_str = ":" + slot |
153 |
+ if sub_slot: |
154 |
+ slot_str += "/" + sub_slot |
155 |
+ if slot_operator: |
156 |
+ slot_str += slot_operator |
157 |
+ |
158 |
+ if slot_str: |
159 |
+ ii = atom_str.find(slot_str) |
160 |
+ colored_idx.update(range(ii, ii + len(slot_str))) |
161 |
+ atom_str = atom_str.replace(slot_str, colorize("BAD", slot_str), 1) |
162 |
|
163 |
if use and atom.use.tokens: |
164 |
use_part_start = atom_str.find("[") |
165 |
use_part_end = atom_str.find("]") |
166 |
|
167 |
new_tokens = [] |
168 |
+ # Compute start index in non-colored atom. |
169 |
+ ii = str(atom).find("[") + 1 |
170 |
for token in atom.use.tokens: |
171 |
if token.lstrip("-!").rstrip("=?") in use: |
172 |
new_tokens.append(colorize("BAD", token)) |
173 |
+ colored_idx.update(range(ii, ii + len(token))) |
174 |
else: |
175 |
new_tokens.append(token) |
176 |
+ ii += 1 + len(token) |
177 |
|
178 |
atom_str = atom_str[:use_part_start] \ |
179 |
+ "[%s]" % (",".join(new_tokens),) + \ |
180 |
atom_str[use_part_end+1:] |
181 |
|
182 |
- return atom_str |
183 |
+ return atom_str, colored_idx |
184 |
|
185 |
# Show unconditional use deps first, since those |
186 |
# are more problematic than the conditional kind. |
187 |
@@ -469,37 +532,48 @@ class slot_conflict_handler(object): |
188 |
ordered_list.append(parent_atom) |
189 |
for parent_atom in ordered_list: |
190 |
parent, atom = parent_atom |
191 |
- msg.append(2*indent) |
192 |
- if isinstance(parent, |
193 |
- (PackageArg, AtomArg)): |
194 |
- # For PackageArg and AtomArg types, it's |
195 |
+ if isinstance(parent, PackageArg): |
196 |
+ # For PackageArg it's |
197 |
# redundant to display the atom attribute. |
198 |
- msg.append("%s" % (parent,)) |
199 |
+ msg.append("%s\n" % (parent,)) |
200 |
+ elif isinstance(parent, AtomArg): |
201 |
+ msg.append("%s (Argument)\n" % (atom,)) |
202 |
else: |
203 |
# Display the specific atom from SetArg or |
204 |
# Package types. |
205 |
version_violated = False |
206 |
- sub_slot_violated = False |
207 |
+ slot_violated = False |
208 |
use = [] |
209 |
for (type, sub_type), parents in collision_reasons.items(): |
210 |
for x in parents: |
211 |
if parent == x[0] and atom == x[1]: |
212 |
if type == "version": |
213 |
version_violated = True |
214 |
- elif type == "sub-slot": |
215 |
- sub_slot_violated = True |
216 |
+ elif type == "slot": |
217 |
+ slot_violated = True |
218 |
elif type == "use": |
219 |
use.append(sub_type) |
220 |
break |
221 |
|
222 |
- atom_str = highlight_violations(atom.unevaluated_atom, version_violated, use) |
223 |
+ atom_str, colored_idx = highlight_violations(atom.unevaluated_atom, |
224 |
+ version_violated, use, slot_violated) |
225 |
|
226 |
- if version_violated or sub_slot_violated: |
227 |
+ if version_violated or slot_violated: |
228 |
self.is_a_version_conflict = True |
229 |
|
230 |
- msg.append("%s required by %s" % (atom_str, parent)) |
231 |
- msg.append("\n") |
232 |
- |
233 |
+ cur_line = "%s required by %s\n" % (atom_str, parent) |
234 |
+ marker_line = "" |
235 |
+ for ii in range(len(cur_line)): |
236 |
+ if ii in colored_idx: |
237 |
+ marker_line += "^" |
238 |
+ else: |
239 |
+ marker_line += " " |
240 |
+ marker_line += "\n" |
241 |
+ msg.append(2*indent) |
242 |
+ msg.append(cur_line) |
243 |
+ msg.append(2*indent) |
244 |
+ msg.append(marker_line) |
245 |
+ |
246 |
if not selected_for_display: |
247 |
msg.append(2*indent) |
248 |
msg.append("(no parents that aren't satisfied by other packages in this slot)\n") |
249 |
@@ -519,7 +593,6 @@ class slot_conflict_handler(object): |
250 |
|
251 |
def get_explanation(self): |
252 |
msg = "" |
253 |
- _pkg_use_enabled = self.depgraph._pkg_use_enabled |
254 |
|
255 |
if self.is_a_version_conflict: |
256 |
return None |