summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pym/portage/__init__.py76
-rw-r--r--pym/portage/dbapi/porttree.py82
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()