blob: 7e684a6ab88ace074cc3c1b24020767bc2fa4833 [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 """
Trent Aptedc1618e72023-09-25 10:30:14 +1000164 logging.info("Generating %s files to %s.", protoc_version, output)
Alex Klein1699fab2022-09-08 08:46:06 -0600165 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
Trent Aptedc1618e72023-09-25 10:30:14 +1000250 seds = [f"/{address}/!s/{find}/{sub}/g"]
Trent Apted8f5782a2023-07-11 10:25:02 +1000251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 if protoc_version is ProtocVersion.CHROMITE:
253 # We also need to change the google.protobuf imports to point directly
254 # at the chromite.third_party version of the library.
255 # The SDK version of the proto is meant to be used with the protobuf
256 # libraries installed in the SDK, so leave those as google.protobuf.
Trent Apted8f5782a2023-07-11 10:25:02 +1000257 # For CHROMITE_PYI, types for the protobuf imports come from type stubs,
258 # which won't map if the imports are renamed to third_party.
Alex Klein1699fab2022-09-08 08:46:06 -0600259 g_p_address = "^from google.protobuf"
260 g_p_find = r"from \([^ ]*\) import \(.*\)$"
261 g_p_sub = "from chromite.third_party.\\1 import \\2"
Trent Aptedc1618e72023-09-25 10:30:14 +1000262 seds.append(f"/{g_p_address}/s/{g_p_find}/{g_p_sub}/")
Alex Klein1699fab2022-09-08 08:46:06 -0600263
Trent Apted8f5782a2023-07-11 10:25:02 +1000264 if protoc_version is ProtocVersion.CHROMITE_PYI:
265 # Workaround https://github.com/protocolbuffers/protobuf/issues/11402
266 # until cl/560557754 in in the protoc version used.
Trent Aptedc1618e72023-09-25 10:30:14 +1000267 untyped_empty_slot_list = "s/\\(^ *__slots__ = \\)\\[]/\\1()/"
Trent Apted8f5782a2023-07-11 10:25:02 +1000268
269 # Suppress errors on GRPC options field numbers using ClassVar outside
270 # of a class body. See b/297782342.
Trent Aptedc1618e72023-09-25 10:30:14 +1000271 ignore_class_var_in_file_scope = (
272 "s/^[A-Z_]*: _ClassVar\\[int]/& # type: ignore/"
273 )
Trent Apted8f5782a2023-07-11 10:25:02 +1000274 seds.extend((untyped_empty_slot_list, ignore_class_var_in_file_scope))
275
276 pb2 = list(directory.rglob(f"*_pb2.{protoc_version.get_suffix()}"))
Alex Klein1699fab2022-09-08 08:46:06 -0600277 if pb2:
Trent Aptedc1618e72023-09-25 10:30:14 +1000278 cros_build_lib.dbg_run(["sed", "-i", ";".join(seds)] + pb2)
Alex Kleinf9859972019-03-14 17:11:42 -0600279
280
Alex Klein1699fab2022-09-08 08:46:06 -0600281def CompileProto(
282 protoc_version: ProtocVersion,
283 output: Optional[Path] = None,
284 dir_subset: SubdirectorySet = SubdirectorySet.DEFAULT,
285 postprocess: bool = True,
286):
287 """Compile the Build API protobuf files.
Alex Kleinf9859972019-03-14 17:11:42 -0600288
Alex Kleinb6d52022022-10-18 08:55:06 -0600289 By default, this will compile from infra/proto/src to api/gen. The output
Alex Klein1699fab2022-09-08 08:46:06 -0600290 directory may be changed, but the imports will always be treated as if it is
291 in the default location.
Alex Kleinf9859972019-03-14 17:11:42 -0600292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 Args:
Alex Kleina0442682022-10-10 13:47:38 -0600294 output: The output directory.
Alex Kleinb6d52022022-10-18 08:55:06 -0600295 protoc_version: Which protoc to use for the compilation.
Alex Kleina0442682022-10-10 13:47:38 -0600296 dir_subset: What proto to compile.
297 postprocess: Whether to run the postprocess step.
Alex Klein1699fab2022-09-08 08:46:06 -0600298 """
Alex Klein1699fab2022-09-08 08:46:06 -0600299 source = protoc_version.get_proto_dir() / "src"
300 if not output:
301 output = protoc_version.get_gen_dir()
Alex Kleinf9859972019-03-14 17:11:42 -0600302
Alex Klein1699fab2022-09-08 08:46:06 -0600303 protoc_bin_path = InstallProtoc(protoc_version)
Trent Apted8f5782a2023-07-11 10:25:02 +1000304 _CleanTargetDirectory(output, protoc_version)
Alex Klein1699fab2022-09-08 08:46:06 -0600305 _GenerateFiles(source, output, protoc_version, dir_subset, protoc_bin_path)
Trent Apted8f5782a2023-07-11 10:25:02 +1000306 _InstallMissingInits(output, protoc_version)
Alex Klein1699fab2022-09-08 08:46:06 -0600307 if postprocess:
308 _PostprocessFiles(output, protoc_version)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700309
310
311def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -0600312 """Build the argument parser."""
313 parser = commandline.ArgumentParser(description=__doc__)
314 standard_group = parser.add_argument_group(
315 "Committed Bindings",
316 description="Options for generating the bindings in chromite/api/.",
317 )
318 standard_group.add_argument(
319 "--chromite",
320 dest="protoc_version",
321 action="append_const",
322 const=ProtocVersion.CHROMITE,
Alex Klein54c891a2023-01-24 10:45:41 -0700323 help="Generate only the chromite bindings. Generates all by default. "
324 "The chromite bindings are compatible with the version of protobuf "
325 "in chromite/third_party.",
Alex Klein1699fab2022-09-08 08:46:06 -0600326 )
327 standard_group.add_argument(
Trent Apted8f5782a2023-07-11 10:25:02 +1000328 "--pyi",
329 dest="protoc_version",
330 action="append_const",
331 const=ProtocVersion.CHROMITE_PYI,
332 help="Generate only the pyi type annotations.",
333 )
334 standard_group.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600335 "--sdk",
336 dest="protoc_version",
337 action="append_const",
338 const=ProtocVersion.SDK,
Alex Klein54c891a2023-01-24 10:45:41 -0700339 help="Generate only the SDK bindings. Generates all by default. The "
340 "SDK bindings are compiled by protoc in the SDK, and is compatible "
Alex Klein1699fab2022-09-08 08:46:06 -0600341 "with the version of protobuf in the SDK (i.e. the one installed by "
342 "the ebuild).",
343 )
Alex Klein098f7982021-03-01 13:15:29 -0700344
Alex Klein1699fab2022-09-08 08:46:06 -0600345 dest_group = parser.add_argument_group(
346 "Out of Tree Bindings",
347 description="Options for generating bindings in a custom location.",
348 )
349 dest_group.add_argument(
350 "--destination",
351 type="path",
352 help="A directory where a single version of the proto should be "
353 "generated. When not given, the proto generates in all default "
354 "locations instead.",
355 )
356 dest_group.add_argument(
357 "--dest-sdk",
358 action="store_const",
359 dest="dest_protoc",
360 default=ProtocVersion.CHROMITE,
361 const=ProtocVersion.SDK,
Alex Klein54c891a2023-01-24 10:45:41 -0700362 help="Generate the SDK version of the protos in --destination instead "
363 "of the chromite version.",
Alex Klein1699fab2022-09-08 08:46:06 -0600364 )
365 dest_group.add_argument(
366 "--all-proto",
367 action="store_const",
368 dest="dir_subset",
369 default=SubdirectorySet.DEFAULT,
370 const=SubdirectorySet.ALL,
371 help="Compile ALL proto instead of just the subset needed for the API. "
372 "Only considered when generating out of tree bindings.",
373 )
374 dest_group.add_argument(
375 "--skip-postprocessing",
376 action="store_false",
377 dest="postprocess",
378 default=True,
379 help="Skip postprocessing files.",
380 )
381 return parser
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700382
383
384def _ParseArguments(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600385 """Parse and validate arguments."""
386 parser = GetParser()
387 opts = parser.parse_args(argv)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700388
Alex Klein1699fab2022-09-08 08:46:06 -0600389 if not opts.protoc_version:
Trent Apted8f5782a2023-07-11 10:25:02 +1000390 opts.protoc_version = [
391 ProtocVersion.CHROMITE,
392 ProtocVersion.SDK,
393 ProtocVersion.CHROMITE_PYI,
394 ]
Alex Klein098f7982021-03-01 13:15:29 -0700395
Alex Klein1699fab2022-09-08 08:46:06 -0600396 if opts.destination:
397 opts.destination = Path(opts.destination)
Alex Klein177bb942022-05-24 13:32:27 -0600398
Alex Klein1699fab2022-09-08 08:46:06 -0600399 opts.Freeze()
400 return opts
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700401
402
403def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600404 opts = _ParseArguments(argv)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700405
Alex Klein1699fab2022-09-08 08:46:06 -0600406 if opts.destination:
407 # Destination set, only compile a single version in the destination.
408 try:
409 CompileProto(
410 protoc_version=opts.dest_protoc,
411 output=opts.destination,
412 dir_subset=opts.dir_subset,
413 postprocess=opts.postprocess,
414 )
415 except Error as e:
Trent Apted8f5782a2023-07-11 10:25:02 +1000416 cros_build_lib.Die("Error compiling bindings to destination: %s", e)
Alex Klein1699fab2022-09-08 08:46:06 -0600417 else:
418 return 0
Alex Klein098f7982021-03-01 13:15:29 -0700419
Alex Klein1699fab2022-09-08 08:46:06 -0600420 if ProtocVersion.CHROMITE in opts.protoc_version:
421 # Compile the chromite bindings.
422 try:
423 CompileProto(protoc_version=ProtocVersion.CHROMITE)
424 except Error as e:
Trent Apted8f5782a2023-07-11 10:25:02 +1000425 cros_build_lib.Die("Error compiling chromite bindings: %s", e)
426
427 if ProtocVersion.CHROMITE_PYI in opts.protoc_version:
428 try:
429 CompileProto(protoc_version=ProtocVersion.CHROMITE_PYI)
430 except Error as e:
431 cros_build_lib.Die("Error compiling type annotations: %s", e)
Alex Klein098f7982021-03-01 13:15:29 -0700432
Alex Klein1699fab2022-09-08 08:46:06 -0600433 if ProtocVersion.SDK in opts.protoc_version:
434 # Compile the SDK bindings.
435 if not cros_build_lib.IsInsideChroot():
Alex Kleinb6d52022022-10-18 08:55:06 -0600436 # Rerun inside the SDK instead of trying to map all the paths.
Alex Klein1699fab2022-09-08 08:46:06 -0600437 cmd = [
438 (
Mike Frysinger83e7ff22023-08-07 21:42:28 -0400439 constants.CHROOT_SOURCE_ROOT
Alex Klein1699fab2022-09-08 08:46:06 -0600440 / "chromite"
441 / "api"
442 / "compile_build_api_proto"
443 ),
444 "--sdk",
445 ]
446 result = cros_build_lib.dbg_run(cmd, enter_chroot=True, check=False)
447 return result.returncode
448 else:
449 try:
450 CompileProto(protoc_version=ProtocVersion.SDK)
451 except Error as e:
Trent Apted8f5782a2023-07-11 10:25:02 +1000452 cros_build_lib.Die("Error compiling SDK bindings: %s", e)