blob: 0e83097f53c2e6c4632f27c5c21128930923b98d [file] [log] [blame]
Alex Klein9ec04452020-05-18 15:08:24 -06001# -*- coding: utf-8 -*-
2# Copyright 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Script to check if the package(s) have prebuilts.
7
8The script must be run inside the chroot. The output is a json dict mapping the
9package atoms to a boolean for whether a prebuilt exists.
10"""
11
12from __future__ import print_function
13
14import json
15import os
16
17from chromite.lib import commandline
18from chromite.lib import cros_build_lib
19from chromite.lib import osutils
20from chromite.lib import portage_util
Alex Klein18a60af2020-06-11 12:08:47 -060021from chromite.lib.parser import package_info
Alex Klein9ec04452020-05-18 15:08:24 -060022
23if cros_build_lib.IsInsideChroot():
24 from chromite.lib import depgraph
25
26
27def GetParser():
28 """Build the argument parser."""
29 parser = commandline.ArgumentParser(description=__doc__)
30
31 parser.add_argument(
32 '-b',
33 '--build-target',
Alex Klein952ceee2020-09-02 10:13:18 -060034 dest='build_target_name',
Alex Klein9ec04452020-05-18 15:08:24 -060035 help='The build target that is being checked.')
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 parser.add_argument(
42 'packages',
43 nargs='+',
44 help='The package atoms that are being checked.')
45
46 return parser
47
48
49def _ParseArguments(argv):
50 """Parse and validate arguments."""
51 parser = GetParser()
52 opts = parser.parse_args(argv)
53
54 if not os.path.exists(os.path.dirname(opts.output)):
55 parser.error('Path containing the output file does not exist.')
56
57 # Manually parse the packages as CPVs.
58 packages = []
59 for pkg in opts.packages:
Alex Klein18a60af2020-06-11 12:08:47 -060060 cpv = package_info.parse(pkg)
61 if not cpv.atom:
Alex Klein9ec04452020-05-18 15:08:24 -060062 parser.error('Invalid package atom: %s' % pkg)
63
64 packages.append(cpv)
65 opts.packages = packages
66
67 opts.Freeze()
68 return opts
69
70
71def main(argv):
72 opts = _ParseArguments(argv)
73 cros_build_lib.AssertInsideChroot()
74
Alex Klein952ceee2020-09-02 10:13:18 -060075 board = opts.build_target_name
Alex Klein9ec04452020-05-18 15:08:24 -060076 bests = {}
77 for cpv in opts.packages:
Alex Klein18a60af2020-06-11 12:08:47 -060078 bests[cpv.atom] = portage_util.PortageqBestVisible(cpv.atom, board=board)
Alex Klein9ec04452020-05-18 15:08:24 -060079
80 # Emerge args:
81 # g: use binpkgs (needed to find if we have one)
82 # u: update packages to latest version (want updates to invalidate binpkgs)
83 # D: deep -- consider full tree rather that just immediate deps
84 # (changes in dependencies and transitive deps can invalidate a binpkg)
85 # N: Packages with changed use flags should be considered
86 # (changes in dependencies and transitive deps can invalidate a binpkg)
87 # q: quiet (simplifies output)
88 # p: pretend (don't actually install it)
89 args = ['-guDNqp', '--with-bdeps=y', '--color=n']
90 if board:
91 args.append('--board=%s' % board)
92 args.extend('=%s' % best.cpf for best in bests.values())
93
94 generator = depgraph.DepGraphGenerator()
95 generator.Initialize(args)
96
97 results = {}
98 for atom, best in bests.items():
99 results[atom] = generator.HasPrebuilt(best.cpf)
100
101 osutils.WriteFile(opts.output, json.dumps(results))