blob: d5c59b3b258c37ad71bd47ac5040411b636950a8 [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
Adrian Dolef87c5762022-12-15 22:00:50 +0000384@validate.require("sysroot.build_target.name")
385@validate.require("start_time")
386@validate.validation_complete
387def EmergeAndUploadLints(
388 input_proto: toolchain_pb2.DashboardLintRequest,
389 output_proto: toolchain_pb2.DashboardLintResponse,
390 _config,
391):
392 """Lints all platform2 packages and uploads lints to GS"""
393 board = input_proto.sysroot.build_target.name
394 output_proto.gs_path = toolchain.emerge_and_upload_lints(
395 board, input_proto.start_time
396 )
397
398
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000399@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600400@validate.exists("sysroot.path")
401@validate.require("packages")
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000402@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600403def EmergeWithLinting(
404 input_proto: "toolchain_pb2.LinterRequest",
405 output_proto: "toolchain_pb2.LinterResponse",
406 _config: "api_config.ApiConfig",
407):
408 """Emerge packages with linter features enabled and retrieves all findings.
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000409
Alex Klein1699fab2022-09-08 08:46:06 -0600410 Args:
Adrian Dolef87c5762022-12-15 22:00:50 +0000411 input_proto: The input proto with package and sysroot info.
Alex Klein611dddd2022-10-11 17:02:01 -0600412 output_proto: The output proto where findings are stored.
413 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600414 """
415 packages = [
416 controller_util.deserialize_package_info(package)
417 for package in input_proto.packages
418 ]
Ryan Beltran7d191802021-11-24 00:08:17 +0000419
Alex Klein1699fab2022-09-08 08:46:06 -0600420 build_linter = toolchain.BuildLinter(
421 packages,
422 input_proto.sysroot.path,
423 differential=input_proto.filter_modified,
424 )
Ryan Beltran7d191802021-11-24 00:08:17 +0000425
Alex Klein1699fab2022-09-08 08:46:06 -0600426 use_clippy = (
427 toolchain_pb2.LinterFinding.CARGO_CLIPPY
428 not in input_proto.disabled_linters
429 )
430 use_tidy = (
431 toolchain_pb2.LinterFinding.CLANG_TIDY
432 not in input_proto.disabled_linters
433 )
434 use_golint = (
435 toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters
436 )
Ryan Beltran1277cb82022-11-27 03:15:36 +0000437 use_iwyu = (
438 toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters
439 )
Ryan Beltran4425d5f2022-07-20 18:34:33 +0000440
Alex Klein1699fab2022-09-08 08:46:06 -0600441 findings = build_linter.emerge_with_linting(
Ryan Beltran1277cb82022-11-27 03:15:36 +0000442 use_clippy=use_clippy,
443 use_tidy=use_tidy,
444 use_golint=use_golint,
445 use_iwyu=use_iwyu,
Alex Klein1699fab2022-09-08 08:46:06 -0600446 )
Ryan Beltranf9a86f42022-04-13 20:58:18 +0000447
Alex Klein1699fab2022-09-08 08:46:06 -0600448 for finding in findings:
449 locations = []
450 for location in finding.locations:
451 locations.append(
452 toolchain_pb2.LinterFindingLocation(
453 filepath=location.filepath,
454 line_start=location.line_start,
455 line_end=location.line_end,
456 )
457 )
458 output_proto.findings.append(
459 toolchain_pb2.LinterFinding(
460 message=finding.message,
461 locations=locations,
462 linter=LINTER_CODES[finding.linter],
Ryan Beltranc14de9d2023-01-10 23:44:59 +0000463 package=finding.package,
Alex Klein1699fab2022-09-08 08:46:06 -0600464 )
465 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000466
467
468@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600469@validate.require("board")
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000470@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600471def GetToolchainsForBoard(
472 input_proto: "toolchain_pb2.ToolchainsRequest",
473 output_proto: "toolchain_pb2.ToolchainsReponse",
474 _config: "api_config.ApiConfig",
475):
476 """Gets the default and non-default toolchains for a board.
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000477
Alex Klein1699fab2022-09-08 08:46:06 -0600478 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600479 input_proto: The input proto with board and sysroot info.
480 output_proto: The output proto where findings are stored.
481 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600482 """
483 toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board)
484 output_proto.default_toolchains.extend(
485 list(toolchain_lib.FilterToolchains(toolchains, "default", True))
486 )
487 output_proto.nondefault_toolchains.extend(
488 list(toolchain_lib.FilterToolchains(toolchains, "default", False))
489 )