summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-05-25 21:34:21 +0000
committerZac Medico <zmedico@gentoo.org>2008-05-25 21:34:21 +0000
commit6a744a27d3cbb6d1533f7df1a915cccd25e33e75 (patch)
treeb6c8fb29e89182cda8f92c05b0c73330aa39ebde
parente6065abf1b1c07f78cf93cb6cde7fd7d4ec15dad (diff)
downloadportage-6a744a27d3cbb6d1533f7df1a915cccd25e33e75.tar.gz
portage-6a744a27d3cbb6d1533f7df1a915cccd25e33e75.tar.bz2
portage-6a744a27d3cbb6d1533f7df1a915cccd25e33e75.zip
* Add support for Package instances and USE deps in match_from_list().
* Add USE dep matching support to depgraph._iter_atoms_for_pkg(). svn path=/main/trunk/; revision=10419
-rw-r--r--pym/_emerge/__init__.py70
-rw-r--r--pym/portage/dep.py51
-rw-r--r--pym/portage/sets/base.py4
3 files changed, 100 insertions, 25 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index 2616c1be7..1d3fc5f76 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -1268,7 +1268,8 @@ class Package(Task):
__slots__ = ("built", "cpv", "depth",
"installed", "metadata", "onlydeps", "operation",
"root", "type_name",
- "category", "cp", "cpv_slot", "pf", "pv_split", "slot_atom")
+ "category", "cp", "cpv_slot", "cpv_split",
+ "pf", "pv_split", "slot", "slot_atom", "use")
metadata_keys = [
"CHOST", "COUNTER", "DEPEND", "EAPI", "IUSE", "KEYWORDS",
@@ -1277,11 +1278,43 @@ class Package(Task):
def __init__(self, **kwargs):
Task.__init__(self, **kwargs)
+ self.metadata = self._metadata_wrapper(self, self.metadata)
self.cp = portage.cpv_getkey(self.cpv)
- self.slot_atom = "%s:%s" % (self.cp, self.metadata["SLOT"])
- self.cpv_slot = "%s:%s" % (self.cpv, self.metadata["SLOT"])
+ self.slot = self.metadata["SLOT"]
+ self.slot_atom = portage.dep.Atom("%s:%s" % \
+ (self.cp, self.metadata["SLOT"]))
+
+ # This used to be "%s:%s" % (self.cpv, self.slot) but now
+ # is's just a reference to self since match_from_list()
+ # now supports Package references.
+ self.cpv_slot = self
+
self.category, self.pf = portage.catsplit(self.cpv)
- self.pv_split = portage.catpkgsplit(self.cpv)[1:]
+ self.cpv_split = portage.catpkgsplit(self.cpv)
+ self.pv_split = self.cpv_split[1:]
+ self.use = self._use(self.metadata["USE"].split())
+
+ class _use(object):
+ def __init__(self, use):
+ self.enabled = frozenset(use)
+
+ class _metadata_wrapper(dict):
+ """
+ Detect metadata updates and synchronize Package attributes.
+ """
+ def __init__(self, pkg, metadata):
+ dict.__init__(self, metadata.iteritems())
+ self._pkg = pkg
+
+ def __setitem__(self, k, v):
+ dict.__setitem__(self, k, v)
+ if k == "USE":
+ self._pkg.use = self._pkg._use(v.split())
+
+ def _metadata_setitem(self, k, v):
+ self._metadata_setitem_orig(k, v)
+ if k == "USE":
+ self.use = self._use(self)
def _get_hash_key(self):
hash_key = getattr(self, "_hash_key", None)
@@ -3035,18 +3068,7 @@ class depgraph(object):
installed=installed, metadata=metadata,
onlydeps=onlydeps, root=root, type_name=pkg_type)
self._pkg_cache[pkg] = pkg
- myarg = None
- if root == self.target_root:
- try:
- myarg = self._iter_atoms_for_pkg(pkg).next()
- except StopIteration:
- pass
- except portage.exception.InvalidDependString:
- if not installed:
- # masked by corruption
- continue
- if not installed and myarg:
- found_available_arg = True
+
if not installed or (installed and matched_packages):
# Only enforce visibility on installed packages
# if there is at least one other visible package
@@ -3085,6 +3107,22 @@ class depgraph(object):
# it's expensive.
pkgsettings.setcpv(cpv, mydb=pkg.metadata)
pkg.metadata["USE"] = pkgsettings["PORTAGE_USE"]
+
+ myarg = None
+ if root == self.target_root:
+ try:
+ # Ebuild USE must have been calculated prior
+ # to this point, in case atoms have USE deps.
+ myarg = self._iter_atoms_for_pkg(pkg).next()
+ except StopIteration:
+ pass
+ except portage.exception.InvalidDependString:
+ if not installed:
+ # masked by corruption
+ continue
+ if not installed and myarg:
+ found_available_arg = True
+
if atom.use and not pkg.built:
use = pkg.metadata["USE"].split()
if atom.use.enabled.difference(use):
diff --git a/pym/portage/dep.py b/pym/portage/dep.py
index 75d4f4c47..ae6363d07 100644
--- a/pym/portage/dep.py
+++ b/pym/portage/dep.py
@@ -759,6 +759,9 @@ def match_from_list(mydep, candidate_list):
@return: A list of package atoms that match the given package atom
"""
+ if not candidate_list:
+ return []
+
from portage.util import writemsg
if "!" == mydep[:1]:
mydep = mydep[1:]
@@ -791,13 +794,21 @@ def match_from_list(mydep, candidate_list):
if operator is None:
for x in candidate_list:
- if dep_getkey(x) != mycpv:
+ cp = getattr(x, "cp", None)
+ if cp is None:
+ cp = dep_getkey(x)
+ if cp != mycpv:
continue
mylist.append(x)
elif operator == "=": # Exact match
- mylist = [cpv for cpv in candidate_list if \
- cpvequal(remove_slot(cpv), mycpv)]
+ for x in candidate_list:
+ xcpv = getattr(x, "cpv", None)
+ if xcpv is None:
+ xcpv = dep_getcpv(x)
+ if not cpvequal(xcpv, mycpv):
+ continue
+ mylist.append(x)
elif operator == "=*": # glob match
# XXX: Nasty special casing for leading zeros
@@ -809,7 +820,9 @@ def match_from_list(mydep, candidate_list):
myver = "0"+myver
mycpv = mysplit[0]+"/"+mysplit[1]+"-"+myver
for x in candidate_list:
- xs = catpkgsplit(remove_slot(x))
+ xs = getattr(x, "cpv_split", None)
+ if xs is None:
+ xs = catpkgsplit(remove_slot(x))
myver = xs[2].lstrip("0")
if not myver or not myver[0].isdigit():
myver = "0"+myver
@@ -819,7 +832,9 @@ def match_from_list(mydep, candidate_list):
elif operator == "~": # version, any revision, match
for x in candidate_list:
- xs = catpkgsplit(remove_slot(x))
+ xs = getattr(x, "cpv_split", None)
+ if xs is None:
+ xs = catpkgsplit(remove_slot(x))
if xs is None:
raise InvalidData(x)
if not cpvequal(xs[0]+"/"+xs[1]+"-"+xs[2], mycpv_cps[0]+"/"+mycpv_cps[1]+"-"+mycpv_cps[2]):
@@ -831,8 +846,13 @@ def match_from_list(mydep, candidate_list):
elif operator in [">", ">=", "<", "<="]:
mysplit = ["%s/%s" % (cat, pkg), ver, rev]
for x in candidate_list:
+ xs = getattr(x, "cpv_split", None)
+ if xs is None:
+ xs = catpkgsplit(remove_slot(x))
+ xcat, xpkg, xver, xrev = xs
+ xs = ["%s/%s" % (xcat, xpkg), xver, xrev]
try:
- result = pkgcmp(pkgsplit(remove_slot(x)), mysplit)
+ result = pkgcmp(xs, mysplit)
except ValueError: # pkgcmp may return ValueError during int() conversion
writemsg("\nInvalid package name: %s\n" % x, noiselevel=-1)
raise
@@ -859,9 +879,26 @@ def match_from_list(mydep, candidate_list):
candidate_list = mylist
mylist = []
for x in candidate_list:
- xslot = dep_getslot(x)
+ xslot = getattr(x, "slot", None)
+ if xslot is None and isinstance(x, basestring):
+ xslot = dep_getslot(x)
if xslot is not None and xslot != slot:
continue
mylist.append(x)
+ if mydep.use:
+ candidate_list = mylist
+ mylist = []
+ for x in candidate_list:
+ # Note: IUSE intersection is neglected here since there
+ # is currently no way to access implicit IUSE. However, IUSE
+ # filtering can be added elsewhere in the chain.
+ use = getattr(x, "use", None)
+ if use is not None:
+ if mydep.use.enabled.difference(use.enabled):
+ continue
+ if mydep.use.disabled.intersection(use.enabled):
+ continue
+ mylist.append(x)
+
return mylist
diff --git a/pym/portage/sets/base.py b/pym/portage/sets/base.py
index ac77e95c3..3f85965bc 100644
--- a/pym/portage/sets/base.py
+++ b/pym/portage/sets/base.py
@@ -108,7 +108,7 @@ class PackageSet(object):
atoms = list(self.iterAtomsForPackage(pkg))
if not atoms:
return None
- return best_match_to_list(pkg.cpv_slot, atoms)
+ return best_match_to_list(pkg, atoms)
def iterAtomsForPackage(self, pkg):
"""
@@ -116,7 +116,7 @@ class PackageSet(object):
arguments against the PROVIDE metadata. This will raise an
InvalidDependString exception if PROVIDE is invalid.
"""
- cpv_slot_list = ["%s:%s" % (pkg.cpv, pkg.metadata["SLOT"])]
+ cpv_slot_list = [pkg]
cp = cpv_getkey(pkg.cpv)
self._load() # make sure the atoms are loaded
atoms = self._atommap.get(cp)