Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r12408 - main/trunk/pym/_emerge
Date: Sat, 10 Jan 2009 06:24:56
Message-Id: E1LLXHB-0003fq-KM@stork.gentoo.org
1 Author: zmedico
2 Date: 2009-01-10 06:24:52 +0000 (Sat, 10 Jan 2009)
3 New Revision: 12408
4
5 Modified:
6 main/trunk/pym/_emerge/__init__.py
7 Log:
8 When there are unresolved blockers, display the conflicting packages along
9 with the packages that pulled them in (similar to the slot conflict display).
10 This is helpful for troubleshooting cases in which blockers don't solve
11 automatically and the reasons are not apparent from the normal merge list
12 display.
13
14
15 Modified: main/trunk/pym/_emerge/__init__.py
16 ===================================================================
17 --- main/trunk/pym/_emerge/__init__.py 2009-01-10 04:03:19 UTC (rev 12407)
18 +++ main/trunk/pym/_emerge/__init__.py 2009-01-10 06:24:52 UTC (rev 12408)
19 @@ -4484,6 +4484,12 @@
20 self._irrelevant_blockers = digraph()
21 # Contains only unsolvable Package -> Blocker edges
22 self._unsolvable_blockers = digraph()
23 + # Contains all Blocker -> Blocked Package edges
24 + self._blocked_pkgs = digraph()
25 + # Contains world packages that have been protected from
26 + # uninstallation but may not have been added to the graph
27 + # if the graph is not complete yet.
28 + self._blocked_world_pkgs = {}
29 self._slot_collision_info = {}
30 # Slot collision nodes are not allowed to block other packages since
31 # blocker validation is only able to account for one package per slot.
32 @@ -6444,6 +6450,9 @@
33 # is already done and this would be likely to
34 # confuse users if displayed like a normal blocker.
35 continue
36 +
37 + self._blocked_pkgs.add(pkg, blocker)
38 +
39 if parent.operation == "merge":
40 # Maybe the blocked package can be replaced or simply
41 # unmerged to resolve this block.
42 @@ -6462,6 +6471,8 @@
43 # merge of either package is triggered.
44 continue
45
46 + self._blocked_pkgs.add(pkg, blocker)
47 +
48 # Maybe the blocking package can be
49 # unmerged to resolve this block.
50 if parent.operation == "merge" and pkg.installed:
51 @@ -6514,7 +6525,7 @@
52 def _accept_blocker_conflicts(self):
53 acceptable = False
54 for x in ("--buildpkgonly", "--fetchonly",
55 - "--fetch-all-uri", "--nodeps", "--pretend"):
56 + "--fetch-all-uri", "--nodeps"):
57 if x in self.myopts:
58 acceptable = True
59 break
60 @@ -6977,6 +6988,7 @@
61 break
62 if not satisfied:
63 skip = True
64 + self._blocked_world_pkgs[inst_pkg] = atom
65 break
66 except portage.exception.InvalidDependString, e:
67 portage.writemsg("!!! Invalid PROVIDE in " + \
68 @@ -7208,6 +7220,74 @@
69 portage.writemsg("\n", noiselevel=-1)
70 for line in wrap(msg, 70):
71 portage.writemsg(prefix + line + "\n", noiselevel=-1)
72 +
73 + # Display the conflicting packages along with the packages
74 + # that pulled them in. This is helpful for troubleshooting
75 + # cases in which blockers don't solve automatically and
76 + # the reasons are not apparent from the normal merge list
77 + # display.
78 +
79 + conflict_pkgs = {}
80 + for blocker in blockers:
81 + for pkg in chain(self._blocked_pkgs.child_nodes(blocker), \
82 + self._blocker_parents.parent_nodes(blocker)):
83 + parent_atoms = self._parent_atoms.get(pkg)
84 + if not parent_atoms:
85 + atom = self._blocked_world_pkgs.get(pkg)
86 + if atom is not None:
87 + parent_atoms = set([("@world", atom)])
88 + if parent_atoms:
89 + conflict_pkgs[pkg] = parent_atoms
90 +
91 + if conflict_pkgs:
92 + msg = []
93 + msg.append("\n")
94 + indent = " "
95 + # Max number of parents shown, to avoid flooding the display.
96 + max_parents = 3
97 + for pkg, parent_atoms in conflict_pkgs.iteritems():
98 +
99 + pruned_list = set()
100 +
101 + # Prefer conflict packages over others.
102 + for parent_atom in parent_atoms:
103 + if len(pruned_list) >= max_parents:
104 + break
105 + parent, atom = parent_atom
106 + if parent in conflict_pkgs:
107 + pruned_list.add(parent_atom)
108 +
109 + for parent_atom in parent_atoms:
110 + if len(pruned_list) >= max_parents:
111 + break
112 + pruned_list.add(parent_atom)
113 +
114 + omitted_parents = len(parent_atoms) - len(pruned_list)
115 + msg.append(indent + "%s pulled in by\n" % pkg)
116 +
117 + for parent_atom in pruned_list:
118 + parent, atom = parent_atom
119 + msg.append(2*indent)
120 + if isinstance(parent,
121 + (PackageArg, AtomArg)):
122 + # For PackageArg and AtomArg types, it's
123 + # redundant to display the atom attribute.
124 + msg.append(str(parent))
125 + else:
126 + # Display the specific atom from SetArg or
127 + # Package types.
128 + msg.append("%s required by %s" % (atom, parent))
129 + msg.append("\n")
130 +
131 + if omitted_parents:
132 + msg.append(2*indent)
133 + msg.append("(and %d more)\n" % omitted_parents)
134 +
135 + msg.append("\n")
136 +
137 + sys.stderr.write("".join(msg))
138 + sys.stderr.flush()
139 +
140 if "--quiet" not in self.myopts:
141 show_blocker_docs_link()