Files
Dawid Małecki fd150efa29 Exclude Android specific symbols from the ReactApple snapshot (#56243)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56243

Modifies C++ API parser config to accept `exclude_symbols` at the platform level and sets `Android` symbols to be excluded from the ReactApple snapshot.

Changelog:
[Internal]

Reviewed By: cipolleschi

Differential Revision: D98298766

fbshipit-source-id: 70b39fe4935e6791701c173e7c9e12532c2817a5
2026-03-31 08:32:57 -07:00

157 lines
5.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.
"""
Config parsing module for C++ API snapshot generation.
This module handles parsing of the config.yml file and provides
structured objects representing API views and their variants.
"""
import os
from dataclasses import dataclass, field
import yaml
@dataclass
class ApiViewVariant:
"""Represents a build variant (e.g., debug, release) for an API view."""
name: str
definitions: dict[str, str | int] = field(default_factory=dict)
@dataclass
class ApiViewSnapshotConfig:
"""
A fully resolved configuration for generating a single snapshot.
This combines the base view settings with variant-specific definitions.
"""
snapshot_name: str
inputs: list[str]
exclude_patterns: list[str]
definitions: dict[str, str | int]
codegen_platform: str | None = None
input_filter: bool = False
exclude_symbols: list[str] = field(default_factory=list)
def parse_config(
raw_config: dict,
base_dir: str,
) -> list[ApiViewSnapshotConfig]:
"""
Parse a raw config dictionary and return a flattened list of snapshot configs.
The config must contain:
- An optional top-level ``exclude_patterns`` list that is prepended to
every platform's own ``exclude_patterns``.
- A ``platforms`` mapping whose values are per-platform view configs.
Args:
raw_config: Dictionary containing the parsed YAML config
base_dir: Base directory for resolving relative input paths
Returns:
Flattened list of ApiViewSnapshotConfig objects for all views and variants
"""
global_exclude_patterns: list[str] = raw_config.get("exclude_patterns") or []
global_exclude_symbols: list[str] = raw_config.get("exclude_symbols") or []
platforms: dict = raw_config.get("platforms") or {}
snapshot_configs = []
for view_name, view_config in platforms.items():
inputs = [
path if path.startswith("/") else os.path.join(base_dir, path)
for path in (view_config.get("inputs") or [])
]
codegen_config = view_config.get("codegen") or {}
codegen_platform = codegen_config.get("platform")
exclude_patterns = view_config.get("exclude_patterns") or []
input_filter = view_config.get("input_filter", False)
base_definitions = view_config.get("definitions") or {}
exclude_platform_patterns = view_config.get("exclude_patterns") or []
seen: set[str] = set()
merged_patterns: list[str] = []
for pattern in global_exclude_patterns + exclude_platform_patterns:
if pattern not in seen:
merged_patterns.append(pattern)
seen.add(pattern)
exclude_patterns = merged_patterns
platform_exclude_symbols = view_config.get("exclude_symbols") or []
seen_symbols: set[str] = set()
merged_symbols: list[str] = []
for symbol in global_exclude_symbols + platform_exclude_symbols:
if symbol not in seen_symbols:
merged_symbols.append(symbol)
seen_symbols.add(symbol)
exclude_symbols = merged_symbols
raw_variants = view_config.get("variants") or {}
variants = [
ApiViewVariant(
name=variant_name,
definitions=variant_config.get("definitions") or {},
)
for variant_name, variant_config in raw_variants.items()
]
if not variants:
snapshot_configs.append(
ApiViewSnapshotConfig(
snapshot_name=view_name,
inputs=inputs,
exclude_patterns=exclude_patterns,
definitions=base_definitions,
codegen_platform=codegen_platform,
input_filter=input_filter,
exclude_symbols=exclude_symbols,
)
)
else:
for variant in variants:
merged_definitions = {**base_definitions, **variant.definitions}
variant_suffix = variant.name.capitalize()
snapshot_configs.append(
ApiViewSnapshotConfig(
snapshot_name=f"{view_name}{variant_suffix}",
inputs=inputs,
exclude_patterns=exclude_patterns,
definitions=merged_definitions,
codegen_platform=codegen_platform,
input_filter=input_filter,
exclude_symbols=exclude_symbols,
)
)
return snapshot_configs
def parse_config_file(
config_path: str,
base_dir: str,
) -> list[ApiViewSnapshotConfig]:
"""
Parse the config.yml file and return a flattened list of snapshot configs.
Args:
config_path: Path to the config.yml file
base_dir: Base directory for resolving relative input paths
Returns:
Flattened list of ApiViewSnapshotConfig objects for all views and variants
"""
with open(config_path, "r") as stream:
raw_config = yaml.safe_load(stream)
return parse_config(raw_config, base_dir)