Allow flags from IUSE_IMPLICIT in REQUIRED_USE. Move checks to resolution time.
authorSebastian Luther <SebastianLuther@gmx.de>
Tue, 13 Apr 2010 20:03:47 +0000 (22:03 +0200)
committerZac Medico <zmedico@gentoo.org>
Wed, 11 Aug 2010 01:31:56 +0000 (18:31 -0700)
bin/repoman
pym/_emerge/Scheduler.py
pym/_emerge/depgraph.py

index 2a53bd27ee0588f19c4aa0a231d572ef79083a1d..e5797632374785a044a250944769b1f0892a1f74 100755 (executable)
@@ -1795,7 +1795,9 @@ for x in scanlist:
                                        relative_path + ": REQUIRED_USE" + \
                                        " not supported with EAPI='%s'" % (eapi,))
                        try:
-                               portage.dep.check_required_use(required_use, "", myaux["IUSE"].split())
+                               iuse = repoman_settings._get_implicit_iuse()
+                               iuse.update(myaux["IUSE"].split())
+                               portage.dep.check_required_use(required_use, "", iuse)
                        except portage.exception.InvalidRequiredUseString as e:
                                stats["REQUIRED_USE.syntax"] = stats["REQUIRED_USE.syntax"] + 1
                                fails["REQUIRED_USE.syntax"].append(
index d5c152f153bea1b163a0c892e3eab593914acc97..ae9cbcaa87ccc5e534d6196d4185deb91960508b 100644 (file)
@@ -721,63 +721,6 @@ class Scheduler(PollScheduler):
                        return 1
                return os.EX_OK
 
-       def _check_required_use(self):
-               # Make sure all constraints expressed in REQUIRED_USE are satisfied
-
-               failures = 0
-               shown_verifying_msg = False
-               for x in self._mergelist:
-                       if not isinstance(x, Package):
-                               continue
-
-                       if x.operation == "uninstall":
-                               continue
-
-                       if x.metadata["EAPI"] in ("0", "1", "2", "3"):
-                               continue
-
-                       if not x.metadata["REQUIRED_USE"]:
-                               continue
-
-                       if not shown_verifying_msg:
-                               shown_verifying_msg = True
-                               self._status_msg("Verifying use flag constraints")
-
-                       required_use = x.metadata["REQUIRED_USE"]
-                       use = x.metadata["USE"].split()
-                       iuse = x.metadata["IUSE"].split()
-
-                       try:
-                               sat, unsat = portage.dep.check_required_use(required_use, use, iuse)
-                       except portage.exception.InvalidRequiredUseString as e:
-                               failures += 1
-                               portage.writemsg("!!! Invalid REQUIRED_USE specified by " + \
-                                       "'%s': %s\n" % (x.cpv, str(e)), noiselevel=-1)
-                               del e
-                               continue
-
-                       if unsat:
-                               failures += 1
-                               if sat:
-                                       #not all constraints are violated, display the them all to not annoy
-                                       #the user with another violated constraint after he fixed the first one
-                                       portage.writemsg(
-                                               "!!! Use flag constraints for '%s' not met.\n" % x.cpv + \
-                                               "!!! violated constraint(s): '%s'\n" % unsat + \
-                                               "!!! all constraint(s):      '%s'\n" % required_use, noiselevel=-1)
-                               else:
-                                       portage.writemsg(
-                                               "!!! Use flag constraints for '%s' not met.\n" % x.cpv + \
-                                               "!!! constraint(s): '%s'\n" % required_use, noiselevel=-1)
-               if failures:
-                       portage.writemsg("\n")
-                       portage.writemsg("Explanation: || ( a b c ): at least one of 'a', 'b' or 'c' must be enabled\n")
-                       portage.writemsg("Explanation: ^^ ( a b c ): exactly one of 'a', 'b' or 'c' must be enabled\n")
-                       portage.writemsg("Explanation: a? ( b ): b needs to be enabled if a is enabled\n")
-                       portage.writemsg("Explanation: '!'-prefix reverses the required state\n")
-                       return 1
-               return os.EX_OK
-
        def _add_prefetchers(self):
 
                if not self._parallel_fetch:
@@ -1047,14 +990,10 @@ class Scheduler(PollScheduler):
                if rval != os.EX_OK and not keep_going:
                        return rval
 
-               rval = self._check_required_use()
-               if rval != os.EX_OK:
-                       return rval
-
                rval = self._run_pkg_pretend()
                if rval != os.EX_OK:
                        return rval
-                       
+
                while True:
                        rval = self._merge()
                        if rval == os.EX_OK or fetchonly or not keep_going:
index 91b3a1548be1262be3a2d81b0fb68f5179faf5f6..e9f7c4426fd1509da9f9b20be8b77e1b59a1502c 100644 (file)
@@ -2835,6 +2835,24 @@ 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 \
+                                               pkg.metadata["EAPI"] not in ("0", "1", "2", "3"):
+                                               required_use = pkg.metadata["REQUIRED_USE"]
+                                               use = pkg.use.enabled
+                                               iuse = self._frozen_config.settings._get_implicit_iuse()
+                                               iuse.update(pkg.iuse.all)
+                                               try:
+                                                       sat, unsat = portage.dep.check_required_use(
+                                                               pkg.metadata["REQUIRED_USE"], use, iuse)
+                                               except portage.exception.InvalidRequiredUseString as e:
+                                                       portage.writemsg("!!! Invalid REQUIRED_USE specified by " + \
+                                                               "'%s': %s\n" % (pkg.cpv, str(e)), noiselevel=-1)
+                                                       del e
+                                                       continue
+                                               if unsat:
+                                                       continue
+
                                        if pkg.cp == atom_cp:
                                                if highest_version is None:
                                                        highest_version = pkg
@@ -6180,6 +6198,24 @@ def _get_masking_status(pkg, pkgsettings, root_config):
                                        mreasons.append(
                                                _MaskReason("invalid", "invalid: %s" % (msg,)))
 
+               if pkg.metadata["REQUIRED_USE"] and \
+                       pkg.metadata["EAPI"] not in ("0", "1", "2", "3"):
+                       required_use = pkg.metadata["REQUIRED_USE"]
+                       use = pkg.use.enabled
+                       iuse = pkgsettings._get_implicit_iuse()
+                       iuse.update(pkg.iuse.all)
+                       try:
+                               sat, unsat = portage.dep.check_required_use(
+                                       required_use, use, iuse)
+                       except portage.exception.InvalidRequiredUseString:
+                               mreasons.append("invalid: REQUIRED_USE")
+                       else:
+                               if unsat:
+                                       msg = "violated use flag constraints: '%s'" % unsat
+                                       if sat:
+                                               msg += ", other constraints: '%s'" % sat
+                                       mreasons.append(msg)
+
        if not pkg.metadata["SLOT"]:
                mreasons.append(
                        _MaskReason("invalid", "SLOT: undefined"))