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)
+ pkg_type = "ebuild"
+ if installed:
+ pkg_type = "installed"
+ elif built:
+ pkg_type = "binary"
+ return visible(self.settings,
+ Package(type_name=pkg_type, root=self.settings["ROOT"],
+ cpv=cpv, built=built, installed=installed, metadata=metadata))
def _xmatch(self, level, atom):
"""
if updates:
mydb.aux_update(mycpv, updates)
-def visible(pkgsettings, cpv, metadata, built=False, installed=False):
+def visible(pkgsettings, pkg):
"""
Check if a package is visible. This can raise an InvalidDependString
exception if LICENSE is invalid.
@rtype: Boolean
@returns: True if the package is visible, False otherwise.
"""
- if not metadata["SLOT"]:
+ if not pkg.metadata["SLOT"]:
return False
- if built and not installed and \
- metadata["CHOST"] != pkgsettings["CHOST"]:
+ if pkg.built and not pkg.installed and \
+ pkg.metadata["CHOST"] != pkgsettings["CHOST"]:
return False
if built and not installed:
# we can have an old binary which has no EPREFIX information
- if "EPREFIX" not in metadata or not metadata["EPREFIX"]:
+ if "EPREFIX" not in pkg.metadata or not pkg.metadata["EPREFIX"]:
return False
- if len(metadata["EPREFIX"].strip()) < len(pkgsettings["EPREFIX"]):
+ if len(pkg.metadata["EPREFIX"].strip()) < len(pkgsettings["EPREFIX"]):
return False
- if not portage.eapi_is_supported(metadata["EAPI"]):
+ if not portage.eapi_is_supported(pkg.metadata["EAPI"]):
return False
- if not installed and pkgsettings.getMissingKeywords(cpv, metadata):
+ if not pkg.installed and \
+ pkgsettings.getMissingKeywords(pkg.cpv, pkg.metadata):
return False
- if pkgsettings.getMaskAtom(cpv, metadata):
+ if pkgsettings.getMaskAtom(pkg.cpv, pkg.metadata):
return False
- if pkgsettings.getProfileMaskAtom(cpv, metadata):
+ if pkgsettings.getProfileMaskAtom(pkg.cpv, pkg.metadata):
return False
- if pkgsettings.getMissingLicenses(cpv, metadata):
+ try:
+ if pkgsettings.getMissingLicenses(pkg.cpv, pkg.metadata):
+ return False
+ except portage.exception.InvalidDependString:
return False
return True
class Package(object):
__slots__ = ("__weakref__", "built", "cpv", "depth",
"installed", "metadata", "root", "onlydeps", "type_name",
- "cpv_slot", "slot_atom", "_digraph_node")
+ "cp", "cpv_slot", "slot_atom", "_digraph_node")
def __init__(self, **kwargs):
for myattr in self.__slots__:
if myattr == "__weakref__":
myvalue = kwargs.get(myattr, None)
setattr(self, myattr, myvalue)
- self.slot_atom = "%s:%s" % \
- (portage.cpv_getkey(self.cpv), self.metadata["SLOT"])
-
+ self.cp = portage.cpv_getkey(self.cpv)
+ self.slot_atom = "%s:%s" % (self.cp, self.metadata["SLOT"])
self.cpv_slot = "%s:%s" % (self.cpv, self.metadata["SLOT"])
status = "merge"
return 0
if pkg.installed:
- # Warn if all matching ebuilds are masked or
- # the installed package itself is masked. Do
- # not warn if there are simply no matching
- # ebuilds since that would be annoying in some
- # cases:
- #
- # - binary packages installed from an overlay
- # that is not listed in PORTDIR_OVERLAY
- #
- # - multi-slot atoms listed in the world file
- # to prevent depclean from removing them
-
- if arg_atoms:
- selective = "selective" in self.myparams
- portdb = self.trees[pkg.root]["porttree"].dbapi
- for arg, atom in arg_atoms:
- all_ebuilds_masked = bool(
- portdb.xmatch("match-all", atom) and
- not portdb.xmatch("bestmatch-visible", atom))
- if all_ebuilds_masked and not selective:
- self._missing_args.append((arg, atom))
-
- if not visible(pkgsettings, pkg.cpv, pkg.metadata,
- built=pkg.built, installed=pkg.installed):
+ # Warn if an installed package is masked and it
+ # is pulled into the graph.
+ if not visible(pkgsettings, pkg):
self._masked_installed.append((pkg, pkgsettings))
if args:
if pkg.installed and "selective" not in self.myparams:
self._unsatisfied_deps_for_display.append(
((myroot, atom), {}))
- return 0, myfavorites
+ # Previous behavior was to bail out in this case, but
+ # since the dep is satisfied by the installed package,
+ # it's more friendly to continue building the graph
+ # and just show a warning message. Therefore, only bail
+ # out here if the atom is not from either the system or
+ # world set.
+ if not (isinstance(arg, SetArg) and \
+ arg.name in ("system", "world")):
+ return 0, myfavorites
self._dep_stack.append(
Dependency(atom=atom, onlydeps=onlydeps, root=myroot, parent=arg))
else:
metadata["USE"] = ""
- try:
- if not visible(pkgsettings, cpv, metadata,
- built=built, installed=installed):
- continue
- except portage.exception.InvalidDependString:
- # masked by corruption
+ if not visible(pkgsettings, Package(built=built,
+ cpv=cpv, root=myroot, type_name=pkg_type,
+ installed=installed, metadata=metadata)):
continue
filtered_db.cpv_inject(cpv, metadata=metadata)
empty = "empty" in self.myparams
selective = "selective" in self.myparams
noreplace = "--noreplace" in self.myopts
- reinstall = False
# Behavior of the "selective" parameter depends on
# whether or not a package matches an argument atom.
# If an installed package provides an old-style
for db, pkg_type, built, installed, db_keys in dbs:
if existing_node:
break
- if installed and not find_existing_node and \
- (reinstall or not selective) and \
- (matched_packages or empty):
- # We only need to select an installed package in the
- # following cases:
- # 1) there is no other choice
- # 2) selective is True
- continue
+ if installed and not find_existing_node:
+ want_reinstall = empty or \
+ (found_available_arg and not selective)
+ if want_reinstall and matched_packages:
+ continue
if hasattr(db, "xmatch"):
cpv_list = db.xmatch("match-all", atom)
else:
if not installed:
if myarg:
found_available_arg = True
- try:
- if not visible(pkgsettings, cpv, metadata,
- built=built, installed=installed):
- continue
- except portage.exception.InvalidDependString:
- # masked by corruption
+ if not visible(pkgsettings, Package(built=built,
+ cpv=cpv, installed=installed, metadata=metadata,
+ type_name=pkg_type)):
continue
# At this point, we've found the highest visible
# match from the current repo. Any lower versions
if not installed and \
("--newuse" in self.myopts or \
"--reinstall" in self.myopts) and \
- vardb.cpv_exists(cpv):
+ cpv in vardb.match(atom):
pkgsettings.setcpv(cpv, mydb=metadata)
forced_flags = set()
forced_flags.update(pkgsettings.useforce)
self._reinstall_for_flags(
forced_flags, old_use, old_iuse,
cur_use, cur_iuse)
- if reinstall_for_flags:
- reinstall = True
if not installed:
must_reinstall = empty or \
(myarg and not selective)
not must_reinstall and \
cpv in vardb.match(atom):
break
- if installed:
- must_reinstall = empty or \
- (found_available_arg and not selective)
- if must_reinstall:
- break
# Metadata accessed above is cached internally by
# each db in order to optimize visibility checks.
# Now that all possible checks visibility checks
pkgsettings.setcpv(cpv, mydb=metadata)
metadata["USE"] = pkgsettings["PORTAGE_USE"]
myeb = cpv
- matched_packages.append(
- Package(type_name=pkg_type, root=root,
- cpv=cpv, metadata=metadata,
- built=built, installed=installed,
- onlydeps=onlydeps))
+ pkg = Package(type_name=pkg_type, root=root,
+ cpv=cpv, metadata=metadata,
+ built=built, installed=installed,
+ onlydeps=onlydeps)
+ matched_packages.append(pkg)
if reinstall_for_flags:
- pkg_node = (pkg_type, root, cpv, "merge")
- self._reinstall_nodes[pkg_node] = \
+ self._reinstall_nodes[pkg] = \
reinstall_for_flags
break
for pkg in matched_packages:
print (pkg.type_name + ":").rjust(10), pkg.cpv
+ # Filter out any old-style virtual matches if they are
+ # mixed with new-style virtual matches.
+ cp = portage.dep_getkey(atom)
+ if len(matched_packages) > 1 and \
+ "virtual" == portage.catsplit(cp)[0]:
+ for pkg in matched_packages:
+ if pkg.cp != cp:
+ continue
+ # Got a new-style virtual, so filter
+ # out any old-style virtuals.
+ matched_packages = [pkg for pkg in matched_packages \
+ if pkg.cp == cp]
+ break
+
if len(matched_packages) > 1:
bestmatch = portage.best(
[pkg.cpv for pkg in matched_packages])
matched_packages = [pkg for pkg in matched_packages \
- if pkg.cpv == bestmatch]
+ if portage.dep.cpvequal(pkg.cpv, bestmatch)]
# ordered by type preference ("ebuild" type is the last resort)
return matched_packages[-1], existing_node
get_nodes = mygraph.leaf_nodes
for node in mygraph.order:
if node.root == "/" and \
- "portage" == portage.catsplit(
- portage.cpv_getkey(node.cpv))[-1]:
+ "sys-apps/portage" == portage.cpv_getkey(node.cpv):
portage_node = node
asap_nodes.append(node)
break
print bold('*'+revision)
sys.stdout.write(text)
+ sys.stdout.flush()
self.display_problems()
return os.EX_OK
for cpv in reversed(pkgs):
metadata = dict(izip(metadata_keys,
vardb.aux_get(cpv, metadata_keys)))
- if visible(settings, cpv, metadata,
- built=True, installed=True):
+ if visible(settings, Package(built=True, cpv=cpv,
+ installed=True, metadata=metadata, type_name="installed")):
pkgs = [cpv]
break
if len(pkgs) > 1:
_doebuild_manifest_exempt_depend = 0
_doebuild_manifest_checked = None
+_doebuild_broken_manifests = set()
def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
fetchonly=0, cleanup=0, dbkey=None, use_cache=1, fetchall=0, tree=None,
# Always verify the ebuild checksums before executing it.
pkgdir = os.path.dirname(myebuild)
manifest_path = os.path.join(pkgdir, "Manifest")
- global _doebuild_manifest_checked
+ global _doebuild_manifest_checked, _doebuild_broken_manifests
+ if manifest_path in _doebuild_broken_manifests:
+ return 1
# Avoid checking the same Manifest several times in a row during a
# regen with an empty cache.
if _doebuild_manifest_checked != manifest_path:
if not os.path.exists(manifest_path):
writemsg("!!! Manifest file not found: '%s'\n" % manifest_path,
noiselevel=-1)
+ _doebuild_broken_manifests.add(manifest_path)
return 1
mf = Manifest(pkgdir, mysettings["DISTDIR"])
try:
except portage.exception.FileNotFound, e:
writemsg("!!! A file listed in the Manifest " + \
"could not be found: %s\n" % str(e), noiselevel=-1)
+ _doebuild_broken_manifests.add(manifest_path)
return 1
except portage.exception.DigestException, e:
writemsg("!!! Digest verification failed:\n", noiselevel=-1)
writemsg("!!! Reason: %s\n" % e.value[1], noiselevel=-1)
writemsg("!!! Got: %s\n" % e.value[2], noiselevel=-1)
writemsg("!!! Expected: %s\n" % e.value[3], noiselevel=-1)
+ _doebuild_broken_manifests.add(manifest_path)
return 1
# Make sure that all of the ebuilds are actually listed in the
# Manifest.
writemsg("!!! A file is not listed in the " + \
"Manifest: '%s'\n" % os.path.join(pkgdir, f),
noiselevel=-1)
+ _doebuild_broken_manifests.add(manifest_path)
return 1
_doebuild_manifest_checked = manifest_path
all_available = True
versions = {}
for atom in atoms:
- avail_pkg = best(mydbapi.match(atom))
+ avail_pkg = mydbapi.match(atom)
if avail_pkg:
+ avail_pkg = avail_pkg[-1] # highest (ascending order)
avail_slot = "%s:%s" % (dep_getkey(atom),
mydbapi.aux_get(avail_pkg, ["SLOT"])[0])
elif not avail_pkg:
if hasattr(mydbapi, "xmatch"):
has_mask = bool(mydbapi.xmatch("match-all", atom))
if (selective or use_binaries or not has_mask):
- avail_pkg = best(vardb.match(atom))
+ avail_pkg = vardb.match(atom)
if avail_pkg:
+ avail_pkg = avail_pkg[-1] # highest (ascending order)
avail_slot = "%s:%s" % (dep_getkey(atom),
vardb.aux_get(avail_pkg, ["SLOT"])[0])
if not avail_pkg: