diff options
-rw-r--r-- | pym/portage/__init__.py | 76 | ||||
-rw-r--r-- | pym/portage/dbapi/porttree.py | 82 |
2 files changed, 91 insertions, 67 deletions
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 760819f41..84548e3ab 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -1834,6 +1834,82 @@ class config(object): if has_changed: self.reset(keeping_pkg=1,use_cache=use_cache) + 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 diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 3990a827e..f794f23d9 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)""" @@ -661,20 +661,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() - + 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 +675,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: + 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=self) - use = self.doebuild_settings.get("USE", "") + 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() |