self.verbose = verbose
self.searchdesc = searchdesc
self.setconfig = root_config.setconfig
- _portdb = root_config.trees["porttree"].dbapi
- if _portdb._have_root_eclass_dir:
- self.portdb = _portdb
- else:
- def fake_portdb():
- pass
- self.portdb = fake_portdb
- self._dbs = [root_config.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 = root_config.trees["porttree"].dbapi
+ bindb = root_config.trees["bintree"].dbapi
+ vardb = root_config.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()
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)
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"""
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]:
full_package = None
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" % \
except SystemExit, e:
raise # Needed else can't exit
except Exception, e:
- print >> sys.stderr, "\n\n!!! Problem in '%s' dependencies." % mykey
+ print >> sys.stderr, "\n\n!!! Problem in '%s' dependencies." % atom
print >> sys.stderr, "!!!", str(e), getattr(e, "__module__", None)
raise
return myaction, myopts, myfiles
def validate_ebuild_environment(trees):
- pass
+ for myroot in trees:
+ settings = trees[myroot]["vartree"].settings
+ settings.validate()
def load_emerge_config(trees=None):
kwargs = {}
abs_profile_path = os.path.join(self["PORTAGE_CONFIGROOT"],
PROFILE_PATH.lstrip(os.path.sep))
- if not os.path.islink(abs_profile_path) and \
+ if not self.profile_path or (not os.path.islink(abs_profile_path) and \
not os.path.exists(os.path.join(abs_profile_path, "parent")) and \
- os.path.exists(os.path.join(self["PORTDIR"], "profiles")):
+ os.path.exists(os.path.join(self["PORTDIR"], "profiles"))):
writemsg("\a\n\n!!! %s is not a symlink and will probably prevent most merges.\n" % abs_profile_path,
noiselevel=-1)
writemsg("!!! It should point into a profile within %s/profiles/\n" % self["PORTDIR"])
# * Masked flags, such as those from {,package}use.mask
# * Forced flags, such as those from {,package}use.force
# * build and bootstrap flags used by bootstrap.sh
+ # * The "test" flag that's enabled by FEATURES=test
# Do this even when there's no package since setcpv() can
# optimize away regenerate() calls.
# build and bootstrap flags used by bootstrap.sh
iuse_implicit.add("build")
iuse_implicit.add("bootstrap")
+ iuse_implicit.add("test")
# prefix flag is used in Prefix
iuse_implicit.add("prefix")
fd_pipes = keywords.get("fd_pipes")
if fd_pipes is None:
- fd_pipes = {0:0, 1:1, 2:2}
+ fd_pipes = {
+ 0:sys.stdin.fileno(),
+ 1:sys.stdout.fileno(),
+ 2:sys.stderr.fileno(),
+ }
# In some cases the above print statements don't flush stdout, so
# it needs to be flushed before allowing a child process to use it
# so that output always shows in the correct order.
if avail_pkg:
avail_slot = "%s:%s" % (dep_getkey(atom),
mydbapi.aux_get(avail_pkg, ["SLOT"])[0])
- elif not avail_pkg and \
- (use_binaries or not mydbapi.cp_list(dep_getkey(atom))):
- # With --usepkgonly, count installed packages as "available".
- # Note that --usepkgonly currently has no package.mask support.
- # See bug #149816.
- avail_pkg = best(vardb.match(atom))
- if avail_pkg:
- avail_slot = "%s:%s" % (dep_getkey(atom),
- vardb.aux_get(avail_pkg, ["SLOT"])[0])
+ elif not avail_pkg:
+ has_mask = False
+ if hasattr(mydbapi, "xmatch"):
+ has_mask = bool(mydbapi.xmatch("match-all", atom))
+ if (use_binaries or not has_mask):
+ avail_pkg = best(vardb.match(atom))
+ if avail_pkg:
+ avail_slot = "%s:%s" % (dep_getkey(atom),
+ vardb.aux_get(avail_pkg, ["SLOT"])[0])
if not avail_pkg:
all_available = False
break
settings = config(config_root=config_root, target_root=target_root,
config_incrementals=portage.const.INCREMENTALS)
settings.lock()
- settings.validate()
myroots = [(settings["ROOT"], settings)]
if settings["ROOT"] != "/":
backupenv.pop(k, None)
settings.regenerate()
settings.lock()
- settings.validate()
myroots.append((settings["ROOT"], settings))
for myroot, mysettings in myroots: