blob: 6ff55da39084bfe5d3b11eb0e358a69a9cc18389 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2018 The ChromiumOS Authors
Alex Kleinf4dc4f52018-12-05 13:55:12 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Alex Kleinf9859972019-03-14 17:11:42 -06005"""Compile the Build API's proto.
6
7Install proto using CIPD to ensure a consistent protoc version.
8"""
Alex Kleinf4dc4f52018-12-05 13:55:12 -07009
Alex Klein098f7982021-03-01 13:15:29 -070010import enum
Chris McDonald1672ddb2021-07-21 11:48:23 -060011import logging
Alex Kleinb382e4b2022-05-23 16:29:19 -060012from pathlib import Path
Sean McAllister6a5eaa02021-05-26 10:47:14 -060013import tempfile
Alex Klein177bb942022-05-24 13:32:27 -060014from typing import Iterable, Optional
Alex Kleinf4dc4f52018-12-05 13:55:12 -070015
Alex Kleinb382e4b2022-05-23 16:29:19 -060016from chromite.lib import cipd
Alex Kleinf4dc4f52018-12-05 13:55:12 -070017from chromite.lib import commandline
Alex Kleinc33c1912019-02-15 10:29:13 -070018from chromite.lib import constants
Alex Kleinf4dc4f52018-12-05 13:55:12 -070019from chromite.lib import cros_build_lib
Sean McAllister6a5eaa02021-05-26 10:47:14 -060020from chromite.lib import git
Alex Kleinf9859972019-03-14 17:11:42 -060021from chromite.lib import osutils
22
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040023
Alex Klein098f7982021-03-01 13:15:29 -070024# Chromite's protobuf library version (third_party/google/protobuf).
Trent Apted5a2038f2023-07-26 15:23:46 +100025PROTOC_VERSION = "21.9"
Alex Kleinf9859972019-03-14 17:11:42 -060026
Trent Apted5a2038f2023-07-26 15:23:46 +100027# Protobuf dropped the major version number after 3.20, jumping to 21.0. But
28# some places (e.g., in protobuf/__init__.py) refer to this as 4.21.0.
29PROTOC_MAJOR_VERSION = "4"
30
31_CIPD_PACKAGE = "infra/3pp/tools/protoc/linux-amd64"
32_CIPD_PACKAGE_VERSION = f"version:2@{PROTOC_VERSION}"
Alex Kleinb382e4b2022-05-23 16:29:19 -060033
Alex Kleinf9859972019-03-14 17:11:42 -060034
Alex Klein5534f992019-09-16 16:31:23 -060035class Error(Exception):
Alex Klein1699fab2022-09-08 08:46:06 -060036 """Base error class for the module."""
Alex Klein5534f992019-09-16 16:31:23 -060037
38
39class GenerationError(Error):
Alex Klein1699fab2022-09-08 08:46:06 -060040 """A failure we can't recover from."""
Alex Klein5534f992019-09-16 16:31:23 -060041
42
Alex Klein098f7982021-03-01 13:15:29 -070043@enum.unique
44class ProtocVersion(enum.Enum):
Alex Klein1699fab2022-09-08 08:46:06 -060045 """Enum for possible protoc versions."""
Alex Klein098f7982021-03-01 13:15:29 -070046
Alex Klein1699fab2022-09-08 08:46:06 -060047 # The SDK version of the bindings use the protoc in the SDK, and so is
48 # compatible with the protobuf library in the SDK, i.e. the one installed
49 # via the ebuild.
50 SDK = enum.auto()
51 # The Chromite version of the bindings uses a protoc binary downloaded from
52 # CIPD that matches the version of the protobuf library in
53 # chromite/third_party/google/protobuf.
54 CHROMITE = enum.auto()
Trent Apted8f5782a2023-07-11 10:25:02 +100055 # Type annotations for the chromite bindings.
56 CHROMITE_PYI = enum.auto()
Alex Klein177bb942022-05-24 13:32:27 -060057
Alex Klein1699fab2022-09-08 08:46:06 -060058 def get_gen_dir(self) -> Path:
59 """Get the chromite/api directory path."""
60 if self is ProtocVersion.SDK:
Mike Frysingera69df982023-03-21 16:52:27 -040061 return constants.CHROMITE_DIR / "api" / "gen_sdk"
Trent Apted8f5782a2023-07-11 10:25:02 +100062 return constants.CHROMITE_DIR / "api" / "gen"
Alex Klein177bb942022-05-24 13:32:27 -060063
Alex Klein1699fab2022-09-08 08:46:06 -060064 def get_proto_dir(self) -> Path:
65 """Get the proto directory for the target protoc."""
Mike Frysingera69df982023-03-21 16:52:27 -040066 return constants.CHROMITE_DIR / "infra" / "proto"
Alex Klein1699fab2022-09-08 08:46:06 -060067
68 def get_protoc_command(self, cipd_root: Optional[Path] = None) -> Path:
69 """Get protoc command path."""
Alex Klein1699fab2022-09-08 08:46:06 -060070 if self is ProtocVersion.SDK:
71 return Path("protoc")
Trent Apted8f5782a2023-07-11 10:25:02 +100072 assert cipd_root
73 return cipd_root / "bin" / "protoc"
74
75 def get_suffix(self) -> str:
76 """Get the file suffix of generated output."""
77 return "pyi" if self is ProtocVersion.CHROMITE_PYI else "py"
Alex Kleindfad94c2022-05-23 16:59:47 -060078
Alex Klein098f7982021-03-01 13:15:29 -070079
Alex Klein851f4ee2022-03-29 16:03:45 -060080@enum.unique
81class SubdirectorySet(enum.Enum):
Alex Klein1699fab2022-09-08 08:46:06 -060082 """Enum for the subsets of the proto to compile."""
Alex Klein851f4ee2022-03-29 16:03:45 -060083
Alex Klein1699fab2022-09-08 08:46:06 -060084 ALL = enum.auto()
85 DEFAULT = enum.auto()
Alex Klein851f4ee2022-03-29 16:03:45 -060086
Alex Klein1699fab2022-09-08 08:46:06 -060087 def get_source_dirs(
88 self, source: Path, chromeos_config_path: Path
89 ) -> Iterable[Path]:
90 """Get the directories for the given subdirectory set."""
91 if self is self.ALL:
92 return [
93 source,
94 chromeos_config_path / "proto" / "chromiumos",
95 ]
96
97 subdirs = [
98 source / "analysis_service",
99 source / "chromite",
100 source / "chromiumos",
101 source / "config",
102 source / "test_platform",
103 source / "device",
104 chromeos_config_path / "proto" / "chromiumos",
105 ]
106 return subdirs
Alex Klein851f4ee2022-03-29 16:03:45 -0600107
108
Alex Kleindfad94c2022-05-23 16:59:47 -0600109def InstallProtoc(protoc_version: ProtocVersion) -> Path:
Alex Klein1699fab2022-09-08 08:46:06 -0600110 """Install protoc from CIPD."""
Trent Apted8f5782a2023-07-11 10:25:02 +1000111 if protoc_version is ProtocVersion.SDK:
Alex Klein1699fab2022-09-08 08:46:06 -0600112 cipd_root = None
113 else:
114 cipd_root = Path(
115 cipd.InstallPackage(
116 cipd.GetCIPDFromCache(), _CIPD_PACKAGE, _CIPD_PACKAGE_VERSION
117 )
118 )
119 return protoc_version.get_protoc_command(cipd_root)
Alex Klein5534f992019-09-16 16:31:23 -0600120
Alex Kleinf9859972019-03-14 17:11:42 -0600121
Trent Apted8f5782a2023-07-11 10:25:02 +1000122def _CleanTargetDirectory(directory: Path, protoc_version: ProtocVersion):
Alex Klein1699fab2022-09-08 08:46:06 -0600123 """Remove any existing generated files in the directory.
Alex Kleinf9859972019-03-14 17:11:42 -0600124
Alex Klein1699fab2022-09-08 08:46:06 -0600125 This clean only removes the generated files to avoid accidentally destroying
126 __init__.py customizations down the line. That will leave otherwise empty
127 directories in place if things get moved. Neither case is relevant at the
128 time of writing, but lingering empty directories seemed better than
129 diagnosing accidental __init__.py changes.
Alex Kleinf9859972019-03-14 17:11:42 -0600130
Alex Klein1699fab2022-09-08 08:46:06 -0600131 Args:
Alex Kleina0442682022-10-10 13:47:38 -0600132 directory: Path to be cleaned up.
Trent Apted8f5782a2023-07-11 10:25:02 +1000133 protoc_version: The type of generated files to be cleaned.
Alex Klein1699fab2022-09-08 08:46:06 -0600134 """
135 logging.info("Cleaning old files from %s.", directory)
Trent Apted8f5782a2023-07-11 10:25:02 +1000136 for current in directory.rglob(f"*_pb2.{protoc_version.get_suffix()}"):
Alex Klein1699fab2022-09-08 08:46:06 -0600137 # Remove old generated files.
138 current.unlink()
Trent Apted8f5782a2023-07-11 10:25:02 +1000139
140 # Note the generator does not currently make __init__.pyi files but, if it
141 # did, we'd want them to be cleaned up here.
142 for current in directory.rglob(f"__init__.{protoc_version.get_suffix()}"):
Alex Klein1699fab2022-09-08 08:46:06 -0600143 # Remove empty init files to clean up otherwise empty directories.
144 if not current.stat().st_size:
145 current.unlink()
Alex Kleinf9859972019-03-14 17:11:42 -0600146
Alex Klein5534f992019-09-16 16:31:23 -0600147
Alex Klein1699fab2022-09-08 08:46:06 -0600148def _GenerateFiles(
149 source: Path,
150 output: Path,
151 protoc_version: ProtocVersion,
152 dir_subset: SubdirectorySet,
153 protoc_bin_path: Path,
154):
155 """Generate the proto files from the |source| tree into |output|.
Alex Kleinf9859972019-03-14 17:11:42 -0600156
Alex Klein1699fab2022-09-08 08:46:06 -0600157 Args:
Alex Kleina0442682022-10-10 13:47:38 -0600158 source: Path to the proto source root directory.
159 output: Path to the output root directory.
160 protoc_version: Which protoc to use.
161 dir_subset: The subset of the proto to compile.
162 protoc_bin_path: The protoc command to use.
Alex Klein1699fab2022-09-08 08:46:06 -0600163 """
164 logging.info("Generating files to %s.", output)
165 osutils.SafeMakedirs(output)
Alex Klein098f7982021-03-01 13:15:29 -0700166
Alex Klein1699fab2022-09-08 08:46:06 -0600167 targets = []
Alex Kleinf9859972019-03-14 17:11:42 -0600168
Mike Frysinger903c1f72023-08-08 14:05:10 -0400169 chromeos_config_path = constants.SOURCE_ROOT / "src" / "config"
Alex Klein098f7982021-03-01 13:15:29 -0700170
Alex Klein1699fab2022-09-08 08:46:06 -0600171 with tempfile.TemporaryDirectory() as tempdir:
172 if not chromeos_config_path.exists():
173 chromeos_config_path = Path(tempdir) / "config"
Alex Klein5534f992019-09-16 16:31:23 -0600174
Alex Klein1699fab2022-09-08 08:46:06 -0600175 logging.info("Creating shallow clone of chromiumos/config")
176 git.Clone(
177 chromeos_config_path,
178 "%s/chromiumos/config" % constants.EXTERNAL_GOB_URL,
179 depth=1,
180 )
Sean McAllister6a5eaa02021-05-26 10:47:14 -0600181
Alex Klein1699fab2022-09-08 08:46:06 -0600182 for src_dir in dir_subset.get_source_dirs(source, chromeos_config_path):
183 targets.extend(list(src_dir.rglob("*.proto")))
Andrew Lamb59ed32e2021-07-26 15:14:37 -0600184
Trent Apted8f5782a2023-07-11 10:25:02 +1000185 output_type = (
186 "pyi" if protoc_version is ProtocVersion.CHROMITE_PYI else "python"
187 )
Alex Klein1699fab2022-09-08 08:46:06 -0600188 cmd = [
189 protoc_bin_path,
190 "-I",
191 chromeos_config_path / "proto",
Trent Apted8f5782a2023-07-11 10:25:02 +1000192 f"--{output_type}_out",
Alex Klein1699fab2022-09-08 08:46:06 -0600193 output,
194 "--proto_path",
195 source,
196 ]
197 cmd.extend(targets)
Sean McAllister6a5eaa02021-05-26 10:47:14 -0600198
Alex Klein1699fab2022-09-08 08:46:06 -0600199 result = cros_build_lib.dbg_run(
200 cmd,
201 cwd=source,
202 check=False,
203 enter_chroot=protoc_version is ProtocVersion.SDK,
204 )
Sean McAllister6a5eaa02021-05-26 10:47:14 -0600205
Alex Klein1699fab2022-09-08 08:46:06 -0600206 if result.returncode:
207 raise GenerationError(
208 "Error compiling the proto. See the output for a " "message."
209 )
Alex Kleinf9859972019-03-14 17:11:42 -0600210
211
Trent Apted8f5782a2023-07-11 10:25:02 +1000212def _InstallMissingInits(directory: Path, protoc_version: ProtocVersion):
Alex Klein54c891a2023-01-24 10:45:41 -0700213 """Add missing __init__.py files in the generated protobuf folders."""
Trent Apted8f5782a2023-07-11 10:25:02 +1000214 if protoc_version is ProtocVersion.CHROMITE_PYI:
215 # For pyi, rely on module markers left behind by CHROMITE flows to avoid
216 # additional clutter.
217 return
218
Alex Klein1699fab2022-09-08 08:46:06 -0600219 logging.info("Adding missing __init__.py files in %s.", directory)
220 # glob ** returns only directories.
221 for current in directory.rglob("**"):
222 (current / "__init__.py").touch()
Alex Kleinf9859972019-03-14 17:11:42 -0600223
224
Alex Klein177bb942022-05-24 13:32:27 -0600225def _PostprocessFiles(directory: Path, protoc_version: ProtocVersion):
Alex Klein1699fab2022-09-08 08:46:06 -0600226 """Do postprocessing on the generated files.
Alex Kleinf9859972019-03-14 17:11:42 -0600227
Alex Klein1699fab2022-09-08 08:46:06 -0600228 Args:
Alex Kleina0442682022-10-10 13:47:38 -0600229 directory: The root directory containing the generated files that are
230 to be processed.
231 protoc_version: Which protoc is being used to generate the files.
Alex Klein1699fab2022-09-08 08:46:06 -0600232 """
233 logging.info("Postprocessing: Fix imports in %s.", directory)
234 # We are using a negative address here (the /address/! portion of the sed
235 # command) to make sure we don't change any imports from protobuf itself.
236 address = "^from google.protobuf"
237 # Find: 'from x import y_pb2 as x_dot_y_pb2'.
238 # "\(^google.protobuf[^ ]*\)" matches the module we're importing from.
239 # - \( and \) are for groups in sed.
240 # - ^google.protobuf prevents changing the import for protobuf's files.
Alex Klein54c891a2023-01-24 10:45:41 -0700241 # - [^ ] = Not a space. The [:space:] character set is too broad, but
242 # would technically work too.
Alex Klein1699fab2022-09-08 08:46:06 -0600243 find = r"^from \([^ ]*\) import \([^ ]*\)_pb2 as \([^ ]*\)$"
244 # Substitute: 'from chromite.api.gen[_sdk].x import y_pb2 as x_dot_y_pb2'.
245 if protoc_version is ProtocVersion.SDK:
246 sub = "from chromite.api.gen_sdk.\\1 import \\2_pb2 as \\3"
247 else:
248 sub = "from chromite.api.gen.\\1 import \\2_pb2 as \\3"
Alex Klein098f7982021-03-01 13:15:29 -0700249
Alex Klein1699fab2022-09-08 08:46:06 -0600250 from_sed = [
251 "sed",
252 "-i",
253 "/%(address)s/!s/%(find)s/%(sub)s/g"
254 % {"address": address, "find": find, "sub": sub},
Alex Kleind20d8162021-06-21 12:40:44 -0600255 ]
Alex Kleind20d8162021-06-21 12:40:44 -0600256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 seds = [from_sed]
Trent Apted8f5782a2023-07-11 10:25:02 +1000258
Alex Klein1699fab2022-09-08 08:46:06 -0600259 if protoc_version is ProtocVersion.CHROMITE:
260 # We also need to change the google.protobuf imports to point directly
261 # at the chromite.third_party version of the library.
262 # The SDK version of the proto is meant to be used with the protobuf
263 # libraries installed in the SDK, so leave those as google.protobuf.
Trent Apted8f5782a2023-07-11 10:25:02 +1000264 # For CHROMITE_PYI, types for the protobuf imports come from type stubs,
265 # which won't map if the imports are renamed to third_party.
Alex Klein1699fab2022-09-08 08:46:06 -0600266 g_p_address = "^from google.protobuf"
267 g_p_find = r"from \([^ ]*\) import \(.*\)$"
268 g_p_sub = "from chromite.third_party.\\1 import \\2"
269 google_protobuf_sed = [
270 "sed",
271 "-i",
272 "/%(address)s/s/%(find)s/%(sub)s/g"
273 % {"address": g_p_address, "find": g_p_find, "sub": g_p_sub},
274 ]
275 seds.append(google_protobuf_sed)
276
Trent Apted8f5782a2023-07-11 10:25:02 +1000277 if protoc_version is ProtocVersion.CHROMITE_PYI:
278 # Workaround https://github.com/protocolbuffers/protobuf/issues/11402
279 # until cl/560557754 in in the protoc version used.
280 untyped_empty_slot_list = [
281 "sed",
282 "-E",
283 "-i",
284 "s/(^ *__slots__ = )\\[]/\\1()/",
285 ]
286
287 # Suppress errors on GRPC options field numbers using ClassVar outside
288 # of a class body. See b/297782342.
289 ignore_class_var_in_file_scope = [
290 "sed",
291 "-i",
292 "s/^[A-Z_]*: _ClassVar\\[int]/& # type: ignore/",
293 ]
294 seds.extend((untyped_empty_slot_list, ignore_class_var_in_file_scope))
295
296 pb2 = list(directory.rglob(f"*_pb2.{protoc_version.get_suffix()}"))
Alex Klein1699fab2022-09-08 08:46:06 -0600297 if pb2:
298 for sed in seds:
299 cros_build_lib.dbg_run(sed + pb2)
Alex Kleinf9859972019-03-14 17:11:42 -0600300
301
Alex Klein1699fab2022-09-08 08:46:06 -0600302def CompileProto(
303 protoc_version: ProtocVersion,
304 output: Optional[Path] = None,
305 dir_subset: SubdirectorySet = SubdirectorySet.DEFAULT,
306 postprocess: bool = True,
307):
308 """Compile the Build API protobuf files.
Alex Kleinf9859972019-03-14 17:11:42 -0600309
Alex Kleinb6d52022022-10-18 08:55:06 -0600310 By default, this will compile from infra/proto/src to api/gen. The output
Alex Klein1699fab2022-09-08 08:46:06 -0600311 directory may be changed, but the imports will always be treated as if it is
312 in the default location.
Alex Kleinf9859972019-03-14 17:11:42 -0600313
Alex Klein1699fab2022-09-08 08:46:06 -0600314 Args:
Alex Kleina0442682022-10-10 13:47:38 -0600315 output: The output directory.
Alex Kleinb6d52022022-10-18 08:55:06 -0600316 protoc_version: Which protoc to use for the compilation.
Alex Kleina0442682022-10-10 13:47:38 -0600317 dir_subset: What proto to compile.
318 postprocess: Whether to run the postprocess step.
Alex Klein1699fab2022-09-08 08:46:06 -0600319 """
Alex Klein1699fab2022-09-08 08:46:06 -0600320 source = protoc_version.get_proto_dir() / "src"
321 if not output:
322 output = protoc_version.get_gen_dir()
Alex Kleinf9859972019-03-14 17:11:42 -0600323
Alex Klein1699fab2022-09-08 08:46:06 -0600324 protoc_bin_path = InstallProtoc(protoc_version)
Trent Apted8f5782a2023-07-11 10:25:02 +1000325 _CleanTargetDirectory(output, protoc_version)
Alex Klein1699fab2022-09-08 08:46:06 -0600326 _GenerateFiles(source, output, protoc_version, dir_subset, protoc_bin_path)
Trent Apted8f5782a2023-07-11 10:25:02 +1000327 _InstallMissingInits(output, protoc_version)
Alex Klein1699fab2022-09-08 08:46:06 -0600328 if postprocess:
329 _PostprocessFiles(output, protoc_version)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700330
331
332def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -0600333 """Build the argument parser."""
334 parser = commandline.ArgumentParser(description=__doc__)
335 standard_group = parser.add_argument_group(
336 "Committed Bindings",
337 description="Options for generating the bindings in chromite/api/.",
338 )
339 standard_group.add_argument(
340 "--chromite",
341 dest="protoc_version",
342 action="append_const",
343 const=ProtocVersion.CHROMITE,
Alex Klein54c891a2023-01-24 10:45:41 -0700344 help="Generate only the chromite bindings. Generates all by default. "
345 "The chromite bindings are compatible with the version of protobuf "
346 "in chromite/third_party.",
Alex Klein1699fab2022-09-08 08:46:06 -0600347 )
348 standard_group.add_argument(
Trent Apted8f5782a2023-07-11 10:25:02 +1000349 "--pyi",
350 dest="protoc_version",
351 action="append_const",
352 const=ProtocVersion.CHROMITE_PYI,
353 help="Generate only the pyi type annotations.",
354 )
355 standard_group.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600356 "--sdk",
357 dest="protoc_version",
358 action="append_const",
359 const=ProtocVersion.SDK,
Alex Klein54c891a2023-01-24 10:45:41 -0700360 help="Generate only the SDK bindings. Generates all by default. The "
361 "SDK bindings are compiled by protoc in the SDK, and is compatible "
Alex Klein1699fab2022-09-08 08:46:06 -0600362 "with the version of protobuf in the SDK (i.e. the one installed by "
363 "the ebuild).",
364 )
Alex Klein098f7982021-03-01 13:15:29 -0700365
Alex Klein1699fab2022-09-08 08:46:06 -0600366 dest_group = parser.add_argument_group(
367 "Out of Tree Bindings",
368 description="Options for generating bindings in a custom location.",
369 )
370 dest_group.add_argument(
371 "--destination",
372 type="path",
373 help="A directory where a single version of the proto should be "
374 "generated. When not given, the proto generates in all default "
375 "locations instead.",
376 )
377 dest_group.add_argument(
378 "--dest-sdk",
379 action="store_const",
380 dest="dest_protoc",
381 default=ProtocVersion.CHROMITE,
382 const=ProtocVersion.SDK,
Alex Klein54c891a2023-01-24 10:45:41 -0700383 help="Generate the SDK version of the protos in --destination instead "
384 "of the chromite version.",
Alex Klein1699fab2022-09-08 08:46:06 -0600385 )
386 dest_group.add_argument(
387 "--all-proto",
388 action="store_const",
389 dest="dir_subset",
390 default=SubdirectorySet.DEFAULT,
391 const=SubdirectorySet.ALL,
392 help="Compile ALL proto instead of just the subset needed for the API. "
393 "Only considered when generating out of tree bindings.",
394 )
395 dest_group.add_argument(
396 "--skip-postprocessing",
397 action="store_false",
398 dest="postprocess",
399 default=True,
400 help="Skip postprocessing files.",
401 )
402 return parser
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700403
404
405def _ParseArguments(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600406 """Parse and validate arguments."""
407 parser = GetParser()
408 opts = parser.parse_args(argv)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700409
Alex Klein1699fab2022-09-08 08:46:06 -0600410 if not opts.protoc_version:
Trent Apted8f5782a2023-07-11 10:25:02 +1000411 opts.protoc_version = [
412 ProtocVersion.CHROMITE,
413 ProtocVersion.SDK,
414 ProtocVersion.CHROMITE_PYI,
415 ]
Alex Klein098f7982021-03-01 13:15:29 -0700416
Alex Klein1699fab2022-09-08 08:46:06 -0600417 if opts.destination:
418 opts.destination = Path(opts.destination)
Alex Klein177bb942022-05-24 13:32:27 -0600419
Alex Klein1699fab2022-09-08 08:46:06 -0600420 opts.Freeze()
421 return opts
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700422
423
424def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600425 opts = _ParseArguments(argv)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700426
Alex Klein1699fab2022-09-08 08:46:06 -0600427 if opts.destination:
428 # Destination set, only compile a single version in the destination.
429 try:
430 CompileProto(
431 protoc_version=opts.dest_protoc,
432 output=opts.destination,
433 dir_subset=opts.dir_subset,
434 postprocess=opts.postprocess,
435 )
436 except Error as e:
Trent Apted8f5782a2023-07-11 10:25:02 +1000437 cros_build_lib.Die("Error compiling bindings to destination: %s", e)
Alex Klein1699fab2022-09-08 08:46:06 -0600438 else:
439 return 0
Alex Klein098f7982021-03-01 13:15:29 -0700440
Alex Klein1699fab2022-09-08 08:46:06 -0600441 if ProtocVersion.CHROMITE in opts.protoc_version:
442 # Compile the chromite bindings.
443 try:
444 CompileProto(protoc_version=ProtocVersion.CHROMITE)
445 except Error as e:
Trent Apted8f5782a2023-07-11 10:25:02 +1000446 cros_build_lib.Die("Error compiling chromite bindings: %s", e)
447
448 if ProtocVersion.CHROMITE_PYI in opts.protoc_version:
449 try:
450 CompileProto(protoc_version=ProtocVersion.CHROMITE_PYI)
451 except Error as e:
452 cros_build_lib.Die("Error compiling type annotations: %s", e)
Alex Klein098f7982021-03-01 13:15:29 -0700453
Alex Klein1699fab2022-09-08 08:46:06 -0600454 if ProtocVersion.SDK in opts.protoc_version:
455 # Compile the SDK bindings.
456 if not cros_build_lib.IsInsideChroot():
Alex Kleinb6d52022022-10-18 08:55:06 -0600457 # Rerun inside the SDK instead of trying to map all the paths.
Alex Klein1699fab2022-09-08 08:46:06 -0600458 cmd = [
459 (
Mike Frysinger83e7ff22023-08-07 21:42:28 -0400460 constants.CHROOT_SOURCE_ROOT
Alex Klein1699fab2022-09-08 08:46:06 -0600461 / "chromite"
462 / "api"
463 / "compile_build_api_proto"
464 ),
465 "--sdk",
466 ]
467 result = cros_build_lib.dbg_run(cmd, enter_chroot=True, check=False)
468 return result.returncode
469 else:
470 try:
471 CompileProto(protoc_version=ProtocVersion.SDK)
472 except Error as e:
Trent Apted8f5782a2023-07-11 10:25:02 +1000473 cros_build_lib.Die("Error compiling SDK bindings: %s", e)