This patch cleans up the blocker validation logic. Unlike the previous implementatio...
authorZac Medico <zmedico@gentoo.org>
Sat, 9 Dec 2006 23:10:47 +0000 (23:10 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 9 Dec 2006 23:10:47 +0000 (23:10 -0000)
svn path=/main/trunk/; revision=5245

bin/emerge

index 77de52d25306c25df67957ecab5e4b7f425fa019..9970ad0e8da19697305c1ec098eb4655865bd550 100755 (executable)
@@ -1439,72 +1439,72 @@ class depgraph:
 
                for blocker in self.blocker_parents.keys():
                        mytype, myroot, mydep = blocker
-                       vardb = self.trees[myroot]["vartree"].dbapi
-                       blocked_pkgs = vardb.match(mydep)
-                       blocked_after_update = self.mydbapi[myroot].match(mydep)
-                       if not blocked_pkgs and not blocked_after_update:
+                       initial_db = self.trees[myroot]["vartree"].dbapi
+                       final_db = self.mydbapi[myroot]
+                       blocked_initial = initial_db.match(mydep)
+                       blocked_final = final_db.match(mydep)
+                       if not blocked_initial and not blocked_final:
                                del self.blocker_parents[blocker]
-                       else:
-                               """It may be possible to circumvent this block via correct
-                               ordering of upgrades.  If necessary, create hard deps to
-                               enforce correct merge order."""
-                               fakedb = self.mydbapi[myroot]
-                               new_pkgs = []
-                               unresolvable = False
-                               for cpv in blocked_pkgs:
-                                       myslot = vardb.aux_get(cpv, ["SLOT"])[0]
-                                       myslot_atom = "%s:%s" % (portage.dep_getkey(cpv), myslot)
-                                       mymatches = fakedb.match(myslot_atom)
-                                       if mymatches:
-                                               new_pkgs.append((myslot_atom, mymatches[0]))
-                                       else:
-                                               """There's an installed package that's blocked and
-                                               there's no upgrade found to invalidate it, so leave
-                                               this blocker in the digraph."""
-                                               unresolvable = True
-                                               break
-                               if unresolvable:
-                                       # Keep trying to invalidate as many blockers as possible.
-                                       continue
-
-                               for parent in list(self.blocker_parents[blocker]):
-                                       ptype, proot, pcpv, pstatus = parent
-                                       pdbapi = self.trees[proot][self.pkg_tree_map[ptype]].dbapi
-                                       pslot = pdbapi.aux_get(pcpv, ["SLOT"])[0]
-                                       pslot_atom = "%s:%s" % (portage.dep_getkey(pcpv), pslot)
-                                       depends_on_merge_order = False
-                                       for myslot_atom, pkg in new_pkgs:
-                                               if pslot_atom == myslot_atom:
-                                                       """A merge within a slot invalidates the block,
-                                                       so the order does not need to be enforced."""
+                               continue
+                       blocked_slots_initial = {}
+                       blocked_slots_final = {}
+                       for cpv in blocked_initial:
+                               blocked_slots_initial[cpv] = \
+                                       "%s:%s" % (portage.dep_getkey(cpv),
+                                               initial_db.aux_get(cpv, ["SLOT"])[0])
+                       for cpv in blocked_final:
+                               blocked_slots_final[cpv] = \
+                                       "%s:%s" % (portage.dep_getkey(cpv),
+                                               final_db.aux_get(cpv, ["SLOT"])[0])
+                       for parent in list(self.blocker_parents[blocker]):
+                               ptype, proot, pcpv, pstatus = parent
+                               pdbapi = self.trees[proot][self.pkg_tree_map[ptype]].dbapi
+                               pslot = pdbapi.aux_get(pcpv, ["SLOT"])[0]
+                               pslot_atom = "%s:%s" % (portage.dep_getkey(pcpv), pslot)
+                               unresolved_blocks = False
+                               depends_on_order = set()
+                               for cpv in blocked_initial:
+                                       slot_atom = blocked_slots_initial[cpv]
+                                       if slot_atom == pslot_atom:
+                                               # The parent blocks an initial package in the same
+                                               # slot as itself.  The merge/nomerge status of neither
+                                               # node matters.  In any case, this particular block is
+                                               # automatically resolved.
+                                               continue
+                                       if slot_atom not in blocked_slots_final.values():
+                                               upgrade_matches = final_db.match(slot_atom)
+                                               if upgrade_matches:
+                                                       # Apparently an upgrade may be able to invalidate
+                                                       # this block.
+                                                       upgrade_node = \
+                                                               self.pkg_node_map[proot][upgrade_matches[0]]
+                                                       depends_on_order.add(upgrade_node)
                                                        continue
-                                               if pkg in blocked_after_update:
-                                                       """This isn't a case of a package blocking itself,
-                                                       and the block is still valid in the final state, so
-                                                       this one is unresolvable."""
-                                                       unresolvable = True
-                                                       break
+                                       # None of the above blocker resolutions techniques apply,
+                                       # so apparently this one is unresolvable.
+                                       unresolved_blocks = True
+                               for cpv in blocked_final:
+                                       slot_atom = blocked_slots_final[cpv]
+                                       if slot_atom == pslot_atom:
+                                               # The parent blocks itself, so the merge order does not
+                                               # need to be enforced.
+                                               continue
+                                       # None of the above blocker resolutions techniques apply,
+                                       # so apparently this one is unresolvable.
+                                       unresolved_blocks = True
+                               if not unresolved_blocks and depends_on_order:
+                                       for node in depends_on_order:
                                                # Enforce correct merge order with a hard dep.
-                                               node = self.pkg_node_map[proot][pkg]
                                                self.digraph.addnode(node, parent,
                                                        priority=DepPriority(buildtime=True))
-                                               """Count references to this blocker so that it can be
-                                               invalidated after nodes referencing it have been merged."""
+                                               # Count references to this blocker so that it can be
+                                               # invalidated after nodes referencing it have been
+                                               # merged.
                                                self.blocker_digraph.addnode(node, blocker)
-                                               depends_on_merge_order = True
-                                       if unresolvable:
-                                               break
-                                       elif not depends_on_merge_order:
-                                               self.blocker_parents[blocker].remove(parent)
-                               if unresolvable:
-                                       """This blocker can not be solved, so make sure that it is
-                                       removed from the digraph if it has already been added."""
-                                       if self.blocker_digraph.contains(blocker):
-                                               self.blocker_digraph.remove(blocker)
-                                       # Keep trying to invalidate as many blockers as possible.
-                                       continue
-                               if not self.blocker_parents[blocker]:
-                                       del self.blocker_parents[blocker]
+                               if not unresolved_blocks and not depends_on_order:
+                                       self.blocker_parents[blocker].remove(parent)
+                       if not self.blocker_parents[blocker]:
+                               del self.blocker_parents[blocker]
                # Validate blockers that depend on merge order.
                if not self.blocker_digraph.empty():
                        self.altlist()