summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-12-21 10:26:34 +0000
committerZac Medico <zmedico@gentoo.org>2007-12-21 10:26:34 +0000
commit2e5858fb04d5ce4c110f9d9264ceacc125a7786a (patch)
treeb47337a8433f7365c5b34b0aec6f1754e184eb70 /bin
parent5928d901e485205d78ed72cb2631eada83a94db8 (diff)
downloadportage-2e5858fb04d5ce4c110f9d9264ceacc125a7786a.tar.gz
portage-2e5858fb04d5ce4c110f9d9264ceacc125a7786a.tar.bz2
portage-2e5858fb04d5ce4c110f9d9264ceacc125a7786a.zip
emerge --search enhancements:
* support for searching installed packages * visibility filtering for both installed and binary packages (trunk r9026:9029) svn path=/main/branches/2.1.2/; revision=9030
Diffstat (limited to 'bin')
-rwxr-xr-xbin/emerge121
1 files changed, 95 insertions, 26 deletions
diff --git a/bin/emerge b/bin/emerge
index a762968d3..cefdb76b1 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -402,17 +402,28 @@ class search:
self.spinner = spinner
self.verbose = verbose
self.searchdesc = searchdesc
- _portdb = trees["porttree"].dbapi
- if _portdb._have_root_eclass_dir:
- self.portdb = _portdb
- else:
- def fake_portdb():
- pass
- self.portdb = fake_portdb
- self._dbs = [trees["bintree"].dbapi]
- for attrib in ("aux_get", "cp_all",
- "xmatch", "findname", "getfetchlist"):
- setattr(fake_portdb, attrib, getattr(self, "_"+attrib))
+
+ def fake_portdb():
+ pass
+ self.portdb = fake_portdb
+ for attrib in ("aux_get", "cp_all",
+ "xmatch", "findname", "getfetchlist"):
+ setattr(fake_portdb, attrib, getattr(self, "_"+attrib))
+
+ self._dbs = []
+
+ portdb = trees["porttree"].dbapi
+ bindb = trees["bintree"].dbapi
+ vardb = trees["vartree"].dbapi
+
+ if portdb._have_root_eclass_dir:
+ self._dbs.append(portdb)
+
+ if bindb.cp_all():
+ self._dbs.append(bindb)
+
+ self._dbs.append(vardb)
+ self._portdb = portdb
def _cp_all(self):
cp_all = set()
@@ -430,6 +441,12 @@ class search:
def _findname(self, *args, **kwargs):
for db in self._dbs:
+ if db is not self._portdb:
+ # We don't want findname to return anything
+ # unless it's an ebuild in a portage tree.
+ # Otherwise, it's already built and we don't
+ # care about it.
+ continue
func = getattr(db, "findname", None)
if func:
value = func(*args, **kwargs)
@@ -444,30 +461,73 @@ class search:
value = func(*args, **kwargs)
if value:
return value
- return None
+ return [], []
+
+ def _visible(self, db, cpv, metadata):
+ installed = db is self.vartree.dbapi
+ built = installed or db is not self._portdb
+ return visible(self.settings, cpv, metadata,
+ built=built, installed=installed)
def _xmatch(self, level, atom):
- if level.startswith("bestmatch-"):
- matches = []
+ """
+ This method does not expand old-style virtuals because it
+ is restricted to returning matches for a single ${CATEGORY}/${PN}
+ and old-style virual matches unreliable for that when querying
+ multiple package databases. If necessary, old-style virtuals
+ can be performed on atoms prior to calling this method.
+ """
+ cp = portage.dep_getkey(atom)
+ if level == "match-all":
+ matches = set()
for db in self._dbs:
- bestmatch = None
if hasattr(db, "xmatch"):
- bestmatch = db.xmatch(level, atom)
+ matches.update(db.xmatch(level, atom))
else:
- bestmatch = portage.best(db.match(atom))
- if bestmatch:
- matches.append(bestmatch)
- return portage.best(matches)
- else:
+ matches.update(db.match(atom))
+ result = list(x for x in matches if portage.cpv_getkey(x) == cp)
+ db._cpv_sort_ascending(result)
+ elif level == "match-visible":
matches = set()
for db in self._dbs:
if hasattr(db, "xmatch"):
matches.update(db.xmatch(level, atom))
else:
- matches.update(db.match(atom))
- matches = list(matches)
- db._cpv_sort_ascending(matches)
- return matches
+ db_keys = list(db._aux_cache_keys)
+ for cpv in db.match(atom):
+ metadata = dict(izip(db_keys,
+ db.aux_get(cpv, db_keys)))
+ if not self._visible(db, cpv, metadata):
+ continue
+ matches.add(cpv)
+ result = list(x for x in matches if portage.cpv_getkey(x) == cp)
+ db._cpv_sort_ascending(result)
+ elif level == "bestmatch-visible":
+ result = None
+ for db in self._dbs:
+ if hasattr(db, "xmatch"):
+ cpv = db.xmatch("bestmatch-visible", atom)
+ if not cpv or portage.cpv_getkey(cpv) != cp:
+ continue
+ if not result or cpv == portage.best([cpv, result]):
+ result = cpv
+ else:
+ db_keys = list(db._aux_cache_keys)
+ # break out of this loop with highest visible
+ # match, checked in descending order
+ for cpv in reversed(db.match(atom)):
+ if portage.cpv_getkey(cpv) != cp:
+ continue
+ metadata = dict(izip(db_keys,
+ db.aux_get(cpv, db_keys)))
+ if not self._visible(db, cpv, metadata):
+ continue
+ if not result or cpv == portage.best([cpv, result]):
+ result = cpv
+ break
+ else:
+ raise NotImplementedError(level)
+ return result
def execute(self,searchkey):
"""Performs the search for the supplied search key"""
@@ -534,6 +594,7 @@ class search:
print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]"
print "[ Applications found : "+white(str(self.mlen))+" ]"
print " "
+ vardb = self.vartree.dbapi
for mtype in self.matches:
for match,masked in self.matches[mtype]:
if mtype=="pkg":
@@ -586,8 +647,16 @@ class search:
mysum[0] = "Unknown (missing digest for %s)" % \
str(e)
+ available = False
+ for db in self._dbs:
+ if db is not vardb and \
+ db.cpv_exists(mycpv):
+ available = True
+ break
+
if self.verbose:
- print " ", darkgreen("Latest version available:"),myversion
+ if available:
+ print " ", darkgreen("Latest version available:"),myversion
print " ", self.getInstallationStatus(mycat+'/'+mypkg)
if myebuild:
print " %s %s" % \