From 2e5858fb04d5ce4c110f9d9264ceacc125a7786a Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Fri, 21 Dec 2007 10:26:34 +0000 Subject: 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 --- bin/emerge | 121 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 26 deletions(-) (limited to 'bin/emerge') 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" % \ -- cgit v1.2.3-1-g7c22