Make --skipfirst handle missing dependencies by dropping the merge tasks
authorZac Medico <zmedico@gentoo.org>
Thu, 29 May 2008 19:50:50 +0000 (19:50 -0000)
committerZac Medico <zmedico@gentoo.org>
Thu, 29 May 2008 19:50:50 +0000 (19:50 -0000)
that have missing dependencies. This involves creating an entirely new
depgraph each time that a missing dependency is discovered. This isn't
the most efficient approach but it's simple and it works well.

This new behavior can server as a fix for bug #12768 by calling emerge
--resume --skipfirst each time that emerge exits unsuccessfully. This
was possible before, but now packages with unsatisfied dependencies
will be properly identified and dropped from the list.

svn path=/main/trunk/; revision=10478

pym/_emerge/__init__.py

index 98b81fe5f23e72b3103da24c9508656a07730700..d61cdb53ac99e01ba1e206a1f76508d9d5c67bde 100644 (file)
@@ -5273,13 +5273,6 @@ class depgraph(object):
                if not isinstance(mergelist, list):
                        mergelist = []
 
-               if mergelist and "--skipfirst" in self.myopts:
-                       for i, task in enumerate(mergelist):
-                               if isinstance(task, list) and \
-                                       task and task[-1] == "merge":
-                                       del mergelist[i]
-                                       break
-
                fakedb = self.mydbapi
                trees = self.trees
                serialized_tasks = []
@@ -8360,11 +8353,39 @@ def action_build(settings, trees, mtimedb,
                if show_spinner:
                        print "Calculating dependencies  ",
                myparams = create_depgraph_params(myopts, myaction)
-               mydepgraph = depgraph(settings, trees,
-                       myopts, myparams, spinner)
+
+               resume_data = mtimedb["resume"]
+               mergelist = resume_data["mergelist"]
+               if mergelist and "--skipfirst" in myopts:
+                       for i, task in enumerate(mergelist):
+                               if isinstance(task, list) and \
+                                       task and task[-1] == "merge":
+                                       del mergelist[i]
+                                       break
+
                success = False
                try:
-                       success = mydepgraph.loadResumeCommand(mtimedb["resume"])
+                       while True:
+                               mydepgraph = depgraph(settings, trees,
+                                       myopts, myparams, spinner)
+                               try:
+                                       success = mydepgraph.loadResumeCommand(mtimedb["resume"])
+                               except depgraph.UnsatisfiedResumeDep, e:
+                                       if "--skipfirst" not in myopts:
+                                               raise
+                                       unsatisfied_parents = set(dep.parent for dep in e.value)
+                                       pruned_mergelist = []
+                                       for task in mergelist:
+                                               if isinstance(task, list) and \
+                                                       tuple(task) in unsatisfied_parents:
+                                                               continue
+                                               pruned_mergelist.append(task)
+                                       if not pruned_mergelist:
+                                               raise
+                                       mergelist[:] = pruned_mergelist
+                                       continue
+                               else:
+                                       break
                except (portage.exception.PackageNotFound,
                        mydepgraph.UnsatisfiedResumeDep), e:
                        if show_spinner:
@@ -8398,7 +8419,9 @@ def action_build(settings, trees, mtimedb,
                                msg = "The resume list contains packages " + \
                                        "with dependencies that have not been " + \
                                        "installed yet. Please restart/continue " + \
-                                       "the operation manually."
+                                       "the operation manually, or use --skipfirst " + \
+                                       "to skip the first package in the list and " + \
+                                       "any other packages that may have missing dependencies."
                                for line in wrap(msg, 72):
                                        out.eerror(line)
                        elif isinstance(e, portage.exception.PackageNotFound):