summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-09-30 21:25:28 +0000
committerZac Medico <zmedico@gentoo.org>2007-09-30 21:25:28 +0000
commitef019ad47d51df02deccb780f135d01e3314eab9 (patch)
tree3a5984747d149d000877cee78e4657085124ad97
parent6eeb6fd8c40df09d0c5d462c5fa91e8e7b273b40 (diff)
downloadportage-ef019ad47d51df02deccb780f135d01e3314eab9.tar.gz
portage-ef019ad47d51df02deccb780f135d01e3314eab9.tar.bz2
portage-ef019ad47d51df02deccb780f135d01e3314eab9.zip
Reimplement portdbapi.visible() so that is works without
using self.xmatch(). This should be 100% compatible with the previous implementation and have comparable performance. By eliminating the xmatch() dependency, the code becomes more generically usable, like for visibility filtering of binary packages. It seems that it will be necessary to move this code outside of the dbapi since visiblity filtering is really a resolver level function and to solve things like bug #88613 will require a more flexible approach. since the current internal svn path=/main/trunk/; revision=7892
-rw-r--r--pym/portage/dbapi/porttree.py96
1 files changed, 51 insertions, 45 deletions
diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index 357b17232..dc54efe5c 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -7,7 +7,7 @@ from portage.const import REPO_NAME_LOC
from portage.data import portage_gid, secpass
from portage.dbapi import dbapi
from portage.dep import use_reduce, paren_reduce, dep_getslot, dep_getkey, \
- match_from_list, match_to_list
+ match_from_list, match_to_list, remove_slot
from portage.exception import OperationNotPermitted, PortageException, \
UntrustedSignature, SecurityViolation, InvalidSignature, MissingSignature, \
FileNotFound, InvalidDependString
@@ -585,54 +585,60 @@ class portdbapi(dbapi):
"""two functions in one. Accepts a list of cpv values and uses the package.mask *and*
packages file to remove invisible entries, returning remaining items. This function assumes
that all entries in mylist have the same category and package name."""
- if (mylist is None) or (len(mylist) == 0):
+ if not mylist:
return []
- newlist = mylist[:]
- #first, we mask out packages in the package.mask file
- mykey = newlist[0]
- cpv = catpkgsplit(mykey)
- if not cpv:
+
+ mysplit = catpkgsplit(mylist[0])
+ if not mysplit:
#invalid cat/pkg-v
- print "visible(): invalid cat/pkg-v:", mykey
+ writemsg("visible(): invalid cat/pkg-v: %s\n" % (mylist[0], ),
+ noiselevel=-1)
return []
- mycp = cpv[0] + "/" + cpv[1]
- maskdict = self.mysettings.pmaskdict
- unmaskdict = self.mysettings.punmaskdict
- if maskdict.has_key(mycp):
- for x in maskdict[mycp]:
- mymatches = self.xmatch("match-all", x)
- if mymatches is None:
- #error in package.mask file; print warning and continue:
- print "visible(): package.mask entry \"" + x + "\" is invalid, ignoring..."
- continue
- for y in mymatches:
- unmask = 0
- if unmaskdict.has_key(mycp):
- for z in unmaskdict[mycp]:
- mymatches_unmask = self.xmatch("match-all",z)
- if y in mymatches_unmask:
- unmask = 1
- break
- if unmask == 0:
- try:
- newlist.remove(y)
- except ValueError:
- pass
-
- profile_atoms = self.mysettings.prevmaskdict.get(mycp)
- if profile_atoms:
- for x in profile_atoms:
- #important: only match against the still-unmasked entries...
- #notice how we pass "newlist" to the xmatch() call below....
- #Without this, ~ deps in the packages files are broken.
- mymatches=self.xmatch("match-list",x,mylist=newlist)
- if mymatches is None:
- #error in packages file; print warning and continue:
- print "emerge: visible(): profile packages entry \""+x+"\" is invalid, ignoring..."
- continue
- newlist = [cpv for cpv in newlist if cpv in mymatches]
+ mycp = "%s/%s" % (mysplit[0], mysplit[1])
- return newlist
+ cpv_slots = []
+ for cpv in mylist:
+ try:
+ myslot = self.aux_get(cpv, ["SLOT"])[0]
+ 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]
def gvisible(self,mylist):
"strip out group-masked (not in current group) entries"