Merged from trunk 7994:8001
authorFabian Groffen <grobian@gentoo.org>
Mon, 8 Oct 2007 17:33:36 +0000 (17:33 -0000)
committerFabian Groffen <grobian@gentoo.org>
Mon, 8 Oct 2007 17:33:36 +0000 (17:33 -0000)
   | 7995    | Move the "commit" mode manifest generation earlier in order  |
   | zmedico | to avoid digest verification issues when FEATURES="strict"   |
   |         | is enabled.                                                  |

   | 7996    | Remove duplicate call to digestgen().                        |
   | zmedico |                                                              |

   | 7997    | Factor the KEYWORDS masking logic out of portdbapi.visible() |
   | zmedico | and move it to config.getMissingEeywords(). This will allow  |
   |         | the code to be reused for binary packages.                   |

   | 7998    | Allow config.setcpv() to take a dictionary of package        |
   | zmedico | metadata in place of a dbapi instance so that extra cache    |
   |         | pulls can be avoided.                                        |

   | 7999    | Restore profile masking support to getmaskingstatus().       |
   | zmedico |                                                              |

   | 8000    | Cache IUSE for portdbapi.gvisible() calls.                   |
   | zmedico |                                                              |

   | 8001    | Factor package.mask and profile masking logic out of         |
   | zmedico | portdbapi.visible() and move it to config.getMaskAtom() and  |
   |         | getProfileMaskAtom(). This will allow the code to be reused  |
   |         | for binary packages.                                         |

svn path=/main/branches/prefix/; revision=8007

bin/repoman
pym/portage/__init__.py
pym/portage/dbapi/porttree.py

index d7dcd075b9fb888a4c4d6c0e28f31ba0f10c623a..fa7749c12b64096fde209f30ecd5e1a779d8b3e8 100755 (executable)
@@ -846,12 +846,16 @@ for x in scanlist:
        catdir,pkgdir=x.split("/")
        checkdir=repodir+"/"+x
 
-       if mymode == "manifest":
+       if mymode == "manifest" or \
+               mymode in ("commit", "fix") and "--pretend" not in myoptions:
                repoman_settings["O"] = checkdir
                if not portage.digestgen([], repoman_settings, myportdb=portdb):
                        print "Unable to generate manifest."
                        dofail = 1
-               continue
+               if mymode == "manifest":
+                       continue
+               elif dofail:
+                       sys.exit(1)
 
        checkdirlist=os.listdir(checkdir)
        ebuildlist=[]
@@ -1001,13 +1005,6 @@ for x in scanlist:
                                fails["svn.IO_error"].append(checkdir+"/files svn info")
                        continue
 
-       if mymode in ("fix", "commit") and \
-               "--pretend" not in myoptions:
-               repoman_settings["O"] = checkdir
-               if not portage.digestgen([], repoman_settings, myportdb=portdb):
-                       print "Unable to generate manifest."
-                       sys.exit(1)
-
        mf = Manifest(checkdir, repoman_settings["DISTDIR"])
        mydigests=mf.getTypeDigests("DIST")
 
index e29e15338efa00a3f5bbb7a0ca1cc1a29e1e3198..05e23ad8837c8f3a36576d1dd8c83d39251cb21b 100644 (file)
@@ -1773,7 +1773,11 @@ class config(object):
                pkginternaluse = ""
                iuse = ""
                if mydb:
-                       slot, iuse = mydb.aux_get(self.mycpv, ["SLOT", "IUSE"])
+                       if isinstance(mydb, dict):
+                               slot = mydb["SLOT"]
+                               iuse = mydb["IUSE"]
+                       else:
+                               slot, iuse = mydb.aux_get(self.mycpv, ["SLOT", "IUSE"])
                        cpv_slot = "%s:%s" % (self.mycpv, slot)
                        pkginternaluse = []
                        for x in iuse.split():
@@ -1843,6 +1847,140 @@ class config(object):
                if has_changed:
                        self.reset(keeping_pkg=1,use_cache=use_cache)
 
