blob: 8b50e784bac0646b880beabb82675127ce7ca7ca [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
Trent Apted39e74d32023-09-04 11:24:40 +100016from chromite.api.gen.chromite.api import artifacts_pb2
Tiancong Wang24a3df72019-08-20 15:48:51 -070017from chromite.api.gen.chromite.api import toolchain_pb2
Trent Apted39e74d32023-09-04 11:24:40 +100018from chromite.api.gen.chromiumos import builder_config_pb2
19from chromite.api.gen.chromiumos import common_pb2
Greg Edelstondae510a2023-06-30 15:25:36 -060020from chromite.lib import cros_build_lib
Jack Neus4ee7b1d2022-06-27 19:54:18 +000021from chromite.lib import toolchain as toolchain_lib
Chris McDonald1672ddb2021-07-21 11:48:23 -060022from chromite.lib import toolchain_util
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000023from chromite.service import toolchain
Ryan Beltran7d191802021-11-24 00:08:17 +000024
Mike Frysingerea11fdd2022-05-06 22:59:33 -040025
Jack Neus4ee7b1d2022-06-27 19:54:18 +000026if TYPE_CHECKING:
Alex Klein1699fab2022-09-08 08:46:06 -060027 from chromite.api import api_config
Jack Neus4ee7b1d2022-06-27 19:54:18 +000028
Trent Apted39e74d32023-09-04 11:24:40 +100029
30PrepareForBuildResponse = artifacts_pb2.PrepareForBuildResponse
31BuilderConfig = builder_config_pb2.BuilderConfig
32PackageInfo = common_pb2.PackageInfo
33
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +000034# TODO(b/229665884): Move the implementation details for most/all endpoints to:
35# chromite/services/toolchain.py
36# This migration has been done for linting endpoints but not yet for others.
Chris McDonald1672ddb2021-07-21 11:48:23 -060037
Alex Klein1699fab2022-09-08 08:46:06 -060038_Handlers = collections.namedtuple("_Handlers", ["name", "prepare", "bundle"])
LaMont Jonesb20b3d92019-11-23 11:47:48 -070039_TOOLCHAIN_ARTIFACT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -060040 BuilderConfig.Artifacts.UNVERIFIED_LLVM_PGO_FILE: _Handlers(
41 "UnverifiedLlvmPgoFile",
42 toolchain_util.PrepareForBuild,
43 toolchain_util.BundleArtifacts,
44 ),
45 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
46 "UnverifiedChromeBenchmarkAfdoFile",
47 toolchain_util.PrepareForBuild,
48 toolchain_util.BundleArtifacts,
49 ),
50 BuilderConfig.Artifacts.CHROME_DEBUG_BINARY: _Handlers(
51 "ChromeDebugBinary",
52 toolchain_util.PrepareForBuild,
53 toolchain_util.BundleArtifacts,
54 ),
55 BuilderConfig.Artifacts.UNVERIFIED_CHROME_BENCHMARK_PERF_FILE: _Handlers(
56 "UnverifiedChromeBenchmarkPerfFile",
57 toolchain_util.PrepareForBuild,
58 toolchain_util.BundleArtifacts,
59 ),
60 BuilderConfig.Artifacts.VERIFIED_CHROME_BENCHMARK_AFDO_FILE: _Handlers(
61 "VerifiedChromeBenchmarkAfdoFile",
62 toolchain_util.PrepareForBuild,
63 toolchain_util.BundleArtifacts,
64 ),
65 BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
66 "UnverifiedKernelCwpAfdoFile",
67 toolchain_util.PrepareForBuild,
68 toolchain_util.BundleArtifacts,
69 ),
70 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: _Handlers(
71 "VerifiedKernelCwpAfdoFile",
72 toolchain_util.PrepareForBuild,
73 toolchain_util.BundleArtifacts,
74 ),
75 BuilderConfig.Artifacts.UNVERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
76 "UnverifiedChromeCwpAfdoFile",
77 toolchain_util.PrepareForBuild,
78 toolchain_util.BundleArtifacts,
79 ),
80 BuilderConfig.Artifacts.VERIFIED_CHROME_CWP_AFDO_FILE: _Handlers(
81 "VerifiedChromeCwpAfdoFile",
82 toolchain_util.PrepareForBuild,
83 toolchain_util.BundleArtifacts,
84 ),
85 BuilderConfig.Artifacts.VERIFIED_RELEASE_AFDO_FILE: _Handlers(
86 "VerifiedReleaseAfdoFile",
87 toolchain_util.PrepareForBuild,
88 toolchain_util.BundleArtifacts,
89 ),
90 BuilderConfig.Artifacts.TOOLCHAIN_WARNING_LOGS: _Handlers(
91 "ToolchainWarningLogs",
92 toolchain_util.PrepareForBuild,
93 toolchain_util.BundleArtifacts,
94 ),
95 BuilderConfig.Artifacts.CHROME_AFDO_PROFILE_FOR_ANDROID_LINUX: _Handlers(
96 "ChromeAFDOProfileForAndroidLinux",
97 toolchain_util.PrepareForBuild,
98 toolchain_util.BundleArtifacts,
99 ),
100 BuilderConfig.Artifacts.CLANG_CRASH_DIAGNOSES: _Handlers(
101 "ClangCrashDiagnoses",
102 toolchain_util.PrepareForBuild,
103 toolchain_util.BundleArtifacts,
104 ),
105 BuilderConfig.Artifacts.COMPILER_RUSAGE_LOG: _Handlers(
106 "CompilerRusageLogs",
107 toolchain_util.PrepareForBuild,
108 toolchain_util.BundleArtifacts,
109 ),
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700110}
111
Alex Kleinab87ceb2023-01-24 12:00:51 -0700112# pylint: disable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800113_TOOLCHAIN_COMMIT_HANDLERS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600114 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE: "VerifiedKernelCwpAfdoFile"
Tiancong Wangd5214132021-01-12 10:43:57 -0800115}
Alex Kleinab87ceb2023-01-24 12:00:51 -0700116# pylint: enable=line-too-long
Tiancong Wangd5214132021-01-12 10:43:57 -0800117
LaMont Jonese7821672020-04-09 08:56:26 -0600118
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700119# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
120# this should be changed.
121@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600122@validate.require("artifact_types")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700123# Note: chroot and sysroot are unspecified the first time that the build_target
124# recipe calls PrepareForBuild. The second time, they are specified. No
125# validation check because "all" values are valid.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700126@validate.validation_complete
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000127def PrepareForBuild(
Alex Klein1699fab2022-09-08 08:46:06 -0600128 input_proto: "toolchain_pb2.PrepareForToolchainBuildRequest",
129 output_proto: "toolchain_pb2.PrepareForToolchainBuildResponse",
130 _config: "api_config.ApiConfig",
131):
132 """Prepare to build toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700133
Alex Klein1699fab2022-09-08 08:46:06 -0600134 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
135 artifact_name (str): name of the artifact type.
136 chroot (chroot_lib.Chroot): chroot. Will be None if the chroot has not
137 yet been created.
138 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas).
139 Will be an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700140 build_target_name (str): name of the build target (e.g., atlas). Will be
Alex Klein1699fab2022-09-08 08:46:06 -0600141 an empty string if the sysroot has not yet been created.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700142 input_artifacts ({(str) name:[str gs_locations]}): locations for
143 possible input artifacts. The handler is expected to know which
144 keys it should be using, and ignore any keys that it does not
145 understand.
Alex Klein1699fab2022-09-08 08:46:06 -0600146 profile_info ({(str) name: (str) value}) Dictionary containing profile
147 information.
LaMont Jonesa215f1e2019-12-06 10:18:58 -0700148
Alex Klein1699fab2022-09-08 08:46:06 -0600149 They locate and modify any ebuilds and/or source required for the artifact
Alex Kleinab87ceb2023-01-24 12:00:51 -0700150 being created, then return a value from
151 toolchain_util.PrepareForBuildReturn.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700152
Alex Klein1699fab2022-09-08 08:46:06 -0600153 This function sets output_proto.build_relevance to the result.
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700154
Alex Klein1699fab2022-09-08 08:46:06 -0600155 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600156 input_proto: The input proto
157 output_proto: The output proto
158 _config): The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600159 """
160 if input_proto.chroot.path:
161 chroot = controller_util.ParseChroot(input_proto.chroot)
162 else:
163 chroot = None
LaMont Jones4579e8c2019-12-06 14:20:37 -0700164
Alex Klein1699fab2022-09-08 08:46:06 -0600165 input_artifacts = collections.defaultdict(list)
166 for art in input_proto.input_artifacts:
167 item = _TOOLCHAIN_ARTIFACT_HANDLERS.get(art.input_artifact_type)
168 if item:
169 input_artifacts[item.name].extend(
170 ["gs://%s" % str(x) for x in art.input_artifact_gs_locations]
171 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700172
Alex Klein1699fab2022-09-08 08:46:06 -0600173 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700174
Alex Klein1699fab2022-09-08 08:46:06 -0600175 results = set()
176 sysroot_path = input_proto.sysroot.path
177 build_target = input_proto.sysroot.build_target.name
178 for artifact_type in input_proto.artifact_types:
179 # Unknown artifact_types are an error.
180 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
181 if handler.prepare:
182 results.add(
183 handler.prepare(
184 handler.name,
185 chroot,
186 sysroot_path,
187 build_target,
188 input_artifacts,
189 profile_info,
190 )
191 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700192
Alex Klein1699fab2022-09-08 08:46:06 -0600193 # Translate the returns from the handlers we called.
194 # If any NEEDED => NEEDED
195 # elif any UNKNOWN => UNKNOWN
196 # elif any POINTLESS => POINTLESS
197 # else UNKNOWN.
198 if toolchain_util.PrepareForBuildReturn.NEEDED in results:
199 output_proto.build_relevance = PrepareForBuildResponse.NEEDED
200 elif toolchain_util.PrepareForBuildReturn.UNKNOWN in results:
201 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
202 elif toolchain_util.PrepareForBuildReturn.POINTLESS in results:
203 output_proto.build_relevance = PrepareForBuildResponse.POINTLESS
204 else:
205 output_proto.build_relevance = PrepareForBuildResponse.UNKNOWN
206 return controller.RETURN_CODE_SUCCESS
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700207
208
209# TODO(crbug/1031213): When @faux is expanded to have more than success/failure,
210# this should be changed.
211@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600212@validate.require("chroot.path", "output_dir", "artifact_types")
213@validate.exists("output_dir")
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700214@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600215def BundleArtifacts(
216 input_proto: "toolchain_pb2.BundleToolchainRequest",
217 output_proto: "toolchain_pb2.BundleToolchainResponse",
218 _config: "api_config.ApiConfig",
219):
220 """Bundle valid toolchain artifacts.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700221
Alex Klein1699fab2022-09-08 08:46:06 -0600222 The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
223 artifact_name (str): name of the artifact type
224 chroot (chroot_lib.Chroot): chroot
225 sysroot_path (str): sysroot path inside the chroot (e.g., /build/atlas),
226 or None.
227 chrome_root (str): path to chrome root. (e.g., /b/s/w/ir/k/chrome)
Alex Klein611dddd2022-10-11 17:02:01 -0600228 build_target_name (str): name of the build target (e.g. atlas), or None.
Alex Klein1699fab2022-09-08 08:46:06 -0600229 output_dir (str): absolute path where artifacts are being bundled.
Alex Klein611dddd2022-10-11 17:02:01 -0600230 (e.g., /b/s/w/ir/k/recipe_cleanup/artifactssptfMU)
Alex Klein1699fab2022-09-08 08:46:06 -0600231 profile_info ({(str) name: (str) value}) Dictionary containing profile
232 information.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700233
Alex Klein1699fab2022-09-08 08:46:06 -0600234 Note: the actual upload to GS is done by CI, not here.
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700235
Alex Klein1699fab2022-09-08 08:46:06 -0600236 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600237 input_proto: The input proto
238 output_proto: The output proto
239 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600240 """
241 chroot = controller_util.ParseChroot(input_proto.chroot)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700242
Alex Klein1699fab2022-09-08 08:46:06 -0600243 profile_info = _GetProfileInfoDict(input_proto.profile_info)
LaMont Jones45ca6c42020-02-05 09:39:09 -0700244
Alex Klein1699fab2022-09-08 08:46:06 -0600245 output_path = Path(input_proto.output_dir)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600246
Alex Klein1699fab2022-09-08 08:46:06 -0600247 for artifact_type in input_proto.artifact_types:
248 if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
249 logging.error("%s not understood", artifact_type)
250 return controller.RETURN_CODE_UNRECOVERABLE
Alex Kleincd03a5e2021-10-18 13:23:47 -0600251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
253 if not handler or not handler.bundle:
254 logging.warning(
255 "%s does not have a handler with a bundle function.",
256 artifact_type,
257 )
258 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600259
Alex Klein1699fab2022-09-08 08:46:06 -0600260 artifacts = handler.bundle(
261 handler.name,
262 chroot,
263 input_proto.sysroot.path,
264 input_proto.sysroot.build_target.name,
265 input_proto.output_dir,
266 profile_info,
267 )
268 if not artifacts:
269 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600270
Alex Klein1699fab2022-09-08 08:46:06 -0600271 # Filter out artifacts that do not exist or are empty.
272 usable_artifacts = []
273 for artifact in artifacts:
274 artifact_path = output_path / artifact
275 if not artifact_path.exists():
276 logging.warning("%s is not in the output directory.", artifact)
277 elif not artifact_path.stat().st_size:
278 logging.warning("%s is empty.", artifact)
279 else:
280 usable_artifacts.append(artifact)
Alex Kleincd03a5e2021-10-18 13:23:47 -0600281
Alex Klein1699fab2022-09-08 08:46:06 -0600282 if not usable_artifacts:
283 logging.warning(
284 "No usable artifacts for artifact type %s", artifact_type
285 )
286 continue
Alex Kleincd03a5e2021-10-18 13:23:47 -0600287
Alex Klein1699fab2022-09-08 08:46:06 -0600288 # Add all usable artifacts.
289 art_info = output_proto.artifacts_info.add()
290 art_info.artifact_type = artifact_type
291 for artifact in usable_artifacts:
292 art_info.artifacts.add().path = artifact
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700293
294
Tiancong Wangd5214132021-01-12 10:43:57 -0800295def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):
Alex Klein1699fab2022-09-08 08:46:06 -0600296 """Add successful status to the faux response."""
297 file_info = output_proto.updated_files.add()
298 file_info.path = "/any/modified/file"
299 output_proto.commit_message = "Commit message"
Tiancong Wangd5214132021-01-12 10:43:57 -0800300
301
302@faux.empty_error
303@faux.success(_GetUpdatedFilesResponse)
Alex Klein1699fab2022-09-08 08:46:06 -0600304@validate.require("uploaded_artifacts")
Tiancong Wangd5214132021-01-12 10:43:57 -0800305@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600306def GetUpdatedFiles(
307 input_proto: "toolchain_pb2.GetUpdatedFilesRequest",
308 output_proto: "toolchain_pb2.GetUpdatedFilesResponse",
309 _config: "api_config.ApiConfig",
310):
311 """Use uploaded artifacts to update some updates in a chromeos checkout.
Tiancong Wangd5214132021-01-12 10:43:57 -0800312
Alex Klein1699fab2022-09-08 08:46:06 -0600313 The function will call toolchain_util.GetUpdatedFiles using the type of
314 uploaded artifacts to make some changes in a checkout, and return the list
315 of change files together with commit message.
Alex Klein611dddd2022-10-11 17:02:01 -0600316 updated_artifacts: A list of UpdatedArtifacts type which contains a
317 tuple of artifact info and profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600318 Note: the actual creation of the commit is done by CI, not here.
Tiancong Wangd5214132021-01-12 10:43:57 -0800319
Alex Klein1699fab2022-09-08 08:46:06 -0600320 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600321 input_proto: The input proto
322 output_proto: The output proto
323 _config: The API call config.
Alex Klein1699fab2022-09-08 08:46:06 -0600324 """
325 commit_message = ""
326 for artifact in input_proto.uploaded_artifacts:
327 artifact_type = artifact.artifact_info.artifact_type
328 if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS:
329 logging.error("%s not understood", artifact_type)
330 return controller.RETURN_CODE_UNRECOVERABLE
331 artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type]
332 if artifact_name:
333 assert (
334 len(artifact.artifact_info.artifacts) == 1
335 ), "Only one file to update per each artifact"
336 updated_files, message = toolchain_util.GetUpdatedFiles(
337 artifact_name,
338 artifact.artifact_info.artifacts[0].path,
339 _GetProfileInfoDict(artifact.profile_info),
340 )
341 for f in updated_files:
342 file_info = output_proto.updated_files.add()
343 file_info.path = f
Tiancong Wangd5214132021-01-12 10:43:57 -0800344
Alex Klein1699fab2022-09-08 08:46:06 -0600345 commit_message += message + "\n"
346 output_proto.commit_message = commit_message
347 # No commit footer is added for now. Can add more here if needed
Tiancong Wangd5214132021-01-12 10:43:57 -0800348
349
Alex Klein1699fab2022-09-08 08:46:06 -0600350def _GetProfileInfoDict(profile_info: "toolchain_pb2.ArtifactProfileInfo"):
351 """Convert profile_info to a dict.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000352
Alex Klein1699fab2022-09-08 08:46:06 -0600353 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600354 profile_info: The artifact profile_info.
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000355
Alex Klein1699fab2022-09-08 08:46:06 -0600356 Returns:
Alex Klein611dddd2022-10-11 17:02:01 -0600357 A dictionary containing profile info.
Alex Klein1699fab2022-09-08 08:46:06 -0600358 """
359 ret = {}
360 which = profile_info.WhichOneof("artifact_profile_info")
361 if which:
362 value = getattr(profile_info, which)
Alex Kleinab87ceb2023-01-24 12:00:51 -0700363 # If it is a message, then use the contents of the message. This works
364 # as long as simple types do not have a 'DESCRIPTOR' attribute. (And
365 # protobuf messages do.)
Alex Klein1699fab2022-09-08 08:46:06 -0600366 if getattr(value, "DESCRIPTOR", None):
367 ret.update({k.name: v for k, v in value.ListFields()})
368 else:
369 ret[which] = value
Denis Nikitin62e69862023-02-13 23:37:00 -0800370 arch = getattr(profile_info, "arch", None)
371 if arch:
372 ret["arch"] = arch
Alex Klein1699fab2022-09-08 08:46:06 -0600373 return ret
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000374
375
376LINTER_CODES = {
Alex Klein1699fab2022-09-08 08:46:06 -0600377 "clang_tidy": toolchain_pb2.LinterFinding.CLANG_TIDY,
378 "cargo_clippy": toolchain_pb2.LinterFinding.CARGO_CLIPPY,
379 "go_lint": toolchain_pb2.LinterFinding.GO_LINT,
Ryan Beltranf2a5dcc2022-04-19 20:34:00 +0000380}
381
382
Adrian Dolef87c5762022-12-15 22:00:50 +0000383@validate.require("sysroot.build_target.name")
384@validate.require("start_time")
385@validate.validation_complete
386def EmergeAndUploadLints(
387 input_proto: toolchain_pb2.DashboardLintRequest,
388 output_proto: toolchain_pb2.DashboardLintResponse,
389 _config,
390):
Greg Edelstondae510a2023-06-30 15:25:36 -0600391 """Lint all platform2 packages and uploads lints to GS"""
Adrian Dolef87c5762022-12-15 22:00:50 +0000392 board = input_proto.sysroot.build_target.name
393 output_proto.gs_path = toolchain.emerge_and_upload_lints(
394 board, input_proto.start_time
395 )
396
397
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000398@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600399@validate.exists("sysroot.path")
400@validate.require("packages")
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000401@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600402def EmergeWithLinting(
403 input_proto: "toolchain_pb2.LinterRequest",
404 output_proto: "toolchain_pb2.LinterResponse",
405 _config: "api_config.ApiConfig",
406):
407 """Emerge packages with linter features enabled and retrieves all findings.
Ryan Beltran0df7fb02021-11-10 20:58:51 +0000408
Alex Klein1699fab2022-09-08 08:46:06 -0600409 Args:
Adrian Dolef87c5762022-12-15 22:00:50 +0000410 input_proto: The input proto with package and sysroot info.
Alex Klein611dddd2022-10-11 17:02:01 -0600411 output_proto: The output proto where findings are stored.
412 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600413 """
414 packages = [
415 controller_util.deserialize_package_info(package)
416 for package in input_proto.packages
417 ]
Ryan Beltran7d191802021-11-24 00:08:17 +0000418
Alex Klein1699fab2022-09-08 08:46:06 -0600419 build_linter = toolchain.BuildLinter(
420 packages,
421 input_proto.sysroot.path,
422 differential=input_proto.filter_modified,
423 )
Ryan Beltran7d191802021-11-24 00:08:17 +0000424
Alex Klein1699fab2022-09-08 08:46:06 -0600425 use_clippy = (
426 toolchain_pb2.LinterFinding.CARGO_CLIPPY
427 not in input_proto.disabled_linters
428 )
429 use_tidy = (
430 toolchain_pb2.LinterFinding.CLANG_TIDY
431 not in input_proto.disabled_linters
432 )
433 use_golint = (
434 toolchain_pb2.LinterFinding.GO_LINT not in input_proto.disabled_linters
435 )
Ryan Beltran1277cb82022-11-27 03:15:36 +0000436 use_iwyu = (
437 toolchain_pb2.LinterFinding.IWYU not in input_proto.disabled_linters
438 )
Ryan Beltran4425d5f2022-07-20 18:34:33 +0000439
Alex Klein1699fab2022-09-08 08:46:06 -0600440 findings = build_linter.emerge_with_linting(
Ryan Beltran1277cb82022-11-27 03:15:36 +0000441 use_clippy=use_clippy,
442 use_tidy=use_tidy,
443 use_golint=use_golint,
444 use_iwyu=use_iwyu,
Alex Klein1699fab2022-09-08 08:46:06 -0600445 )
Ryan Beltranf9a86f42022-04-13 20:58:18 +0000446
Alex Klein1699fab2022-09-08 08:46:06 -0600447 for finding in findings:
448 locations = []
449 for location in finding.locations:
450 locations.append(
451 toolchain_pb2.LinterFindingLocation(
452 filepath=location.filepath,
453 line_start=location.line_start,
454 line_end=location.line_end,
455 )
456 )
Alex Klein860d56f2023-07-19 11:16:46 -0600457
458 pkg = PackageInfo()
459 if finding.package:
460 pkg.category = finding.package.category
461 pkg.package_name = finding.package.package
462 pkg.version = finding.package.version
Alex Klein1699fab2022-09-08 08:46:06 -0600463 output_proto.findings.append(
464 toolchain_pb2.LinterFinding(
465 message=finding.message,
466 locations=locations,
467 linter=LINTER_CODES[finding.linter],
Alex Klein860d56f2023-07-19 11:16:46 -0600468 package=pkg,
Alex Klein1699fab2022-09-08 08:46:06 -0600469 )
470 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000471
472
473@faux.all_empty
Alex Klein1699fab2022-09-08 08:46:06 -0600474@validate.require("board")
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000475@validate.validation_complete
Alex Klein1699fab2022-09-08 08:46:06 -0600476def GetToolchainsForBoard(
477 input_proto: "toolchain_pb2.ToolchainsRequest",
478 output_proto: "toolchain_pb2.ToolchainsReponse",
479 _config: "api_config.ApiConfig",
480):
Greg Edelstondae510a2023-06-30 15:25:36 -0600481 """Get the default and non-default toolchains for a board.
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000482
Alex Klein1699fab2022-09-08 08:46:06 -0600483 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600484 input_proto: The input proto with board and sysroot info.
485 output_proto: The output proto where findings are stored.
486 _config: The API call config (unused).
Alex Klein1699fab2022-09-08 08:46:06 -0600487 """
488 toolchains = toolchain_lib.GetToolchainsForBoard(input_proto.board)
489 output_proto.default_toolchains.extend(
490 list(toolchain_lib.FilterToolchains(toolchains, "default", True))
491 )
492 output_proto.nondefault_toolchains.extend(
493 list(toolchain_lib.FilterToolchains(toolchains, "default", False))
494 )
Greg Edelstondae510a2023-06-30 15:25:36 -0600495
496
497@faux.all_empty
Greg Edelstondae510a2023-06-30 15:25:36 -0600498@validate.validation_complete
499def SetupToolchains(
500 input_proto: "toolchain_pb2.SetupToolchainsRequest",
501 output_proto: "toolchain_pb2.SetupToolchainsResponse",
502 config: "api_config.ApiConfig",
503):
504 """Run `cros_setup_toolchains`."""
505 del output_proto, config # Unused.
506 cros_build_lib.AssertInsideChroot()
507 include_boards = [bt.name for bt in input_proto.boards]
508 toolchain.setup_toolchains(include_boards=include_boards)