depgraph: detect deps broken by autounmask
authorZac Medico <zmedico@gentoo.org>
Wed, 25 May 2011 02:52:17 +0000 (19:52 -0700)
committerZac Medico <zmedico@gentoo.org>
Thu, 26 May 2011 06:11:52 +0000 (23:11 -0700)
This will fix bug #368429.

pym/_emerge/depgraph.py

index 21d5c19528107d9a1a0f46a649b06ebe583825b5..5f74b6deb17840cddb86ff6d3d46a7143da969ee 100644 (file)
@@ -2479,14 +2479,17 @@ class depgraph(object):
 
 
        def _show_unsatisfied_dep(self, root, atom, myparent=None, arg=None,
-               check_backtrack=False):
+               check_backtrack=False, check_autounmask_breakage=False):
                """
                When check_backtrack=True, no output is produced and
                the method either returns or raises _backtrack_mask if
                a matching package has been masked by backtracking.
                """
                backtrack_mask = False
+               autounmask_broke_use_dep = False
                atom_set = InternalPackageSet(initial_atoms=(atom.without_use,))
+               atom_set_with_use = InternalPackageSet(initial_atoms=(atom,),
+                       allow_repo=True)
                xinfo = '"%s"' % atom.unevaluated_atom
                if arg:
                        xinfo='"%s"' % arg
@@ -2553,6 +2556,8 @@ class depgraph(object):
                                                                or atom.violated_conditionals(self._pkg_use_enabled(pkg), pkg.iuse.is_valid_flag).use:
                                                                missing_use.append(pkg)
                                                                if not mreasons:
+                                                                       if atom_set_with_use.findAtomForPackage(pkg):
+                                                                               autounmask_broke_use_dep = True
                                                                        continue
                                                except InvalidAtom:
                                                        writemsg("violated_conditionals raised " + \
@@ -2580,6 +2585,12 @@ class depgraph(object):
                        else:
                                return
 
+               if check_autounmask_breakage:
+                       if autounmask_broke_use_dep:
+                               raise self._autounmask_breakage()
+                       else:
+                               return
+
                missing_use_reasons = []
                missing_iuse_reasons = []
                for pkg in missing_use:
@@ -5708,10 +5719,26 @@ class depgraph(object):
                backtracking.
                """
 
+       class _autounmask_breakage(_internal_exception):
+               """
+               This is raised by _show_unsatisfied_dep() when it's called with
+               check_autounmask_breakage=True and a matching package has been
+               been disqualified due to autounmask changes.
+               """
+
        def need_restart(self):
                return self._dynamic_config._need_restart and \
                        not self._dynamic_config._skip_restart
 
+       def autounmask_breakage_detected(self):
+               try:
+                       for pargs, kwargs in self._dynamic_config._unsatisfied_deps_for_display:
+                               self._show_unsatisfied_dep(
+                                       *pargs, check_autounmask_breakage=True, **kwargs)
+               except self._autounmask_breakage:
+                       return True
+               return False
+
        def get_backtrack_parameters(self):
                return {
                        "needed_unstable_keywords":
@@ -5994,6 +6021,18 @@ def _backtrack_depgraph(settings, trees, myopts, myparams,
                                break
                else:
                        break
+
+       if not success and mydepgraph.autounmask_breakage_detected():
+               if "--debug" in myopts:
+                       writemsg_level(
+                               "\n\nautounmask breakage detected\n\n",
+                               noiselevel=-1, level=logging.DEBUG)
+               myopts["--autounmask"] = "n"
+               mydepgraph = depgraph(settings, trees, myopts, myparams, spinner,
+                       frozen_config=frozen_config,
+                       allow_backtracking=allow_backtracking)
+               success, favorites = mydepgraph.select_files(myfiles)
+
        return (success, mydepgraph, favorites)
 
 def resume_depgraph(settings, trees, mtimedb, myopts, myparams, spinner):