blob: 5c782474337f6062044aa94e22d64ee590eb849a [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
Jack Neus4ee7b1d2022-06-27 19:54:18 +000019from chromite.lib import toolchain as toolchain_lib
Chris McDonald1672ddb2021-07-21 11:48:23 -060020from chromite.lib import toolchain_util
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000021from chromite.service import toolchain
Ryan Beltran7d191802021-11-24 00:08:17 +000022
Mike Frysingerea11fdd2022-05-06 22:59:33 -040023
Jack Neus4ee7b1d2022-06-27 19:54:18 +000024if TYPE_CHECKING:
Alex Klein1699fab2022-09-08 08:46:06 -060025 from chromite.api import api_config
Jack Neus4ee7b1d2022-06-27 19:54:18 +000026
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000027# TODO(b/229665884): Move the implementation details for most/all endpoints to:
28# chromite/services/toolchain.py
29# This migration has been done for linting endpoints but not yet for others.
Chris McDonald1672ddb2021-07-21 11:48:23 -060030
Alex Klein1699fab2022-09-08 08:46:06 -060031_Handlers = collections.namedtuple("_Handlers", ["name", "prepare", "bundle"])
LaMont Jonesb20b3d92019-11-23 11:47:48 -070032_TOOLCHAIN_ARTIFACT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -060033 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE: _Handlers(
34 "UnverifiedChromeLlvmOrderfile",
35 toolchain_util.PrepareForBuild,
36 toolchain_util.BundleArtifacts,
37 ),
38 BuilderConfig.Artifacts.VERIFIED_CHROME_LLVM_ORDERFILE: _Handlers(
39 "VerifiedChromeLlvmOrderfile",
40 toolchain_util.PrepareForBuild,
41 toolchain_util.BundleArtifacts,
42 ),
43 BuilderConfig.Artifacts.CHROME_CLANG_WARNINGS_FILE: _Handlers(
44 "ChromeClangWarningsFile",
45 toolchain_util.PrepareForBuild,
46 toolchain_util.BundleArtifacts,
47 ),
48 BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE: _Handlers(
49 "UnverifiedLlvmPgoFile",
50 toolchain_util.PrepareForBuild,
51 toolchain_util.BundleArtifacts,
52 ),
53 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
54 "UnverifiedChromeBenchmarkAfdoFile",
55 toolchain_util.PrepareForBuild,
56 toolchain_util.BundleArtifacts,
57 ),
58 BuilderConfig.Artifacts.CHROME_DEBUG_BINARY: _Handlers(
59 "ChromeDebugBinary",
60 toolchain_util.PrepareForBuild,
61 toolchain_util.BundleArtifacts,
62 ),
63 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_PERF_FILE: _Handlers(
64 "UnverifiedChromeBenchmarkPerfFile",
65 toolchain_util.PrepareForBuild,
66 toolchain_util.BundleArtifacts,
67 ),
68 BuilderConfig.Artifacts.VERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
69 "VerifiedChromeBenchmarkAfdoFile",
70 toolchain_util.PrepareForBuild,
71 toolchain_util.BundleArtifacts,
72 ),
73 BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
74 "UnverifiedKernelCwpAfdoFile",
75 toolchain_util.PrepareForBuild,
76 toolchain_util.BundleArtifacts,
77 ),
78 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
79 "VerifiedKernelCwpAfdoFile",
80 toolchain_util.PrepareForBuild,
81 toolchain_util.BundleArtifacts,
82 ),
83 BuilderConfig.Artifacts.UNVERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
84 "UnverifiedChromeCwpAfdoFile",
85 toolchain_util.PrepareForBuild,
86 toolchain_util.BundleArtifacts,
87 ),
88 BuilderConfig.Artifacts.VERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
89 "VerifiedChromeCwpAfdoFile",
90 toolchain_util.PrepareForBuild,
91 toolchain_util.BundleArtifacts,
92 ),
93 BuilderConfig.Artifacts.VERIFIED_RELEASE_AFDO_FILE: _Handlers(
94 "VerifiedReleaseAfdoFile",
95 toolchain_util.PrepareForBuild,
96 toolchain_util.BundleArtifacts,
97 ),
98 BuilderConfig.Artifacts.TOOLCHAIN_WARNING_LOGS: _Handlers(
99 "ToolchainWarningLogs",
100 toolchain_util.PrepareForBuild,
101 toolchain_util.BundleArtifacts,
102 ),
103 BuilderConfig.Artifacts.CHROME_AFDO_PROFILE_FOR_ANDROID_LINUX: _Handlers(
104 "ChromeAFDOProfileForAndroidLinux",
105 toolchain_util.PrepareForBuild,
106 toolchain_util.BundleArtifacts,
107 ),
108 BuilderConfig.Artifacts.CLANG_CRASH_DIAGNOSES: _Handlers(
109 "ClangCrashDiagnoses",
110 toolchain_util.PrepareForBuild,
111 toolchain_util.BundleArtifacts,
112 ),
113 BuilderConfig.Artifacts.COMPILER_RUSAGE_LOG: _Handlers(
114 "CompilerRusageLogs",
115 toolchain_util.PrepareForBuild,
116 toolchain_util.BundleArtifacts,
117 ),
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700118}
119
Tiancong Wangd5214132021-01-12 10:43:57 -0800120_TOOLCHAIN_COMMIT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600121 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: "VerifiedKernelCwpAfdoFile"
Tiancong Wangd5214132021-01-12 10:43:57 -0800122}
123
LaMont Jonese7821672020-04-09 08:56:26 -0600124
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700125# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
126# this should be changed.
127@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600128@validate.require("artifact_types")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700129# Note: chroot and sysroot are unspecified the first time that the build_target
130# recipe calls PrepareForBuild. The second time, they are specified. No
131# validation check because "all" values are valid.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700132@validate.validation_complete
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000133def PrepareForBuild(
Alex Klein1699fab2022-09-08 08:46:06 -0600134 input_proto: "toolchain_pb2.PrepareForToolchainBuildRequest",
135 output_proto: "toolchain_pb2.PrepareForToolchainBuildResponse",
136 _config: "api_config.ApiConfig",
137):
138 """Prepare to build toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700139
Alex Klein1699fab2022-09-08 08:46:06 -0600140 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
141 artifact_name (str): name of the artifact type.
142 chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not
143 yet been created.
144 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas).
145 Will be an empty string if the sysroot has not yet been created.
146 build_target_name (str): name of the build target (e.g., atlas). Will be
147 an empty string if the sysroot has not yet been created.
148 input_artifacts ({(str) name:[str gs_locations]}): locations for possible
149 input artifacts. The handler is expected to know which keys it should
150 be using, and ignore any keys that it does not understand.
151 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
155 being created, then return a value from toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700156
Alex Klein1699fab2022-09-08 08:46:06 -0600157 This function sets output_proto.build_relevance to the result.
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700158
Alex Klein1699fab2022-09-08 08:46:06 -0600159 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600160 input_proto: The input proto
161 output_proto: The output proto
162 _config): The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600163 """
164 if input_proto.chroot.path:
165 chroot = controller_util.ParseChroot(input_proto.chroot)
166 else:
167 chroot = None
LaMont Jones4579e8c2019-12-06 14:20:37 -0700168
Alex Klein1699fab2022-09-08 08:46:06 -0600169 input_artifacts = collections.defaultdict(list)
170 for art in input_proto.input_artifacts:
171 item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type)
172 if item:
173 input_artifacts[item.name].extend(
174 ["gs://%s" % str(x) for x in art.input_artifact_gs_locations]
175 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700176
Alex Klein1699fab2022-09-08 08:46:06 -0600177 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700178
Alex Klein1699fab2022-09-08 08:46:06 -0600179 results = set()
180 sysroot_path = input_proto.sysroot.path
181 build_target = input_proto.sysroot.build_target.name
182 for artifact_type in input_proto.artifact_types:
183 # Unknown artifact_types are an error.
184 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
185 if handler.prepare:
186 results.add(
187 handler.prepare(
188 handler.name,
189 chroot,
190 sysroot_path,
191 build_target,
192 input_artifacts,
193 profile_info,
194 )
195 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700196
Alex Klein1699fab2022-09-08 08:46:06 -0600197 # Translate the returns from the handlers we called.
198 # If any NEEDED => NEEDED
199 # elif any UNKNOWN => UNKNOWN
200 # elif any POINTLESS => POINTLESS
201 # else UNKNOWN.
202 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
203 output_proto.build_relevance = PrepareForBuildResponse.NEEDED
204 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
205 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
206 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
207 output_proto.build_relevance = PrepareForBuildResponse.POINTLESS
208 else:
209 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
210 return controller.RETURN_CODE_SUCCESS
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700211
212
213# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
214# this should be changed.
215@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600216@validate.require("chroot.path", "output_dir", "artifact_types")
217@validate.exists("output_dir")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700218@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600219def BundleArtifacts(
220 input_proto: "toolchain_pb2.BundleToolchainRequest",
221 output_proto: "toolchain_pb2.BundleToolchainResponse",
222 _config: "api_config.ApiConfig",
223):
224 """Bundle valid toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700225
Alex Klein1699fab2022-09-08 08:46:06 -0600226 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
227 artifact_name (str): name of the artifact type
228 chroot (chroot_lib.Chroot): chroot
229 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas),
230 or None.
231 chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome)
Alex Klein611dddd2022-10-11 17:02:01 -0600232 build_target_name (str): name of the build target (e.g. atlas), or None.
Alex Klein1699fab2022-09-08 08:46:06 -0600233 output_dir (str): absolute path where artifacts are being bundled.
Alex Klein611dddd2022-10-11 17:02:01 -0600234 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
Alex Klein1699fab2022-09-08 08:46:06 -0600235 profile_info ({(str) name: (str) value}) Dictionary containing profile
236 information.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700237
Alex Klein1699fab2022-09-08 08:46:06 -0600238 Note: the actual upload to GS is done by CI, not here.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700239
Alex Klein1699fab2022-09-08 08:46:06 -0600240 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600241 input_proto: The input proto
242 output_proto: The output proto
243 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600244 """
245 chroot = controller_util.ParseChroot(input_proto.chroot)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700246
Alex Klein1699fab2022-09-08 08:46:06 -0600247 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700248
Alex Klein1699fab2022-09-08 08:46:06 -0600249 output_path = Path(input_proto.output_dir)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600250
Alex Klein1699fab2022-09-08 08:46:06 -0600251 for artifact_type in input_proto.artifact_types:
252 if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
253 logging.error("%s not understood", artifact_type)
254 return controller.RETURN_CODE_UNRECOVERABLE
Alex Kleincd03a5e2021-10-18 13:23:47 -0600255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
257 if not handler or not handler.bundle:
258 logging.warning(
259 "%s does not have a handler with a bundle function.",
260 artifact_type,
261 )
262 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600263
Alex Klein1699fab2022-09-08 08:46:06 -0600264 artifacts = handler.bundle(
265 handler.name,
266 chroot,
267 input_proto.sysroot.path,
268 input_proto.sysroot.build_target.name,
269 input_proto.output_dir,
270 profile_info,
271 )
272 if not artifacts:
273 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600274
Alex Klein1699fab2022-09-08 08:46:06 -0600275 # Filter out artifacts that do not exist or are empty.
276 usable_artifacts = []
277 for artifact in artifacts:
278 artifact_path = output_path / artifact
279 if not artifact_path.exists():
280 logging.warning("%s is not in the output directory.", artifact)
281 elif not artifact_path.stat().st_size:
282 logging.warning("%s is empty.", artifact)
283 else:
284 usable_artifacts.append(artifact)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600285
Alex Klein1699fab2022-09-08 08:46:06 -0600286 if not usable_artifacts:
287 logging.warning(
288 "No usable artifacts for artifact type %s", artifact_type
289 )
290 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600291
Alex Klein1699fab2022-09-08 08:46:06 -0600292 # Add all usable artifacts.
293 art_info = output_proto.artifacts_info.add()
294 art_info.artifact_type = artifact_type
295 for artifact in usable_artifacts:
296 art_info.artifacts.add().path = artifact
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700297
298
Tiancong Wangd5214132021-01-12 10:43:57 -0800299def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600300 """Add successful status to the faux response."""
301 file_info = output_proto.updated_files.add()
302 file_info.path = "/any/modified/file"
303 output_proto.commit_message = "Commit message"
Tiancong Wangd5214132021-01-12 10:43:57 -0800304
305
306@faux.empty_error
307@faux.success(_GetUpdatedFilesResponse)
Alex Klein1699fab2022-09-08 08:46:06 -0600308@validate.require("uploaded_artifacts")
Tiancong Wangd5214132021-01-12 10:43:57 -0800309@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600310def GetUpdatedFiles(
311 input_proto: "toolchain_pb2.GetUpdatedFilesRequest",
312 output_proto: "toolchain_pb2.GetUpdatedFilesResponse",
313 _config: "api_config.ApiConfig",
314):
315 """Use uploaded artifacts to update some updates in a chromeos checkout.
Tiancong Wangd5214132021-01-12 10:43:57 -0800316
Alex Klein1699fab2022-09-08 08:46:06 -0600317 The function will call toolchain_util.GetUpdatedFiles using the type of
318 uploaded artifacts to make some changes in a checkout, and return the list
319 of change files together with commit message.
Alex Klein611dddd2022-10-11 17:02:01 -0600320 updated_artifacts: A list of UpdatedArtifacts type which contains a
321 tuple of artifact info and profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600322 Note: the actual creation of the commit is done by CI, not here.
Tiancong Wangd5214132021-01-12 10:43:57 -0800323
Alex Klein1699fab2022-09-08 08:46:06 -0600324 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600325 input_proto: The input proto
326 output_proto: The output proto
327 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600328 """
329 commit_message = ""
330 for artifact in input_proto.uploaded_artifacts:
331 artifact_type = artifact.artifact_info.artifact_type
332 if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS:
333 logging.error("%s not understood", artifact_type)
334 return controller.RETURN_CODE_UNRECOVERABLE
335 artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type]
336 if artifact_name:
337 assert (
338 len(artifact.artifact_info.artifacts) == 1
339 ), "Only one file to update per each artifact"
340 updated_files, message = toolchain_util.GetUpdatedFiles(
341 artifact_name,
342 artifact.artifact_info.artifacts[0].path,
343 _GetProfileInfoDict(artifact.profile_info),
344 )
345 for f in updated_files:
346 file_info = output_proto.updated_files.add()
347 file_info.path = f
Tiancong Wangd5214132021-01-12 10:43:57 -0800348
Alex Klein1699fab2022-09-08 08:46:06 -0600349 commit_message += message + "\n"
350 output_proto.commit_message = commit_message
351 # No commit footer is added for now. Can add more here if needed
Tiancong Wangd5214132021-01-12 10:43:57 -0800352
353
Alex Klein1699fab2022-09-08 08:46:06 -0600354def _GetProfileInfoDict(profile_info: "toolchain_pb2.ArtifactProfileInfo"):
355 """Convert profile_info to a dict.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000356
Alex Klein1699fab2022-09-08 08:46:06 -0600357 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600358 profile_info: The artifact profile_info.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000359
Alex Klein1699fab2022-09-08 08:46:06 -0600360 Returns:
Alex Klein611dddd2022-10-11 17:02:01 -0600361 A dictionary containing profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600362 """
363 ret = {}
364 which = profile_info.WhichOneof("artifact_profile_info")
365 if which:
366 value = getattr(profile_info, which)
367 # If it is a message, then use the contents of the message. This works as
368 # long as simple types do not have a 'DESCRIPTOR' attribute. (And protobuf
369 # messages do.)
370 if getattr(value, "DESCRIPTOR", None):
371 ret.update({k.name: v for k, v in value.ListFields()})
372 else:
373 ret[which] = value
374 return ret
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000375
376
377LINTER_CODES = {
Alex Klein1699fab2022-09-08 08:46:06 -0600378 "clang_tidy": toolchain_pb2.LinterFinding.CLANG_TIDY,
379 "cargo_clippy": toolchain_pb2.LinterFinding.CARGO_CLIPPY,
380 "go_lint": toolchain_pb2.LinterFinding.GO_LINT,
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000381}
382
383
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000384@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600385@validate.exists("sysroot.path")
386@validate.require("packages")
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000387@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600388def EmergeWithLinting(
389 input_proto: "toolchain_pb2.LinterRequest",
390 output_proto: "toolchain_pb2.LinterResponse",
391 _config: "api_config.ApiConfig",
392):
393 """Emerge packages with linter features enabled and retrieves all findings.
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000394
Alex Klein1699fab2022-09-08 08:46:06 -0600395 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600396 input_proto: The nput proto with package and sysroot info.
397 output_proto: The output proto where findings are stored.
398 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600399 """
400 packages = [
401 controller_util.deserialize_package_info(package)
402 for package in input_proto.packages
403 ]
Ryan Beltran7d191802021-11-24 00:08:17 +0000404
Alex Klein1699fab2022-09-08 08:46:06 -0600405 build_linter = toolchain.BuildLinter(
406 packages,
407 input_proto.sysroot.path,
408 differential=input_proto.filter_modified,
409 )
Ryan Beltran7d191802021-11-24 00:08:17 +0000410
Alex Klein1699fab2022-09-08 08:46:06 -0600411 use_clippy = (
412 toolchain_pb2.LinterFinding.CARGO_CLIPPY
413 not in input_proto.disabled_linters
414 )
415 use_tidy = (
416 toolchain_pb2.LinterFinding.CLANG_TIDY
417 not in input_proto.disabled_linters
418 )
419 use_golint = (
420 toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters
421 )
Ryan Beltran1277cb82022-11-27 03:15:36 +0000422 use_iwyu = (
423 toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters
424 )
Ryan Beltran4425d5f2022-07-20 18:34:33 +0000425
Alex Klein1699fab2022-09-08 08:46:06 -0600426 findings = build_linter.emerge_with_linting(
Ryan Beltran1277cb82022-11-27 03:15:36 +0000427 use_clippy=use_clippy,
428 use_tidy=use_tidy,
429 use_golint=use_golint,
430 use_iwyu=use_iwyu,
Alex Klein1699fab2022-09-08 08:46:06 -0600431 )
Ryan Beltranf9a86f42022-04-13 20:58:18 +0000432
Alex Klein1699fab2022-09-08 08:46:06 -0600433 for finding in findings:
434 locations = []
435 for location in finding.locations:
436 locations.append(
437 toolchain_pb2.LinterFindingLocation(
438 filepath=location.filepath,
439 line_start=location.line_start,
440 line_end=location.line_end,
441 )
442 )
443 output_proto.findings.append(
444 toolchain_pb2.LinterFinding(
445 message=finding.message,
446 locations=locations,
447 linter=LINTER_CODES[finding.linter],
448 )
449 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000450
451
452@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600453@validate.require("board")
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000454@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600455def GetToolchainsForBoard(
456 input_proto: "toolchain_pb2.ToolchainsRequest",
457 output_proto: "toolchain_pb2.ToolchainsReponse",
458 _config: "api_config.ApiConfig",
459):
460 """Gets the default and non-default toolchains for a board.
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000461
Alex Klein1699fab2022-09-08 08:46:06 -0600462 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600463 input_proto: The input proto with board and sysroot info.
464 output_proto: The output proto where findings are stored.
465 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600466 """
467 toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board)
468 output_proto.default_toolchains.extend(
469 list(toolchain_lib.FilterToolchains(toolchains, "default", True))
470 )
471 output_proto.nondefault_toolchains.extend(
472 list(toolchain_lib.FilterToolchains(toolchains, "default", False))
473 )