Make || choices independent of REQUIRED_USE.
authorZac Medico <zmedico@gentoo.org>
Wed, 2 Feb 2011 21:29:42 +0000 (13:29 -0800)
committerZac Medico <zmedico@gentoo.org>
Wed, 2 Feb 2011 23:34:30 +0000 (15:34 -0800)
pym/_emerge/depgraph.py
pym/portage/tests/resolver/test_required_use.py

index b84f94234fbb398adc73785a8718af2e36f7264f..7d323add7be5c9076525265a0ce043ce80130508 100644 (file)
@@ -197,8 +197,6 @@ class _dynamic_depgraph_config(object):
                self._initially_unsatisfied_deps = []
                self._ignored_deps = []
                self._highest_pkg_cache = {}
-
-               self._unsat_req_use = {}
                self._pkg_config_issues = {}
 
                if runtime_pkg_mask is None:
@@ -849,6 +847,34 @@ class depgraph(object):
                                        raise
                                del e
 
+               # NOTE: REQUIRED_USE checks are delayed until after
+               # package selection, since want to prompt the user
+               # for USE adjustment rather than have REQUIRED_USE
+               # affect package selection and || dep choices.
+               if not pkg.built and pkg.metadata["REQUIRED_USE"] and \
+                       eapi_has_required_use(pkg.metadata["EAPI"]):
+                       required_use_is_sat = check_required_use(
+                               pkg.metadata["REQUIRED_USE"],
+                               self._pkg_use_enabled(pkg),
+                               pkg.iuse.is_valid_flag)
+                       if not required_use_is_sat:
+                               if dep.atom is not None and dep.parent is not None:
+                                       self._add_parent_atom(pkg, (dep.parent, dep.atom))
+
+                               if arg_atoms:
+                                       for parent_atom in arg_atoms:
+                                               parent, atom = parent_atom
+                                               self._add_parent_atom(pkg, parent_atom)
+
+                               config_issues = \
+                                       self._dynamic_config._pkg_config_issues.setdefault(pkg, {})
+                               parent_atoms = config_issues.setdefault("required use", set())
+                               all_parent_atoms = self._dynamic_config._parent_atoms.get(pkg)
+                               if all_parent_atoms is not None:
+                                       for parent, atom in all_parent_atoms:
+                                               parent_atoms.add((parent, pkg.root, atom))
+                               return 0
+
                if not pkg.onlydeps:
                        if not pkg.installed and \
                                "empty" not in self._dynamic_config.myparams and \
@@ -1917,14 +1943,8 @@ class depgraph(object):
                                                        self._dynamic_config._unsatisfied_deps_for_display.append(
                                                                ((myroot, atom), {"myparent" : arg}))
                                                        return 0, myfavorites
-                                               pkg = self._dynamic_config._unsat_req_use.get((myroot, atom))
-                                               if pkg is not None:
-                                                       config_issues = \
-                                                               self._dynamic_config._pkg_config_issues.setdefault(pkg, {})
-                                                       parent_atoms = config_issues.setdefault("required use", set())
-                                                       parent_atoms.add((arg, myroot, atom))
-                                               else:
-                                                       self._dynamic_config._missing_args.append((arg, atom))
+
+                                               self._dynamic_config._missing_args.append((arg, atom))
                                                continue
                                        if atom.cp != pkg.cp:
                                                # For old-style virtuals, we need to repeat the
@@ -1957,12 +1977,13 @@ class depgraph(object):
                                                if self._dynamic_config._need_restart:
                                                        pass
                                                elif isinstance(arg, SetArg):
-                                                       sys.stderr.write(("\n\n!!! Problem resolving " + \
+                                                       writemsg(("\n\n!!! Problem resolving " + \
                                                                "dependencies for %s from %s\n") % \
-                                                               (atom, arg.arg))
+                                                               (atom, arg.arg), noiselevel=-1)
                                                else:
-                                                       sys.stderr.write(("\n\n!!! Problem resolving " + \
-                                                               "dependencies for %s\n") % atom)
+                                                       writemsg(("\n\n!!! Problem resolving " + \
+                                                               "dependencies for %s\n") % \
+                                                               (atom,), noiselevel=-1)
                                                return 0, myfavorites
 
                                except portage.exception.MissingSignature as e:
@@ -3022,7 +3043,6 @@ class depgraph(object):
                # represented by the found_available_arg flag.
                found_available_arg = False
                packages_with_invalid_use_config = []
-               pkgs_with_unsat_req_use = []
                for find_existing_node in True, False:
                        if existing_node:
                                break
@@ -3204,24 +3224,6 @@ class depgraph(object):
                                                                packages_with_invalid_use_config.append(pkg)
                                                        continue
 
-                                       #check REQUIRED_USE constraints
-                                       if not pkg.built and pkg.metadata["REQUIRED_USE"] and \
-                                               eapi_has_required_use(pkg.metadata["EAPI"]):
-                                               required_use = pkg.metadata["REQUIRED_USE"]
-                                               use = self._pkg_use_enabled(pkg)
-                                               try:
-                                                       required_use_is_sat = check_required_use(
-                                                               pkg.metadata["REQUIRED_USE"], use, pkg.iuse.is_valid_flag)
-                                               except portage.exception.InvalidDependString as e:
-                                                       portage.writemsg("!!! Invalid REQUIRED_USE specified by " + \
-                                                               "'%s': %s\n" % (pkg.cpv, str(e)), noiselevel=-1)
-                                                       del e
-                                                       continue
-                                               if not required_use_is_sat:
-                                                       packages_with_invalid_use_config.append(pkg)
-                                                       pkgs_with_unsat_req_use.append(pkg)
-                                                       continue
-
                                        if pkg.cp == atom_cp:
                                                if highest_version is None:
                                                        highest_version = pkg
@@ -3303,9 +3305,6 @@ class depgraph(object):
                                        break
 
                if not matched_packages:
-                       if pkgs_with_unsat_req_use:
-                               self._dynamic_config._unsat_req_use[(root, atom)] = \
-                                       pkgs_with_unsat_req_use[0]
                        return None, None
 
                if "--debug" in self._frozen_config.myopts:
index 90ccb3da01b6d1223e948f56aff297d86b231706..c8810faef7bad5c2f47f7c892d31e2a0501eac05 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2011 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from portage.tests import TestCase
@@ -88,3 +88,27 @@ class RequiredUSETestCase(TestCase):
                                self.assertEqual(test_case.test_success, True, test_case.fail_msg)
                finally:
                        playground.cleanup()
+
+       def testRequiredUseOrDeps(self):
+               
+               ebuilds = {
+                       "dev-libs/A-1": { "IUSE": "+x +y", "REQUIRED_USE": "^^ ( x y )", "EAPI": "4" },
+                       "dev-libs/B-1": { "IUSE": "+x +y", "REQUIRED_USE": "",           "EAPI": "4" },
+                       "app-misc/p-1": { "RDEPEND": "|| ( =dev-libs/A-1 =dev-libs/B-1 )" },
+                       }
+
+               test_cases = (
+                               # This should fail and show a REQUIRED_USE error for
+                               # dev-libs/A-1, since this choice it preferred.
+                               ResolverPlaygroundTestCase(
+                                       ["=app-misc/p-1"],
+                                       success = False),
+                       )
+
+               playground = ResolverPlayground(ebuilds=ebuilds)
+               try:
+                       for test_case in test_cases:
+                               playground.run_TestCase(test_case)
+                               self.assertEqual(test_case.test_success, True, test_case.fail_msg)
+               finally:
+                       playground.cleanup()