Skip to content

Commit d74eb7a

Browse files
committed
feat: validate schema hash before running tests
1 parent d5a5172 commit d74eb7a

3 files changed

Lines changed: 52 additions & 5 deletions

File tree

regresql/regresql.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ func Test(root, runFilter, formatName, outputPath string, commit bool) {
155155
// Cache config for plan quality analysis
156156
SetGlobalConfig(config)
157157

158+
// Validate schema hasn't changed since last snapshot build
159+
if err := ValidateSchemaHash(root); err != nil {
160+
fmt.Printf("Error: %s\n", err)
161+
os.Exit(1)
162+
}
163+
158164
if err := TestConnectionString(config.PgUri); err != nil {
159165
fmt.Print(err.Error())
160166
os.Exit(2)

regresql/snapshot.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,49 @@ func DetectSnapshotFormat(path string) SnapshotFormat {
490490

491491
return FormatCustom
492492
}
493+
494+
func computeSchemaHash(schemaPath string) (string, error) {
495+
format := DetectSnapshotFormat(schemaPath)
496+
return computeFileHash(schemaPath, format)
497+
}
498+
499+
func ValidateSchemaHash(root string) error {
500+
snapshotsDir := GetSnapshotsDir(root)
501+
502+
metadata, err := ReadSnapshotMetadata(snapshotsDir)
503+
if err != nil {
504+
fmt.Fprintf(os.Stderr, "Warning: no snapshot metadata found. Consider using 'regresql snapshot build' for reproducible tests.\n")
505+
return nil
506+
}
507+
508+
if metadata.Current == nil || metadata.Current.SchemaPath == "" {
509+
return nil
510+
}
511+
512+
// Check if schema file still exists
513+
if _, err := os.Stat(metadata.Current.SchemaPath); os.IsNotExist(err) {
514+
// Schema file referenced in metadata doesn't exist - stale metadata
515+
return nil
516+
}
517+
518+
currentHash, err := computeSchemaHash(metadata.Current.SchemaPath)
519+
if err != nil {
520+
return fmt.Errorf("failed to hash schema %s: %w", metadata.Current.SchemaPath, err)
521+
}
522+
523+
if currentHash != metadata.Current.SchemaHash {
524+
return fmt.Errorf(`schema has changed since last snapshot build
525+
526+
Schema file: %s
527+
Expected: %s
528+
Current: %s
529+
530+
Run 'regresql snapshot build --schema=%s' to rebuild the snapshot`,
531+
metadata.Current.SchemaPath,
532+
metadata.Current.SchemaHash[:20]+"...",
533+
currentHash[:20]+"...",
534+
metadata.Current.SchemaPath)
535+
}
536+
537+
return nil
538+
}

regresql/snapshot_build.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,6 @@ func execSQLFile(db *sql.DB, path string) error {
181181
return nil
182182
}
183183

184-
func computeSchemaHash(schemaPath string) (string, error) {
185-
format := DetectSnapshotFormat(schemaPath)
186-
return computeFileHash(schemaPath, format)
187-
}
188-
189184
func applySchemaFile(pguri, schemaPath string) error {
190185
format := DetectSnapshotFormat(schemaPath)
191186

0 commit comments

Comments
 (0)