summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-05-25 03:59:35 +0000
committerZac Medico <zmedico@gentoo.org>2008-05-25 03:59:35 +0000
commit6c6ac86ee1505015bd5f671e4ae6cdad8d7b53c1 (patch)
tree122325584e45e0e748844c12608b8c81c3781cc8
parentddfd90ccf7aa26c18c29d8aa82c38f384fe3b9a6 (diff)
downloadportage-6c6ac86ee1505015bd5f671e4ae6cdad8d7b53c1.tar.gz
portage-6c6ac86ee1505015bd5f671e4ae6cdad8d7b53c1.tar.bz2
portage-6c6ac86ee1505015bd5f671e4ae6cdad8d7b53c1.zip
Merge the Atom class and dbapi._iter_match() from trunk r10387 and r10394.
Everything related to USE deps has been omitted for now. svn path=/main/branches/2.1.2/; revision=10403
-rwxr-xr-xbin/emerge3
-rwxr-xr-xbin/repoman1
-rw-r--r--pym/portage.py102
-rw-r--r--pym/portage_dep.py44
4 files changed, 98 insertions, 52 deletions
diff --git a/bin/emerge b/bin/emerge
index fbc797a33..dafb3bb66 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -3044,7 +3044,8 @@ class depgraph(object):
# List of acceptable packages, ordered by type preference.
matched_packages = []
highest_version = None
- atom_cp = portage.dep_getkey(atom)
+ atom = portage_dep.Atom(atom)
+ atom_cp = atom.cp
existing_node = None
myeb = None
usepkgonly = "--usepkgonly" in self.myopts
diff --git a/bin/repoman b/bin/repoman
index f1735dc42..9f48a1536 100755
--- a/bin/repoman
+++ b/bin/repoman
@@ -1709,6 +1709,7 @@ for x in scanlist:
is_blocker = atom.startswith("!")
if is_blocker:
atom = token.lstrip("!")
+ atom = portage_dep.Atom(atom)
if mytype == "DEPEND" and \
not is_blocker and \
not inherited_java_eclass and \
diff --git a/pym/portage.py b/pym/portage.py
index 75301819b..a4f17a234 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -5725,8 +5725,15 @@ def dep_expand(mydep, mydb=None, use_cache=1, settings=None):
myindex = orig_dep.index(mydep)
prefix = orig_dep[:myindex]
postfix = orig_dep[myindex+len(mydep):]
- return prefix + cpv_expand(
- mydep, mydb=mydb, use_cache=use_cache, settings=settings) + postfix
+ expanded = cpv_expand(mydep, mydb=mydb,
+ use_cache=use_cache, settings=settings)
+ try:
+ return portage_dep.Atom(prefix + expanded + postfix)
+ except portage.exception.InvalidAtom:
+ # Missing '=' prefix is allowed for backward compatibility.
+ if not isvalidatom("=" + prefix + expanded + postfix):
+ raise
+ return portage_dep.Atom("=" + prefix + expanded + postfix)
def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None,
use_cache=1, use_binaries=0, myroot="/", trees=None):
@@ -6288,15 +6295,29 @@ class dbapi(object):
'return: ["0",">=sys-libs/bar-1.0","http://www.foo.com"] or [] if mycpv not found'
raise NotImplementedError
- def match(self,origdep,use_cache=1):
+ def match(self, origdep, use_cache=1):
+ """Given a dependency, try to find packages that match
+ Args:
+ origdep - Depend atom
+ use_cache - Boolean indicating if we should use the cache or not
+ NOTE: Do we ever not want the cache?
+ Returns:
+ a list of packages that match origdep
+ """
mydep = dep_expand(origdep, mydb=self, settings=self.settings)
- mykey=dep_getkey(mydep)
- mylist = match_from_list(mydep,self.cp_list(mykey,use_cache=use_cache))
- myslot = portage_dep.dep_getslot(mydep)
- if myslot is not None:
- mylist = [cpv for cpv in mylist \
- if self.aux_get(cpv, ["SLOT"])[0] == myslot]
- return mylist
+ return list(self._iter_match(mydep,
+ self.cp_list(mydep.cp, use_cache=use_cache)))
+
+ def _iter_match(self, atom, cpv_iter):
+ cpv_iter = match_from_list(atom, cpv_iter)
+ if atom.slot:
+ cpv_iter = self._iter_match_slot(atom, cpv_iter)
+ return cpv_iter
+
+ def _iter_match_slot(self, atom, cpv_iter):
+ for cpv in cpv_iter:
+ if self.aux_get(cpv, ["SLOT"])[0] == atom.slot:
+ yield cpv
def match2(self,mydep,mykey,mylist):
writemsg("DEPRECATED: dbapi.match2\n")
@@ -6795,13 +6816,8 @@ class vardbapi(dbapi):
if self.matchcache.has_key(mycat):
del self.mtdircache[mycat]
del self.matchcache[mycat]
- mymatch = match_from_list(mydep,
- self.cp_list(mykey, use_cache=use_cache))
- myslot = portage_dep.dep_getslot(mydep)
- if myslot is not None:
- mymatch = [cpv for cpv in mymatch \
- if self.aux_get(cpv, ["SLOT"])[0] == myslot]
- return mymatch
+ return list(self._iter_match(mydep,
+ self.cp_list(mydep.cp, use_cache=use_cache)))
try:
curmtime=os.stat(self.root+VDB_PATH+"/"+mycat)[stat.ST_MTIME]
except (IOError, OSError):
@@ -6812,11 +6828,8 @@ class vardbapi(dbapi):
self.mtdircache[mycat]=curmtime
self.matchcache[mycat]={}
if not self.matchcache[mycat].has_key(mydep):
- mymatch=match_from_list(mydep,self.cp_list(mykey,use_cache=use_cache))
- myslot = portage_dep.dep_getslot(mydep)
- if myslot is not None:
- mymatch = [cpv for cpv in mymatch \
- if self.aux_get(cpv, ["SLOT"])[0] == myslot]
+ mymatch = list(self._iter_match(mydep,
+ self.cp_list(mydep.cp, use_cache=use_cache)))
self.matchcache[mycat][mydep]=mymatch
return self.matchcache[mycat][mydep][:]
@@ -7819,22 +7832,14 @@ class portdbapi(dbapi):
# Find the minimum matching version. This is optimized to
# minimize the number of metadata accesses (improves performance
# especially in cases where metadata needs to be generated).
- if mydep == mykey:
- mylist = self.cp_list(mykey)
- else:
- mylist = match_from_list(mydep, self.cp_list(mykey))
+ cpv_iter = iter(self.cp_list(mykey))
+ if mydep != mykey:
+ cpv_iter = self._iter_match(mydep, cpv_iter)
myval = ""
- if mylist:
- if myslot is None:
- myval = mylist[0]
- else:
- for cpv in mylist:
- try:
- if self.aux_get(cpv, ["SLOT"])[0] == myslot:
- myval = cpv
- break
- except KeyError:
- pass # ebuild masked by corruption
+ for cpv in cpv_iter:
+ myval = cpv
+ break
+
elif level in ("minimum-visible", "bestmatch-visible"):
# Find the minimum matching visible version. This is optimized to
# minimize the number of metadata accesses (improves performance
@@ -7870,24 +7875,27 @@ class portdbapi(dbapi):
continue
myval = cpv
break
- elif level=="bestmatch-list":
+ elif level == "bestmatch-list":
#dep match -- find best match but restrict search to sublist
- myval=best(match_from_list(mydep,mylist))
- #no point is calling xmatch again since we're not caching list deps
- elif level=="match-list":
+ #no point in calling xmatch again since we're not caching list deps
+
+ myval = best(list(self._iter_match(mydep, mylist)))
+ elif level == "match-list":
#dep match -- find all matches but restrict search to sublist (used in 2nd half of visible())
- myval=match_from_list(mydep,mylist)
- elif level=="match-visible":
+
+ myval = list(self._iter_match(mydep, mylist))
+ elif level == "match-visible":
#dep match -- find all visible matches
- myval = match_from_list(mydep,
- self.xmatch("list-visible", mykey, mydep=mykey, mykey=mykey))
#get all visible packages, then get the matching ones
- elif level=="match-all":
+
+ myval = list(self._iter_match(mydep,
+ self.xmatch("list-visible", mykey, mydep=mykey, mykey=mykey)))
+ elif level == "match-all":
#match *all* visible *and* masked packages
if mydep == mykey:
myval = self.cp_list(mykey)
else:
- myval = match_from_list(mydep, self.cp_list(mykey))
+ myval = list(self._iter_match(mydep, self.cp_list(mykey)))
else:
print "ERROR: xmatch doesn't handle",level,"query!"
raise KeyError
diff --git a/pym/portage_dep.py b/pym/portage_dep.py
index bad51b646..26737d618 100644
--- a/pym/portage_dep.py
+++ b/pym/portage_dep.py
@@ -20,7 +20,7 @@
import re, sys, types
import portage_exception
-from portage_exception import InvalidData
+from portage_exception import InvalidAtom, InvalidData
from portage_versions import catpkgsplit, catsplit, pkgcmp, pkgsplit, ververify
def cpvequal(cpv1, cpv2):
@@ -274,6 +274,20 @@ def dep_opconvert(deplist):
x += 1
return retlist
+class Atom(str):
+
+ def __init__(self, s):
+ str.__init__(self, s)
+ if not isvalidatom(s, allow_blockers=True):
+ raise InvalidAtom(s)
+ self.blocker = "!" == s[:1]
+ if self.blocker:
+ s = s[1:]
+ self.cp = dep_getkey(s)
+ self.cpv = dep_getcpv(s)
+ self.slot = dep_getslot(s)
+ self.operator = get_operator(s)
+
def get_operator(mydep):
"""
Return the operator used in a depstring.
@@ -289,6 +303,9 @@ def get_operator(mydep):
@return: The operator. One of:
'~', '=', '>', '<', '=*', '>=', or '<='
"""
+ operator = getattr(mydep, "operator", None)
+ if operator is not None:
+ return operator
if mydep:
mydep = remove_slot(mydep)
if not mydep:
@@ -325,6 +342,9 @@ def dep_getcpv(mydep):
@rtype: String
@return: The depstring with the operator removed
"""
+ cpv = getattr(mydep, "cpv", None)
+ if cpv is not None:
+ return cpv
global _dep_getcpv_cache
retval = _dep_getcpv_cache.get(mydep, None)
if retval is not None:
@@ -358,13 +378,20 @@ def dep_getslot(mydep):
@rtype: String
@return: The slot
"""
- colon = mydep.rfind(":")
+ slot = getattr(mydep, "slot", None)
+ if slot is not None:
+ return slot
+ colon = mydep.find(":")
if colon != -1:
return mydep[colon+1:]
return None
def remove_slot(mydep):
- colon = mydep.rfind(":")
+ """
+ Removes dep components from the right side of an atom:
+ * slot
+ """
+ colon = mydep.find(":")
if colon != -1:
mydep = mydep[:colon]
return mydep
@@ -389,6 +416,10 @@ def isvalidatom(atom, allow_blockers=False):
1) 0 if the atom is invalid
2) 1 if the atom is valid
"""
+ if isinstance(atom, Atom):
+ if atom.blocker and not allow_blockers:
+ return 0
+ return 1
global _invalid_atom_chars_regexp
if _invalid_atom_chars_regexp.search(atom):
return 0
@@ -490,6 +521,9 @@ def dep_getkey(mydep):
@rtype: String
@return: The package category/package-version
"""
+ cp = getattr(mydep, "cp", None)
+ if cp is not None:
+ return cp
mydep = dep_getcpv(mydep)
if mydep and isspecific(mydep):
mysplit = catpkgsplit(mydep)
@@ -565,8 +599,10 @@ def match_from_list(mydep, candidate_list):
"""
from portage_util import writemsg
- if mydep[0] == "!":
+ if "!" == mydep[:1]:
mydep = mydep[1:]
+ if not isinstance(mydep, Atom):
+ mydep = Atom(mydep)
mycpv = dep_getcpv(mydep)
mycpv_cps = catpkgsplit(mycpv) # Can be None if not specific