Crucible: Fix Formatting Churn (#5)
RC#1 — build wrote 2-space instead of .editorconfig's 4-space
- editorconfig_format.go: the glob translator escaped {/} as literals, so [*.{json,jsonc}]→indent_size=4 never matched any file and formatting fell back to [*]→2. Implemented real editorconfig brace expansion — {a,b,c} alternation and {n..m} numeric ranges. Nothing is hardcoded; saveLockfile already read .editorconfig, it just got the wrong section.
RC#2 — validate wrote a lockfile (it must be read-only)
- The three registry collectors persisted lockfiles as a side effect of collection; ValidateProject calls collection outside its snapshot guard, so the write leaked. Threaded a persistLocks bool through collectGeneratedRegistryDatasets and the damagetypes/itemprops/racialtypes collectors. Only buildNativeUnchecked (the real build allocator) passes true; validate, discovery, packaging queries, and wiki discovery pass false.
Tests added: editorconfig_glob_test.go (brace match + 4-space via brace glob), registry_readonly_test.go (read-only writes nothing; persist writes allocations).
Reviewed-on: #5
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
This commit was merged in pull request #5.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package topdata
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const damagetypesRegistryTestTypes = `{
|
||||
"rows": [
|
||||
{"id": 0, "key": "damagetype:bludgeoning", "label": "Bludgeoning", "group_label": "Physical", "damage_type_group": 0},
|
||||
{"id": 1, "key": "damagetype:piercing", "label": "Piercing", "group_label": "Physical", "damage_type_group": 0}
|
||||
]
|
||||
}
|
||||
`
|
||||
|
||||
// validate-topdata must never modify source lockfiles. Collection in read-only
|
||||
// mode must leave the registry lock byte-identical even though the rows carry
|
||||
// explicit ids that would otherwise mark the lock "modified".
|
||||
func TestCollectGeneratedRegistryDatasetsReadOnlyDoesNotWriteLock(t *testing.T) {
|
||||
dataDir := t.TempDir()
|
||||
regDir := filepath.Join(dataDir, "damagetypes", "registry")
|
||||
mkdirAll(t, regDir)
|
||||
writeFile(t, filepath.Join(regDir, "types.json"), damagetypesRegistryTestTypes)
|
||||
|
||||
lockPath := filepath.Join(regDir, "lock.json")
|
||||
original := "{\n \"damagetype:bludgeoning\": 0,\n \"damagetype:piercing\": 1\n}\n"
|
||||
writeFile(t, lockPath, original)
|
||||
|
||||
if _, err := collectGeneratedRegistryDatasets(dataDir, false); err != nil {
|
||||
t.Fatalf("read-only collection failed: %v", err)
|
||||
}
|
||||
|
||||
got, err := os.ReadFile(lockPath)
|
||||
if err != nil {
|
||||
t.Fatalf("read lockfile: %v", err)
|
||||
}
|
||||
if string(got) != original {
|
||||
t.Fatalf("read-only collection must not modify lockfile.\nwant: %q\ngot: %q", original, string(got))
|
||||
}
|
||||
}
|
||||
|
||||
// build-topdata still persists allocated ids to source lockfiles.
|
||||
func TestCollectGeneratedRegistryDatasetsPersistWritesLock(t *testing.T) {
|
||||
dataDir := t.TempDir()
|
||||
regDir := filepath.Join(dataDir, "damagetypes", "registry")
|
||||
mkdirAll(t, regDir)
|
||||
writeFile(t, filepath.Join(regDir, "types.json"), damagetypesRegistryTestTypes)
|
||||
|
||||
lockPath := filepath.Join(regDir, "lock.json")
|
||||
writeFile(t, lockPath, "{\n \"damagetype:bludgeoning\": 0\n}\n")
|
||||
|
||||
if _, err := collectGeneratedRegistryDatasets(dataDir, true); err != nil {
|
||||
t.Fatalf("persisting collection failed: %v", err)
|
||||
}
|
||||
|
||||
lockData, err := loadLockfile(lockPath)
|
||||
if err != nil {
|
||||
t.Fatalf("load lockfile: %v", err)
|
||||
}
|
||||
if lockData["damagetype:piercing"] != 1 {
|
||||
t.Fatalf("persisting collection should record allocated id; got %#v", lockData)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user