Sorting changes

This commit is contained in:
2026-05-17 14:43:09 +02:00
parent 574349b929
commit b5a3a715a4
10 changed files with 276 additions and 36 deletions
+40 -19
View File
@@ -297,9 +297,10 @@ type AutogenConsumerConfig struct {
}
type PartsRowsConfig struct {
RowDefaults map[string]string `json:"row_defaults" yaml:"row_defaults"`
ACBonus PartsRowsACBonusConfig `json:"acbonus" yaml:"acbonus"`
Datasets map[string]PartsRowsDatasetConfig `json:"datasets" yaml:"datasets"`
NullUndiscoveredRows bool `json:"null_undiscovered_rows" yaml:"null_undiscovered_rows"`
RowDefaults map[string]string `json:"row_defaults" yaml:"row_defaults"`
ACBonus PartsRowsACBonusConfig `json:"acbonus" yaml:"acbonus"`
Datasets map[string]PartsRowsDatasetConfig `json:"datasets" yaml:"datasets"`
}
type PartsRowsDatasetConfig struct {
@@ -1395,6 +1396,9 @@ func validateGeneratedConfig(cfg GeneratedConfig) []error {
}
func partsRowsConfigConfigured(cfg PartsRowsConfig) bool {
if cfg.NullUndiscoveredRows {
return true
}
if len(cfg.RowDefaults) > 0 {
return true
}
@@ -1412,26 +1416,43 @@ func partsRowsConfigConfigured(cfg PartsRowsConfig) bool {
func validatePartsRowsConfig(fieldPrefix string, cfg PartsRowsConfig) []error {
var failures []error
failures = append(failures, validatePartsRowsACBonusPolicy(fieldPrefix+".acbonus.default", cfg.ACBonus.Default, false)...)
for dataset, policy := range cfg.ACBonus.Datasets {
dataset = strings.TrimSpace(dataset)
if dataset == "" {
failures = append(failures, fmt.Errorf("%s.acbonus.datasets contains an empty dataset key", fieldPrefix))
continue
if partsRowsProjectACBonusConfigured(cfg) {
failures = append(failures, validatePartsRowsACBonusPolicy(fieldPrefix+".acbonus.default", cfg.ACBonus.Default, false)...)
for dataset, policy := range cfg.ACBonus.Datasets {
dataset = strings.TrimSpace(dataset)
if dataset == "" {
failures = append(failures, fmt.Errorf("%s.acbonus.datasets contains an empty dataset key", fieldPrefix))
continue
}
failures = append(failures, validatePartsRowsACBonusPolicy(fieldPrefix+".acbonus.datasets."+dataset, policy, true)...)
}
failures = append(failures, validatePartsRowsACBonusPolicy(fieldPrefix+".acbonus.datasets."+dataset, policy, true)...)
}
for dataset, datasetCfg := range cfg.Datasets {
dataset = strings.TrimSpace(dataset)
if dataset == "" {
failures = append(failures, fmt.Errorf("%s.datasets contains an empty dataset key", fieldPrefix))
continue
for dataset, datasetCfg := range cfg.Datasets {
dataset = strings.TrimSpace(dataset)
if dataset == "" {
failures = append(failures, fmt.Errorf("%s.datasets contains an empty dataset key", fieldPrefix))
continue
}
failures = append(failures, validatePartsRowsACBonusPolicy(fieldPrefix+".datasets."+dataset+".acbonus", datasetCfg.ACBonus, true)...)
}
failures = append(failures, validatePartsRowsACBonusPolicy(fieldPrefix+".datasets."+dataset+".acbonus", datasetCfg.ACBonus, true)...)
}
return failures
}
func partsRowsProjectACBonusConfigured(cfg PartsRowsConfig) bool {
if strings.TrimSpace(cfg.ACBonus.Default.Strategy) != "" {
return true
}
if len(cfg.ACBonus.Datasets) > 0 {
return true
}
for _, dataset := range cfg.Datasets {
if strings.TrimSpace(dataset.ACBonus.Strategy) != "" {
return true
}
}
return false
}
func validatePartsRowsACBonusPolicy(fieldPrefix string, policy PartsRowsACBonusPolicy, allowEmpty bool) []error {
strategy := strings.TrimSpace(policy.Strategy)
if strategy == "" {
@@ -1441,9 +1462,9 @@ func validatePartsRowsACBonusPolicy(fieldPrefix string, policy PartsRowsACBonusP
return []error{fmt.Errorf("%s.strategy is required", fieldPrefix)}
}
switch strategy {
case "descending_row_id_sort_key":
case "ascending_row_id_sort_key", "descending_row_id_sort_key":
var failures []error
if policy.MaxRowID <= 0 {
if strategy == "descending_row_id_sort_key" && policy.MaxRowID <= 0 {
failures = append(failures, fmt.Errorf("%s.max_row_id must be greater than 0", fieldPrefix))
}
if policy.Divisor <= 0 {
+39 -1
View File
@@ -885,7 +885,7 @@ func TestValidateLayoutAcceptsGeneratedTopData2DAConfig(t *testing.T) {
PartsRows: PartsRowsConfig{
RowDefaults: map[string]string{"COSTMODIFIER": "0"},
ACBonus: PartsRowsACBonusConfig{
Default: PartsRowsACBonusPolicy{Strategy: "descending_row_id_sort_key", MaxRowID: 999, Divisor: 100, Format: "%.2f"},
Default: PartsRowsACBonusPolicy{Strategy: "ascending_row_id_sort_key", Divisor: 100, Format: "%.2f"},
Datasets: map[string]PartsRowsACBonusPolicy{
"chest": {Strategy: "fixed", Value: "0.00"},
},
@@ -907,6 +907,44 @@ func TestValidateLayoutAcceptsGeneratedTopData2DAConfig(t *testing.T) {
}
}
func TestValidateLayoutAcceptsGeneratedPartsRowsNullUndiscoveredWithoutACBonusPolicy(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"},
PartsRows: PartsRowsConfig{
NullUndiscoveredRows: true,
},
},
},
},
},
},
}
if err := proj.ValidateLayout(); err != nil {
t.Fatalf("ValidateLayout returned error: %v", err)
}
}
func TestValidateLayoutRejectsEscapingGeneratedTopData2DAConfig(t *testing.T) {
root := t.TempDir()
mkdirAll(t, filepath.Join(root, "assets"))