+       def getMaskAtom(self, cpv, metadata):
+               """
+               Take a package and return a matching package.mask atom, or None if no
+               such atom exists or it has been cancelled by package.unmask. PROVIDE
+               is not checked, so atoms will not be found for old-style virtuals.
+
+               @param cpv: The package name
+               @type cpv: String
+               @param metadata: A dictionary of raw package metadata
+               @type metadata: dict
+               @rtype: String
+               @return: An matching atom string or None if one is not found.
+               """
+
+               cp = cpv_getkey(cpv)
+               mask_atoms = self.pmaskdict.get(cp)
+               if mask_atoms:
+                       pkg_list = ["%s:%s" % (cpv, metadata["SLOT"])]
+                       unmask_atoms = self.punmaskdict.get(cp)
+                       for x in mask_atoms:
+                               if not match_from_list(x, pkg_list):
+                                       continue
+                               masked = True
+                               if unmask_atoms:
+                                       for y in unmask_atoms:
+                                               if match_from_list(y, pkg_list):
+                                                       masked = False
+                                                       break
+                               if not masked:
+                                       continue
+                               return x
+               return None
+
+       def getProfileMaskAtom(self, cpv, metadata):
+               """
+               Take a package and return a matching profile atom, or None if no
+               such atom exists. Note that a profile atom may or may not have a "*"
+               prefix. PROVIDE is not checked, so atoms will not be found for
+               old-style virtuals.
+
+               @param cpv: The package name
+               @type cpv: String
+               @param metadata: A dictionary of raw package metadata
+               @type metadata: dict
+               @rtype: String
+               @return: An matching profile atom string or None if one is not found.
+               """
+
+               cp = cpv_getkey(cpv)
+               profile_atoms = self.prevmaskdict.get(cp)
+               if profile_atoms:
+                       pkg_list = ["%s:%s" % (cpv, metadata["SLOT"])]
+                       for x in profile_atoms:
+                               if match_from_list(x.lstrip("*"), pkg_list):
+                                       continue
+                               return x
+               return None
+
+       def getMissingKeywords(self, cpv, metadata):
+               """
+               Take a package and return a list of any KEYWORDS that the user may
+               may need to accept for the given package. If the KEYWORDS are empty
+               and the the ** keyword has not been accepted, the returned list will
+               contain ** alone (in order to distiguish from the case of "none
+               missing").
+
+               @param cpv: The package name (for package.keywords support)
+               @type cpv: String
+               @param metadata: A dictionary of raw package metadata
+               @type metadata: dict
+               @rtype: List
+               @return: A list of KEYWORDS that have not been accepted.
+               """
+
+               # Hack: Need to check the env directly here as otherwise stacking 
+               # doesn't work properly as negative values are lost in the config
+               # object (bug #139600)
+               egroups = self.configdict["backupenv"].get(
+                       "ACCEPT_KEYWORDS", "").split()
+               mygroups = metadata["KEYWORDS"].split()
+               # Repoman may modify this attribute as necessary.
+               pgroups = self["ACCEPT_KEYWORDS"].split()
+               match=0
+               cp = dep_getkey(cpv)
+               pkgdict = self.pkeywordsdict.get(cp)
+               if pkgdict:
+                       cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
+                       matches = match_to_list(cpv_slot, pkgdict.keys())
+                       for atom in matches:
+                               pgroups.extend(pkgdict[atom])
+                       pgroups.extend(egroups)
+                       if matches:
+                               # normalize pgroups with incrementals logic so it 
+                               # matches ACCEPT_KEYWORDS behavior
+                               inc_pgroups = set()
+                               for x in pgroups:
+                                       if x == "-*":
+                                               inc_pgroups.clear()
+                                       elif x.startswith("-"):
+                                               inc_pgroups.discard(x[1:])
+                                       elif x not in inc_pgroups:
+                                               inc_pgroups.add(x)
+                               pgroups = inc_pgroups
+                               del inc_pgroups
+               hasstable = False
+               hastesting = False
+               for gp in mygroups:
+                       if gp == "*" or (gp == "-*" and len(mygroups) == 1):
+                               writemsg(("--- WARNING: Package '%s' uses" + \
+                                       " '%s' keyword.\n") % (cpv, gp), noiselevel=-1)
+                               if gp == "*":
+                                       match = 1
+                                       break
+                       elif gp in pgroups:
+                               match=1
+                               break
+                       elif gp.startswith("~"):
+                               hastesting = True
+                       elif not gp.startswith("-"):
+                               hasstable = True
+               if not match and \
+                       ((hastesting and "~*" in pgroups) or \
+                       (hasstable and "*" in pgroups) or "**" in pgroups):
+                       match=1
+               if match:
+                       missing = []
+               else:
+                       if not mygroups:
+                               # If KEYWORDS is empty then we still have to return something
+                               # in order to distiguish from the case of "none missing".
+                               mygroups.append("**")
+                       missing = mygroups
+               return missing
+
        def getMissingLicenses(self, cpv, metadata):
                """
                Take a LICENSE string and return a list any licenses that the user may
@@ -5014,6 +5152,18 @@ def getmaskingstatus(mycpv, settings=None, portdb=None):
 
        rValue = []
 
+       # profile checking
+       revmaskdict=settings.prevmaskdict
+       if revmaskdict.has_key(mycp):
+               for x in revmaskdict[mycp]:
+                       if x[0]=="*":
+                               myatom = x[1:]
+                       else:
+                               myatom = x
+                       if not match_to_list(mycpv, [myatom]):
+                               rValue.append("profile")
+                               break
+
        # package.mask checking
        maskdict=settings.pmaskdict
        unmaskdict=settings.punmaskdict
index 3990a827e986bff5ff50cd3c8e5ce80ed999c057..ee8c4776d622bbe6a9059dde2e16731d5e80b37d 100644 (file)
@@ -22,7 +22,7 @@ from portage import eclass_cache, auxdbkeys, auxdbkeylen, doebuild, flatten, \
        listdir, dep_expand, eapi_is_supported, key_expand, dep_check
 
 import os, stat, sys
-
+from itertools import izip
 
 class portdbapi(dbapi):
        """this tree will scan a portage directory located at root (passed to init)"""
@@ -117,7 +117,8 @@ class portdbapi(dbapi):
                                self.auxdb[x] = self.auxdbmodule(
                                        self.depcachedir, x, filtered_auxdbkeys, gid=portage_gid)
                # Selectively cache metadata in order to optimize dep matching.
-               self._aux_cache_keys = set(["EAPI", "KEYWORDS", "LICENSE", "SLOT"])
+               self._aux_cache_keys = set(
+                       ["EAPI", "IUSE", "KEYWORDS", "LICENSE", "SLOT"])
                self._aux_cache = {}
                self._broken_ebuilds = set()
 
@@ -603,57 +604,22 @@ class portdbapi(dbapi):
                if not mylist:
                        return []
 
-               mysplit = catpkgsplit(mylist[0])
-               if not mysplit:
-                       #invalid cat/pkg-v
-                       writemsg("visible(): invalid cat/pkg-v: %s\n" % (mylist[0], ),
-                               noiselevel=-1)
-                       return []
-               mycp = "%s/%s" % (mysplit[0], mysplit[1])
-
-               cpv_slots = []
+               db_keys = ["SLOT"]
+               visible = []
+               getMaskAtom = self.mysettings.getMaskAtom
+               getProfileMaskAtom = self.mysettings.getProfileMaskAtom
                for cpv in mylist:
                        try:
-                               myslot = self.aux_get(cpv, ["SLOT"])[0]
+                               metadata = dict(izip(db_keys, self.aux_get(cpv, db_keys)))
                        except KeyError:
                                # masked by corruption
                                continue
-                       cpv_slots.append("%s:%s" % (cpv, myslot))
-
-               if cpv_slots:
-                       mask_atoms = self.mysettings.pmaskdict.get(mycp)
-                       if mask_atoms:
-                               unmask_atoms = self.mysettings.punmaskdict.get(mycp)
-                               for x in mask_atoms:
-                                       masked_pkgs = match_from_list(x, cpv_slots)
-                                       if not masked_pkgs:
-                                               continue
-                                       if unmask_atoms:
-                                               for y in unmask_atoms:
-                                                       unmasked_pkgs = match_from_list(y, masked_pkgs)
-                                                       if unmasked_pkgs:
-                                                               masked_pkgs = [pkg for pkg in masked_pkgs \
-                                                                       if pkg not in unmasked_pkgs]
-                                                               if not masked_pkgs:
-                                                                       break
-                                       if masked_pkgs:
-                                               cpv_slots = [pkg for pkg in cpv_slots \
-                                                       if pkg not in masked_pkgs]
-                                               if not cpv_slots:
-                                                       break
-
-               if cpv_slots:
-                       profile_atoms = self.mysettings.prevmaskdict.get(mycp)
-                       if profile_atoms:
-                               for x in profile_atoms:
-                                       cpv_slots = match_from_list(x.lstrip("*"), cpv_slots)
-                                       if not cpv_slots:
-                                               break
-
-               if not cpv_slots:
-                       return cpv_slots
-
-               return [remove_slot(pkg) for pkg in cpv_slots]
+                       if getMaskAtom(cpv, metadata):
+                               continue
+                       if getProfileMaskAtom(cpv, metadata):
+                               continue
+                       visible.append(cpv)
+               return visible
 
        def gvisible(self,mylist):
                "strip out group-masked (not in current group) entries"
@@ -661,20 +627,12 @@ class portdbapi(dbapi):
                if mylist is None:
                        return []
                newlist=[]
-
-               accept_keywords = self.mysettings["ACCEPT_KEYWORDS"].split()
-               pkgdict = self.mysettings.pkeywordsdict
-               aux_keys = ["KEYWORDS", "LICENSE", "EAPI", "SLOT"]
-
-               # Hack: Need to check the env directly here as otherwise stacking 
-               # doesn't work properly as negative values are lost in the config
-               # object (bug #139600)
-               egroups = self.mysettings.configdict["backupenv"].get(
-                       "ACCEPT_KEYWORDS", "").split()
-
+               aux_keys = ["IUSE", "KEYWORDS", "LICENSE", "EAPI", "SLOT"]
+               metadata = {}
                for mycpv in mylist:
+                       metadata.clear()
                        try:
-                               keys, licenses, eapi, slot = self.aux_get(mycpv, aux_keys)
+                               metadata.update(izip(aux_keys, self.aux_get(mycpv, aux_keys)))
                        except KeyError:
                                continue
                        except PortageException, e:
@@ -683,66 +641,22 @@ class portdbapi(dbapi):
                                writemsg("!!! %s\n" % str(e), noiselevel=-1)
                                del e
                                continue
-                       mygroups = keys.split()
-                       # Repoman may modify this attribute as necessary.
-                       pgroups = accept_keywords[:]
-                       match=0
-                       cp = dep_getkey(mycpv)
-                       if pkgdict.has_key(cp):
-                               cpv_slot = "%s:%s" % (mycpv, slot)
-                               matches = match_to_list(cpv_slot, pkgdict[cp].keys())
-                               for atom in matches:
-                                       pgroups.extend(pkgdict[cp][atom])
-                               pgroups.extend(egroups)
-                               if matches:
-                                       # normalize pgroups with incrementals logic so it 
-                                       # matches ACCEPT_KEYWORDS behavior
-                                       inc_pgroups = []
-                                       for x in pgroups:
-                                               if x == "-*":
-                                                       inc_pgroups = []
-                                               elif x[0] == "-":
-                                                       try:
-                                                               inc_pgroups.remove(x[1:])
-                                                       except ValueError:
-                                                               pass
-                                               elif x not in inc_pgroups:
-                                                       inc_pgroups.append(x)
-                                       pgroups = inc_pgroups
-                                       del inc_pgroups
-                       hasstable = False
-                       hastesting = False
-                       for gp in mygroups:
-                               if gp == "*" or (gp == "-*" and len(mygroups) == 1):
-                                       writemsg("--- WARNING: Package '%s' uses '%s' keyword.\n" % (mycpv, gp),
-                                               noiselevel=-1)
-                                       if gp == "*":
-                                               match = 1
-                                               break
-                               elif gp in pgroups:
-                                       match=1
-                                       break
-                               elif gp[0] == "~":
-                                       hastesting = True
-                               elif gp[0] != "-":
-                                       hasstable = True
-                       if not match and ((hastesting and "~*" in pgroups) or (hasstable and "*" in pgroups) or "**" in pgroups):
-                               match=1
-                       use = ""
-                       if "?" in licenses:
-                               self.doebuild_settings.setcpv(mycpv, mydb=self)
-                               use = self.doebuild_settings.get("USE", "")
+                       if not eapi_is_supported(metadata["EAPI"]):
+                               continue
+                       if self.mysettings.getMissingKeywords(mycpv, metadata):
+                               continue
+                       metadata["USE"] = ""
+                       if "?" in metadata["LICENSE"]:
+                               self.doebuild_settings.setcpv(mycpv, mydb=metadata)
+                               metadata["USE"] = self.doebuild_settings.get("USE", "")
                        try:
-                               if self.mysettings.getMissingLicenses(mycpv,
-                                       {"LICENSE":licenses, "SLOT":slot, "USE":use}):
-                                       match = 0
+                               if self.mysettings.getMissingLicenses(mycpv, metadata):
+                                       continue
                        except InvalidDependString:
-                               match = 0
-                       if match and eapi_is_supported(eapi):
-                               newlist.append(mycpv)
+                               continue
+                       newlist.append(mycpv)
                return newlist
 
-
 def close_portdbapi_caches():
        for i in portdbapi.portdbapi_instances:
                i.close_caches()