From a4afa723a8eb1f1e0ab22ac6a8ffcdcd7ba2c40f Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Mon, 8 Oct 2007 17:33:36 +0000 Subject: [PATCH] Merged from trunk 7994:8001 | 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 | 15 ++-- pym/portage/__init__.py | 152 +++++++++++++++++++++++++++++++++- pym/portage/dbapi/porttree.py | 146 +++++++------------------------- 3 files changed, 187 insertions(+), 126 deletions(-) diff --git a/bin/repoman b/bin/repoman index d7dcd075b..fa7749c12 100755 --- a/bin/repoman +++ b/bin/repoman @@ -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") diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index e29e15338..05e23ad88 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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 diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 3990a827e..ee8c4776d 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -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() -- 2.26.2