Files
Jakub Piasecki 32f1dcd804 Generate snapshots in parallel (#56184)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56184

Changelog: [Internal]

Updates the snapshot generator script to run generation steps for all snapshots in parallel instead of in sequence, significantly improving the generation time.

Reviewed By: cortinico

Differential Revision: D97714334

fbshipit-source-id: b643dd7bb2fa4f3f9db1495bc7a44c0069a25274
2026-03-24 02:34:59 -07:00

115 lines
3.3 KiB
Python

# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
"""
Doxygen configuration and execution utilities.
"""
import os
import subprocess
_DOXYGEN_CONFIG_FILE = ".doxygen.config.generated"
def get_doxygen_bin() -> str:
return os.environ.get("DOXYGEN_BIN", "doxygen")
def build_doxygen_config(
directory: str,
include_directories: list[str] = None,
exclude_patterns: list[str] = None,
definitions: dict[str, str | int] = None,
input_filter: str = None,
output_dir: str = "api",
config_file: str = _DOXYGEN_CONFIG_FILE,
) -> None:
if include_directories is None:
include_directories = []
if exclude_patterns is None:
exclude_patterns = []
if definitions is None:
definitions = {}
include_directories_str = " ".join(include_directories)
exclude_patterns_str = "\\\n".join(exclude_patterns)
if len(exclude_patterns) > 0:
exclude_patterns_str = f"\\\n{exclude_patterns_str}"
definitions_str = " ".join(
[
f'{key}="{value}"' if isinstance(value, str) else f"{key}={value}"
for key, value in definitions.items()
]
)
input_filter_str = input_filter if input_filter else ""
with open(os.path.join(directory, ".doxygen.config.template")) as f:
template = f.read()
config = (
template.replace("${INPUTS}", include_directories_str)
.replace("${EXCLUDE_PATTERNS}", exclude_patterns_str)
.replace("${PREDEFINED}", definitions_str)
.replace("${DOXYGEN_INPUT_FILTER}", input_filter_str)
.replace("${OUTPUT_DIR}", output_dir)
)
with open(os.path.join(directory, config_file), "w") as f:
f.write(config)
def run_doxygen(
working_dir: str,
include_directories: list[str],
exclude_patterns: list[str],
definitions: dict[str, str | int],
input_filter: str = None,
verbose: bool = True,
output_dir: str = "api",
config_file: str = _DOXYGEN_CONFIG_FILE,
label: str = "",
) -> None:
"""Generate Doxygen config, run Doxygen, and clean up the config file."""
prefix = f"[{label}] " if label else ""
if verbose:
print(f"{prefix}Generating Doxygen config file")
build_doxygen_config(
working_dir,
include_directories=include_directories,
exclude_patterns=exclude_patterns,
definitions=definitions,
input_filter=input_filter,
output_dir=output_dir,
config_file=config_file,
)
if verbose:
print(f"{prefix}Running Doxygen")
if input_filter:
print(f"{prefix}Using input filter: {input_filter}")
doxygen_bin = get_doxygen_bin()
result = subprocess.run(
[doxygen_bin, config_file],
cwd=working_dir,
capture_output=True,
text=True,
)
if result.returncode != 0:
if verbose:
print(f"{prefix}Doxygen finished with error: {result.stderr}")
raise RuntimeError(f"Doxygen finished with error: {result.stderr}")
elif verbose:
print(f"{prefix}Doxygen finished successfully")
if verbose:
print(f"{prefix}Deleting Doxygen config file")
os.remove(os.path.join(working_dir, config_file))