1 |
Author: zmedico |
2 |
Date: 2008-04-27 00:32:06 +0000 (Sun, 27 Apr 2008) |
3 |
New Revision: 9989 |
4 |
|
5 |
Modified: |
6 |
main/branches/2.1.2/bin/emerge |
7 |
Log: |
8 |
Bug #172812 - When a package needs to be uninstalled in advance rather |
9 |
than through replacement, show the corresponding [blocks] entries in the |
10 |
displayed list. In order to show more structure in the --tree display, |
11 |
expand Package -> Uninstall edges into Package -> Blocker -> Uninstall |
12 |
edges. Also, create edges between a package's own blockers and it's |
13 |
Uninstall task since it's blockers become irrelevant as soon as it's |
14 |
uninstalled. (trunk r9983) |
15 |
|
16 |
|
17 |
Modified: main/branches/2.1.2/bin/emerge |
18 |
=================================================================== |
19 |
--- main/branches/2.1.2/bin/emerge 2008-04-27 00:26:28 UTC (rev 9988) |
20 |
+++ main/branches/2.1.2/bin/emerge 2008-04-27 00:32:06 UTC (rev 9989) |
21 |
@@ -1394,7 +1394,7 @@ |
22 |
return str(self._get_hash_key()) |
23 |
|
24 |
class Blocker(Task): |
25 |
- __slots__ = ("root", "atom") |
26 |
+ __slots__ = ("root", "atom", "satisfied") |
27 |
|
28 |
def _get_hash_key(self): |
29 |
try: |
30 |
@@ -3822,6 +3822,7 @@ |
31 |
|
32 |
# Handle interactions between blockers |
33 |
# and uninstallation tasks. |
34 |
+ solved_blockers = set() |
35 |
uninst_task = None |
36 |
if isinstance(node, Uninstall): |
37 |
have_uninstall_task = True |
38 |
@@ -3848,17 +3849,26 @@ |
39 |
for blocker in blocker_nodes: |
40 |
if not myblocker_uninstalls.child_nodes(blocker): |
41 |
myblocker_uninstalls.remove(blocker) |
42 |
+ solved_blockers.add(blocker) |
43 |
|
44 |
if node[-1] != "nomerge": |
45 |
- retlist.append(list(node)) |
46 |
+ retlist.append(node) |
47 |
mygraph.remove(node) |
48 |
+ if isinstance(node, Uninstall): |
49 |
+ # Include satisfied blockers in the merge list so |
50 |
+ # that the user can see why the package had to be |
51 |
+ # uninstalled in advance rather than through |
52 |
+ # replacement. |
53 |
+ for blocker in solved_blockers: |
54 |
+ retlist.append(Blocker(atom=blocker.atom, |
55 |
+ root=blocker.root, satisfied=True)) |
56 |
|
57 |
unsolvable_blockers = set(self._unsolvable_blockers.leaf_nodes()) |
58 |
for node in myblocker_uninstalls.root_nodes(): |
59 |
unsolvable_blockers.add(node) |
60 |
|
61 |
for blocker in unsolvable_blockers: |
62 |
- retlist.append(list(blocker)) |
63 |
+ retlist.append(blocker) |
64 |
|
65 |
# If any Uninstall tasks need to be executed in order |
66 |
# to avoid a conflict, complete the graph with any |
67 |
@@ -3959,15 +3969,53 @@ |
68 |
|
69 |
tree_nodes = [] |
70 |
display_list = [] |
71 |
- mygraph = self.digraph |
72 |
+ mygraph = self.digraph.copy() |
73 |
+ |
74 |
+ # If there are any Uninstall instances, add the corresponding |
75 |
+ # blockers to the digraph (useful for --tree display). |
76 |
+ for uninstall in self._blocker_uninstalls.leaf_nodes(): |
77 |
+ uninstall_parents = \ |
78 |
+ self._blocker_uninstalls.parent_nodes(uninstall) |
79 |
+ if not uninstall_parents: |
80 |
+ continue |
81 |
+ |
82 |
+ # Remove the corresponding "nomerge" node and substitute |
83 |
+ # the Uninstall node. |
84 |
+ inst_pkg = self._pkg_cache[ |
85 |
+ ("installed", uninstall.root, uninstall.cpv, "nomerge")] |
86 |
+ try: |
87 |
+ mygraph.remove(inst_pkg) |
88 |
+ except KeyError: |
89 |
+ pass |
90 |
+ |
91 |
+ try: |
92 |
+ inst_pkg_blockers = self._blocker_parents.child_nodes(inst_pkg) |
93 |
+ except KeyError: |
94 |
+ inst_pkg_blockers = [] |
95 |
+ |
96 |
+ # Break the Package -> Uninstall edges. |
97 |
+ mygraph.remove(uninstall) |
98 |
+ |
99 |
+ # Resolution of a package's blockers |
100 |
+ # depend on it's own uninstallation. |
101 |
+ for blocker in inst_pkg_blockers: |
102 |
+ mygraph.add(uninstall, blocker) |
103 |
+ |
104 |
+ # Expand Package -> Uninstall edges into |
105 |
+ # Package -> Blocker -> Uninstall edges. |
106 |
+ for blocker in uninstall_parents: |
107 |
+ mygraph.add(uninstall, blocker) |
108 |
+ for parent in self._blocker_parents.parent_nodes(blocker): |
109 |
+ if parent != inst_pkg: |
110 |
+ mygraph.add(blocker, parent) |
111 |
+ |
112 |
i = 0 |
113 |
depth = 0 |
114 |
shown_edges = set() |
115 |
for x in mylist: |
116 |
- if "blocks" == x[0]: |
117 |
- display_list.append((x, 0, True)) |
118 |
- continue |
119 |
- graph_key = tuple(x) |
120 |
+ graph_key = x |
121 |
+ if isinstance(graph_key, list): |
122 |
+ graph_key = tuple(graph_key) |
123 |
if "--tree" in self.myopts: |
124 |
depth = len(tree_nodes) |
125 |
while depth and graph_key not in \ |
126 |
@@ -3993,7 +4041,7 @@ |
127 |
selected_parent = None |
128 |
# First, try to avoid a direct cycle. |
129 |
for node in parent_nodes: |
130 |
- if not isinstance(node, Package): |
131 |
+ if not isinstance(node, (Blocker, Package)): |
132 |
continue |
133 |
if node not in traversed_nodes and \ |
134 |
node not in child_nodes: |
135 |
@@ -4005,7 +4053,7 @@ |
136 |
if not selected_parent: |
137 |
# A direct cycle is unavoidable. |
138 |
for node in parent_nodes: |
139 |
- if not isinstance(node, Package): |
140 |
+ if not isinstance(node, (Blocker, Package)): |
141 |
continue |
142 |
if node not in traversed_nodes: |
143 |
edge = (current_node, node) |
144 |
@@ -4017,7 +4065,7 @@ |
145 |
shown_edges.add((current_node, selected_parent)) |
146 |
traversed_nodes.add(selected_parent) |
147 |
add_parents(selected_parent, False) |
148 |
- display_list.append((list(current_node), |
149 |
+ display_list.append((current_node, |
150 |
len(tree_nodes), ordered)) |
151 |
tree_nodes.append(current_node) |
152 |
tree_nodes = [] |
153 |
@@ -4036,8 +4084,6 @@ |
154 |
# being filled in. |
155 |
del mylist[i] |
156 |
continue |
157 |
- if "blocks" == graph_key[0]: |
158 |
- continue |
159 |
if ordered and graph_key[-1] != "nomerge": |
160 |
last_merge_depth = depth |
161 |
continue |
162 |
@@ -4064,6 +4110,7 @@ |
163 |
pkgsettings = self.pkgsettings[myroot] |
164 |
|
165 |
fetch=" " |
166 |
+ indent = " " * depth |
167 |
|
168 |
if x[0]=="blocks": |
169 |
addl=""+red("B")+" "+fetch+" " |
170 |
@@ -4074,7 +4121,7 @@ |
171 |
if "--columns" in self.myopts and "--quiet" in self.myopts: |
172 |
addl = addl + " " + red(resolved) |
173 |
else: |
174 |
- addl = "[blocks " + addl + "] " + red(resolved) |
175 |
+ addl = "[blocks " + addl + "] " + indent + red(resolved) |
176 |
block_parents = self._blocker_parents.parent_nodes(tuple(x)) |
177 |
block_parents = set([pnode[2] for pnode in block_parents]) |
178 |
block_parents = ", ".join(block_parents) |
179 |
@@ -4083,7 +4130,10 @@ |
180 |
(pkg_key, block_parents) |
181 |
else: |
182 |
addl += bad(" (is blocking %s)") % block_parents |
183 |
- blockers.append(addl) |
184 |
+ if isinstance(x, Blocker) and x.satisfied: |
185 |
+ p.append(addl) |
186 |
+ else: |
187 |
+ blockers.append(addl) |
188 |
else: |
189 |
pkg = self._pkg_cache[tuple(x)] |
190 |
metadata = pkg.metadata |
191 |
@@ -4114,8 +4164,7 @@ |
192 |
pkg_use = metadata["USE"].split() |
193 |
try: |
194 |
restrict = flatten(use_reduce(paren_reduce( |
195 |
- mydbapi.aux_get(pkg_key, ["RESTRICT"])[0]), |
196 |
- uselist=pkg_use)) |
197 |
+ pkg.metadata["RESTRICT"]), uselist=pkg_use)) |
198 |
except portage_exception.InvalidDependString, e: |
199 |
if not pkg.installed: |
200 |
restrict = mydbapi.aux_get(pkg_key, ["RESTRICT"])[0] |
201 |
@@ -4197,10 +4246,10 @@ |
202 |
if True: |
203 |
# USE flag display |
204 |
cur_iuse = list(filter_iuse_defaults( |
205 |
- mydbapi.aux_get(pkg_key, ["IUSE"])[0].split())) |
206 |
+ pkg.metadata["IUSE"].split())) |
207 |
|
208 |
forced_flags = set() |
209 |
- pkgsettings.setcpv(pkg_key, mydb=mydbapi) # for package.use.{mask,force} |
210 |
+ pkgsettings.setcpv(pkg.cpv, mydb=pkg.metadata) # for package.use.{mask,force} |
211 |
forced_flags.update(pkgsettings.useforce) |
212 |
forced_flags.update(pkgsettings.usemask) |
213 |
|
214 |
@@ -4375,8 +4424,6 @@ |
215 |
oldlp = mywidth - 30 |
216 |
newlp = oldlp - 30 |
217 |
|
218 |
- indent = " " * depth |
219 |
- |
220 |
# Convert myoldbest from a list to a string. |
221 |
if not myoldbest: |
222 |
myoldbest = "" |
223 |
@@ -4543,8 +4590,9 @@ |
224 |
|
225 |
# Any blockers must be appended to the tail of the list, |
226 |
# so we only need to check the last item. |
227 |
- have_blocker_conflict = \ |
228 |
- bool(task_list and task_list[-1][0] == "blocks") |
229 |
+ have_blocker_conflict = bool(task_list and \ |
230 |
+ (isinstance(task_list[-1], Blocker) and \ |
231 |
+ not task_list[-1].satisfied)) |
232 |
|
233 |
# The user is only notified of a slot conflict if |
234 |
# there are no unresolvable blocker conflicts. |
235 |
@@ -5153,7 +5201,8 @@ |
236 |
world_set = root_config.sets["world"] |
237 |
if "--resume" not in self.myopts: |
238 |
mymergelist = mylist |
239 |
- mtimedb["resume"]["mergelist"]=mymergelist[:] |
240 |
+ mtimedb["resume"]["mergelist"] = [list(x) for x in mymergelist \ |
241 |
+ if isinstance(x, (Package, Uninstall))] |
242 |
mtimedb.commit() |
243 |
|
244 |
myfeat = self.settings.features[:] |
245 |
@@ -7524,6 +7573,8 @@ |
246 |
return retval |
247 |
mergecount=0 |
248 |
for x in mydepgraph.altlist(): |
249 |
+ if isinstance(x, Blocker) and x.satisfied: |
250 |
+ continue |
251 |
if x[0] != "blocks" and x[3] != "nomerge": |
252 |
mergecount+=1 |
253 |
#check for blocking dependencies |
254 |
@@ -7641,6 +7692,8 @@ |
255 |
pkglist = [pkg for pkg in pkglist if pkg[0] != "blocks"] |
256 |
else: |
257 |
for x in pkglist: |
258 |
+ if isinstance(x, Blocker) and x.satisfied: |
259 |
+ continue |
260 |
if x[0] != "blocks": |
261 |
continue |
262 |
retval = mydepgraph.display(mydepgraph.altlist( |
263 |
|
264 |
-- |
265 |
gentoo-commits@l.g.o mailing list |