blob: 910612bac3dee20fc08534431d6e189e9f56213b [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Tiancong Wangaf050172019-07-10 11:52:03 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Toolchain-related operations."""
6
LaMont Jonesb20b3d92019-11-23 11:47:48 -07007import collections
Chris McDonald1672ddb2021-07-21 11:48:23 -06008import logging
Alex Kleincd03a5e2021-10-18 13:23:47 -06009from pathlib import Path
Jack Neus4ee7b1d2022-06-27 19:54:18 +000010from typing import TYPE_CHECKING
LaMont Jonesb20b3d92019-11-23 11:47:48 -070011
LaMont Jones5d2edcb2019-12-23 11:32:03 -070012from chromite.api import controller
Alex Klein076841b2019-08-29 15:19:39 -060013from chromite.api import faux
Alex Klein231d2da2019-07-22 16:44:45 -060014from chromite.api import validate
LaMont Jones5d2edcb2019-12-23 11:32:03 -070015from chromite.api.controller import controller_util
Tiancong Wang24a3df72019-08-20 15:48:51 -070016from chromite.api.gen.chromite.api import toolchain_pb2
LaMont Jonesfd68cb12020-04-29 16:43:06 -060017from chromite.api.gen.chromite.api.artifacts_pb2 import PrepareForBuildResponse
Chris McDonald1672ddb2021-07-21 11:48:23 -060018from chromite.api.gen.chromiumos.builder_config_pb2 import BuilderConfig
Ryan Beltran8daf1dd2023-03-22 21:31:03 +000019from chromite.api.gen.chromiumos.common_pb2 import PackageInfo
Greg Edelstondae510a2023-06-30 15:25:36 -060020from chromite.lib import cros_build_lib
Jack Neus4ee7b1d2022-06-27 19:54:18 +000021from chromite.lib import toolchain as toolchain_lib
Chris McDonald1672ddb2021-07-21 11:48:23 -060022from chromite.lib import toolchain_util
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000023from chromite.service import toolchain
Ryan Beltran7d191802021-11-24 00:08:17 +000024
Mike Frysingerea11fdd2022-05-06 22:59:33 -040025
Jack Neus4ee7b1d2022-06-27 19:54:18 +000026if TYPE_CHECKING:
Alex Klein1699fab2022-09-08 08:46:06 -060027 from chromite.api import api_config
Jack Neus4ee7b1d2022-06-27 19:54:18 +000028
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000029# TODO(b/229665884): Move the implementation details for most/all endpoints to:
30# chromite/services/toolchain.py
31# This migration has been done for linting endpoints but not yet for others.
Chris McDonald1672ddb2021-07-21 11:48:23 -060032
Alex Klein1699fab2022-09-08 08:46:06 -060033_Handlers = collections.namedtuple("_Handlers", ["name", "prepare", "bundle"])
LaMont Jonesb20b3d92019-11-23 11:47:48 -070034_TOOLCHAIN_ARTIFACT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -060035 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE: _Handlers(
36 "UnverifiedChromeLlvmOrderfile",
37 toolchain_util.PrepareForBuild,
38 toolchain_util.BundleArtifacts,
39 ),
40 BuilderConfig.Artifacts.VERIFIED_CHROME_LLVM_ORDERFILE: _Handlers(
41 "VerifiedChromeLlvmOrderfile",
42 toolchain_util.PrepareForBuild,
43 toolchain_util.BundleArtifacts,
44 ),
Alex Klein1699fab2022-09-08 08:46:06 -060045 BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE: _Handlers(
46 "UnverifiedLlvmPgoFile",
47 toolchain_util.PrepareForBuild,
48 toolchain_util.BundleArtifacts,
49 ),
50 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
51 "UnverifiedChromeBenchmarkAfdoFile",
52 toolchain_util.PrepareForBuild,
53 toolchain_util.BundleArtifacts,
54 ),
55 BuilderConfig.Artifacts.CHROME_DEBUG_BINARY: _Handlers(
56 "ChromeDebugBinary",
57 toolchain_util.PrepareForBuild,
58 toolchain_util.BundleArtifacts,
59 ),
60 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_PERF_FILE: _Handlers(
61 "UnverifiedChromeBenchmarkPerfFile",
62 toolchain_util.PrepareForBuild,
63 toolchain_util.BundleArtifacts,
64 ),
65 BuilderConfig.Artifacts.VERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
66 "VerifiedChromeBenchmarkAfdoFile",
67 toolchain_util.PrepareForBuild,
68 toolchain_util.BundleArtifacts,
69 ),
70 BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
71 "UnverifiedKernelCwpAfdoFile",
72 toolchain_util.PrepareForBuild,
73 toolchain_util.BundleArtifacts,
74 ),
75 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
76 "VerifiedKernelCwpAfdoFile",
77 toolchain_util.PrepareForBuild,
78 toolchain_util.BundleArtifacts,
79 ),
80 BuilderConfig.Artifacts.UNVERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
81 "UnverifiedChromeCwpAfdoFile",
82 toolchain_util.PrepareForBuild,
83 toolchain_util.BundleArtifacts,
84 ),
85 BuilderConfig.Artifacts.VERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
86 "VerifiedChromeCwpAfdoFile",
87 toolchain_util.PrepareForBuild,
88 toolchain_util.BundleArtifacts,
89 ),
90 BuilderConfig.Artifacts.VERIFIED_RELEASE_AFDO_FILE: _Handlers(
91 "VerifiedReleaseAfdoFile",
92 toolchain_util.PrepareForBuild,
93 toolchain_util.BundleArtifacts,
94 ),
95 BuilderConfig.Artifacts.TOOLCHAIN_WARNING_LOGS: _Handlers(
96 "ToolchainWarningLogs",
97 toolchain_util.PrepareForBuild,
98 toolchain_util.BundleArtifacts,
99 ),
100 BuilderConfig.Artifacts.CHROME_AFDO_PROFILE_FOR_ANDROID_LINUX: _Handlers(
101 "ChromeAFDOProfileForAndroidLinux",
102 toolchain_util.PrepareForBuild,
103 toolchain_util.BundleArtifacts,
104 ),
105 BuilderConfig.Artifacts.CLANG_CRASH_DIAGNOSES: _Handlers(
106 "ClangCrashDiagnoses",
107 toolchain_util.PrepareForBuild,
108 toolchain_util.BundleArtifacts,
109 ),
110 BuilderConfig.Artifacts.COMPILER_RUSAGE_LOG: _Handlers(
111 "CompilerRusageLogs",
112 toolchain_util.PrepareForBuild,
113 toolchain_util.BundleArtifacts,
114 ),
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700115}
116
Alex Kleinab87ceb2023-01-24 12:00:51 -0700117# pylint: disable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800118_TOOLCHAIN_COMMIT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600119 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: "VerifiedKernelCwpAfdoFile"
Tiancong Wangd5214132021-01-12 10:43:57 -0800120}
Alex Kleinab87ceb2023-01-24 12:00:51 -0700121# pylint: enable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800122
LaMont Jonese7821672020-04-09 08:56:26 -0600123
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700124# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
125# this should be changed.
126@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600127@validate.require("artifact_types")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700128# Note: chroot and sysroot are unspecified the first time that the build_target
129# recipe calls PrepareForBuild. The second time, they are specified. No
130# validation check because "all" values are valid.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700131@validate.validation_complete
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000132def PrepareForBuild(
Alex Klein1699fab2022-09-08 08:46:06 -0600133 input_proto: "toolchain_pb2.PrepareForToolchainBuildRequest",
134 output_proto: "toolchain_pb2.PrepareForToolchainBuildResponse",
135 _config: "api_config.ApiConfig",
136):
137 """Prepare to build toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700138
Alex Klein1699fab2022-09-08 08:46:06 -0600139 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
140 artifact_name (str): name of the artifact type.
141 chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not
142 yet been created.
143 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas).
144 Will be an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700145 build_target_name (str): name of the build target (e.g., atlas). Will be
Alex Klein1699fab2022-09-08 08:46:06 -0600146 an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700147 input_artifacts ({(str) name:[str gs_locations]}): locations for
148 possible input artifacts. The handler is expected to know which
149 keys it should be using, and ignore any keys that it does not
150 understand.
Alex Klein1699fab2022-09-08 08:46:06 -0600151 profile_info ({(str) name: (str) value}) Dictionary containing profile
152 information.
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700153
Alex Klein1699fab2022-09-08 08:46:06 -0600154 They locate and modify any ebuilds and/or source required for the artifact
Alex Kleinab87ceb2023-01-24 12:00:51 -0700155 being created, then return a value from
156 toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700157
Alex Klein1699fab2022-09-08 08:46:06 -0600158 This function sets output_proto.build_relevance to the result.
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700159
Alex Klein1699fab2022-09-08 08:46:06 -0600160 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600161 input_proto: The input proto
162 output_proto: The output proto
163 _config): The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600164 """
165 if input_proto.chroot.path:
166 chroot = controller_util.ParseChroot(input_proto.chroot)
167 else:
168 chroot = None
LaMont Jones4579e8c2019-12-06 14:20:37 -0700169
Alex Klein1699fab2022-09-08 08:46:06 -0600170 input_artifacts = collections.defaultdict(list)
171 for art in input_proto.input_artifacts:
172 item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type)
173 if item:
174 input_artifacts[item.name].extend(
175 ["gs://%s" % str(x) for x in art.input_artifact_gs_locations]
176 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700177
Alex Klein1699fab2022-09-08 08:46:06 -0600178 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700179
Alex Klein1699fab2022-09-08 08:46:06 -0600180 results = set()
181 sysroot_path = input_proto.sysroot.path
182 build_target = input_proto.sysroot.build_target.name
183 for artifact_type in input_proto.artifact_types:
184 # Unknown artifact_types are an error.
185 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
186 if handler.prepare:
187 results.add(
188 handler.prepare(
189 handler.name,
190 chroot,
191 sysroot_path,
192 build_target,
193 input_artifacts,
194 profile_info,
195 )
196 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700197
Alex Klein1699fab2022-09-08 08:46:06 -0600198 # Translate the returns from the handlers we called.
199 # If any NEEDED => NEEDED
200 # elif any UNKNOWN => UNKNOWN
201 # elif any POINTLESS => POINTLESS
202 # else UNKNOWN.
203 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
204 output_proto.build_relevance = PrepareForBuildResponse.NEEDED
205 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
206 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
207 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
208 output_proto.build_relevance = PrepareForBuildResponse.POINTLESS
209 else:
210 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
211 return controller.RETURN_CODE_SUCCESS
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700212
213
214# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
215# this should be changed.
216@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600217@validate.require("chroot.path", "output_dir", "artifact_types")
218@validate.exists("output_dir")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700219@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600220def BundleArtifacts(
221 input_proto: "toolchain_pb2.BundleToolchainRequest",
222 output_proto: "toolchain_pb2.BundleToolchainResponse",
223 _config: "api_config.ApiConfig",
224):
225 """Bundle valid toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700226
Alex Klein1699fab2022-09-08 08:46:06 -0600227 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
228 artifact_name (str): name of the artifact type
229 chroot (chroot_lib.Chroot): chroot
230 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas),
231 or None.
232 chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome)
Alex Klein611dddd2022-10-11 17:02:01 -0600233 build_target_name (str): name of the build target (e.g. atlas), or None.
Alex Klein1699fab2022-09-08 08:46:06 -0600234 output_dir (str): absolute path where artifacts are being bundled.
Alex Klein611dddd2022-10-11 17:02:01 -0600235 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
Alex Klein1699fab2022-09-08 08:46:06 -0600236 profile_info ({(str) name: (str) value}) Dictionary containing profile
237 information.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700238
Alex Klein1699fab2022-09-08 08:46:06 -0600239 Note: the actual upload to GS is done by CI, not here.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700240
Alex Klein1699fab2022-09-08 08:46:06 -0600241 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600242 input_proto: The input proto
243 output_proto: The output proto
244 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600245 """
246 chroot = controller_util.ParseChroot(input_proto.chroot)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700247
Alex Klein1699fab2022-09-08 08:46:06 -0600248 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700249
Alex Klein1699fab2022-09-08 08:46:06 -0600250 output_path = Path(input_proto.output_dir)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 for artifact_type in input_proto.artifact_types:
253 if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
254 logging.error("%s not understood", artifact_type)
255 return controller.RETURN_CODE_UNRECOVERABLE
Alex Kleincd03a5e2021-10-18 13:23:47 -0600256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
258 if not handler or not handler.bundle:
259 logging.warning(
260 "%s does not have a handler with a bundle function.",
261 artifact_type,
262 )
263 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 artifacts = handler.bundle(
266 handler.name,
267 chroot,
268 input_proto.sysroot.path,
269 input_proto.sysroot.build_target.name,
270 input_proto.output_dir,
271 profile_info,
272 )
273 if not artifacts:
274 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600275
Alex Klein1699fab2022-09-08 08:46:06 -0600276 # Filter out artifacts that do not exist or are empty.
277 usable_artifacts = []
278 for artifact in artifacts:
279 artifact_path = output_path / artifact
280 if not artifact_path.exists():
281 logging.warning("%s is not in the output directory.", artifact)
282 elif not artifact_path.stat().st_size:
283 logging.warning("%s is empty.", artifact)
284 else:
285 usable_artifacts.append(artifact)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600286
Alex Klein1699fab2022-09-08 08:46:06 -0600287 if not usable_artifacts:
288 logging.warning(
289 "No usable artifacts for artifact type %s", artifact_type
290 )
291 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 # Add all usable artifacts.
294 art_info = output_proto.artifacts_info.add()
295 art_info.artifact_type = artifact_type
296 for artifact in usable_artifacts:
297 art_info.artifacts.add().path = artifact
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700298
299
Tiancong Wangd5214132021-01-12 10:43:57 -0800300def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600301 """Add successful status to the faux response."""
302 file_info = output_proto.updated_files.add()
303 file_info.path = "/any/modified/file"
304 output_proto.commit_message = "Commit message"
Tiancong Wangd5214132021-01-12 10:43:57 -0800305
306
307@faux.empty_error
308@faux.success(_GetUpdatedFilesResponse)
Alex Klein1699fab2022-09-08 08:46:06 -0600309@validate.require("uploaded_artifacts")
Tiancong Wangd5214132021-01-12 10:43:57 -0800310@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600311def GetUpdatedFiles(
312 input_proto: "toolchain_pb2.GetUpdatedFilesRequest",
313 output_proto: "toolchain_pb2.GetUpdatedFilesResponse",
314 _config: "api_config.ApiConfig",
315):
316 """Use uploaded artifacts to update some updates in a chromeos checkout.
Tiancong Wangd5214132021-01-12 10:43:57 -0800317
Alex Klein1699fab2022-09-08 08:46:06 -0600318 The function will call toolchain_util.GetUpdatedFiles using the type of
319 uploaded artifacts to make some changes in a checkout, and return the list
320 of change files together with commit message.
Alex Klein611dddd2022-10-11 17:02:01 -0600321 updated_artifacts: A list of UpdatedArtifacts type which contains a
322 tuple of artifact info and profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600323 Note: the actual creation of the commit is done by CI, not here.
Tiancong Wangd5214132021-01-12 10:43:57 -0800324
Alex Klein1699fab2022-09-08 08:46:06 -0600325 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600326 input_proto: The input proto
327 output_proto: The output proto
328 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600329 """
330 commit_message = ""
331 for artifact in input_proto.uploaded_artifacts:
332 artifact_type = artifact.artifact_info.artifact_type
333 if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS:
334 logging.error("%s not understood", artifact_type)
335 return controller.RETURN_CODE_UNRECOVERABLE
336 artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type]
337 if artifact_name:
338 assert (
339 len(artifact.artifact_info.artifacts) == 1
340 ), "Only one file to update per each artifact"
341 updated_files, message = toolchain_util.GetUpdatedFiles(
342 artifact_name,
343 artifact.artifact_info.artifacts[0].path,
344 _GetProfileInfoDict(artifact.profile_info),
345 )
346 for f in updated_files:
347 file_info = output_proto.updated_files.add()
348 file_info.path = f
Tiancong Wangd5214132021-01-12 10:43:57 -0800349
Alex Klein1699fab2022-09-08 08:46:06 -0600350 commit_message += message + "\n"
351 output_proto.commit_message = commit_message
352 # No commit footer is added for now. Can add more here if needed
Tiancong Wangd5214132021-01-12 10:43:57 -0800353
354
Alex Klein1699fab2022-09-08 08:46:06 -0600355def _GetProfileInfoDict(profile_info: "toolchain_pb2.ArtifactProfileInfo"):
356 """Convert profile_info to a dict.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000357
Alex Klein1699fab2022-09-08 08:46:06 -0600358 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600359 profile_info: The artifact profile_info.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000360
Alex Klein1699fab2022-09-08 08:46:06 -0600361 Returns:
Alex Klein611dddd2022-10-11 17:02:01 -0600362 A dictionary containing profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600363 """
364 ret = {}
365 which = profile_info.WhichOneof("artifact_profile_info")
366 if which:
367 value = getattr(profile_info, which)
Alex Kleinab87ceb2023-01-24 12:00:51 -0700368 # If it is a message, then use the contents of the message. This works
369 # as long as simple types do not have a 'DESCRIPTOR' attribute. (And
370 # protobuf messages do.)
Alex Klein1699fab2022-09-08 08:46:06 -0600371 if getattr(value, "DESCRIPTOR", None):
372 ret.update({k.name: v for k, v in value.ListFields()})
373 else:
374 ret[which] = value
Denis Nikitin62e69862023-02-13 23:37:00 -0800375 arch = getattr(profile_info, "arch", None)
376 if arch:
377 ret["arch"] = arch
Alex Klein1699fab2022-09-08 08:46:06 -0600378 return ret
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000379
380
381LINTER_CODES = {
Alex Klein1699fab2022-09-08 08:46:06 -0600382 "clang_tidy": toolchain_pb2.LinterFinding.CLANG_TIDY,
383 "cargo_clippy": toolchain_pb2.LinterFinding.CARGO_CLIPPY,
384 "go_lint": toolchain_pb2.LinterFinding.GO_LINT,
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000385}
386
387
Adrian Dolef87c5762022-12-15 22:00:50 +0000388@validate.require("sysroot.build_target.name")
389@validate.require("start_time")
390@validate.validation_complete
391def EmergeAndUploadLints(
392 input_proto: toolchain_pb2.DashboardLintRequest,
393 output_proto: toolchain_pb2.DashboardLintResponse,
394 _config,
395):
Greg Edelstondae510a2023-06-30 15:25:36 -0600396 """Lint all platform2 packages and uploads lints to GS"""
Adrian Dolef87c5762022-12-15 22:00:50 +0000397 board = input_proto.sysroot.build_target.name
398 output_proto.gs_path = toolchain.emerge_and_upload_lints(
399 board, input_proto.start_time
400 )
401
402
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000403@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600404@validate.exists("sysroot.path")
405@validate.require("packages")
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000406@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600407def EmergeWithLinting(
408 input_proto: "toolchain_pb2.LinterRequest",
409 output_proto: "toolchain_pb2.LinterResponse",
410 _config: "api_config.ApiConfig",
411):
412 """Emerge packages with linter features enabled and retrieves all findings.
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000413
Alex Klein1699fab2022-09-08 08:46:06 -0600414 Args:
Adrian Dolef87c5762022-12-15 22:00:50 +0000415 input_proto: The input proto with package and sysroot info.
Alex Klein611dddd2022-10-11 17:02:01 -0600416 output_proto: The output proto where findings are stored.
417 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600418 """
419 packages = [
420 controller_util.deserialize_package_info(package)
421 for package in input_proto.packages
422 ]
Ryan Beltran7d191802021-11-24 00:08:17 +0000423
Alex Klein1699fab2022-09-08 08:46:06 -0600424 build_linter = toolchain.BuildLinter(
425 packages,
426 input_proto.sysroot.path,
427 differential=input_proto.filter_modified,
428 )
Ryan Beltran7d191802021-11-24 00:08:17 +0000429
Alex Klein1699fab2022-09-08 08:46:06 -0600430 use_clippy = (
431 toolchain_pb2.LinterFinding.CARGO_CLIPPY
432 not in input_proto.disabled_linters
433 )
434 use_tidy = (
435 toolchain_pb2.LinterFinding.CLANG_TIDY
436 not in input_proto.disabled_linters
437 )
438 use_golint = (
439 toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters
440 )
Ryan Beltran1277cb82022-11-27 03:15:36 +0000441 use_iwyu = (
442 toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters
443 )
Ryan Beltran4425d5f2022-07-20 18:34:33 +0000444
Alex Klein1699fab2022-09-08 08:46:06 -0600445 findings = build_linter.emerge_with_linting(
Ryan Beltran1277cb82022-11-27 03:15:36 +0000446 use_clippy=use_clippy,
447 use_tidy=use_tidy,
448 use_golint=use_golint,
449 use_iwyu=use_iwyu,
Alex Klein1699fab2022-09-08 08:46:06 -0600450 )
Ryan Beltranf9a86f42022-04-13 20:58:18 +0000451
Alex Klein1699fab2022-09-08 08:46:06 -0600452 for finding in findings:
453 locations = []
454 for location in finding.locations:
455 locations.append(
456 toolchain_pb2.LinterFindingLocation(
457 filepath=location.filepath,
458 line_start=location.line_start,
459 line_end=location.line_end,
460 )
461 )
Alex Klein860d56f2023-07-19 11:16:46 -0600462
463 pkg = PackageInfo()
464 if finding.package:
465 pkg.category = finding.package.category
466 pkg.package_name = finding.package.package
467 pkg.version = finding.package.version
Alex Klein1699fab2022-09-08 08:46:06 -0600468 output_proto.findings.append(
469 toolchain_pb2.LinterFinding(
470 message=finding.message,
471 locations=locations,
472 linter=LINTER_CODES[finding.linter],
Alex Klein860d56f2023-07-19 11:16:46 -0600473 package=pkg,
Alex Klein1699fab2022-09-08 08:46:06 -0600474 )
475 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000476
477
478@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600479@validate.require("board")
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000480@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600481def GetToolchainsForBoard(
482 input_proto: "toolchain_pb2.ToolchainsRequest",
483 output_proto: "toolchain_pb2.ToolchainsReponse",
484 _config: "api_config.ApiConfig",
485):
Greg Edelstondae510a2023-06-30 15:25:36 -0600486 """Get the default and non-default toolchains for a board.
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000487
Alex Klein1699fab2022-09-08 08:46:06 -0600488 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600489 input_proto: The input proto with board and sysroot info.
490 output_proto: The output proto where findings are stored.
491 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600492 """
493 toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board)
494 output_proto.default_toolchains.extend(
495 list(toolchain_lib.FilterToolchains(toolchains, "default", True))
496 )
497 output_proto.nondefault_toolchains.extend(
498 list(toolchain_lib.FilterToolchains(toolchains, "default", False))
499 )
Greg Edelstondae510a2023-06-30 15:25:36 -0600500
501
502@faux.all_empty
Greg Edelstondae510a2023-06-30 15:25:36 -0600503@validate.validation_complete
504def SetupToolchains(
505 input_proto: "toolchain_pb2.SetupToolchainsRequest",
506 output_proto: "toolchain_pb2.SetupToolchainsResponse",
507 config: "api_config.ApiConfig",
508):
509 """Run `cros_setup_toolchains`."""
510 del output_proto, config # Unused.
511 cros_build_lib.AssertInsideChroot()
512 include_boards = [bt.name for bt in input_proto.boards]
513 toolchain.setup_toolchains(include_boards=include_boards)