fix(project): a module resref names a file, not a resource
ci / ci (pull_request) Successful in 3m50s
ci / ci (pull_request) Successful in 3m50s
module.resref is the name of the built .mod on disk, so the 16-byte resref limit never applied to it — NWN:EE module file names are routinely longer. The blanket check rejected ShadowsOverWestgate (19 characters) and blocked sow-module#60. It is now validated as a file name instead, which still rejects a resref that is a path or an empty string. The limit is kept where the value really does become a resref: a project with paths.assets and no haks[] names its single generated HAK after the module resref, and a HAK name is a resref the engine loads. That case now says what to do about it rather than refusing every long module name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1093,6 +1093,78 @@ func TestValidateLayoutAllowsMissingAssetsDir(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// module.resref names the built .mod FILE, not a resource inside an archive, so the
|
||||
// 16-byte resref limit does not apply to it. NWN:EE module file names are commonly
|
||||
// longer (ShadowsOverWestgate.mod is 19). The limit still binds everywhere a resref
|
||||
// really is a resref — see TestValidateLayoutRejectsLongResRefWhenItNamesAHAK.
|
||||
func TestValidateLayoutAllowsLongModuleResRef(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
mkdirAll(t, filepath.Join(root, "build"))
|
||||
|
||||
proj := &Project{
|
||||
Root: root,
|
||||
Config: Config{
|
||||
Module: ModuleConfig{Name: "Shadows Over Westgate", ResRef: "ShadowsOverWestgate"},
|
||||
Paths: PathConfig{Source: "src", Build: "build"},
|
||||
},
|
||||
}
|
||||
|
||||
if err := proj.ValidateLayout(); err != nil {
|
||||
t.Fatalf("ValidateLayout rejected a 19-character module file name: %v", err)
|
||||
}
|
||||
if got, want := filepath.Base(proj.ModuleArchivePath()), "ShadowsOverWestgate.mod"; got != want {
|
||||
t.Fatalf("ModuleArchivePath() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// A module.resref that is not a usable file name is still rejected.
|
||||
func TestValidateLayoutRejectsModuleResRefThatIsAPath(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
|
||||
proj := &Project{
|
||||
Root: root,
|
||||
Config: Config{
|
||||
Module: ModuleConfig{Name: "Test", ResRef: "../escape/mod"},
|
||||
Paths: PathConfig{Source: "src", Build: "build"},
|
||||
},
|
||||
}
|
||||
|
||||
err := proj.ValidateLayout()
|
||||
if err == nil {
|
||||
t.Fatal("ValidateLayout accepted a module.resref containing a path")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "module.resref") {
|
||||
t.Fatalf("error does not name the offending field: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// When a project declares no haks, the module resref becomes the name of the single
|
||||
// generated HAK — and a HAK name IS a resref the engine loads. The limit applies
|
||||
// there, so a long name is only allowed for projects that build no HAKs.
|
||||
func TestValidateLayoutRejectsLongResRefWhenItNamesAHAK(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
mkdirAll(t, filepath.Join(root, "assets"))
|
||||
|
||||
proj := &Project{
|
||||
Root: root,
|
||||
Config: Config{
|
||||
Module: ModuleConfig{Name: "Shadows Over Westgate", ResRef: "ShadowsOverWestgate"},
|
||||
Paths: PathConfig{Source: "src", Assets: "assets", Build: "build"},
|
||||
},
|
||||
}
|
||||
|
||||
err := proj.ValidateLayout()
|
||||
if err == nil {
|
||||
t.Fatal("ValidateLayout accepted a 19-character name for a generated HAK")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "16") {
|
||||
t.Fatalf("error does not explain the resref limit: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// paths.build is an OUTPUT dir the builder creates (MkdirAll) before writing, so
|
||||
// a bare clone with no build dir yet must still validate/build with no pre-step
|
||||
// (R2/parity). Only a build path that exists but is not a directory is an error.
|
||||
|
||||
Reference in New Issue
Block a user