Fix Autogen Lockfile Overrides
This commit is contained in:
@@ -9195,6 +9195,7 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
||||
mkdirAll(t, filepath.Join(projRoot, "src"))
|
||||
mkdirAll(t, filepath.Join(projRoot, "assets"))
|
||||
mkdirAll(t, filepath.Join(projRoot, "build"))
|
||||
mkdirAll(t, filepath.Join(projRoot, ".cache"))
|
||||
mkdirAll(t, filepath.Join(projRoot, "topdata", "data", "visualeffects"))
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "data", "visualeffects", "base.json"), `{
|
||||
@@ -9301,6 +9302,191 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildNativePrefersRemoteReleasedHeadVisualeffectsManifestOverFreshCache(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
projRoot := filepath.Join(root, "project")
|
||||
mkdirAll(t, filepath.Join(projRoot, "src"))
|
||||
mkdirAll(t, filepath.Join(projRoot, "assets"))
|
||||
mkdirAll(t, filepath.Join(projRoot, "build"))
|
||||
mkdirAll(t, filepath.Join(projRoot, ".cache"))
|
||||
mkdirAll(t, filepath.Join(projRoot, "topdata", "data", "visualeffects"))
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "data", "visualeffects", "base.json"), `{
|
||||
"output": "visualeffects.2da",
|
||||
"columns": ["Label", "Type_FD", "OrientWithGround", "Imp_HeadCon_Node", "OrientWithObject"],
|
||||
"rows": [
|
||||
{"key": "visualeffects:existing", "id": 17, "Label": "EXISTING", "Type_FD": "F", "OrientWithGround": "0", "Imp_HeadCon_Node": "****", "OrientWithObject": "0"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "data", "visualeffects", "lock.json"), `{
|
||||
"visualeffects:existing": 17,
|
||||
"visualeffects:headaccessory_bandana": 42
|
||||
}`+"\n")
|
||||
mkdirAll(t, filepath.Join(projRoot, "reference"))
|
||||
writeFile(t, filepath.Join(projRoot, "reference", "build.py"), "print('ok')\n")
|
||||
|
||||
cachePath := filepath.Join(projRoot, ".cache", "sow-head-vfx-manifest.json")
|
||||
writeFile(t, cachePath, `{
|
||||
"id": "head_visualeffects",
|
||||
"generated_at": "2026-04-25T00:00:00Z",
|
||||
"entries": [
|
||||
{
|
||||
"group": "head_features",
|
||||
"model_stem": "hfx_hair_bangs",
|
||||
"source": "head_features/hair/hfx_hair_bangs.mdl"
|
||||
}
|
||||
]
|
||||
}`+"\n")
|
||||
cacheTime := time.Date(2026, 4, 25, 10, 0, 0, 0, time.UTC)
|
||||
setFileTime(t, cachePath, cacheTime)
|
||||
|
||||
manifestJSON := `{
|
||||
"id": "head_visualeffects",
|
||||
"repo": "ShadowsOverWestgate/sow-assets",
|
||||
"ref": "remote-manifest",
|
||||
"generated_at": "2026-04-25T12:00:00Z",
|
||||
"entries": [
|
||||
{
|
||||
"group": "head_accessories",
|
||||
"model_stem": "hfx_bandana",
|
||||
"source": "head_accessories/hfx_bandana.mdl"
|
||||
}
|
||||
]
|
||||
}` + "\n"
|
||||
|
||||
var server *httptest.Server
|
||||
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/api/v1/repos/ShadowsOverWestgate/sow-assets/releases/tags/head-vfx-manifest-current":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"assets":[{"name":"sow-head-vfx-manifest.json","updated_at":"2026-04-25T12:00:00Z","browser_download_url":"` + server.URL + `/downloads/sow-head-vfx-manifest.json"}]}`))
|
||||
case "/downloads/sow-head-vfx-manifest.json":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(manifestJSON))
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
runGitTest(t, "", "init", "-b", "main", projRoot)
|
||||
runGitTest(t, projRoot, "remote", "add", "origin", server.URL+"/ShadowsOverWestgate/sow-module.git")
|
||||
|
||||
proj := &project.Project{
|
||||
Root: projRoot,
|
||||
Config: project.Config{
|
||||
Module: project.ModuleConfig{Name: "Test", ResRef: "test"},
|
||||
Paths: project.PathConfig{Source: "src", Assets: "assets", Build: "build"},
|
||||
TopData: project.TopDataConfig{
|
||||
Source: "topdata",
|
||||
Build: "build/topdata",
|
||||
},
|
||||
Autogen: project.AutogenConfig{
|
||||
Consumers: []project.AutogenConsumerConfig{
|
||||
{
|
||||
ID: "head_visualeffects",
|
||||
Producer: "head_visualeffects",
|
||||
Dataset: "visualeffects",
|
||||
Mode: "head_visualeffects",
|
||||
Root: "vfxs",
|
||||
Include: []string{"head_accessories/**/*.mdl", "head_features/**/*.mdl"},
|
||||
Derive: project.AutogenDeriveConfig{
|
||||
Kind: "model_stem",
|
||||
GroupFrom: "first_path_segment",
|
||||
},
|
||||
Manifest: project.AutogenManifestConfig{
|
||||
ReleaseTag: "head-vfx-manifest-current",
|
||||
AssetName: "sow-head-vfx-manifest.json",
|
||||
CacheName: "sow-head-vfx-manifest.json",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := BuildNative(proj, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("BuildNative failed: %v", err)
|
||||
}
|
||||
|
||||
visualeffectsBytes, err := os.ReadFile(filepath.Join(result.Output2DADir, "visualeffects.2da"))
|
||||
if err != nil {
|
||||
t.Fatalf("read visualeffects.2da: %v", err)
|
||||
}
|
||||
text := string(visualeffectsBytes)
|
||||
if !strings.Contains(text, "42\theadaccessory_BANDANA\tD\t0\thfx_bandana\t1") {
|
||||
t.Fatalf("expected remote manifest entry with preserved lock id, got:\n%s", text)
|
||||
}
|
||||
if strings.Contains(text, "HAIR_BANGS") {
|
||||
t.Fatalf("expected fresh remote manifest to replace cached manifest contents, got:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPackageInvalidatesFreshAutogenCacheWhenReleaseAssetIsNewer(t *testing.T) {
|
||||
root := topPackageTestProject(t)
|
||||
proj := testProject(root)
|
||||
proj.Config.TopData.ReferenceBuilder = ""
|
||||
proj.Config.Autogen.Consumers = nil
|
||||
|
||||
result, err := BuildAndPackage(proj, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("initial BuildAndPackage failed: %v", err)
|
||||
}
|
||||
|
||||
sourceTime := time.Now().Add(-6 * time.Hour)
|
||||
outputTime := time.Now().Add(-4 * time.Hour)
|
||||
setTopDataSourceTimes(t, root, sourceTime)
|
||||
setCompiledOutputTimes(t, result, outputTime)
|
||||
|
||||
cachePath := filepath.Join(root, ".cache", "sow-head-vfx-manifest.json")
|
||||
writeFile(t, cachePath, `{"id":"head_visualeffects","generated_at":"2026-04-25T10:00:00Z","entries":[{"group":"head_accessories","model_stem":"hfx_bandana","source":"head_accessories/hfx_bandana.mdl"}]}`+"\n")
|
||||
setFileTime(t, cachePath, time.Now())
|
||||
|
||||
var server *httptest.Server
|
||||
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/api/v1/repos/ShadowsOverWestgate/sow-assets/releases/tags/head-vfx-manifest-current":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"assets":[{"name":"sow-head-vfx-manifest.json","updated_at":"3026-04-25T12:00:00Z","browser_download_url":"` + server.URL + `/downloads/sow-head-vfx-manifest.json"}]}`))
|
||||
case "/downloads/sow-head-vfx-manifest.json":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"id":"head_visualeffects","entries":[{"group":"head_accessories","model_stem":"hfx_bandana","source":"head_accessories/hfx_bandana.mdl"}]}`))
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
runGitTest(t, "", "init", "-b", "main", root)
|
||||
runGitTest(t, root, "remote", "add", "origin", server.URL+"/ShadowsOverWestgate/sow-module.git")
|
||||
|
||||
proj.Config.Autogen.Consumers = []project.AutogenConsumerConfig{
|
||||
{
|
||||
ID: "head_visualeffects",
|
||||
Producer: "head_visualeffects",
|
||||
Dataset: "visualeffects",
|
||||
Mode: "head_visualeffects",
|
||||
Optional: true,
|
||||
Root: "vfxs",
|
||||
Include: []string{"head_accessories/**/*.mdl", "head_features/**/*.mdl"},
|
||||
Derive: project.AutogenDeriveConfig{
|
||||
Kind: "model_stem",
|
||||
GroupFrom: "first_path_segment",
|
||||
},
|
||||
Manifest: project.AutogenManifestConfig{
|
||||
ReleaseTag: "head-vfx-manifest-current",
|
||||
AssetName: "sow-head-vfx-manifest.json",
|
||||
CacheName: "sow-head-vfx-manifest.json",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := BuildPackage(proj, nil); err == nil || !strings.Contains(err.Error(), "older than source file") {
|
||||
t.Fatalf("expected newer remote autogen manifest to invalidate compiled output, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildNativeRejectsGitRepoTopDataAssetsOverride(t *testing.T) {
|
||||
root := testProjectRoot(t)
|
||||
mkdirAll(t, filepath.Join(root, "topdata", "data", "parts"))
|
||||
|
||||
Reference in New Issue
Block a user