Skip to content

Commit 3b634bc

Browse files
j-piaseckimeta-codesync[bot]
authored andcommitted
Run the snapshot comparison on CI (#56207)
Summary: Pull Request resolved: #56207 Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D96101927 fbshipit-source-id: 06c6dd11c145be44bcdd97f14683a222c66c96c6
1 parent 866e55c commit 3b634bc

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,5 @@ __pycache__/
183183
# Doxygen XML output used for C++ API tracking
184184
/packages/react-native/**/api/xml
185185
/packages/react-native/**/api/codegen
186-
/packages/react-native/**/.doxygen.config.generated
186+
/packages/react-native/**/.doxygen.config.*.generated
187187
/scripts/cxx-api/codegen

scripts/cxx-api/parser/__main__.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ def run_command(
3636
"""Run a subprocess command with consistent error handling."""
3737
result = subprocess.run(cmd, **kwargs)
3838
if result.returncode != 0:
39-
if verbose:
40-
print(f"{label} finished with error: {result.stderr}")
39+
stderr_output = result.stderr or ""
40+
if isinstance(stderr_output, bytes):
41+
stderr_output = stderr_output.decode("utf-8", errors="replace")
42+
print(f"{label} failed (exit code {result.returncode})", file=sys.stderr)
43+
if stderr_output:
44+
print(stderr_output, file=sys.stderr)
4145
raise RuntimeError(
4246
f"{label} finished with error (exit code {result.returncode})"
4347
)
@@ -54,9 +58,11 @@ def build_codegen(
5458
) -> str:
5559
react_native_dir = os.path.join(get_react_native_dir(), "packages", "react-native")
5660

61+
node_bin = os.environ.get("NODE_BIN", "node")
62+
5763
run_command(
5864
[
59-
"node",
65+
node_bin,
6066
"./scripts/generate-codegen-artifacts.js",
6167
"--path",
6268
"./",
@@ -254,6 +260,11 @@ def main():
254260
action="store_true",
255261
help="Generate snapshots to a temp directory and compare against committed ones",
256262
)
263+
parser.add_argument(
264+
"--validate-output",
265+
type=str,
266+
help="File path to write validate results to (used with --validate)",
267+
)
257268
parser.add_argument(
258269
"--snapshot-dir",
259270
type=str,
@@ -337,7 +348,11 @@ def main():
337348
if args.validate:
338349
snapshot_dir = args.snapshot_dir or get_default_snapshot_dir()
339350

340-
if not validate_snapshots(snapshot_output_dir, snapshot_dir):
351+
if not validate_snapshots(
352+
snapshot_output_dir,
353+
snapshot_dir,
354+
output_file=args.validate_output,
355+
):
341356
sys.exit(1)
342357

343358
print("All snapshot validations passed")

scripts/cxx-api/parser/snapshot_diff.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,40 @@
99

1010
import difflib
1111
import os
12+
import sys
1213

1314

14-
def validate_snapshots(generated_dir: str, committed_dir: str) -> bool:
15+
def validate_snapshots(
16+
generated_dir: str, committed_dir: str, output_file: str | None = None
17+
) -> bool:
1518
"""Compare generated snapshots against committed ones.
1619
1720
Returns True if validation passes (snapshots match or no committed snapshots).
1821
Returns False if snapshots differ.
22+
23+
If output_file is provided, writes comparison results to that file
24+
instead of stdout.
1925
"""
26+
out = open(output_file, "w") if output_file else sys.stdout
27+
try:
28+
return _check_snapshots_impl(generated_dir, committed_dir, out)
29+
finally:
30+
if output_file:
31+
out.close()
32+
33+
34+
def _check_snapshots_impl(generated_dir: str, committed_dir: str, out) -> bool:
2035
if not os.path.isdir(committed_dir):
21-
print(f"No committed snapshots directory found at: {committed_dir}")
22-
print("Skipping comparison (no baseline to compare against)")
36+
print(f"No committed snapshots directory found at: {committed_dir}", file=out)
37+
print("Skipping comparison (no baseline to compare against)", file=out)
2338
return True
2439

2540
committed_files = sorted(f for f in os.listdir(committed_dir) if f.endswith(".api"))
2641
generated_files = sorted(f for f in os.listdir(generated_dir) if f.endswith(".api"))
2742

2843
if not committed_files:
29-
print("No committed snapshot files found")
30-
print("Skipping comparison (no baseline to compare against)")
44+
print("No committed snapshot files found", file=out)
45+
print("Skipping comparison (no baseline to compare against)", file=out)
3146
return True
3247

3348
committed_set = set(committed_files)
@@ -40,13 +55,14 @@ def validate_snapshots(generated_dir: str, committed_dir: str) -> bool:
4055

4156
if filename not in generated_set:
4257
print(
43-
f"FAIL: {filename} exists in committed snapshots but was not generated"
58+
f"FAIL: {filename} exists in committed snapshots but was not generated",
59+
file=out,
4460
)
4561
all_passed = False
4662
continue
4763

4864
if filename not in committed_set:
49-
print(f"OK: {filename} generated (no committed baseline)")
65+
print(f"OK: {filename} generated (no committed baseline)", file=out)
5066
continue
5167

5268
with open(committed_path) as f:
@@ -55,9 +71,9 @@ def validate_snapshots(generated_dir: str, committed_dir: str) -> bool:
5571
generated_content = f.read()
5672

5773
if committed_content == generated_content:
58-
print(f"OK: {filename} matches committed snapshot")
74+
print(f"OK: {filename} matches committed snapshot", file=out)
5975
else:
60-
print(f"FAIL: {filename} differs from committed snapshot")
76+
print(f"FAIL: {filename} differs from committed snapshot", file=out)
6177
diff = "\n".join(
6278
difflib.unified_diff(
6379
committed_content.splitlines(),
@@ -67,7 +83,7 @@ def validate_snapshots(generated_dir: str, committed_dir: str) -> bool:
6783
lineterm="",
6884
)
6985
)
70-
print(diff)
86+
print(diff, file=out)
7187
all_passed = False
7288

7389
return all_passed

0 commit comments

Comments
 (0)