blob: c2622839edac72965dce9dbcab44ef90e35b596d [file] [log] [blame]
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script to check if the package(s) have prebuilts.
The script must be run inside the chroot. The output is a json dict mapping the
package atoms to a boolean for whether a prebuilt exists.
"""
import json
import logging
import os
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib.parser import package_info
if cros_build_lib.IsInsideChroot():
from chromite.lib import depgraph
def GetParser():
"""Build the argument parser."""
parser = commandline.ArgumentParser(description=__doc__)
parser.add_argument(
"-b",
"--build-target",
dest="build_target_name",
help="The build target that is being checked.",
)
parser.add_argument(
"--output",
type="path",
required=True,
help="The file path where the result json should be stored.",
)
parser.add_argument(
"packages", nargs="+", help="The package atoms that are being checked."
)
return parser
def _ParseArguments(argv):
"""Parse and validate arguments."""
parser = GetParser()
opts = parser.parse_args(argv)
if not os.path.exists(os.path.dirname(opts.output)):
parser.error("Path containing the output file does not exist.")
# Manually parse the packages as CPVs.
packages = []
for pkg in opts.packages:
cpv = package_info.parse(pkg)
if not cpv.atom:
parser.error("Invalid package atom: %s" % pkg)
packages.append(cpv)
opts.packages = packages
opts.Freeze()
return opts
def main(argv):
opts = _ParseArguments(argv)
cros_build_lib.AssertInsideChroot()
board = opts.build_target_name
portage_binhost = portage_util.PortageqEnvvar("PORTAGE_BINHOST", board)
logging.info("PORTAGE_BINHOST: %s", portage_binhost)
results = {}
bests = {}
for cpv in opts.packages:
query = cpv.cpvr or cpv.atom
try:
bests[query] = portage_util.PortageqBestVisible(query, board=board)
logging.debug("Resolved %s best visible to %s", query, bests[query])
except portage_util.NoVisiblePackageError:
results[query] = False
if bests:
args = [
# Fetch remote binpkg databases.
"--getbinpkg",
# Update packages to the latest version (we want updates to
# invalidate installed packages).
"--update",
# Consider full tree rather than just immediate deps (changes in
# dependencies and transitive deps can invalidate a binpkg).
"--deep",
# Packages with changed USE flags should be considered (changes in
# dependencies and transitive deps can invalidate a binpkg).
"--newuse",
# Simplifies output.
"--quiet",
# Don't actually install it :).
"--pretend",
"--selective=n",
# We run build_packages by default with these flags which can
# trigger rebuilds (and ignoring of binpkgs) in more cases.
"--newrepo",
"--with-test-deps=y",
]
if board:
args.append("--board=%s" % board)
args.extend("=%s" % best.cpvr for best in bests.values())
generator = depgraph.DepGraphGenerator()
logging.debug(
"Initializing depgraph with: %s", cros_build_lib.CmdToStr(args)
)
generator.Initialize(args)
for atom, best in bests.items():
results[atom] = generator.HasPrebuilt(best.cpvr)
osutils.WriteFile(opts.output, json.dumps(results))