blob: 0735ed72c6109677e27d3d03b7cdffafc68f0c6b [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
Jack Neus4ee7b1d2022-06-27 19:54:18 +000020from chromite.lib import toolchain as toolchain_lib
Chris McDonald1672ddb2021-07-21 11:48:23 -060021from chromite.lib import toolchain_util
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000022from chromite.service import toolchain
Ryan Beltran7d191802021-11-24 00:08:17 +000023
Mike Frysingerea11fdd2022-05-06 22:59:33 -040024
Jack Neus4ee7b1d2022-06-27 19:54:18 +000025if TYPE_CHECKING:
Alex Klein1699fab2022-09-08 08:46:06 -060026 from chromite.api import api_config
Jack Neus4ee7b1d2022-06-27 19:54:18 +000027
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000028# TODO(b/229665884): Move the implementation details for most/all endpoints to:
29# chromite/services/toolchain.py
30# This migration has been done for linting endpoints but not yet for others.
Chris McDonald1672ddb2021-07-21 11:48:23 -060031
Alex Klein1699fab2022-09-08 08:46:06 -060032_Handlers = collections.namedtuple("_Handlers", ["name", "prepare", "bundle"])
LaMont Jonesb20b3d92019-11-23 11:47:48 -070033_TOOLCHAIN_ARTIFACT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -060034 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE: _Handlers(
35 "UnverifiedChromeLlvmOrderfile",
36 toolchain_util.PrepareForBuild,
37 toolchain_util.BundleArtifacts,
38 ),
39 BuilderConfig.Artifacts.VERIFIED_CHROME_LLVM_ORDERFILE: _Handlers(
40 "VerifiedChromeLlvmOrderfile",
41 toolchain_util.PrepareForBuild,
42 toolchain_util.BundleArtifacts,
43 ),
44 BuilderConfig.Artifacts.CHROME_CLANG_WARNINGS_FILE: _Handlers(
45 "ChromeClangWarningsFile",
46 toolchain_util.PrepareForBuild,
47 toolchain_util.BundleArtifacts,
48 ),
49 BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE: _Handlers(
50 "UnverifiedLlvmPgoFile",
51 toolchain_util.PrepareForBuild,
52 toolchain_util.BundleArtifacts,
53 ),
54 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
55 "UnverifiedChromeBenchmarkAfdoFile",
56 toolchain_util.PrepareForBuild,
57 toolchain_util.BundleArtifacts,
58 ),
59 BuilderConfig.Artifacts.CHROME_DEBUG_BINARY: _Handlers(
60 "ChromeDebugBinary",
61 toolchain_util.PrepareForBuild,
62 toolchain_util.BundleArtifacts,
63 ),
64 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_PERF_FILE: _Handlers(
65 "UnverifiedChromeBenchmarkPerfFile",
66 toolchain_util.PrepareForBuild,
67 toolchain_util.BundleArtifacts,
68 ),
69 BuilderConfig.Artifacts.VERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
70 "VerifiedChromeBenchmarkAfdoFile",
71 toolchain_util.PrepareForBuild,
72 toolchain_util.BundleArtifacts,
73 ),
74 BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
75 "UnverifiedKernelCwpAfdoFile",
76 toolchain_util.PrepareForBuild,
77 toolchain_util.BundleArtifacts,
78 ),
79 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
80 "VerifiedKernelCwpAfdoFile",
81 toolchain_util.PrepareForBuild,
82 toolchain_util.BundleArtifacts,
83 ),
84 BuilderConfig.Artifacts.UNVERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
85 "UnverifiedChromeCwpAfdoFile",
86 toolchain_util.PrepareForBuild,
87 toolchain_util.BundleArtifacts,
88 ),
89 BuilderConfig.Artifacts.VERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
90 "VerifiedChromeCwpAfdoFile",
91 toolchain_util.PrepareForBuild,
92 toolchain_util.BundleArtifacts,
93 ),
94 BuilderConfig.Artifacts.VERIFIED_RELEASE_AFDO_FILE: _Handlers(
95 "VerifiedReleaseAfdoFile",
96 toolchain_util.PrepareForBuild,
97 toolchain_util.BundleArtifacts,
98 ),
99 BuilderConfig.Artifacts.TOOLCHAIN_WARNING_LOGS: _Handlers(
100 "ToolchainWarningLogs",
101 toolchain_util.PrepareForBuild,
102 toolchain_util.BundleArtifacts,
103 ),
104 BuilderConfig.Artifacts.CHROME_AFDO_PROFILE_FOR_ANDROID_LINUX: _Handlers(
105 "ChromeAFDOProfileForAndroidLinux",
106 toolchain_util.PrepareForBuild,
107 toolchain_util.BundleArtifacts,
108 ),
109 BuilderConfig.Artifacts.CLANG_CRASH_DIAGNOSES: _Handlers(
110 "ClangCrashDiagnoses",
111 toolchain_util.PrepareForBuild,
112 toolchain_util.BundleArtifacts,
113 ),
114 BuilderConfig.Artifacts.COMPILER_RUSAGE_LOG: _Handlers(
115 "CompilerRusageLogs",
116 toolchain_util.PrepareForBuild,
117 toolchain_util.BundleArtifacts,
118 ),
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700119}
120
Alex Kleinab87ceb2023-01-24 12:00:51 -0700121# pylint: disable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800122_TOOLCHAIN_COMMIT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600123 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: "VerifiedKernelCwpAfdoFile"
Tiancong Wangd5214132021-01-12 10:43:57 -0800124}
Alex Kleinab87ceb2023-01-24 12:00:51 -0700125# pylint: enable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800126
LaMont Jonese7821672020-04-09 08:56:26 -0600127
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700128# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
129# this should be changed.
130@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600131@validate.require("artifact_types")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700132# Note: chroot and sysroot are unspecified the first time that the build_target
133# recipe calls PrepareForBuild. The second time, they are specified. No
134# validation check because "all" values are valid.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700135@validate.validation_complete
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000136def PrepareForBuild(
Alex Klein1699fab2022-09-08 08:46:06 -0600137 input_proto: "toolchain_pb2.PrepareForToolchainBuildRequest",
138 output_proto: "toolchain_pb2.PrepareForToolchainBuildResponse",
139 _config: "api_config.ApiConfig",
140):
141 """Prepare to build toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700142
Alex Klein1699fab2022-09-08 08:46:06 -0600143 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
144 artifact_name (str): name of the artifact type.
145 chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not
146 yet been created.
147 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas).
148 Will be an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700149 build_target_name (str): name of the build target (e.g., atlas). Will be
Alex Klein1699fab2022-09-08 08:46:06 -0600150 an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700151 input_artifacts ({(str) name:[str gs_locations]}): locations for
152 possible input artifacts. The handler is expected to know which
153 keys it should be using, and ignore any keys that it does not
154 understand.
Alex Klein1699fab2022-09-08 08:46:06 -0600155 profile_info ({(str) name: (str) value}) Dictionary containing profile
156 information.
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700157
Alex Klein1699fab2022-09-08 08:46:06 -0600158 They locate and modify any ebuilds and/or source required for the artifact
Alex Kleinab87ceb2023-01-24 12:00:51 -0700159 being created, then return a value from
160 toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700161
Alex Klein1699fab2022-09-08 08:46:06 -0600162 This function sets output_proto.build_relevance to the result.
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700163
Alex Klein1699fab2022-09-08 08:46:06 -0600164 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600165 input_proto: The input proto
166 output_proto: The output proto
167 _config): The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600168 """
169 if input_proto.chroot.path:
170 chroot = controller_util.ParseChroot(input_proto.chroot)
171 else:
172 chroot = None
LaMont Jones4579e8c2019-12-06 14:20:37 -0700173
Alex Klein1699fab2022-09-08 08:46:06 -0600174 input_artifacts = collections.defaultdict(list)
175 for art in input_proto.input_artifacts:
176 item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type)
177 if item:
178 input_artifacts[item.name].extend(
179 ["gs://%s" % str(x) for x in art.input_artifact_gs_locations]
180 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700181
Alex Klein1699fab2022-09-08 08:46:06 -0600182 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700183
Alex Klein1699fab2022-09-08 08:46:06 -0600184 results = set()
185 sysroot_path = input_proto.sysroot.path
186 build_target = input_proto.sysroot.build_target.name
187 for artifact_type in input_proto.artifact_types:
188 # Unknown artifact_types are an error.
189 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
190 if handler.prepare:
191 results.add(
192 handler.prepare(
193 handler.name,
194 chroot,
195 sysroot_path,
196 build_target,
197 input_artifacts,
198 profile_info,
199 )
200 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700201
Alex Klein1699fab2022-09-08 08:46:06 -0600202 # Translate the returns from the handlers we called.
203 # If any NEEDED => NEEDED
204 # elif any UNKNOWN => UNKNOWN
205 # elif any POINTLESS => POINTLESS
206 # else UNKNOWN.
207 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
208 output_proto.build_relevance = PrepareForBuildResponse.NEEDED
209 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
210 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
211 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
212 output_proto.build_relevance = PrepareForBuildResponse.POINTLESS
213 else:
214 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
215 return controller.RETURN_CODE_SUCCESS
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700216
217
218# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
219# this should be changed.
220@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600221@validate.require("chroot.path", "output_dir", "artifact_types")
222@validate.exists("output_dir")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700223@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600224def BundleArtifacts(
225 input_proto: "toolchain_pb2.BundleToolchainRequest",
226 output_proto: "toolchain_pb2.BundleToolchainResponse",
227 _config: "api_config.ApiConfig",
228):
229 """Bundle valid toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700230
Alex Klein1699fab2022-09-08 08:46:06 -0600231 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
232 artifact_name (str): name of the artifact type
233 chroot (chroot_lib.Chroot): chroot
234 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas),
235 or None.
236 chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome)
Alex Klein611dddd2022-10-11 17:02:01 -0600237 build_target_name (str): name of the build target (e.g. atlas), or None.
Alex Klein1699fab2022-09-08 08:46:06 -0600238 output_dir (str): absolute path where artifacts are being bundled.
Alex Klein611dddd2022-10-11 17:02:01 -0600239 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
Alex Klein1699fab2022-09-08 08:46:06 -0600240 profile_info ({(str) name: (str) value}) Dictionary containing profile
241 information.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700242
Alex Klein1699fab2022-09-08 08:46:06 -0600243 Note: the actual upload to GS is done by CI, not here.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700244
Alex Klein1699fab2022-09-08 08:46:06 -0600245 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600246 input_proto: The input proto
247 output_proto: The output proto
248 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600249 """
250 chroot = controller_util.ParseChroot(input_proto.chroot)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700253
Alex Klein1699fab2022-09-08 08:46:06 -0600254 output_path = Path(input_proto.output_dir)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 for artifact_type in input_proto.artifact_types:
257 if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
258 logging.error("%s not understood", artifact_type)
259 return controller.RETURN_CODE_UNRECOVERABLE
Alex Kleincd03a5e2021-10-18 13:23:47 -0600260
Alex Klein1699fab2022-09-08 08:46:06 -0600261 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
262 if not handler or not handler.bundle:
263 logging.warning(
264 "%s does not have a handler with a bundle function.",
265 artifact_type,
266 )
267 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600268
Alex Klein1699fab2022-09-08 08:46:06 -0600269 artifacts = handler.bundle(
270 handler.name,
271 chroot,
272 input_proto.sysroot.path,
273 input_proto.sysroot.build_target.name,
274 input_proto.output_dir,
275 profile_info,
276 )
277 if not artifacts:
278 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600279
Alex Klein1699fab2022-09-08 08:46:06 -0600280 # Filter out artifacts that do not exist or are empty.
281 usable_artifacts = []
282 for artifact in artifacts:
283 artifact_path = output_path / artifact
284 if not artifact_path.exists():
285 logging.warning("%s is not in the output directory.", artifact)
286 elif not artifact_path.stat().st_size:
287 logging.warning("%s is empty.", artifact)
288 else:
289 usable_artifacts.append(artifact)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600290
Alex Klein1699fab2022-09-08 08:46:06 -0600291 if not usable_artifacts:
292 logging.warning(
293 "No usable artifacts for artifact type %s", artifact_type
294 )
295 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600296
Alex Klein1699fab2022-09-08 08:46:06 -0600297 # Add all usable artifacts.
298 art_info = output_proto.artifacts_info.add()
299 art_info.artifact_type = artifact_type
300 for artifact in usable_artifacts:
301 art_info.artifacts.add().path = artifact
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700302
303
Tiancong Wangd5214132021-01-12 10:43:57 -0800304def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600305 """Add successful status to the faux response."""
306 file_info = output_proto.updated_files.add()
307 file_info.path = "/any/modified/file"
308 output_proto.commit_message = "Commit message"
Tiancong Wangd5214132021-01-12 10:43:57 -0800309
310
311@faux.empty_error
312@faux.success(_GetUpdatedFilesResponse)
Alex Klein1699fab2022-09-08 08:46:06 -0600313@validate.require("uploaded_artifacts")
Tiancong Wangd5214132021-01-12 10:43:57 -0800314@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600315def GetUpdatedFiles(
316 input_proto: "toolchain_pb2.GetUpdatedFilesRequest",
317 output_proto: "toolchain_pb2.GetUpdatedFilesResponse",
318 _config: "api_config.ApiConfig",
319):
320 """Use uploaded artifacts to update some updates in a chromeos checkout.
Tiancong Wangd5214132021-01-12 10:43:57 -0800321
Alex Klein1699fab2022-09-08 08:46:06 -0600322 The function will call toolchain_util.GetUpdatedFiles using the type of
323 uploaded artifacts to make some changes in a checkout, and return the list
324 of change files together with commit message.
Alex Klein611dddd2022-10-11 17:02:01 -0600325 updated_artifacts: A list of UpdatedArtifacts type which contains a
326 tuple of artifact info and profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600327 Note: the actual creation of the commit is done by CI, not here.
Tiancong Wangd5214132021-01-12 10:43:57 -0800328
Alex Klein1699fab2022-09-08 08:46:06 -0600329 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600330 input_proto: The input proto
331 output_proto: The output proto
332 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600333 """
334 commit_message = ""
335 for artifact in input_proto.uploaded_artifacts:
336 artifact_type = artifact.artifact_info.artifact_type
337 if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS:
338 logging.error("%s not understood", artifact_type)
339 return controller.RETURN_CODE_UNRECOVERABLE
340 artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type]
341 if artifact_name:
342 assert (
343 len(artifact.artifact_info.artifacts) == 1
344 ), "Only one file to update per each artifact"
345 updated_files, message = toolchain_util.GetUpdatedFiles(
346 artifact_name,
347 artifact.artifact_info.artifacts[0].path,
348 _GetProfileInfoDict(artifact.profile_info),
349 )
350 for f in updated_files:
351 file_info = output_proto.updated_files.add()
352 file_info.path = f
Tiancong Wangd5214132021-01-12 10:43:57 -0800353
Alex Klein1699fab2022-09-08 08:46:06 -0600354 commit_message += message + "\n"
355 output_proto.commit_message = commit_message
356 # No commit footer is added for now. Can add more here if needed
Tiancong Wangd5214132021-01-12 10:43:57 -0800357
358
Alex Klein1699fab2022-09-08 08:46:06 -0600359def _GetProfileInfoDict(profile_info: "toolchain_pb2.ArtifactProfileInfo"):
360 """Convert profile_info to a dict.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000361
Alex Klein1699fab2022-09-08 08:46:06 -0600362 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600363 profile_info: The artifact profile_info.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000364
Alex Klein1699fab2022-09-08 08:46:06 -0600365 Returns:
Alex Klein611dddd2022-10-11 17:02:01 -0600366 A dictionary containing profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600367 """
368 ret = {}
369 which = profile_info.WhichOneof("artifact_profile_info")
370 if which:
371 value = getattr(profile_info, which)
Alex Kleinab87ceb2023-01-24 12:00:51 -0700372 # If it is a message, then use the contents of the message. This works
373 # as long as simple types do not have a 'DESCRIPTOR' attribute. (And
374 # protobuf messages do.)
Alex Klein1699fab2022-09-08 08:46:06 -0600375 if getattr(value, "DESCRIPTOR", None):
376 ret.update({k.name: v for k, v in value.ListFields()})
377 else:
378 ret[which] = value
Denis Nikitin62e69862023-02-13 23:37:00 -0800379 arch = getattr(profile_info, "arch", None)
380 if arch:
381 ret["arch"] = arch
Alex Klein1699fab2022-09-08 08:46:06 -0600382 return ret
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000383
384
385LINTER_CODES = {
Alex Klein1699fab2022-09-08 08:46:06 -0600386 "clang_tidy": toolchain_pb2.LinterFinding.CLANG_TIDY,
387 "cargo_clippy": toolchain_pb2.LinterFinding.CARGO_CLIPPY,
388 "go_lint": toolchain_pb2.LinterFinding.GO_LINT,
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000389}
390
391
Adrian Dolef87c5762022-12-15 22:00:50 +0000392@validate.require("sysroot.build_target.name")
393@validate.require("start_time")
394@validate.validation_complete
395def EmergeAndUploadLints(
396 input_proto: toolchain_pb2.DashboardLintRequest,
397 output_proto: toolchain_pb2.DashboardLintResponse,
398 _config,
399):
400 """Lints all platform2 packages and uploads lints to GS"""
401 board = input_proto.sysroot.build_target.name
402 output_proto.gs_path = toolchain.emerge_and_upload_lints(
403 board, input_proto.start_time
404 )
405
406
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000407@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600408@validate.exists("sysroot.path")
409@validate.require("packages")
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000410@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600411def EmergeWithLinting(
412 input_proto: "toolchain_pb2.LinterRequest",
413 output_proto: "toolchain_pb2.LinterResponse",
414 _config: "api_config.ApiConfig",
415):
416 """Emerge packages with linter features enabled and retrieves all findings.
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000417
Alex Klein1699fab2022-09-08 08:46:06 -0600418 Args:
Adrian Dolef87c5762022-12-15 22:00:50 +0000419 input_proto: The input proto with package and sysroot info.
Alex Klein611dddd2022-10-11 17:02:01 -0600420 output_proto: The output proto where findings are stored.
421 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600422 """
423 packages = [
424 controller_util.deserialize_package_info(package)
425 for package in input_proto.packages
426 ]
Ryan Beltran7d191802021-11-24 00:08:17 +0000427
Alex Klein1699fab2022-09-08 08:46:06 -0600428 build_linter = toolchain.BuildLinter(
429 packages,
430 input_proto.sysroot.path,
431 differential=input_proto.filter_modified,
432 )
Ryan Beltran7d191802021-11-24 00:08:17 +0000433
Alex Klein1699fab2022-09-08 08:46:06 -0600434 use_clippy = (
435 toolchain_pb2.LinterFinding.CARGO_CLIPPY
436 not in input_proto.disabled_linters
437 )
438 use_tidy = (
439 toolchain_pb2.LinterFinding.CLANG_TIDY
440 not in input_proto.disabled_linters
441 )
442 use_golint = (
443 toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters
444 )
Ryan Beltran1277cb82022-11-27 03:15:36 +0000445 use_iwyu = (
446 toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters
447 )
Ryan Beltran4425d5f2022-07-20 18:34:33 +0000448
Alex Klein1699fab2022-09-08 08:46:06 -0600449 findings = build_linter.emerge_with_linting(
Ryan Beltran1277cb82022-11-27 03:15:36 +0000450 use_clippy=use_clippy,
451 use_tidy=use_tidy,
452 use_golint=use_golint,
453 use_iwyu=use_iwyu,
Alex Klein1699fab2022-09-08 08:46:06 -0600454 )
Ryan Beltranf9a86f42022-04-13 20:58:18 +0000455
Alex Klein1699fab2022-09-08 08:46:06 -0600456 for finding in findings:
457 locations = []
458 for location in finding.locations:
459 locations.append(
460 toolchain_pb2.LinterFindingLocation(
461 filepath=location.filepath,
462 line_start=location.line_start,
463 line_end=location.line_end,
464 )
465 )
466 output_proto.findings.append(
467 toolchain_pb2.LinterFinding(
468 message=finding.message,
469 locations=locations,
470 linter=LINTER_CODES[finding.linter],
Ryan Beltran8daf1dd2023-03-22 21:31:03 +0000471 package=PackageInfo(
472 category=finding.package.category,
473 package_name=finding.package.package,
474 version=finding.package.version,
475 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600476 )
477 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000478
479
480@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600481@validate.require("board")
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000482@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600483def GetToolchainsForBoard(
484 input_proto: "toolchain_pb2.ToolchainsRequest",
485 output_proto: "toolchain_pb2.ToolchainsReponse",
486 _config: "api_config.ApiConfig",
487):
488 """Gets the default and non-default toolchains for a board.
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000489
Alex Klein1699fab2022-09-08 08:46:06 -0600490 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600491 input_proto: The input proto with board and sysroot info.
492 output_proto: The output proto where findings are stored.
493 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600494 """
495 toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board)
496 output_proto.default_toolchains.extend(
497 list(toolchain_lib.FilterToolchains(toolchains, "default", True))
498 )
499 output_proto.nondefault_toolchains.extend(
500 list(toolchain_lib.FilterToolchains(toolchains, "default", False))
501 )