blob: 268e51761419615273892ec39d3a2f2bf7b38938 [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
76 bests = {}
77 for cpv in opts.packages:
78 bests[cpv.atom] = portage_util.PortageqBestVisible(
79 cpv.atom, board=board
80 )
Mike Frysinger065bb3d2023-06-21 14:25:15 -040081 logging.debug(
82 "Resolved %s best visible to %s", cpv.atom, bests[cpv.atom]
83 )
Alex Klein9ec04452020-05-18 15:08:24 -060084
Alex Klein1699fab2022-09-08 08:46:06 -060085 # Emerge args:
86 # g: use binpkgs (needed to find if we have one)
Alex Klein68b270c2023-04-14 14:42:50 -060087 # u: update packages to the latest version (want updates to invalidate
88 # binpkgs)
Alex Klein1699fab2022-09-08 08:46:06 -060089 # D: deep -- consider full tree rather that just immediate deps
90 # (changes in dependencies and transitive deps can invalidate a binpkg)
91 # N: Packages with changed use flags should be considered
92 # (changes in dependencies and transitive deps can invalidate a binpkg)
93 # q: quiet (simplifies output)
94 # p: pretend (don't actually install it)
95 args = ["-guDNqp", "--with-bdeps=y", "--color=n"]
96 if board:
97 args.append("--board=%s" % board)
98 args.extend("=%s" % best.cpvr for best in bests.values())
Alex Klein9ec04452020-05-18 15:08:24 -060099
Mike Frysinger065bb3d2023-06-21 14:25:15 -0400100 logging.debug(
101 "Initializing depgraph with: %s", cros_build_lib.CmdToStr(args)
102 )
Alex Klein1699fab2022-09-08 08:46:06 -0600103 generator = depgraph.DepGraphGenerator()
104 generator.Initialize(args)
Alex Klein9ec04452020-05-18 15:08:24 -0600105
Alex Klein1699fab2022-09-08 08:46:06 -0600106 results = {}
107 for atom, best in bests.items():
108 results[atom] = generator.HasPrebuilt(best.cpvr)
Alex Klein9ec04452020-05-18 15:08:24 -0600109
Alex Klein1699fab2022-09-08 08:46:06 -0600110 osutils.WriteFile(opts.output, json.dumps(results))