blob: 77953b110366e4a4d714f4aef2e4d68b768f0559 [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 ),
45 BuilderConfig.Artifacts.CHROME_CLANG_WARNINGS_FILE: _Handlers(
46 "ChromeClangWarningsFile",
47 toolchain_util.PrepareForBuild,
48 toolchain_util.BundleArtifacts,
49 ),
50 BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE: _Handlers(
51 "UnverifiedLlvmPgoFile",
52 toolchain_util.PrepareForBuild,
53 toolchain_util.BundleArtifacts,
54 ),
55 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
56 "UnverifiedChromeBenchmarkAfdoFile",
57 toolchain_util.PrepareForBuild,
58 toolchain_util.BundleArtifacts,
59 ),
60 BuilderConfig.Artifacts.CHROME_DEBUG_BINARY: _Handlers(
61 "ChromeDebugBinary",
62 toolchain_util.PrepareForBuild,
63 toolchain_util.BundleArtifacts,
64 ),
65 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_PERF_FILE: _Handlers(
66 "UnverifiedChromeBenchmarkPerfFile",
67 toolchain_util.PrepareForBuild,
68 toolchain_util.BundleArtifacts,
69 ),
70 BuilderConfig.Artifacts.VERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
71 "VerifiedChromeBenchmarkAfdoFile",
72 toolchain_util.PrepareForBuild,
73 toolchain_util.BundleArtifacts,
74 ),
75 BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
76 "UnverifiedKernelCwpAfdoFile",
77 toolchain_util.PrepareForBuild,
78 toolchain_util.BundleArtifacts,
79 ),
80 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
81 "VerifiedKernelCwpAfdoFile",
82 toolchain_util.PrepareForBuild,
83 toolchain_util.BundleArtifacts,
84 ),
85 BuilderConfig.Artifacts.UNVERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
86 "UnverifiedChromeCwpAfdoFile",
87 toolchain_util.PrepareForBuild,
88 toolchain_util.BundleArtifacts,
89 ),
90 BuilderConfig.Artifacts.VERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
91 "VerifiedChromeCwpAfdoFile",
92 toolchain_util.PrepareForBuild,
93 toolchain_util.BundleArtifacts,
94 ),
95 BuilderConfig.Artifacts.VERIFIED_RELEASE_AFDO_FILE: _Handlers(
96 "VerifiedReleaseAfdoFile",
97 toolchain_util.PrepareForBuild,
98 toolchain_util.BundleArtifacts,
99 ),
100 BuilderConfig.Artifacts.TOOLCHAIN_WARNING_LOGS: _Handlers(
101 "ToolchainWarningLogs",
102 toolchain_util.PrepareForBuild,
103 toolchain_util.BundleArtifacts,
104 ),
105 BuilderConfig.Artifacts.CHROME_AFDO_PROFILE_FOR_ANDROID_LINUX: _Handlers(
106 "ChromeAFDOProfileForAndroidLinux",
107 toolchain_util.PrepareForBuild,
108 toolchain_util.BundleArtifacts,
109 ),
110 BuilderConfig.Artifacts.CLANG_CRASH_DIAGNOSES: _Handlers(
111 "ClangCrashDiagnoses",
112 toolchain_util.PrepareForBuild,
113 toolchain_util.BundleArtifacts,
114 ),
115 BuilderConfig.Artifacts.COMPILER_RUSAGE_LOG: _Handlers(
116 "CompilerRusageLogs",
117 toolchain_util.PrepareForBuild,
118 toolchain_util.BundleArtifacts,
119 ),
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700120}
121
Alex Kleinab87ceb2023-01-24 12:00:51 -0700122# pylint: disable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800123_TOOLCHAIN_COMMIT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600124 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: "VerifiedKernelCwpAfdoFile"
Tiancong Wangd5214132021-01-12 10:43:57 -0800125}
Alex Kleinab87ceb2023-01-24 12:00:51 -0700126# pylint: enable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800127
LaMont Jonese7821672020-04-09 08:56:26 -0600128
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700129# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
130# this should be changed.
131@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600132@validate.require("artifact_types")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700133# Note: chroot and sysroot are unspecified the first time that the build_target
134# recipe calls PrepareForBuild. The second time, they are specified. No
135# validation check because "all" values are valid.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700136@validate.validation_complete
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000137def PrepareForBuild(
Alex Klein1699fab2022-09-08 08:46:06 -0600138 input_proto: "toolchain_pb2.PrepareForToolchainBuildRequest",
139 output_proto: "toolchain_pb2.PrepareForToolchainBuildResponse",
140 _config: "api_config.ApiConfig",
141):
142 """Prepare to build toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700143
Alex Klein1699fab2022-09-08 08:46:06 -0600144 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
145 artifact_name (str): name of the artifact type.
146 chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not
147 yet been created.
148 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas).
149 Will be an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700150 build_target_name (str): name of the build target (e.g., atlas). Will be
Alex Klein1699fab2022-09-08 08:46:06 -0600151 an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700152 input_artifacts ({(str) name:[str gs_locations]}): locations for
153 possible input artifacts. The handler is expected to know which
154 keys it should be using, and ignore any keys that it does not
155 understand.
Alex Klein1699fab2022-09-08 08:46:06 -0600156 profile_info ({(str) name: (str) value}) Dictionary containing profile
157 information.
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700158
Alex Klein1699fab2022-09-08 08:46:06 -0600159 They locate and modify any ebuilds and/or source required for the artifact
Alex Kleinab87ceb2023-01-24 12:00:51 -0700160 being created, then return a value from
161 toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700162
Alex Klein1699fab2022-09-08 08:46:06 -0600163 This function sets output_proto.build_relevance to the result.
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700164
Alex Klein1699fab2022-09-08 08:46:06 -0600165 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600166 input_proto: The input proto
167 output_proto: The output proto
168 _config): The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600169 """
170 if input_proto.chroot.path:
171 chroot = controller_util.ParseChroot(input_proto.chroot)
172 else:
173 chroot = None
LaMont Jones4579e8c2019-12-06 14:20:37 -0700174
Alex Klein1699fab2022-09-08 08:46:06 -0600175 input_artifacts = collections.defaultdict(list)
176 for art in input_proto.input_artifacts:
177 item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type)
178 if item:
179 input_artifacts[item.name].extend(
180 ["gs://%s" % str(x) for x in art.input_artifact_gs_locations]
181 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700182
Alex Klein1699fab2022-09-08 08:46:06 -0600183 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700184
Alex Klein1699fab2022-09-08 08:46:06 -0600185 results = set()
186 sysroot_path = input_proto.sysroot.path
187 build_target = input_proto.sysroot.build_target.name
188 for artifact_type in input_proto.artifact_types:
189 # Unknown artifact_types are an error.
190 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
191 if handler.prepare:
192 results.add(
193 handler.prepare(
194 handler.name,
195 chroot,
196 sysroot_path,
197 build_target,
198 input_artifacts,
199 profile_info,
200 )
201 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700202
Alex Klein1699fab2022-09-08 08:46:06 -0600203 # Translate the returns from the handlers we called.
204 # If any NEEDED => NEEDED
205 # elif any UNKNOWN => UNKNOWN
206 # elif any POINTLESS => POINTLESS
207 # else UNKNOWN.
208 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
209 output_proto.build_relevance = PrepareForBuildResponse.NEEDED
210 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
211 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
212 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
213 output_proto.build_relevance = PrepareForBuildResponse.POINTLESS
214 else:
215 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
216 return controller.RETURN_CODE_SUCCESS
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700217
218
219# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
220# this should be changed.
221@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600222@validate.require("chroot.path", "output_dir", "artifact_types")
223@validate.exists("output_dir")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700224@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600225def BundleArtifacts(
226 input_proto: "toolchain_pb2.BundleToolchainRequest",
227 output_proto: "toolchain_pb2.BundleToolchainResponse",
228 _config: "api_config.ApiConfig",
229):
230 """Bundle valid toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700231
Alex Klein1699fab2022-09-08 08:46:06 -0600232 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
233 artifact_name (str): name of the artifact type
234 chroot (chroot_lib.Chroot): chroot
235 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas),
236 or None.
237 chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome)
Alex Klein611dddd2022-10-11 17:02:01 -0600238 build_target_name (str): name of the build target (e.g. atlas), or None.
Alex Klein1699fab2022-09-08 08:46:06 -0600239 output_dir (str): absolute path where artifacts are being bundled.
Alex Klein611dddd2022-10-11 17:02:01 -0600240 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
Alex Klein1699fab2022-09-08 08:46:06 -0600241 profile_info ({(str) name: (str) value}) Dictionary containing profile
242 information.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700243
Alex Klein1699fab2022-09-08 08:46:06 -0600244 Note: the actual upload to GS is done by CI, not here.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700245
Alex Klein1699fab2022-09-08 08:46:06 -0600246 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600247 input_proto: The input proto
248 output_proto: The output proto
249 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600250 """
251 chroot = controller_util.ParseChroot(input_proto.chroot)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700252
Alex Klein1699fab2022-09-08 08:46:06 -0600253 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700254
Alex Klein1699fab2022-09-08 08:46:06 -0600255 output_path = Path(input_proto.output_dir)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 for artifact_type in input_proto.artifact_types:
258 if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
259 logging.error("%s not understood", artifact_type)
260 return controller.RETURN_CODE_UNRECOVERABLE
Alex Kleincd03a5e2021-10-18 13:23:47 -0600261
Alex Klein1699fab2022-09-08 08:46:06 -0600262 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
263 if not handler or not handler.bundle:
264 logging.warning(
265 "%s does not have a handler with a bundle function.",
266 artifact_type,
267 )
268 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600269
Alex Klein1699fab2022-09-08 08:46:06 -0600270 artifacts = handler.bundle(
271 handler.name,
272 chroot,
273 input_proto.sysroot.path,
274 input_proto.sysroot.build_target.name,
275 input_proto.output_dir,
276 profile_info,
277 )
278 if not artifacts:
279 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600280
Alex Klein1699fab2022-09-08 08:46:06 -0600281 # Filter out artifacts that do not exist or are empty.
282 usable_artifacts = []
283 for artifact in artifacts:
284 artifact_path = output_path / artifact
285 if not artifact_path.exists():
286 logging.warning("%s is not in the output directory.", artifact)
287 elif not artifact_path.stat().st_size:
288 logging.warning("%s is empty.", artifact)
289 else:
290 usable_artifacts.append(artifact)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600291
Alex Klein1699fab2022-09-08 08:46:06 -0600292 if not usable_artifacts:
293 logging.warning(
294 "No usable artifacts for artifact type %s", artifact_type
295 )
296 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600297
Alex Klein1699fab2022-09-08 08:46:06 -0600298 # Add all usable artifacts.
299 art_info = output_proto.artifacts_info.add()
300 art_info.artifact_type = artifact_type
301 for artifact in usable_artifacts:
302 art_info.artifacts.add().path = artifact
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700303
304
Tiancong Wangd5214132021-01-12 10:43:57 -0800305def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600306 """Add successful status to the faux response."""
307 file_info = output_proto.updated_files.add()
308 file_info.path = "/any/modified/file"
309 output_proto.commit_message = "Commit message"
Tiancong Wangd5214132021-01-12 10:43:57 -0800310
311
312@faux.empty_error
313@faux.success(_GetUpdatedFilesResponse)
Alex Klein1699fab2022-09-08 08:46:06 -0600314@validate.require("uploaded_artifacts")
Tiancong Wangd5214132021-01-12 10:43:57 -0800315@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600316def GetUpdatedFiles(
317 input_proto: "toolchain_pb2.GetUpdatedFilesRequest",
318 output_proto: "toolchain_pb2.GetUpdatedFilesResponse",
319 _config: "api_config.ApiConfig",
320):
321 """Use uploaded artifacts to update some updates in a chromeos checkout.
Tiancong Wangd5214132021-01-12 10:43:57 -0800322
Alex Klein1699fab2022-09-08 08:46:06 -0600323 The function will call toolchain_util.GetUpdatedFiles using the type of
324 uploaded artifacts to make some changes in a checkout, and return the list
325 of change files together with commit message.
Alex Klein611dddd2022-10-11 17:02:01 -0600326 updated_artifacts: A list of UpdatedArtifacts type which contains a
327 tuple of artifact info and profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600328 Note: the actual creation of the commit is done by CI, not here.
Tiancong Wangd5214132021-01-12 10:43:57 -0800329
Alex Klein1699fab2022-09-08 08:46:06 -0600330 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600331 input_proto: The input proto
332 output_proto: The output proto
333 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600334 """
335 commit_message = ""
336 for artifact in input_proto.uploaded_artifacts:
337 artifact_type = artifact.artifact_info.artifact_type
338 if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS:
339 logging.error("%s not understood", artifact_type)
340 return controller.RETURN_CODE_UNRECOVERABLE
341 artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type]
342 if artifact_name:
343 assert (
344 len(artifact.artifact_info.artifacts) == 1
345 ), "Only one file to update per each artifact"
346 updated_files, message = toolchain_util.GetUpdatedFiles(
347 artifact_name,
348 artifact.artifact_info.artifacts[0].path,
349 _GetProfileInfoDict(artifact.profile_info),
350 )
351 for f in updated_files:
352 file_info = output_proto.updated_files.add()
353 file_info.path = f
Tiancong Wangd5214132021-01-12 10:43:57 -0800354
Alex Klein1699fab2022-09-08 08:46:06 -0600355 commit_message += message + "\n"
356 output_proto.commit_message = commit_message
357 # No commit footer is added for now. Can add more here if needed
Tiancong Wangd5214132021-01-12 10:43:57 -0800358
359
Alex Klein1699fab2022-09-08 08:46:06 -0600360def _GetProfileInfoDict(profile_info: "toolchain_pb2.ArtifactProfileInfo"):
361 """Convert profile_info to a dict.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000362
Alex Klein1699fab2022-09-08 08:46:06 -0600363 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600364 profile_info: The artifact profile_info.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000365
Alex Klein1699fab2022-09-08 08:46:06 -0600366 Returns:
Alex Klein611dddd2022-10-11 17:02:01 -0600367 A dictionary containing profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600368 """
369 ret = {}
370 which = profile_info.WhichOneof("artifact_profile_info")
371 if which:
372 value = getattr(profile_info, which)
Alex Kleinab87ceb2023-01-24 12:00:51 -0700373 # If it is a message, then use the contents of the message. This works
374 # as long as simple types do not have a 'DESCRIPTOR' attribute. (And
375 # protobuf messages do.)
Alex Klein1699fab2022-09-08 08:46:06 -0600376 if getattr(value, "DESCRIPTOR", None):
377 ret.update({k.name: v for k, v in value.ListFields()})
378 else:
379 ret[which] = value
Denis Nikitin62e69862023-02-13 23:37:00 -0800380 arch = getattr(profile_info, "arch", None)
381 if arch:
382 ret["arch"] = arch
Alex Klein1699fab2022-09-08 08:46:06 -0600383 return ret
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000384
385
386LINTER_CODES = {
Alex Klein1699fab2022-09-08 08:46:06 -0600387 "clang_tidy": toolchain_pb2.LinterFinding.CLANG_TIDY,
388 "cargo_clippy": toolchain_pb2.LinterFinding.CARGO_CLIPPY,
389 "go_lint": toolchain_pb2.LinterFinding.GO_LINT,
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000390}
391
392
Adrian Dolef87c5762022-12-15 22:00:50 +0000393@validate.require("sysroot.build_target.name")
394@validate.require("start_time")
395@validate.validation_complete
396def EmergeAndUploadLints(
397 input_proto: toolchain_pb2.DashboardLintRequest,
398 output_proto: toolchain_pb2.DashboardLintResponse,
399 _config,
400):
Greg Edelstondae510a2023-06-30 15:25:36 -0600401 """Lint all platform2 packages and uploads lints to GS"""
Adrian Dolef87c5762022-12-15 22:00:50 +0000402 board = input_proto.sysroot.build_target.name
403 output_proto.gs_path = toolchain.emerge_and_upload_lints(
404 board, input_proto.start_time
405 )
406
407
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000408@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600409@validate.exists("sysroot.path")
410@validate.require("packages")
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000411@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600412def EmergeWithLinting(
413 input_proto: "toolchain_pb2.LinterRequest",
414 output_proto: "toolchain_pb2.LinterResponse",
415 _config: "api_config.ApiConfig",
416):
417 """Emerge packages with linter features enabled and retrieves all findings.
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000418
Alex Klein1699fab2022-09-08 08:46:06 -0600419 Args:
Adrian Dolef87c5762022-12-15 22:00:50 +0000420 input_proto: The input proto with package and sysroot info.
Alex Klein611dddd2022-10-11 17:02:01 -0600421 output_proto: The output proto where findings are stored.
422 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600423 """
424 packages = [
425 controller_util.deserialize_package_info(package)
426 for package in input_proto.packages
427 ]
Ryan Beltran7d191802021-11-24 00:08:17 +0000428
Alex Klein1699fab2022-09-08 08:46:06 -0600429 build_linter = toolchain.BuildLinter(
430 packages,
431 input_proto.sysroot.path,
432 differential=input_proto.filter_modified,
433 )
Ryan Beltran7d191802021-11-24 00:08:17 +0000434
Alex Klein1699fab2022-09-08 08:46:06 -0600435 use_clippy = (
436 toolchain_pb2.LinterFinding.CARGO_CLIPPY
437 not in input_proto.disabled_linters
438 )
439 use_tidy = (
440 toolchain_pb2.LinterFinding.CLANG_TIDY
441 not in input_proto.disabled_linters
442 )
443 use_golint = (
444 toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters
445 )
Ryan Beltran1277cb82022-11-27 03:15:36 +0000446 use_iwyu = (
447 toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters
448 )
Ryan Beltran4425d5f2022-07-20 18:34:33 +0000449
Alex Klein1699fab2022-09-08 08:46:06 -0600450 findings = build_linter.emerge_with_linting(
Ryan Beltran1277cb82022-11-27 03:15:36 +0000451 use_clippy=use_clippy,
452 use_tidy=use_tidy,
453 use_golint=use_golint,
454 use_iwyu=use_iwyu,
Alex Klein1699fab2022-09-08 08:46:06 -0600455 )
Ryan Beltranf9a86f42022-04-13 20:58:18 +0000456
Alex Klein1699fab2022-09-08 08:46:06 -0600457 for finding in findings:
458 locations = []
459 for location in finding.locations:
460 locations.append(
461 toolchain_pb2.LinterFindingLocation(
462 filepath=location.filepath,
463 line_start=location.line_start,
464 line_end=location.line_end,
465 )
466 )
467 output_proto.findings.append(
468 toolchain_pb2.LinterFinding(
469 message=finding.message,
470 locations=locations,
471 linter=LINTER_CODES[finding.linter],
Ryan Beltran8daf1dd2023-03-22 21:31:03 +0000472 package=PackageInfo(
473 category=finding.package.category,
474 package_name=finding.package.package,
475 version=finding.package.version,
476 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600477 )
478 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000479
480
481@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600482@validate.require("board")
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000483@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600484def GetToolchainsForBoard(
485 input_proto: "toolchain_pb2.ToolchainsRequest",
486 output_proto: "toolchain_pb2.ToolchainsReponse",
487 _config: "api_config.ApiConfig",
488):
Greg Edelstondae510a2023-06-30 15:25:36 -0600489 """Get the default and non-default toolchains for a board.
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000490
Alex Klein1699fab2022-09-08 08:46:06 -0600491 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600492 input_proto: The input proto with board and sysroot info.
493 output_proto: The output proto where findings are stored.
494 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600495 """
496 toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board)
497 output_proto.default_toolchains.extend(
498 list(toolchain_lib.FilterToolchains(toolchains, "default", True))
499 )
500 output_proto.nondefault_toolchains.extend(
501 list(toolchain_lib.FilterToolchains(toolchains, "default", False))
502 )
Greg Edelstondae510a2023-06-30 15:25:36 -0600503
504
505@faux.all_empty
506@validate.require("chroot.path")
507@validate.validation_complete
508def SetupToolchains(
509 input_proto: "toolchain_pb2.SetupToolchainsRequest",
510 output_proto: "toolchain_pb2.SetupToolchainsResponse",
511 config: "api_config.ApiConfig",
512):
513 """Run `cros_setup_toolchains`."""
514 del output_proto, config # Unused.
515 cros_build_lib.AssertInsideChroot()
516 include_boards = [bt.name for bt in input_proto.boards]
517 toolchain.setup_toolchains(include_boards=include_boards)