Refactor the way that depgraph.altlist(), _complete_graph(), and
authorZac Medico <zmedico@gentoo.org>
Sun, 27 Apr 2008 00:21:24 +0000 (00:21 -0000)
committerZac Medico <zmedico@gentoo.org>
Sun, 27 Apr 2008 00:21:24 +0000 (00:21 -0000)
validate_blockers() interact with eachother. This simplifies things
by eliminating the need for recursive calls to validate_blockers().
(trunk r9977)

svn path=/main/branches/2.1.2/; revision=9984

bin/emerge

index feceb85758aa7d06a32e92a2c6401f7d1bac2966..9aba5e6dbb52650345220607fbccfb1d6779e5fa 100755 (executable)
@@ -2706,10 +2706,9 @@ class depgraph(object):
                                        missing += 1
                                        print "Missing binary for:",xs[2]
 
-               if not self._complete_graph():
-                       return False, myfavorites
-
-               if not self.validate_blockers():
+               try:
+                       self.altlist()
+               except self._unknown_internal_error:
                        return False, myfavorites
 
                # We're true here unless we are missing binaries.
@@ -3379,25 +3378,6 @@ class depgraph(object):
                        if not self.blocker_parents[blocker]:
                                del self.blocker_parents[blocker]
 
-               # This checks whether or not it's possible to resolve blocker
-               # conflicts that depend on installation order or require
-               # uninstallation of a currently installed package. Note that
-               # this can lead to the current method being called recursively
-               # if changes to the dependency graph are required.
-               try:
-                       self.altlist()
-               except self._unknown_internal_error:
-                       return False
-
-               if self._slot_collision_info:
-                       # The user is only notified of a slot collision if there are no
-                       # unresolvable blocks.
-                       for x in self.altlist():
-                               if x[0] == "blocks":
-                                       self._slot_collision_info.clear()
-                                       return True
-                       if not self._accept_collisions():
-                               return False
                return True
 
        def _accept_collisions(self):
@@ -3422,6 +3402,7 @@ class depgraph(object):
        def altlist(self, reversed=False):
 
                while self._serialized_tasks_cache is None:
+                       self._resolve_conflicts()
                        try:
                                self._serialized_tasks_cache = self._serialize_tasks()
                        except self._serialize_tasks_retry:
@@ -3432,6 +3413,13 @@ class depgraph(object):
                        retlist.reverse()
                return retlist
 
+       def _resolve_conflicts(self):
+               if not self._complete_graph():
+                       raise self._unknown_internal_error()
+
+               if not self.validate_blockers():
+                       raise self._unknown_internal_error()
+
        def _serialize_tasks(self):
                mygraph=self.digraph.copy()
                # Prune "nomerge" root nodes if nothing depends on them, since
@@ -3851,10 +3839,6 @@ class depgraph(object):
                        not complete and \
                        not myblocker_parents:
                        self.myparams.add("complete")
-                       if not self._complete_graph():
-                               raise self._unknown_internal_error("")
-                       if not self.validate_blockers():
-                               raise self._unknown_internal_error("")
                        raise self._serialize_tasks_retry("")
 
                return retlist
@@ -4525,7 +4509,17 @@ class depgraph(object):
                to ensure that the user is notified of problems with the graph.
                """
 
-               self._show_slot_collision_notice()
+               task_list = self.altlist()
+
+               # Any blockers must be appended to the tail of the list,
+               # so we only need to check the last item.
+               have_blocker_conflict = \
+                       bool(task_list and task_list[-1][0] == "blocks")
+
+               # The user is only notified of a slot conflict if
+               # there are no unresolvable blocker conflicts.
+               if not have_blocker_conflict:
+                       self._show_slot_collision_notice()
 
                # TODO: Add generic support for "set problem" handlers so that
                # the below warnings aren't special cases for world only.