blob: ed75fc4bcb5bc6dd1ce7fbc5ec4a7a0a610e9011 [file] [log] [blame]
Alex Klein9ec04452020-05-18 15:08:24 -06001# Copyright 2020 The Chromium OS Authors. All rights reserved.
2# 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
12import os
13
14from chromite.lib import commandline
15from chromite.lib import cros_build_lib
16from chromite.lib import osutils
17from chromite.lib import portage_util
Alex Klein18a60af2020-06-11 12:08:47 -060018from chromite.lib.parser import package_info
Alex Klein9ec04452020-05-18 15:08:24 -060019
Mike Frysinger807d8282022-04-28 22:45:17 -040020
Alex Klein9ec04452020-05-18 15:08:24 -060021if cros_build_lib.IsInsideChroot():
Alex Klein1699fab2022-09-08 08:46:06 -060022 from chromite.lib import depgraph
Alex Klein9ec04452020-05-18 15:08:24 -060023
24
25def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -060026 """Build the argument parser."""
27 parser = commandline.ArgumentParser(description=__doc__)
Alex Klein9ec04452020-05-18 15:08:24 -060028
Alex Klein1699fab2022-09-08 08:46:06 -060029 parser.add_argument(
30 "-b",
31 "--build-target",
32 dest="build_target_name",
33 help="The build target that is being checked.",
34 )
35 parser.add_argument(
36 "--output",
37 type="path",
38 required=True,
39 help="The file path where the result json should be stored.",
40 )
41 parser.add_argument(
42 "packages", nargs="+", help="The package atoms that are being checked."
43 )
Alex Klein9ec04452020-05-18 15:08:24 -060044
Alex Klein1699fab2022-09-08 08:46:06 -060045 return parser
Alex Klein9ec04452020-05-18 15:08:24 -060046
47
48def _ParseArguments(argv):
Alex Klein1699fab2022-09-08 08:46:06 -060049 """Parse and validate arguments."""
50 parser = GetParser()
51 opts = parser.parse_args(argv)
Alex Klein9ec04452020-05-18 15:08:24 -060052
Alex Klein1699fab2022-09-08 08:46:06 -060053 if not os.path.exists(os.path.dirname(opts.output)):
54 parser.error("Path containing the output file does not exist.")
Alex Klein9ec04452020-05-18 15:08:24 -060055
Alex Klein1699fab2022-09-08 08:46:06 -060056 # Manually parse the packages as CPVs.
57 packages = []
58 for pkg in opts.packages:
59 cpv = package_info.parse(pkg)
60 if not cpv.atom:
61 parser.error("Invalid package atom: %s" % pkg)
Alex Klein9ec04452020-05-18 15:08:24 -060062
Alex Klein1699fab2022-09-08 08:46:06 -060063 packages.append(cpv)
64 opts.packages = packages
Alex Klein9ec04452020-05-18 15:08:24 -060065
Alex Klein1699fab2022-09-08 08:46:06 -060066 opts.Freeze()
67 return opts
Alex Klein9ec04452020-05-18 15:08:24 -060068
69
70def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -060071 opts = _ParseArguments(argv)
72 cros_build_lib.AssertInsideChroot()
Alex Klein9ec04452020-05-18 15:08:24 -060073
Alex Klein1699fab2022-09-08 08:46:06 -060074 board = opts.build_target_name
75 bests = {}
76 for cpv in opts.packages:
77 bests[cpv.atom] = portage_util.PortageqBestVisible(
78 cpv.atom, board=board
79 )
Alex Klein9ec04452020-05-18 15:08:24 -060080
Alex Klein1699fab2022-09-08 08:46:06 -060081 # Emerge args:
82 # g: use binpkgs (needed to find if we have one)
83 # u: update packages to latest version (want updates to invalidate binpkgs)
84 # D: deep -- consider full tree rather that just immediate deps
85 # (changes in dependencies and transitive deps can invalidate a binpkg)
86 # N: Packages with changed use flags should be considered
87 # (changes in dependencies and transitive deps can invalidate a binpkg)
88 # q: quiet (simplifies output)
89 # p: pretend (don't actually install it)
90 args = ["-guDNqp", "--with-bdeps=y", "--color=n"]
91 if board:
92 args.append("--board=%s" % board)
93 args.extend("=%s" % best.cpvr for best in bests.values())
Alex Klein9ec04452020-05-18 15:08:24 -060094
Alex Klein1699fab2022-09-08 08:46:06 -060095 generator = depgraph.DepGraphGenerator()
96 generator.Initialize(args)
Alex Klein9ec04452020-05-18 15:08:24 -060097
Alex Klein1699fab2022-09-08 08:46:06 -060098 results = {}
99 for atom, best in bests.items():
100 results[atom] = generator.HasPrebuilt(best.cpvr)
Alex Klein9ec04452020-05-18 15:08:24 -0600101
Alex Klein1699fab2022-09-08 08:46:06 -0600102 osutils.WriteFile(opts.output, json.dumps(results))