blob: c2622839edac72965dce9dbcab44ef90e35b596d [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2020 The ChromiumOS Authors
Alex Klein9ec04452020-05-18 15:08:24 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Script to check if the package(s) have prebuilts.
6
7The script must be run inside the chroot. The output is a json dict mapping the
8package atoms to a boolean for whether a prebuilt exists.
9"""
10
Alex Klein9ec04452020-05-18 15:08:24 -060011import json
Mike Frysinger065bb3d2023-06-21 14:25:15 -040012import logging
Alex Klein9ec04452020-05-18 15:08:24 -060013import os
14
15from chromite.lib import commandline
16from chromite.lib import cros_build_lib
17from chromite.lib import osutils
18from chromite.lib import portage_util
Alex Klein18a60af2020-06-11 12:08:47 -060019from chromite.lib.parser import package_info
Alex Klein9ec04452020-05-18 15:08:24 -060020
Mike Frysinger807d8282022-04-28 22:45:17 -040021
Alex Klein9ec04452020-05-18 15:08:24 -060022if cros_build_lib.IsInsideChroot():
Alex Klein1699fab2022-09-08 08:46:06 -060023 from chromite.lib import depgraph
Alex Klein9ec04452020-05-18 15:08:24 -060024
25
26def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -060027 """Build the argument parser."""
28 parser = commandline.ArgumentParser(description=__doc__)
Alex Klein9ec04452020-05-18 15:08:24 -060029
Alex Klein1699fab2022-09-08 08:46:06 -060030 parser.add_argument(
31 "-b",
32 "--build-target",
33 dest="build_target_name",
34 help="The build target that is being checked.",
35 )
36 parser.add_argument(
37 "--output",
38 type="path",
39 required=True,
40 help="The file path where the result json should be stored.",
41 )
42 parser.add_argument(
43 "packages", nargs="+", help="The package atoms that are being checked."
44 )
Alex Klein9ec04452020-05-18 15:08:24 -060045
Alex Klein1699fab2022-09-08 08:46:06 -060046 return parser
Alex Klein9ec04452020-05-18 15:08:24 -060047
48
49def _ParseArguments(argv):
Alex Klein1699fab2022-09-08 08:46:06 -060050 """Parse and validate arguments."""
51 parser = GetParser()
52 opts = parser.parse_args(argv)
Alex Klein9ec04452020-05-18 15:08:24 -060053
Alex Klein1699fab2022-09-08 08:46:06 -060054 if not os.path.exists(os.path.dirname(opts.output)):
55 parser.error("Path containing the output file does not exist.")
Alex Klein9ec04452020-05-18 15:08:24 -060056
Alex Klein1699fab2022-09-08 08:46:06 -060057 # Manually parse the packages as CPVs.
58 packages = []
59 for pkg in opts.packages:
60 cpv = package_info.parse(pkg)
61 if not cpv.atom:
62 parser.error("Invalid package atom: %s" % pkg)
Alex Klein9ec04452020-05-18 15:08:24 -060063
Alex Klein1699fab2022-09-08 08:46:06 -060064 packages.append(cpv)
65 opts.packages = packages
Alex Klein9ec04452020-05-18 15:08:24 -060066
Alex Klein1699fab2022-09-08 08:46:06 -060067 opts.Freeze()
68 return opts
Alex Klein9ec04452020-05-18 15:08:24 -060069
70
71def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -060072 opts = _ParseArguments(argv)
73 cros_build_lib.AssertInsideChroot()
Alex Klein9ec04452020-05-18 15:08:24 -060074
Alex Klein1699fab2022-09-08 08:46:06 -060075 board = opts.build_target_name
Cindy Lin397a0b12023-06-29 22:09:17 +000076
77 portage_binhost = portage_util.PortageqEnvvar("PORTAGE_BINHOST", board)
78 logging.info("PORTAGE_BINHOST: %s", portage_binhost)
79
Mike Frysingerfbb98992023-06-21 14:34:54 -040080 results = {}
Alex Klein1699fab2022-09-08 08:46:06 -060081 bests = {}
82 for cpv in opts.packages:
Mike Frysinger3917d982023-06-21 14:38:34 -040083 query = cpv.cpvr or cpv.atom
Mike Frysingerfbb98992023-06-21 14:34:54 -040084 try:
Mike Frysinger3917d982023-06-21 14:38:34 -040085 bests[query] = portage_util.PortageqBestVisible(query, board=board)
86 logging.debug("Resolved %s best visible to %s", query, bests[query])
Mike Frysingerfbb98992023-06-21 14:34:54 -040087 except portage_util.NoVisiblePackageError:
Mike Frysinger3917d982023-06-21 14:38:34 -040088 results[query] = False
Alex Klein9ec04452020-05-18 15:08:24 -060089
Mike Frysingerfbb98992023-06-21 14:34:54 -040090 if bests:
Mike Frysingerf264c172023-06-21 14:46:05 -040091 args = [
92 # Fetch remote binpkg databases.
93 "--getbinpkg",
94 # Update packages to the latest version (we want updates to
95 # invalidate installed packages).
96 "--update",
97 # Consider full tree rather than just immediate deps (changes in
98 # dependencies and transitive deps can invalidate a binpkg).
99 "--deep",
100 # Packages with changed USE flags should be considered (changes in
101 # dependencies and transitive deps can invalidate a binpkg).
102 "--newuse",
103 # Simplifies output.
104 "--quiet",
105 # Don't actually install it :).
106 "--pretend",
Mike Frysinger8569dd02023-06-21 14:55:42 -0400107 "--selective=n",
Mike Frysinger516f5de2023-06-28 13:41:41 -0400108 # We run build_packages by default with these flags which can
109 # trigger rebuilds (and ignoring of binpkgs) in more cases.
110 "--newrepo",
111 "--with-test-deps=y",
Mike Frysingerf264c172023-06-21 14:46:05 -0400112 ]
Mike Frysingerfbb98992023-06-21 14:34:54 -0400113 if board:
114 args.append("--board=%s" % board)
115 args.extend("=%s" % best.cpvr for best in bests.values())
Alex Klein9ec04452020-05-18 15:08:24 -0600116
Mike Frysingerfbb98992023-06-21 14:34:54 -0400117 generator = depgraph.DepGraphGenerator()
118 logging.debug(
119 "Initializing depgraph with: %s", cros_build_lib.CmdToStr(args)
120 )
121 generator.Initialize(args)
Alex Klein9ec04452020-05-18 15:08:24 -0600122
Mike Frysingerfbb98992023-06-21 14:34:54 -0400123 for atom, best in bests.items():
124 results[atom] = generator.HasPrebuilt(best.cpvr)
Alex Klein9ec04452020-05-18 15:08:24 -0600125
Alex Klein1699fab2022-09-08 08:46:06 -0600126 osutils.WriteFile(opts.output, json.dumps(results))