Migrate parts data to assets repo
This commit is contained in:
@@ -75,6 +75,7 @@ type EffectiveConfig struct {
|
||||
Paths EffectivePathConfig `json:"paths" yaml:"paths"`
|
||||
Outputs EffectiveOutputConfig `json:"outputs" yaml:"outputs"`
|
||||
Build BuildConfig `json:"build" yaml:"build"`
|
||||
Generated GeneratedConfig `json:"generated_assets" yaml:"generated_assets"`
|
||||
Inventory InventoryConfig `json:"inventory" yaml:"inventory"`
|
||||
Validation ValidationConfig `json:"validation" yaml:"validation"`
|
||||
Scripts EffectiveScriptsConfig `json:"scripts" yaml:"scripts"`
|
||||
@@ -256,6 +257,11 @@ func (p *Project) EffectiveConfig() EffectiveConfig {
|
||||
},
|
||||
},
|
||||
}
|
||||
generated := p.Config.Generated
|
||||
for index := range generated.TopData2DA {
|
||||
generated.TopData2DA[index].Output = expandPathTemplate(defaultString(generated.TopData2DA[index].Output, "{paths.cache}/generated-assets/"+generated.TopData2DA[index].ID), paths)
|
||||
}
|
||||
|
||||
extract := p.Config.Extract
|
||||
extract.Layout = defaultString(extract.Layout, DefaultExtractLayout)
|
||||
extract.HAKDiscovery = defaultString(extract.HAKDiscovery, DefaultExtractHAKDiscovery)
|
||||
@@ -352,6 +358,7 @@ func (p *Project) EffectiveConfig() EffectiveConfig {
|
||||
Paths: paths,
|
||||
Outputs: outputs,
|
||||
Build: p.Config.Build,
|
||||
Generated: generated,
|
||||
Inventory: inventory,
|
||||
Validation: validation,
|
||||
Scripts: scripts,
|
||||
@@ -439,6 +446,7 @@ func markMissingDefaults(provenance ConfigProvenance) {
|
||||
"outputs.module_archive": DefaultModuleArchiveTemplate,
|
||||
"outputs.hak_manifest": DefaultHAKManifest,
|
||||
"outputs.hak_archive": DefaultHAKArchiveTemplate,
|
||||
"generated_assets.topdata_2da": "no generated topdata 2DA assets",
|
||||
"inventory.source_extensions": "NWN source resource extensions",
|
||||
"inventory.asset_extensions": "NWN asset resource extensions",
|
||||
"inventory.source_json_pattern": DefaultSourceJSONPattern,
|
||||
|
||||
@@ -83,6 +83,7 @@ type Config struct {
|
||||
Paths PathConfig `json:"paths" yaml:"paths"`
|
||||
Outputs OutputConfig `json:"outputs" yaml:"outputs"`
|
||||
Build BuildConfig `json:"build" yaml:"build"`
|
||||
Generated GeneratedConfig `json:"generated_assets" yaml:"generated_assets"`
|
||||
HAKs []HAKConfig `json:"haks" yaml:"haks"`
|
||||
Inventory InventoryConfig `json:"inventory" yaml:"inventory"`
|
||||
Validation ValidationConfig `json:"validation" yaml:"validation"`
|
||||
@@ -118,6 +119,19 @@ type BuildConfig struct {
|
||||
KeepExistingHAKs bool `json:"keep_existing_haks,omitempty" yaml:"keep_existing_haks,omitempty"`
|
||||
}
|
||||
|
||||
type GeneratedConfig struct {
|
||||
TopData2DA []GeneratedTopData2DAConfig `json:"topdata_2da" yaml:"topdata_2da"`
|
||||
}
|
||||
|
||||
type GeneratedTopData2DAConfig struct {
|
||||
ID string `json:"id" yaml:"id"`
|
||||
Source string `json:"source" yaml:"source"`
|
||||
Output string `json:"output" yaml:"output"`
|
||||
IncludeDatasets []string `json:"include_datasets" yaml:"include_datasets"`
|
||||
PackageRoot string `json:"package_root" yaml:"package_root"`
|
||||
Autogen AutogenConsumerConfig `json:"autogen" yaml:"autogen"`
|
||||
}
|
||||
|
||||
type InventoryConfig struct {
|
||||
SourceExtensions []string `json:"source_extensions" yaml:"source_extensions"`
|
||||
AssetExtensions []string `json:"asset_extensions" yaml:"asset_extensions"`
|
||||
@@ -459,6 +473,7 @@ func (p *Project) ValidateLayout() error {
|
||||
"outputs.module_archive": p.Config.Outputs.ModuleArchive,
|
||||
"outputs.hak_manifest": p.Config.Outputs.HAKManifest,
|
||||
"outputs.hak_archive": p.Config.Outputs.HAKArchive,
|
||||
"generated_assets.topdata_2da": "",
|
||||
"validation.profile": p.Config.Validation.Profile,
|
||||
"scripts.source_dir": p.Config.Scripts.SourceDir,
|
||||
"scripts.cache": p.Config.Scripts.Cache,
|
||||
@@ -496,6 +511,7 @@ func (p *Project) ValidateLayout() error {
|
||||
failures = append(failures, validateRelativePath("outputs.module_archive", effective.Outputs.ModuleArchive)...)
|
||||
failures = append(failures, validateRelativePath("outputs.hak_manifest", effective.Outputs.HAKManifest)...)
|
||||
failures = append(failures, validateRelativePath("outputs.hak_archive", effective.Outputs.HAKArchive)...)
|
||||
failures = append(failures, validateGeneratedConfig(effective.Generated)...)
|
||||
failures = append(failures, validateRelativePath("scripts.cache", effective.Scripts.Cache)...)
|
||||
failures = append(failures, validateRelativePath("scripts.source_dir", effective.Scripts.SourceDir)...)
|
||||
failures = append(failures, validateRelativePath("topdata.compiled_2da_dir", effective.TopData.Compiled2DADir)...)
|
||||
@@ -1301,6 +1317,56 @@ func validateAutogenConfig(cfg AutogenConfig) []error {
|
||||
return failures
|
||||
}
|
||||
|
||||
func validateGeneratedConfig(cfg GeneratedConfig) []error {
|
||||
var failures []error
|
||||
seen := map[string]struct{}{}
|
||||
for index, top2da := range cfg.TopData2DA {
|
||||
fieldPrefix := fmt.Sprintf("generated_assets.topdata_2da[%d]", index)
|
||||
id := strings.TrimSpace(top2da.ID)
|
||||
if id == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.id is required", fieldPrefix))
|
||||
} else {
|
||||
if _, exists := seen[id]; exists {
|
||||
failures = append(failures, fmt.Errorf("%s.id %q is duplicated", fieldPrefix, id))
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
}
|
||||
if strings.TrimSpace(top2da.Source) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.source is required", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateTreeRootPath(fieldPrefix+".source", top2da.Source)...)
|
||||
if strings.TrimSpace(top2da.Output) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.output is required", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateRelativePath(fieldPrefix+".output", top2da.Output)...)
|
||||
if strings.TrimSpace(top2da.PackageRoot) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.package_root is required", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateTreeRootPath(fieldPrefix+".package_root", top2da.PackageRoot)...)
|
||||
if len(top2da.IncludeDatasets) == 0 {
|
||||
failures = append(failures, fmt.Errorf("%s.include_datasets must contain at least one pattern", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateGlobList(fieldPrefix+".include_datasets", top2da.IncludeDatasets)...)
|
||||
switch strings.TrimSpace(top2da.Autogen.Mode) {
|
||||
case "parts_rows":
|
||||
case "":
|
||||
failures = append(failures, fmt.Errorf("%s.autogen.mode is required", fieldPrefix))
|
||||
default:
|
||||
failures = append(failures, fmt.Errorf("%s.autogen.mode %q is not supported", fieldPrefix, top2da.Autogen.Mode))
|
||||
}
|
||||
if strings.TrimSpace(top2da.Autogen.Root) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.autogen.root is required", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateTreeRootPath(fieldPrefix+".autogen.root", top2da.Autogen.Root)...)
|
||||
if len(top2da.Autogen.Include) == 0 {
|
||||
failures = append(failures, fmt.Errorf("%s.autogen.include must contain at least one glob", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateGlobList(fieldPrefix+".autogen.include", top2da.Autogen.Include)...)
|
||||
failures = append(failures, validateAutogenDeriveConfig(fieldPrefix+".autogen.derive", top2da.Autogen.Derive)...)
|
||||
}
|
||||
return failures
|
||||
}
|
||||
|
||||
func validateMusicConfig(cfg MusicConfig) []error {
|
||||
var failures []error
|
||||
if cfg.Defaults != nil {
|
||||
|
||||
@@ -859,6 +859,81 @@ func TestValidateLayoutRejectsInvalidAutogenConsumerConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutAcceptsGeneratedTopData2DAConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "assets"))
|
||||
mkdirAll(t, filepath.Join(root, "build"))
|
||||
proj := Project{
|
||||
Root: root,
|
||||
Config: Config{
|
||||
Module: ModuleConfig{Name: "Test", ResRef: "testmod"},
|
||||
Paths: PathConfig{Assets: "assets"},
|
||||
Generated: GeneratedConfig{
|
||||
TopData2DA: []GeneratedTopData2DAConfig{
|
||||
{
|
||||
ID: "parts",
|
||||
Source: "topdata",
|
||||
Output: "{paths.cache}/generated-assets/parts-2da",
|
||||
IncludeDatasets: []string{"parts/**"},
|
||||
PackageRoot: "part",
|
||||
Autogen: AutogenConsumerConfig{
|
||||
ID: "parts",
|
||||
Mode: "parts_rows",
|
||||
Root: "part",
|
||||
Include: []string{"**/*.mdl"},
|
||||
Derive: AutogenDeriveConfig{Kind: "trailing_numeric_suffix", GroupFrom: "first_path_segment"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := proj.ValidateLayout(); err != nil {
|
||||
t.Fatalf("ValidateLayout returned error: %v", err)
|
||||
}
|
||||
effective := proj.EffectiveConfig()
|
||||
if got, want := effective.Generated.TopData2DA[0].Output, ".cache/generated-assets/parts-2da"; got != want {
|
||||
t.Fatalf("expected expanded output %q, got %q", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutRejectsEscapingGeneratedTopData2DAConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "assets"))
|
||||
mkdirAll(t, filepath.Join(root, "build"))
|
||||
proj := Project{
|
||||
Root: root,
|
||||
Config: Config{
|
||||
Module: ModuleConfig{Name: "Test", ResRef: "testmod"},
|
||||
Paths: PathConfig{Assets: "assets"},
|
||||
Generated: GeneratedConfig{
|
||||
TopData2DA: []GeneratedTopData2DAConfig{
|
||||
{
|
||||
ID: "parts",
|
||||
Source: "../topdata",
|
||||
Output: "{paths.cache}/generated-assets/parts-2da",
|
||||
IncludeDatasets: []string{"parts/**"},
|
||||
PackageRoot: "part",
|
||||
Autogen: AutogenConsumerConfig{
|
||||
ID: "parts",
|
||||
Mode: "parts_rows",
|
||||
Root: "part",
|
||||
Include: []string{"**/*.mdl"},
|
||||
Derive: AutogenDeriveConfig{Kind: "trailing_numeric_suffix", GroupFrom: "first_path_segment"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := proj.ValidateLayout()
|
||||
if err == nil || !strings.Contains(err.Error(), "generated_assets.topdata_2da[0].source") {
|
||||
t.Fatalf("expected generated topdata source validation error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutRejectsDuplicateHAKNames(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
|
||||
Reference in New Issue
Block a user