Either apply, print diff, or check. Returns process exit code. Writes use ``newline="\\n"`` and a binary compare so a codegen run on Windows produces the same bytes as one on Linux — otherwise Python's default newline translation would silently bake ``\\r\\n`` into the on-disk artif
(writes: List[FileWrite], dry_run: bool, check_only: bool)
| 4051 | _CLANG_FORMAT_EXE: Optional[str] = None |
| 4052 | _CLANG_FORMAT_RESOLVED = False |
| 4053 | |
| 4054 | |
| 4055 | def _resolve_clang_format() -> Optional[str]: |
| 4056 | """Locate clang-format: $CLANG_FORMAT, then PATH, then VS2022's LLVM.""" |
| 4057 | global _CLANG_FORMAT_EXE, _CLANG_FORMAT_RESOLVED |
| 4058 | if _CLANG_FORMAT_RESOLVED: |
| 4059 | return _CLANG_FORMAT_EXE |
| 4060 | _CLANG_FORMAT_RESOLVED = True |
| 4061 | cand = (os.environ.get("CLANG_FORMAT") |
| 4062 | or shutil.which("clang-format-19") # common on Linux |
| 4063 | or shutil.which("clang-format")) |
| 4064 | if not cand: |
| 4065 | # Windows: VS2022's bundled LLVM. |
| 4066 | vs = ("C:/Program Files/Microsoft Visual Studio/2022/Community/" |
| 4067 | "VC/Tools/Llvm/bin/clang-format.exe") |
| 4068 | if os.path.isfile(vs): |
| 4069 | cand = vs |
| 4070 | _CLANG_FORMAT_EXE = cand |
| 4071 | return cand |
| 4072 | |
| 4073 | |
| 4074 | def _clang_format_content(content: str, path: str) -> str: |
| 4075 | """Format emitted C++ with the project .clang-format so generated files |
| 4076 | match a clang-format pass over the whole tree. clang-format is a hard |
| 4077 | regen dependency (like libclang): the committed generated tree is |
| 4078 | formatted, so emitting unformatted would trip the --check drift gate. |
| 4079 | Use clang-format 19.x (VS2022 LLVM) to match what the tree was committed |
| 4080 | with. Non-C++ artifacts (e.g. the test-only schema header) pass through.""" |
| 4081 | if not (path.endswith(".h") or path.endswith(".cpp")): |
| 4082 | return content |
| 4083 | exe = _resolve_clang_format() |
| 4084 | if not exe: |
| 4085 | raise RuntimeError( |
| 4086 | "clang-format not found — set $CLANG_FORMAT or put it on PATH " |
| 4087 | "(clang-format 19.x, e.g. VS2022's bundled LLVM). Required so the " |
| 4088 | "codegen emits formatted files; without it the --check drift gate " |
| 4089 | "will report spurious changes.") |
| 4090 | # --assume-filename lets clang-format pick up the repo-root .clang-format |
| 4091 | # by walking up from the (real) generated-file path. |
| 4092 | proc = subprocess.run( |
| 4093 | [exe, f"--assume-filename={path}", "--style=file"], |
| 4094 | input=content.encode("utf-8"), |
| 4095 | stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
| 4096 | ) |
| 4097 | if proc.returncode != 0: |
| 4098 | raise RuntimeError( |
| 4099 | f"clang-format failed on {path}: " |
| 4100 | f"{proc.stderr.decode('utf-8', 'replace')}") |
| 4101 | return proc.stdout.decode("utf-8") |
| 4102 | |
| 4103 | |
| 4104 | def apply_writes(writes: List[FileWrite], dry_run: bool, check_only: bool) -> int: |
| 4105 | """Either apply, print diff, or check. Returns process exit code. |
| 4106 | |
| 4107 | Writes use ``newline="\\n"`` and a binary compare so a codegen run on |
| 4108 | Windows produces the same bytes as one on Linux — otherwise Python's |
| 4109 | default newline translation would silently bake ``\\r\\n`` into the |
| 4110 | on-disk artifacts and ``--check`` would still pass because the |
no test coverage detected