Dev Testing + AutoGen Activation

This commit is contained in:
2026-04-25 08:57:10 +02:00
parent b6fff4bed4
commit 4009931fd0
5 changed files with 329 additions and 10 deletions
+35 -8
View File
@@ -23,14 +23,15 @@ import (
)
type BuildResult struct {
ModulePath string
HAKPaths []string
Manifest string
Resources int
HAKAssets int
TopPackageHAK string
TopPackageTLK string
TopPackageFiles int
ModulePath string
HAKPaths []string
Manifest string
AutogenManifestPaths []string
Resources int
HAKAssets int
TopPackageHAK string
TopPackageTLK string
TopPackageFiles int
}
type BuildManifest struct {
@@ -195,6 +196,10 @@ func planOrBuildHAKs(p *project.Project, progress ProgressFunc, writeArchives bo
if err != nil {
return BuildResult{}, err
}
autogenManifests, err := topdata.ProduceAutogenManifests(p)
if err != nil {
return BuildResult{}, err
}
var previousManifest *BuildManifest
if sourceManifest == nil || writeArchives {
previousManifest, err = loadPreviousBuildManifest(p.HAKManifestPath())
@@ -204,6 +209,12 @@ func planOrBuildHAKs(p *project.Project, progress ProgressFunc, writeArchives bo
}
result := BuildResult{HAKAssets: len(assetResources)}
if err := writeAutogenManifestOutputs(progress, autogenManifests); err != nil {
return BuildResult{}, err
}
for _, manifest := range autogenManifests {
result.AutogenManifestPaths = append(result.AutogenManifestPaths, manifest.OutputPath)
}
if len(assetResources) == 0 {
progressf(progress, "Cleaning previous generated HAKs...")
if err := cleanupGeneratedHAKs(p); err != nil {
@@ -318,6 +329,22 @@ func planOrBuildHAKs(p *project.Project, progress ProgressFunc, writeArchives bo
return result, nil
}
func writeAutogenManifestOutputs(progress ProgressFunc, manifests []topdata.ProducedAutogenManifest) error {
if len(manifests) == 0 {
return nil
}
for _, manifest := range manifests {
progressf(progress, fmt.Sprintf("Writing autogen manifest %s...", filepath.Base(manifest.OutputPath)))
if err := os.MkdirAll(filepath.Dir(manifest.OutputPath), 0o755); err != nil {
return fmt.Errorf("create autogen manifest dir: %w", err)
}
if err := os.WriteFile(manifest.OutputPath, manifest.Payload, 0o644); err != nil {
return fmt.Errorf("write autogen manifest %s: %w", manifest.AssetName, err)
}
}
return nil
}
func filterHAKChunksByName(chunks []hakChunk, archiveNames []string) ([]hakChunk, error) {
if len(archiveNames) == 0 {
return chunks, nil
+111
View File
@@ -1451,6 +1451,117 @@ func TestPlanHAKsWritesManifestWithoutArchives(t *testing.T) {
}
}
func TestBuildHAKsWritesConfiguredAutogenManifests(t *testing.T) {
root := t.TempDir()
mustMkdir(t, filepath.Join(root, "src"))
mustMkdir(t, filepath.Join(root, "assets", "part", "belt"))
mustMkdir(t, filepath.Join(root, "assets", "vfxs", "head_accessories"))
mustMkdir(t, filepath.Join(root, "assets", "vfxs", "head_features", "hair"))
mustMkdir(t, filepath.Join(root, "build"))
mustWriteFile(t, filepath.Join(root, "nwn-tool.json"), `{
"module": {
"name": "Test Module",
"resref": "testmod",
"hak_order": ["group:core"]
},
"paths": {
"source": "src",
"assets": "assets",
"build": "build"
},
"autogen": {
"producers": [
{
"id": "parts",
"root": "part",
"include": ["**/*.mdl"],
"derive": {
"kind": "trailing_numeric_suffix",
"group_from": "first_path_segment"
},
"manifest": {
"release_tag": "parts-manifest-current",
"asset_name": "sow-parts-manifest.json",
"cache_name": "sow-parts-manifest.json"
}
},
{
"id": "head_visualeffects",
"root": "vfxs",
"include": ["head_accessories/**/*.mdl", "head_features/**/*.mdl"],
"derive": {
"kind": "model_stem",
"group_from": "first_path_segment"
},
"manifest": {
"release_tag": "head-vfx-manifest-current",
"asset_name": "sow-head-vfx-manifest.json",
"cache_name": "sow-head-vfx-manifest.json"
}
}
]
},
"haks": [
{
"name": "core",
"priority": 1,
"max_bytes": 0,
"split": false,
"include": ["part/**", "vfxs/**"]
}
]
}
`)
mustWriteFile(t, filepath.Join(root, "assets", "part", "belt", "pfa0_belt018.mdl"), "belt")
mustWriteFile(t, filepath.Join(root, "assets", "vfxs", "head_accessories", "hfx_bandana.mdl"), "bandana")
mustWriteFile(t, filepath.Join(root, "assets", "vfxs", "head_features", "hair", "hfx_hair_bangs.mdl"), "hair")
p, err := project.Load(root)
if err != nil {
t.Fatalf("load project: %v", err)
}
if err := p.ValidateLayout(); err != nil {
t.Fatalf("validate layout: %v", err)
}
if err := p.Scan(); err != nil {
t.Fatalf("scan: %v", err)
}
result, err := BuildHAKs(p)
if err != nil {
t.Fatalf("build haks: %v", err)
}
if len(result.AutogenManifestPaths) != 2 {
t.Fatalf("expected 2 autogen manifests, got %d", len(result.AutogenManifestPaths))
}
partsRaw, err := os.ReadFile(filepath.Join(root, "build", "sow-parts-manifest.json"))
if err != nil {
t.Fatalf("read parts manifest: %v", err)
}
if !strings.Contains(string(partsRaw), `"id": "parts"`) || !strings.Contains(string(partsRaw), `"row_id": 18`) {
t.Fatalf("unexpected parts manifest contents:\n%s", string(partsRaw))
}
headRaw, err := os.ReadFile(filepath.Join(root, "build", "sow-head-vfx-manifest.json"))
if err != nil {
t.Fatalf("read head visualeffects manifest: %v", err)
}
text := string(headRaw)
for _, want := range []string{
`"id": "head_visualeffects"`,
`"group": "head_accessories"`,
`"model_stem": "hfx_bandana"`,
`"group": "head_features"`,
`"model_stem": "hfx_hair_bangs"`,
} {
if !strings.Contains(text, want) {
t.Fatalf("expected head visualeffects manifest to contain %q, got:\n%s", want, text)
}
}
}
func TestBuildSkipsEmptyHAKGroupsInModuleOrder(t *testing.T) {
root := t.TempDir()
mustMkdir(t, filepath.Join(root, "src"))