Music Pipeline Implementation

This commit is contained in:
2026-05-07 08:51:42 +02:00
parent 601e89bece
commit f6bb4fe3d7
7 changed files with 1028 additions and 6 deletions
+105 -1
View File
@@ -2083,7 +2083,7 @@ func TestPlanHAKChunksPutsNewestAssetsInLastChunk(t *testing.T) {
t.Fatalf("scan: %v", err)
}
assets, err := collectAssetResources(p, false, nil)
assets, err := collectAssetResources(p, false, nil, nil)
if err != nil {
t.Fatalf("collect asset resources: %v", err)
}
@@ -2579,3 +2579,107 @@ func TestBuildHAKsFailsForDuplicateResourcesInSameHAK(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
}
func TestBuildHAKsConvertsMusicSourcesAndWritesCreditsArtifacts(t *testing.T) {
root := t.TempDir()
mustMkdir(t, filepath.Join(root, "assets", "envi", "music", "westgate"))
mustMkdir(t, filepath.Join(root, "build"))
mustWriteFile(t, filepath.Join(root, "nwn-tool.json"), `{
"module": {
"name": "Test Assets",
"resref": "testassets"
},
"paths": {
"assets": "assets",
"build": "build"
},
"music": {
"prefixes": {
"envi/music/westgate": "mus_wg_"
}
},
"haks": [
{
"name": "envi",
"priority": 1,
"max_bytes": 1048576,
"split": false,
"include": ["envi/**"]
}
]
}
`)
mustWriteFile(t, filepath.Join(root, "assets", "envi", "music", "westgate", "AleandAnecdotes.mp3"), "source-mp3")
mustWriteFile(t, filepath.Join(root, "assets", "envi", "music", "westgate", "CREDITS.md"), "# NWN Music Pack Credits\n\n| Artist | Title | Output File | Original File | Album | Date | License / Copyright | Notes |\n|---|---|---|---|---|---|---|---|\n| Darren Curtis | Ale and Anecdotes | `mus_wg_andnc.bmu` | `AleandAnecdotes.mp3` | Darren's Commercially Free Music | | Darren Curtis Music | |\n")
ffprobePath := filepath.Join(root, "ffprobe")
mustWriteFile(t, ffprobePath, "#!/bin/sh\nprintf '%s\\n' '{\"format\":{\"tags\":{\"artist\":\"Unknown\",\"title\":\"Broken Metadata\"}}}'\n")
if err := os.Chmod(ffprobePath, 0o755); err != nil {
t.Fatalf("chmod ffprobe: %v", err)
}
ffmpegPath := filepath.Join(root, "ffmpeg")
mustWriteFile(t, ffmpegPath, "#!/bin/sh\nfor last; do :; done\nprintf 'bmu-data' > \"$last\"\n")
if err := os.Chmod(ffmpegPath, 0o755); err != nil {
t.Fatalf("chmod ffmpeg: %v", err)
}
t.Setenv("SOW_FFMPEG", ffmpegPath)
t.Setenv("SOW_FFPROBE", ffprobePath)
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.CreditsArtifactPaths) == 0 {
t.Fatal("expected credits artifacts to be written")
}
manifestRaw, err := os.ReadFile(filepath.Join(root, "build", "haks.json"))
if err != nil {
t.Fatalf("read manifest: %v", err)
}
if !strings.Contains(string(manifestRaw), "envi/music/westgate/mus_wg_andnc.bmu") {
t.Fatalf("expected converted bmu in manifest, got %s", string(manifestRaw))
}
if strings.Contains(string(manifestRaw), "AleandAnecdotes.mp3") {
t.Fatalf("did not expect source mp3 in manifest, got %s", string(manifestRaw))
}
creditsRaw, err := os.ReadFile(filepath.Join(root, "build", "credits", "envi", "music", "westgate", "CREDITS.md"))
if err != nil {
t.Fatalf("read generated credits: %v", err)
}
creditsText := string(creditsRaw)
if !strings.Contains(creditsText, "Darren Curtis") || !strings.Contains(creditsText, "mus_wg_andnc.bmu") {
t.Fatalf("unexpected generated credits contents: %s", creditsText)
}
if strings.Contains(creditsText, "Broken Metadata") {
t.Fatalf("manual credits overlay should override bad metadata: %s", creditsText)
}
inventoryRaw, err := os.ReadFile(filepath.Join(root, "build", "credits", "credits.json"))
if err != nil {
t.Fatalf("read credits inventory: %v", err)
}
inventoryText := string(inventoryRaw)
if !strings.Contains(inventoryText, "assets/envi/music/westgate/CREDITS.md") {
t.Fatalf("expected authored credits source in inventory: %s", inventoryText)
}
if !strings.Contains(inventoryText, "build/credits/envi/music/westgate/CREDITS.md") {
t.Fatalf("expected generated credits source in inventory: %s", inventoryText)
}
}