33from __future__ import annotations
44
55import json
6+ import tomllib
67from importlib .metadata import version
78from pathlib import Path
89
1617)
1718from scripts .compiler_differential .constants import (
1819 GOLDEN_CORPUS_PREFIXES ,
20+ GOLDEN_LABEL ,
1921 GOLDEN_MANIFEST_DROPPED_KEYS ,
2022 GOLDEN_MANIFEST_RESOURCE_SECTIONS ,
2123 GOLDEN_MISSING_HINT ,
2224 GOLDEN_MODE_CHECK ,
23- GOLDEN_OPTIONAL_CORPORA ,
2425 GOLDEN_PATH_MASK ,
2526 GOLDEN_RESOURCE_DROPPED_FIELDS ,
27+ GOLDEN_SEED_CORPUS ,
28+ GOLDEN_SEED_RANGE_FILE ,
2629 GOLDEN_SUFFIX ,
2730 GOLDEN_VERSION_MASK ,
31+ GOLDEN_WORK_MASK ,
32+ PROJECT_DIRECTORY ,
2833)
2934from scripts .compiler_differential .models import (
3035 CommandOutcome ,
@@ -43,7 +48,7 @@ def golden_differences(
4348 runs : tuple [EngineRun , ...],
4449 golden_dir : Path ,
4550 mode : str ,
46- masked_paths : tuple [str , ...],
51+ masked_paths : tuple [tuple [ str , str ] , ...],
4752) -> list [Difference ]:
4853 """Check every run against the project's golden, or rewrite it from the first (oracle) run."""
4954
@@ -58,7 +63,9 @@ def golden_differences(
5863 _ = path .write_text (golden_text (payloads [0 ]), encoding = "utf-8" )
5964 return []
6065 if not path .is_file ():
61- if path .parent .name in GOLDEN_OPTIONAL_CORPORA :
66+ if path .parent .name == GOLDEN_SEED_CORPUS and not _seed_in_recorded_range (
67+ golden_dir = golden_dir , name = path .stem
68+ ):
6269 return []
6370 return [
6471 Difference (
@@ -67,7 +74,7 @@ def golden_differences(
6774 location = "file" ,
6875 left = "<missing>" ,
6976 right = GOLDEN_MISSING_HINT ,
70- labels = ("golden" , "hint" ),
77+ labels = (GOLDEN_LABEL , "hint" ),
7178 )
7279 ]
7380 golden : object = json .loads (path .read_text (encoding = "utf-8" ))
@@ -82,7 +89,7 @@ def golden_differences(
8289 location = divergence .location ,
8390 left = divergence .left ,
8491 right = divergence .right ,
85- labels = ("golden" , run .engine ),
92+ labels = (GOLDEN_LABEL , run .engine ),
8693 )
8794 )
8895 return found
@@ -97,7 +104,9 @@ def golden_path(*, golden_dir: Path, project: str) -> Path | None:
97104 return golden_dir / corpus / f"{ name } { GOLDEN_SUFFIX } "
98105
99106
100- def golden_payload (* , run : EngineRun , masked_paths : tuple [str , ...]) -> dict [str , object ]:
107+ def golden_payload (
108+ * , run : EngineRun , masked_paths : tuple [tuple [str , str ], ...]
109+ ) -> dict [str , object ]:
101110 """Return a run's diagnostics, compiled SQL and slimmed manifest with run noise masked."""
102111
103112 return {
@@ -122,7 +131,9 @@ def golden_text(payload: dict[str, object]) -> str:
122131 return json .dumps (payload , indent = 1 , ensure_ascii = False ) + "\n "
123132
124133
125- def _command (* , outcome : CommandOutcome , masked_paths : tuple [str , ...]) -> dict [str , object ]:
134+ def _command (
135+ * , outcome : CommandOutcome , masked_paths : tuple [tuple [str , str ], ...]
136+ ) -> dict [str , object ]:
126137 stdout : str = _masked (text = outcome .stdout , masked_paths = masked_paths )
127138 try :
128139 report : dict [str , object ] | None = as_json_object (json .loads (stdout ))
@@ -141,7 +152,7 @@ def _command(*, outcome: CommandOutcome, masked_paths: tuple[str, ...]) -> dict[
141152 }
142153
143154
144- def _manifest (* , text : str | None , masked_paths : tuple [str , ...]) -> object | None :
155+ def _manifest (* , text : str | None , masked_paths : tuple [tuple [ str , str ] , ...]) -> object | None :
145156 if text is None :
146157 return None
147158 manifest : dict [str , object ] = (
@@ -165,11 +176,50 @@ def _without_code(resource: object) -> object:
165176 }
166177
167178
168- def _masked (* , text : str , masked_paths : tuple [str , ...]) -> str :
169- for path in masked_paths :
170- text = text .replace (path , GOLDEN_PATH_MASK )
179+ def _masked (* , text : str , masked_paths : tuple [tuple [str , str ], ...]) -> str :
180+ text = masked_text (text = text , masks = masked_paths )
171181 return normalize_artifact_text (text ).replace (_SQLBUILD_VERSION , GOLDEN_VERSION_MASK )
172182
173183
174184def _lines (* , text : str ) -> list [str ]:
175185 return text .split ("\n " )
186+
187+
188+ def write_golden_seed_range (* , golden_dir : Path , seed_start : int , seeds : int ) -> None :
189+ """Record the seed range the goldens hold; every seed in it must keep its golden."""
190+
191+ golden_dir .mkdir (parents = True , exist_ok = True )
192+ _ = (golden_dir / GOLDEN_SEED_RANGE_FILE ).write_text (
193+ f"seed_start = { seed_start } \n seeds = { seeds } \n " , encoding = "utf-8"
194+ )
195+
196+
197+ def _seed_in_recorded_range (* , golden_dir : Path , name : str ) -> bool :
198+ path : Path = golden_dir / GOLDEN_SEED_RANGE_FILE
199+ if not path .is_file ():
200+ return False
201+ recorded : dict [str , object ] = tomllib .loads (path .read_text (encoding = "utf-8" ))
202+ start : int = int (str (recorded .get ("seed_start" , 0 )))
203+ index : int = int (name .split ("-" , 1 )[0 ])
204+ return start <= index < start + int (str (recorded .get ("seeds" , 0 )))
205+
206+
207+ def golden_path_masks (* , case_dir : Path , work_dir : Path ) -> tuple [tuple [str , str ], ...]:
208+ """`(path, token)` for the project and work directories, resolved or not, longest first."""
209+
210+ workspace : Path = case_dir / PROJECT_DIRECTORY
211+ masks : set [tuple [str , str ]] = {
212+ (str (workspace ), GOLDEN_PATH_MASK ),
213+ (str (workspace .resolve ()), GOLDEN_PATH_MASK ),
214+ (str (work_dir ), GOLDEN_WORK_MASK ),
215+ (str (work_dir .resolve ()), GOLDEN_WORK_MASK ),
216+ }
217+ return tuple (sorted (masks , key = lambda mask : (- len (mask [0 ]), mask [0 ])))
218+
219+
220+ def masked_text (* , text : str , masks : tuple [tuple [str , str ], ...]) -> str :
221+ """Replace every masked path with its token, longest path first."""
222+
223+ for path , token in masks :
224+ text = text .replace (path , token )
225+ return text
0 commit comments