diff --git a/internal/pipeline/build.go b/internal/pipeline/build.go index 90a14ab..206e308 100644 --- a/internal/pipeline/build.go +++ b/internal/pipeline/build.go @@ -180,7 +180,7 @@ func planHAKs(p *project.Project, progress ProgressFunc) (BuildResult, error) { return planOrBuildHAKs(p, progress, false, nil, "") } -func planOrBuildHAKs(p *project.Project, progress ProgressFunc, writeArchives bool, archiveNames []string, sourceManifestPath string) (BuildResult, error) { +func planOrBuildHAKs(p *project.Project, progress ProgressFunc, writeArchives bool, archiveNames []string, sourceManifestPath string) (result BuildResult, err error) { preserveExistingHAKs := envBool("SOW_BUILD_HAKS_KEEP_EXISTING") progressf(progress, "Validating project...") @@ -197,6 +197,11 @@ func planOrBuildHAKs(p *project.Project, progress ProgressFunc, writeArchives bo if err != nil { return BuildResult{}, err } + defer func() { + if cleanupErr := cleanupPreparedMusicAssets(musicAssets); cleanupErr != nil && err == nil { + err = cleanupErr + } + }() assetResources, err := collectAssetResources(p, false, allowedAssets, musicAssets) if err != nil { return BuildResult{}, err @@ -213,7 +218,7 @@ func planOrBuildHAKs(p *project.Project, progress ProgressFunc, writeArchives bo } } - result := BuildResult{HAKAssets: len(assetResources)} + result = BuildResult{HAKAssets: len(assetResources)} result.CreditsArtifactPaths = append(result.CreditsArtifactPaths, musicAssets.Artifacts...) if err := writeAutogenManifestOutputs(progress, autogenManifests); err != nil { return BuildResult{}, err @@ -1584,7 +1589,7 @@ func cleanupGeneratedHAKs(p *project.Project) error { return nil } -func plannedModuleHAKOrder(p *project.Project) ([]string, error) { +func plannedModuleHAKOrder(p *project.Project) (order []string, err error) { manifest, err := loadPreviousBuildManifest(p.HAKManifestPath()) if err != nil { return nil, err @@ -1597,6 +1602,11 @@ func plannedModuleHAKOrder(p *project.Project) ([]string, error) { if err != nil { return nil, err } + defer func() { + if cleanupErr := cleanupPreparedMusicAssets(musicAssets); cleanupErr != nil && err == nil { + err = cleanupErr + } + }() assetResources, err := collectAssetResources(p, false, nil, musicAssets) if err != nil { return nil, err diff --git a/internal/pipeline/music.go b/internal/pipeline/music.go index ef60f97..f047832 100644 --- a/internal/pipeline/music.go +++ b/internal/pipeline/music.go @@ -48,6 +48,7 @@ type preparedMusicAssets struct { Generated []assetResource SkipSourceRel map[string]struct{} Artifacts []string + TempRoots []string } type musicMetadata struct { @@ -125,7 +126,8 @@ func prepareMusicAssets(p *project.Project) (*preparedMusicAssets, error) { sort.Strings(dirs) generatedByDir := make(map[string][]creditsEntry) - stageRoot := filepath.Join(p.BuildDir(), ".cache", "music") + stageRoot := filepath.Join(p.Root, ".cache", "music") + result.TempRoots = append(result.TempRoots, stageRoot) ffmpegPath, err := resolveFFmpegBinary() if err != nil { @@ -227,7 +229,10 @@ func prepareMusicAssets(p *project.Project) (*preparedMusicAssets, error) { } func writeCreditsArtifacts(p *project.Project, generatedByDir map[string][]creditsEntry) ([]string, error) { - creditsRoot := filepath.Join(p.BuildDir(), "credits") + creditsRoot := filepath.Join(p.Root, ".cache", "credits") + if err := os.RemoveAll(creditsRoot); err != nil { + return nil, fmt.Errorf("reset credits dir: %w", err) + } if err := os.MkdirAll(creditsRoot, 0o755); err != nil { return nil, fmt.Errorf("create credits dir: %w", err) } @@ -310,6 +315,21 @@ func writeCreditsArtifacts(p *project.Project, generatedByDir map[string][]credi return artifacts, nil } +func cleanupPreparedMusicAssets(prepared *preparedMusicAssets) error { + if prepared == nil { + return nil + } + for _, root := range prepared.TempRoots { + if strings.TrimSpace(root) == "" { + continue + } + if err := os.RemoveAll(root); err != nil { + return fmt.Errorf("remove temporary music artifact root %s: %w", root, err) + } + } + return nil +} + func parseCreditsOverlay(path string) (creditsOverlay, error) { entries, err := parseCreditsMarkdown(path) if err != nil { diff --git a/internal/pipeline/pipeline_test.go b/internal/pipeline/pipeline_test.go index 915fcb2..094062c 100644 --- a/internal/pipeline/pipeline_test.go +++ b/internal/pipeline/pipeline_test.go @@ -2659,7 +2659,7 @@ func TestBuildHAKsConvertsMusicSourcesAndWritesCreditsArtifacts(t *testing.T) { 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")) + creditsRaw, err := os.ReadFile(filepath.Join(root, ".cache", "credits", "envi", "music", "westgate", "CREDITS.md")) if err != nil { t.Fatalf("read generated credits: %v", err) } @@ -2671,7 +2671,7 @@ func TestBuildHAKsConvertsMusicSourcesAndWritesCreditsArtifacts(t *testing.T) { t.Fatalf("manual credits overlay should override bad metadata: %s", creditsText) } - inventoryRaw, err := os.ReadFile(filepath.Join(root, "build", "credits", "credits.json")) + inventoryRaw, err := os.ReadFile(filepath.Join(root, ".cache", "credits", "credits.json")) if err != nil { t.Fatalf("read credits inventory: %v", err) } @@ -2679,7 +2679,10 @@ func TestBuildHAKsConvertsMusicSourcesAndWritesCreditsArtifacts(t *testing.T) { 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") { + if !strings.Contains(inventoryText, ".cache/credits/envi/music/westgate/CREDITS.md") { t.Fatalf("expected generated credits source in inventory: %s", inventoryText) } + if _, err := os.Stat(filepath.Join(root, ".cache", "music")); !os.IsNotExist(err) { + t.Fatalf("expected temporary music staging to be cleaned, got err=%v", err) + } }