fix(pipeline): make the full module build work for module-only projects
build-binaries / build-binaries (pull_request) Successful in 2m13s
test-image / build-image (pull_request) Successful in 46s
test / test (pull_request) Successful in 1m23s

`crucible module build` runs the full pipeline (module + HAK producer +
topdata). A module-only project consumes prebuilt HAKs and has no
`paths.assets`, so the HAK stage crashed on the unset assets dir: the
music-credits walk hit `filepath.WalkDir("")` (`lstat : no such file or
directory`) and asset collection hit `filepath.Rel(root, "")`.

Guard both on an unset `AssetsDir()`: an absent assets tree simply means
no authored credits and no asset files to collect, so the HAK stage
no-ops cleanly while topdata generated-2DA assets still build. Honors
spec Decision 3 (canonical `crucible module build`, no `build-module`).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 17:21:59 +02:00
co-authored by Claude Opus 4.8
parent 5c46824ebd
commit e8e8ba421a
3 changed files with 99 additions and 29 deletions
+10 -4
View File
@@ -661,11 +661,17 @@ func collectAssetResources(p *project.Project, requireContent bool, allowed map[
if err != nil {
return nil, err
}
assetsRelPath, err := filepath.Rel(p.Root, p.AssetsDir())
if err != nil {
return nil, fmt.Errorf("resolve assets dir relative path: %w", err)
// A module-only project (consumes prebuilt HAKs, has no paths.assets) has no
// asset files to collect — AssetFiles is empty and AssetsDir() is "". Skip the
// relative-path resolve, which would otherwise fail with `Rel: can't make ""`.
assetsRelPath := ""
if p.AssetsDir() != "" {
assetsRelPath, err = filepath.Rel(p.Root, p.AssetsDir())
if err != nil {
return nil, fmt.Errorf("resolve assets dir relative path: %w", err)
}
assetsRelPath = filepath.ToSlash(assetsRelPath)
}
assetsRelPath = filepath.ToSlash(assetsRelPath)
for _, rel := range p.Inventory.AssetFiles {
if musicAssets != nil {