blob: 0a62c30bb72a3ce7b5d8e4463822d712930872af [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
Alex Kleinab87ceb2023-01-24 12:00:51 -0700120# pylint: disable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800121_TOOLCHAIN_COMMIT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600122 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: "VerifiedKernelCwpAfdoFile"
Tiancong Wangd5214132021-01-12 10:43:57 -0800123}
Alex Kleinab87ceb2023-01-24 12:00:51 -0700124# pylint: enable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800125
LaMont Jonese7821672020-04-09 08:56:26 -0600126
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700127# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
128# this should be changed.
129@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600130@validate.require("artifact_types")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700131# Note: chroot and sysroot are unspecified the first time that the build_target
132# recipe calls PrepareForBuild. The second time, they are specified. No
133# validation check because "all" values are valid.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700134@validate.validation_complete
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000135def PrepareForBuild(
Alex Klein1699fab2022-09-08 08:46:06 -0600136 input_proto: "toolchain_pb2.PrepareForToolchainBuildRequest",
137 output_proto: "toolchain_pb2.PrepareForToolchainBuildResponse",
138 _config: "api_config.ApiConfig",
139):
140 """Prepare to build toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700141
Alex Klein1699fab2022-09-08 08:46:06 -0600142 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
143 artifact_name (str): name of the artifact type.
144 chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not
145 yet been created.
146 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas).
147 Will be an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700148 build_target_name (str): name of the build target (e.g., atlas). Will be
Alex Klein1699fab2022-09-08 08:46:06 -0600149 an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700150 input_artifacts ({(str) name:[str gs_locations]}): locations for
151 possible input artifacts. The handler is expected to know which
152 keys it should be using, and ignore any keys that it does not
153 understand.
Alex Klein1699fab2022-09-08 08:46:06 -0600154 profile_info ({(str) name: (str) value}) Dictionary containing profile
155 information.
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700156
Alex Klein1699fab2022-09-08 08:46:06 -0600157 They locate and modify any ebuilds and/or source required for the artifact
Alex Kleinab87ceb2023-01-24 12:00:51 -0700158 being created, then return a value from
159 toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700160
Alex Klein1699fab2022-09-08 08:46:06 -0600161 This function sets output_proto.build_relevance to the result.
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700162
Alex Klein1699fab2022-09-08 08:46:06 -0600163 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600164 input_proto: The input proto
165 output_proto: The output proto
166 _config): The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600167 """
168 if input_proto.chroot.path:
169 chroot = controller_util.ParseChroot(input_proto.chroot)
170 else:
171 chroot = None
LaMont Jones4579e8c2019-12-06 14:20:37 -0700172
Alex Klein1699fab2022-09-08 08:46:06 -0600173 input_artifacts = collections.defaultdict(list)
174 for art in input_proto.input_artifacts:
175 item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type)
176 if item:
177 input_artifacts[item.name].extend(
178 ["gs://%s" % str(x) for x in art.input_artifact_gs_locations]
179 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700180
Alex Klein1699fab2022-09-08 08:46:06 -0600181 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700182
Alex Klein1699fab2022-09-08 08:46:06 -0600183 results = set()
184 sysroot_path = input_proto.sysroot.path
185 build_target = input_proto.sysroot.build_target.name
186 for artifact_type in input_proto.artifact_types:
187 # Unknown artifact_types are an error.
188 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
189 if handler.prepare:
190 results.add(
191 handler.prepare(
192 handler.name,
193 chroot,
194 sysroot_path,
195 build_target,
196 input_artifacts,
197 profile_info,
198 )
199 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700200
Alex Klein1699fab2022-09-08 08:46:06 -0600201 # Translate the returns from the handlers we called.
202 # If any NEEDED => NEEDED
203 # elif any UNKNOWN => UNKNOWN
204 # elif any POINTLESS => POINTLESS
205 # else UNKNOWN.
206 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
207 output_proto.build_relevance = PrepareForBuildResponse.NEEDED
208 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
209 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
210 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
211 output_proto.build_relevance = PrepareForBuildResponse.POINTLESS
212 else:
213 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
214 return controller.RETURN_CODE_SUCCESS
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700215
216
217# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
218# this should be changed.
219@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600220@validate.require("chroot.path", "output_dir", "artifact_types")
221@validate.exists("output_dir")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700222@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600223def BundleArtifacts(
224 input_proto: "toolchain_pb2.BundleToolchainRequest",
225 output_proto: "toolchain_pb2.BundleToolchainResponse",
226 _config: "api_config.ApiConfig",
227):
228 """Bundle valid toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700229
Alex Klein1699fab2022-09-08 08:46:06 -0600230 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
231 artifact_name (str): name of the artifact type
232 chroot (chroot_lib.Chroot): chroot
233 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas),
234 or None.
235 chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome)
Alex Klein611dddd2022-10-11 17:02:01 -0600236 build_target_name (str): name of the build target (e.g. atlas), or None.
Alex Klein1699fab2022-09-08 08:46:06 -0600237 output_dir (str): absolute path where artifacts are being bundled.
Alex Klein611dddd2022-10-11 17:02:01 -0600238 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
Alex Klein1699fab2022-09-08 08:46:06 -0600239 profile_info ({(str) name: (str) value}) Dictionary containing profile
240 information.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700241
Alex Klein1699fab2022-09-08 08:46:06 -0600242 Note: the actual upload to GS is done by CI, not here.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700243
Alex Klein1699fab2022-09-08 08:46:06 -0600244 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600245 input_proto: The input proto
246 output_proto: The output proto
247 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600248 """
249 chroot = controller_util.ParseChroot(input_proto.chroot)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700250
Alex Klein1699fab2022-09-08 08:46:06 -0600251 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700252
Alex Klein1699fab2022-09-08 08:46:06 -0600253 output_path = Path(input_proto.output_dir)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600254
Alex Klein1699fab2022-09-08 08:46:06 -0600255 for artifact_type in input_proto.artifact_types:
256 if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
257 logging.error("%s not understood", artifact_type)
258 return controller.RETURN_CODE_UNRECOVERABLE
Alex Kleincd03a5e2021-10-18 13:23:47 -0600259
Alex Klein1699fab2022-09-08 08:46:06 -0600260 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
261 if not handler or not handler.bundle:
262 logging.warning(
263 "%s does not have a handler with a bundle function.",
264 artifact_type,
265 )
266 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600267
Alex Klein1699fab2022-09-08 08:46:06 -0600268 artifacts = handler.bundle(
269 handler.name,
270 chroot,
271 input_proto.sysroot.path,
272 input_proto.sysroot.build_target.name,
273 input_proto.output_dir,
274 profile_info,
275 )
276 if not artifacts:
277 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600278
Alex Klein1699fab2022-09-08 08:46:06 -0600279 # Filter out artifacts that do not exist or are empty.
280 usable_artifacts = []
281 for artifact in artifacts:
282 artifact_path = output_path / artifact
283 if not artifact_path.exists():
284 logging.warning("%s is not in the output directory.", artifact)
285 elif not artifact_path.stat().st_size:
286 logging.warning("%s is empty.", artifact)
287 else:
288 usable_artifacts.append(artifact)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600289
Alex Klein1699fab2022-09-08 08:46:06 -0600290 if not usable_artifacts:
291 logging.warning(
292 "No usable artifacts for artifact type %s", artifact_type
293 )
294 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600295
Alex Klein1699fab2022-09-08 08:46:06 -0600296 # Add all usable artifacts.
297 art_info = output_proto.artifacts_info.add()
298 art_info.artifact_type = artifact_type
299 for artifact in usable_artifacts:
300 art_info.artifacts.add().path = artifact
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700301
302
Tiancong Wangd5214132021-01-12 10:43:57 -0800303def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600304 """Add successful status to the faux response."""
305 file_info = output_proto.updated_files.add()
306 file_info.path = "/any/modified/file"
307 output_proto.commit_message = "Commit message"
Tiancong Wangd5214132021-01-12 10:43:57 -0800308
309
310@faux.empty_error
311@faux.success(_GetUpdatedFilesResponse)
Alex Klein1699fab2022-09-08 08:46:06 -0600312@validate.require("uploaded_artifacts")
Tiancong Wangd5214132021-01-12 10:43:57 -0800313@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600314def GetUpdatedFiles(
315 input_proto: "toolchain_pb2.GetUpdatedFilesRequest",
316 output_proto: "toolchain_pb2.GetUpdatedFilesResponse",
317 _config: "api_config.ApiConfig",
318):
319 """Use uploaded artifacts to update some updates in a chromeos checkout.
Tiancong Wangd5214132021-01-12 10:43:57 -0800320
Alex Klein1699fab2022-09-08 08:46:06 -0600321 The function will call toolchain_util.GetUpdatedFiles using the type of
322 uploaded artifacts to make some changes in a checkout, and return the list
323 of change files together with commit message.
Alex Klein611dddd2022-10-11 17:02:01 -0600324 updated_artifacts: A list of UpdatedArtifacts type which contains a
325 tuple of artifact info and profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600326 Note: the actual creation of the commit is done by CI, not here.
Tiancong Wangd5214132021-01-12 10:43:57 -0800327
Alex Klein1699fab2022-09-08 08:46:06 -0600328 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600329 input_proto: The input proto
330 output_proto: The output proto
331 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600332 """
333 commit_message = ""
334 for artifact in input_proto.uploaded_artifacts:
335 artifact_type = artifact.artifact_info.artifact_type
336 if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS:
337 logging.error("%s not understood", artifact_type)
338 return controller.RETURN_CODE_UNRECOVERABLE
339 artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type]
340 if artifact_name:
341 assert (
342 len(artifact.artifact_info.artifacts) == 1
343 ), "Only one file to update per each artifact"
344 updated_files, message = toolchain_util.GetUpdatedFiles(
345 artifact_name,
346 artifact.artifact_info.artifacts[0].path,
347 _GetProfileInfoDict(artifact.profile_info),
348 )
349 for f in updated_files:
350 file_info = output_proto.updated_files.add()
351 file_info.path = f
Tiancong Wangd5214132021-01-12 10:43:57 -0800352
Alex Klein1699fab2022-09-08 08:46:06 -0600353 commit_message += message + "\n"
354 output_proto.commit_message = commit_message
355 # No commit footer is added for now. Can add more here if needed
Tiancong Wangd5214132021-01-12 10:43:57 -0800356
357
Alex Klein1699fab2022-09-08 08:46:06 -0600358def _GetProfileInfoDict(profile_info: "toolchain_pb2.ArtifactProfileInfo"):
359 """Convert profile_info to a dict.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000360
Alex Klein1699fab2022-09-08 08:46:06 -0600361 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600362 profile_info: The artifact profile_info.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000363
Alex Klein1699fab2022-09-08 08:46:06 -0600364 Returns:
Alex Klein611dddd2022-10-11 17:02:01 -0600365 A dictionary containing profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600366 """
367 ret = {}
368 which = profile_info.WhichOneof("artifact_profile_info")
369 if which:
370 value = getattr(profile_info, which)
Alex Kleinab87ceb2023-01-24 12:00:51 -0700371 # If it is a message, then use the contents of the message. This works
372 # as long as simple types do not have a 'DESCRIPTOR' attribute. (And
373 # protobuf messages do.)
Alex Klein1699fab2022-09-08 08:46:06 -0600374 if getattr(value, "DESCRIPTOR", None):
375 ret.update({k.name: v for k, v in value.ListFields()})
376 else:
377 ret[which] = value
Denis Nikitin62e69862023-02-13 23:37:00 -0800378 arch = getattr(profile_info, "arch", None)
379 if arch:
380 ret["arch"] = arch
Alex Klein1699fab2022-09-08 08:46:06 -0600381 return ret
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000382
383
384LINTER_CODES = {
Alex Klein1699fab2022-09-08 08:46:06 -0600385 "clang_tidy": toolchain_pb2.LinterFinding.CLANG_TIDY,
386 "cargo_clippy": toolchain_pb2.LinterFinding.CARGO_CLIPPY,
387 "go_lint": toolchain_pb2.LinterFinding.GO_LINT,
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000388}
389
390
Adrian Dolef87c5762022-12-15 22:00:50 +0000391@validate.require("sysroot.build_target.name")
392@validate.require("start_time")
393@validate.validation_complete
394def EmergeAndUploadLints(
395 input_proto: toolchain_pb2.DashboardLintRequest,
396 output_proto: toolchain_pb2.DashboardLintResponse,
397 _config,
398):
399 """Lints all platform2 packages and uploads lints to GS"""
400 board = input_proto.sysroot.build_target.name
401 output_proto.gs_path = toolchain.emerge_and_upload_lints(
402 board, input_proto.start_time
403 )
404
405
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000406@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600407@validate.exists("sysroot.path")
408@validate.require("packages")
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000409@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600410def EmergeWithLinting(
411 input_proto: "toolchain_pb2.LinterRequest",
412 output_proto: "toolchain_pb2.LinterResponse",
413 _config: "api_config.ApiConfig",
414):
415 """Emerge packages with linter features enabled and retrieves all findings.
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000416
Alex Klein1699fab2022-09-08 08:46:06 -0600417 Args:
Adrian Dolef87c5762022-12-15 22:00:50 +0000418 input_proto: The input proto with package and sysroot info.
Alex Klein611dddd2022-10-11 17:02:01 -0600419 output_proto: The output proto where findings are stored.
420 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600421 """
422 packages = [
423 controller_util.deserialize_package_info(package)
424 for package in input_proto.packages
425 ]
Ryan Beltran7d191802021-11-24 00:08:17 +0000426
Alex Klein1699fab2022-09-08 08:46:06 -0600427 build_linter = toolchain.BuildLinter(
428 packages,
429 input_proto.sysroot.path,
430 differential=input_proto.filter_modified,
431 )
Ryan Beltran7d191802021-11-24 00:08:17 +0000432
Alex Klein1699fab2022-09-08 08:46:06 -0600433 use_clippy = (
434 toolchain_pb2.LinterFinding.CARGO_CLIPPY
435 not in input_proto.disabled_linters
436 )
437 use_tidy = (
438 toolchain_pb2.LinterFinding.CLANG_TIDY
439 not in input_proto.disabled_linters
440 )
441 use_golint = (
442 toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters
443 )
Ryan Beltran1277cb82022-11-27 03:15:36 +0000444 use_iwyu = (
445 toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters
446 )
Ryan Beltran4425d5f2022-07-20 18:34:33 +0000447
Alex Klein1699fab2022-09-08 08:46:06 -0600448 findings = build_linter.emerge_with_linting(
Ryan Beltran1277cb82022-11-27 03:15:36 +0000449 use_clippy=use_clippy,
450 use_tidy=use_tidy,
451 use_golint=use_golint,
452 use_iwyu=use_iwyu,
Alex Klein1699fab2022-09-08 08:46:06 -0600453 )
Ryan Beltranf9a86f42022-04-13 20:58:18 +0000454
Alex Klein1699fab2022-09-08 08:46:06 -0600455 for finding in findings:
456 locations = []
457 for location in finding.locations:
458 locations.append(
459 toolchain_pb2.LinterFindingLocation(
460 filepath=location.filepath,
461 line_start=location.line_start,
462 line_end=location.line_end,
463 )
464 )
465 output_proto.findings.append(
466 toolchain_pb2.LinterFinding(
467 message=finding.message,
468 locations=locations,
469 linter=LINTER_CODES[finding.linter],
Ryan Beltranc14de9d2023-01-10 23:44:59 +0000470 package=finding.package,
Alex Klein1699fab2022-09-08 08:46:06 -0600471 )
472 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000473
474
475@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600476@validate.require("board")
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000477@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600478def GetToolchainsForBoard(
479 input_proto: "toolchain_pb2.ToolchainsRequest",
480 output_proto: "toolchain_pb2.ToolchainsReponse",
481 _config: "api_config.ApiConfig",
482):
483 """Gets the default and non-default toolchains for a board.
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000484
Alex Klein1699fab2022-09-08 08:46:06 -0600485 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600486 input_proto: The input proto with board and sysroot info.
487 output_proto: The output proto where findings are stored.
488 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600489 """
490 toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board)
491 output_proto.default_toolchains.extend(
492 list(toolchain_lib.FilterToolchains(toolchains, "default", True))
493 )
494 output_proto.nondefault_toolchains.extend(
495 list(toolchain_lib.FilterToolchains(toolchains, "default", False))
496 )