Accessories unhardcoded
This commit is contained in:
+101
-11
@@ -371,17 +371,34 @@ type AutogenProducerConfig struct {
|
||||
}
|
||||
|
||||
type AutogenConsumerConfig struct {
|
||||
ID string `json:"id" yaml:"id"`
|
||||
Producer string `json:"producer" yaml:"producer"`
|
||||
Dataset string `json:"dataset" yaml:"dataset"`
|
||||
Mode string `json:"mode" yaml:"mode"`
|
||||
Optional bool `json:"optional,omitempty" yaml:"optional,omitempty"`
|
||||
Root string `json:"root" yaml:"root"`
|
||||
Include []string `json:"include" yaml:"include"`
|
||||
Derive AutogenDeriveConfig `json:"derive" yaml:"derive"`
|
||||
PartsRows PartsRowsConfig `json:"parts_rows" yaml:"parts_rows"`
|
||||
Manifest AutogenManifestConfig `json:"manifest" yaml:"manifest"`
|
||||
LocalOverrideRoot string `json:"local_override_root,omitempty" yaml:"local_override_root,omitempty"`
|
||||
ID string `json:"id" yaml:"id"`
|
||||
Producer string `json:"producer" yaml:"producer"`
|
||||
Dataset string `json:"dataset" yaml:"dataset"`
|
||||
Mode string `json:"mode" yaml:"mode"`
|
||||
Optional bool `json:"optional,omitempty" yaml:"optional,omitempty"`
|
||||
Root string `json:"root" yaml:"root"`
|
||||
Include []string `json:"include" yaml:"include"`
|
||||
Derive AutogenDeriveConfig `json:"derive" yaml:"derive"`
|
||||
PartsRows PartsRowsConfig `json:"parts_rows" yaml:"parts_rows"`
|
||||
HeadVisualeffects HeadVisualeffectsConfig `json:"head_visualeffects" yaml:"head_visualeffects"`
|
||||
Manifest AutogenManifestConfig `json:"manifest" yaml:"manifest"`
|
||||
LocalOverrideRoot string `json:"local_override_root,omitempty" yaml:"local_override_root,omitempty"`
|
||||
}
|
||||
|
||||
type HeadVisualeffectsConfig struct {
|
||||
Groups map[string]HeadVisualeffectGroupConfig `json:"groups" yaml:"groups"`
|
||||
StripModelPrefixes []string `json:"strip_model_prefixes" yaml:"strip_model_prefixes"`
|
||||
KeyFormat string `json:"key_format" yaml:"key_format"`
|
||||
LabelFormat string `json:"label_format" yaml:"label_format"`
|
||||
ModelColumn string `json:"model_column" yaml:"model_column"`
|
||||
RowDefaults map[string]string `json:"row_defaults" yaml:"row_defaults"`
|
||||
}
|
||||
|
||||
type HeadVisualeffectGroupConfig struct {
|
||||
Prefix string `json:"prefix" yaml:"prefix"`
|
||||
ModelColumn string `json:"model_column" yaml:"model_column"`
|
||||
ModelColumns []string `json:"model_columns" yaml:"model_columns"`
|
||||
RowDefaults map[string]string `json:"row_defaults" yaml:"row_defaults"`
|
||||
}
|
||||
|
||||
type PartsRowsConfig struct {
|
||||
@@ -1721,6 +1738,9 @@ func validateAutogenConfig(cfg AutogenConfig) []error {
|
||||
}
|
||||
failures = append(failures, validateGlobList(fieldPrefix+".include", consumer.Include)...)
|
||||
failures = append(failures, validateAutogenDeriveConfig(fieldPrefix+".derive", consumer.Derive)...)
|
||||
if strings.TrimSpace(consumer.Mode) == "head_visualeffects" && headVisualeffectsConfigConfigured(consumer.HeadVisualeffects) {
|
||||
failures = append(failures, validateHeadVisualeffectsConfig(fieldPrefix+".head_visualeffects", consumer.HeadVisualeffects)...)
|
||||
}
|
||||
failures = append(failures, validateAutogenManifestConfig(fieldPrefix+".manifest", consumer.Manifest)...)
|
||||
}
|
||||
|
||||
@@ -1781,6 +1801,76 @@ func validateGeneratedConfig(cfg GeneratedConfig) []error {
|
||||
return failures
|
||||
}
|
||||
|
||||
func headVisualeffectsConfigConfigured(cfg HeadVisualeffectsConfig) bool {
|
||||
return len(cfg.Groups) > 0 ||
|
||||
len(cfg.StripModelPrefixes) > 0 ||
|
||||
strings.TrimSpace(cfg.KeyFormat) != "" ||
|
||||
strings.TrimSpace(cfg.LabelFormat) != "" ||
|
||||
strings.TrimSpace(cfg.ModelColumn) != "" ||
|
||||
len(cfg.RowDefaults) > 0
|
||||
}
|
||||
|
||||
func validateHeadVisualeffectsConfig(fieldPrefix string, cfg HeadVisualeffectsConfig) []error {
|
||||
var failures []error
|
||||
for group, groupCfg := range cfg.Groups {
|
||||
group = strings.TrimSpace(group)
|
||||
if group == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.groups contains an empty group key", fieldPrefix))
|
||||
continue
|
||||
}
|
||||
failures = append(failures, validateTreeRootPath(fieldPrefix+".groups["+group+"]", group)...)
|
||||
prefix := strings.TrimSpace(groupCfg.Prefix)
|
||||
if prefix == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.groups[%s].prefix is required", fieldPrefix, group))
|
||||
}
|
||||
if strings.ContainsAny(prefix, " \t\r\n\x00") {
|
||||
failures = append(failures, fmt.Errorf("%s.groups[%s].prefix must not contain whitespace or NUL bytes", fieldPrefix, group))
|
||||
}
|
||||
if column := strings.TrimSpace(groupCfg.ModelColumn); column != "" && strings.ContainsAny(column, " \t\r\n\x00") {
|
||||
failures = append(failures, fmt.Errorf("%s.groups[%s].model_column must not contain whitespace or NUL bytes", fieldPrefix, group))
|
||||
}
|
||||
for index, column := range groupCfg.ModelColumns {
|
||||
column = strings.TrimSpace(column)
|
||||
if column == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.groups[%s].model_columns[%d] must not be empty", fieldPrefix, group, index))
|
||||
}
|
||||
if strings.ContainsAny(column, " \t\r\n\x00") {
|
||||
failures = append(failures, fmt.Errorf("%s.groups[%s].model_columns[%d] must not contain whitespace or NUL bytes", fieldPrefix, group, index))
|
||||
}
|
||||
}
|
||||
for column := range groupCfg.RowDefaults {
|
||||
column = strings.TrimSpace(column)
|
||||
if column == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.groups[%s].row_defaults contains an empty column name", fieldPrefix, group))
|
||||
}
|
||||
if strings.ContainsAny(column, " \t\r\n\x00") {
|
||||
failures = append(failures, fmt.Errorf("%s.groups[%s].row_defaults[%s] column name must not contain whitespace or NUL bytes", fieldPrefix, group, column))
|
||||
}
|
||||
}
|
||||
}
|
||||
for index, prefix := range cfg.StripModelPrefixes {
|
||||
if strings.TrimSpace(prefix) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.strip_model_prefixes[%d] must not be empty", fieldPrefix, index))
|
||||
}
|
||||
if strings.Contains(prefix, "\x00") {
|
||||
failures = append(failures, fmt.Errorf("%s.strip_model_prefixes[%d] must not contain NUL bytes", fieldPrefix, index))
|
||||
}
|
||||
}
|
||||
if column := strings.TrimSpace(cfg.ModelColumn); column != "" && strings.ContainsAny(column, " \t\r\n\x00") {
|
||||
failures = append(failures, fmt.Errorf("%s.model_column must not contain whitespace or NUL bytes", fieldPrefix))
|
||||
}
|
||||
for column := range cfg.RowDefaults {
|
||||
column = strings.TrimSpace(column)
|
||||
if column == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.row_defaults contains an empty column name", fieldPrefix))
|
||||
}
|
||||
if strings.ContainsAny(column, " \t\r\n\x00") {
|
||||
failures = append(failures, fmt.Errorf("%s.row_defaults[%s] column name must not contain whitespace or NUL bytes", fieldPrefix, column))
|
||||
}
|
||||
}
|
||||
return failures
|
||||
}
|
||||
|
||||
func partsRowsConfigConfigured(cfg PartsRowsConfig) bool {
|
||||
if len(cfg.RowDefaults) > 0 {
|
||||
return true
|
||||
|
||||
@@ -1360,6 +1360,62 @@ func TestValidateLayoutRejectsInvalidAutogenConsumerConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutRejectsInvalidHeadVisualeffectsConfig(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: "Test", ResRef: "test"},
|
||||
Paths: PathConfig{Source: "src", Build: "build"},
|
||||
Autogen: AutogenConfig{
|
||||
Consumers: []AutogenConsumerConfig{
|
||||
{
|
||||
ID: "head_visualeffects",
|
||||
Producer: "head_visualeffects",
|
||||
Dataset: "visualeffects",
|
||||
Mode: "head_visualeffects",
|
||||
Root: "vfxs",
|
||||
Include: []string{"head_jewels/**/*.mdl"},
|
||||
Derive: AutogenDeriveConfig{Kind: "model_stem", GroupFrom: "first_path_segment"},
|
||||
Manifest: AutogenManifestConfig{
|
||||
ReleaseTag: "head-vfx-manifest-current",
|
||||
AssetName: "sow-head-vfx-manifest.json",
|
||||
CacheName: "sow-head-vfx-manifest.json",
|
||||
},
|
||||
HeadVisualeffects: HeadVisualeffectsConfig{
|
||||
Groups: map[string]HeadVisualeffectGroupConfig{
|
||||
"head_jewels": {
|
||||
ModelColumns: []string{"Imp Root M Node"},
|
||||
},
|
||||
},
|
||||
StripModelPrefixes: []string{""},
|
||||
ModelColumn: "Imp HeadCon Node",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := proj.ValidateLayout()
|
||||
if err == nil {
|
||||
t.Fatal("expected head visualeffects validation error")
|
||||
}
|
||||
for _, needle := range []string{
|
||||
"autogen.consumers[0].head_visualeffects.groups[head_jewels].prefix",
|
||||
"autogen.consumers[0].head_visualeffects.groups[head_jewels].model_columns[0]",
|
||||
"autogen.consumers[0].head_visualeffects.strip_model_prefixes[0]",
|
||||
"autogen.consumers[0].head_visualeffects.model_column",
|
||||
} {
|
||||
if !strings.Contains(err.Error(), needle) {
|
||||
t.Fatalf("expected validation error to mention %s, got %v", needle, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutAcceptsGeneratedTopData2DAConfig(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "assets"))
|
||||
|
||||
Reference in New Issue
Block a user