Autogen configuration enabled
This commit is contained in:
@@ -2209,6 +2209,14 @@ func TestBuildHAKsWritesConfiguredHeadVisualeffectsAutogenManifest(t *testing.T)
|
||||
"release_tag": "head-vfx-manifest-current",
|
||||
"asset_name": "sow-head-vfx-manifest.json",
|
||||
"cache_name": "sow-head-vfx-manifest.json"
|
||||
},
|
||||
"head_visualeffects": {
|
||||
"groups": {
|
||||
"head_accessories": {
|
||||
"prefix": "headaccessory",
|
||||
"model_columns": ["Imp_HeadCon_Node", "Imp_Root_H_Node"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -2263,6 +2271,9 @@ func TestBuildHAKsWritesConfiguredHeadVisualeffectsAutogenManifest(t *testing.T)
|
||||
`"model_stem": "tfx_sash"`,
|
||||
`"group": "head_accessories"`,
|
||||
`"model_stem": "hfx_bandana"`,
|
||||
`"head_visualeffects": {`,
|
||||
`"model_columns": [`,
|
||||
`"Imp_Root_H_Node"`,
|
||||
`"group": "head_decorations"`,
|
||||
`"model_stem": "hfx_laurel"`,
|
||||
`"group": "head_features"`,
|
||||
|
||||
+18
-14
@@ -363,11 +363,12 @@ type AutogenReleaseSourceConfig struct {
|
||||
}
|
||||
|
||||
type AutogenProducerConfig struct {
|
||||
ID string `json:"id" yaml:"id"`
|
||||
Root string `json:"root" yaml:"root"`
|
||||
Include []string `json:"include" yaml:"include"`
|
||||
Derive AutogenDeriveConfig `json:"derive" yaml:"derive"`
|
||||
Manifest AutogenManifestConfig `json:"manifest" yaml:"manifest"`
|
||||
ID string `json:"id" yaml:"id"`
|
||||
Root string `json:"root" yaml:"root"`
|
||||
Include []string `json:"include" yaml:"include"`
|
||||
Derive AutogenDeriveConfig `json:"derive" yaml:"derive"`
|
||||
Manifest AutogenManifestConfig `json:"manifest" yaml:"manifest"`
|
||||
HeadVisualeffects HeadVisualeffectsConfig `json:"head_visualeffects" yaml:"head_visualeffects"`
|
||||
}
|
||||
|
||||
type AutogenConsumerConfig struct {
|
||||
@@ -386,19 +387,19 @@ type AutogenConsumerConfig struct {
|
||||
}
|
||||
|
||||
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"`
|
||||
Groups map[string]HeadVisualeffectGroupConfig `json:"groups,omitempty" yaml:"groups"`
|
||||
StripModelPrefixes []string `json:"strip_model_prefixes,omitempty" yaml:"strip_model_prefixes"`
|
||||
KeyFormat string `json:"key_format,omitempty" yaml:"key_format"`
|
||||
LabelFormat string `json:"label_format,omitempty" yaml:"label_format"`
|
||||
ModelColumn string `json:"model_column,omitempty" yaml:"model_column"`
|
||||
RowDefaults map[string]string `json:"row_defaults,omitempty" 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"`
|
||||
ModelColumn string `json:"model_column,omitempty" yaml:"model_column"`
|
||||
ModelColumns []string `json:"model_columns,omitempty" yaml:"model_columns"`
|
||||
RowDefaults map[string]string `json:"row_defaults,omitempty" yaml:"row_defaults"`
|
||||
}
|
||||
|
||||
type PartsRowsConfig struct {
|
||||
@@ -1693,6 +1694,9 @@ func validateAutogenConfig(cfg AutogenConfig) []error {
|
||||
failures = append(failures, validateGlobList(fieldPrefix+".include", producer.Include)...)
|
||||
failures = append(failures, validateAutogenDeriveConfig(fieldPrefix+".derive", producer.Derive)...)
|
||||
failures = append(failures, validateAutogenManifestConfig(fieldPrefix+".manifest", producer.Manifest)...)
|
||||
if headVisualeffectsConfigConfigured(producer.HeadVisualeffects) {
|
||||
failures = append(failures, validateHeadVisualeffectsConfig(fieldPrefix+".head_visualeffects", producer.HeadVisualeffects)...)
|
||||
}
|
||||
}
|
||||
|
||||
for index, consumer := range cfg.Consumers {
|
||||
|
||||
+59
-22
@@ -17,11 +17,12 @@ import (
|
||||
const autogenManifestCacheMaxAge = time.Hour
|
||||
|
||||
type autogenManifest struct {
|
||||
ID string `json:"id"`
|
||||
Repo string `json:"repo"`
|
||||
Ref string `json:"ref"`
|
||||
GeneratedAt string `json:"generated_at"`
|
||||
Entries []autogenManifestEntry `json:"entries"`
|
||||
ID string `json:"id"`
|
||||
Repo string `json:"repo"`
|
||||
Ref string `json:"ref"`
|
||||
GeneratedAt string `json:"generated_at"`
|
||||
HeadVisualeffects *project.HeadVisualeffectsConfig `json:"head_visualeffects,omitempty"`
|
||||
Entries []autogenManifestEntry `json:"entries"`
|
||||
}
|
||||
|
||||
type autogenManifestEntry struct {
|
||||
@@ -57,7 +58,7 @@ func applyAutogenConsumers(p *project.Project, collected []nativeCollectedDatase
|
||||
if !autogenConsumerTargetsCollectedDataset(result, consumer) {
|
||||
continue
|
||||
}
|
||||
entries, err := resolveAutogenConsumerEntries(p, consumer, progress)
|
||||
manifest, err := resolveAutogenConsumerManifest(p, consumer, progress)
|
||||
if err != nil {
|
||||
if consumer.Optional && isIgnorableOptionalAutogenError(err) {
|
||||
if progress != nil {
|
||||
@@ -67,6 +68,7 @@ func applyAutogenConsumers(p *project.Project, collected []nativeCollectedDatase
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
entries := manifest.Entries
|
||||
if len(entries) == 0 {
|
||||
continue
|
||||
}
|
||||
@@ -74,7 +76,7 @@ func applyAutogenConsumers(p *project.Project, collected []nativeCollectedDatase
|
||||
case "parts_rows":
|
||||
result = augmentWithAutogeneratedParts(result, autogenPartsInventory(entries))
|
||||
case "head_visualeffects":
|
||||
result, err = augmentWithAutogeneratedHeadVisualeffects(result, entries, consumer)
|
||||
result, err = augmentWithAutogeneratedHeadVisualeffects(result, entries, consumer, manifest.HeadVisualeffects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -115,7 +117,7 @@ func isIgnorableOptionalAutogenError(err error) bool {
|
||||
strings.Contains(message, "entries is empty")
|
||||
}
|
||||
|
||||
func resolveAutogenConsumerEntries(p *project.Project, consumer project.AutogenConsumerConfig, progress func(string)) ([]autogenManifestEntry, error) {
|
||||
func resolveAutogenConsumerManifest(p *project.Project, consumer project.AutogenConsumerConfig, progress func(string)) (*autogenManifest, error) {
|
||||
overrideRoot, err := resolveAutogenLocalOverrideRoot(p, consumer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -124,9 +126,13 @@ func resolveAutogenConsumerEntries(p *project.Project, consumer project.AutogenC
|
||||
if progress != nil {
|
||||
progress(fmt.Sprintf("Scanning local autogen override for %s from %s...", consumer.ID, overrideRoot))
|
||||
}
|
||||
return scanLocalAutogenEntries(overrideRoot, consumer)
|
||||
entries, err := scanLocalAutogenEntries(overrideRoot, consumer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &autogenManifest{ID: consumer.Producer, Entries: entries}, nil
|
||||
}
|
||||
return resolveReleasedAutogenManifestEntries(p, consumer, progress)
|
||||
return resolveReleasedAutogenManifest(p, consumer, progress)
|
||||
}
|
||||
|
||||
func resolveAutogenLocalOverrideRoot(p *project.Project, consumer project.AutogenConsumerConfig) (string, error) {
|
||||
@@ -331,7 +337,7 @@ func deriveAutogenManifestEntry(rel string, derive project.AutogenDeriveConfig)
|
||||
return entry, true
|
||||
}
|
||||
|
||||
func resolveReleasedAutogenManifestEntries(p *project.Project, consumer project.AutogenConsumerConfig, progress func(string)) ([]autogenManifestEntry, error) {
|
||||
func resolveReleasedAutogenManifest(p *project.Project, consumer project.AutogenConsumerConfig, progress func(string)) (*autogenManifest, error) {
|
||||
cachePath := p.AutogenCachePath(consumer.Manifest.CacheName)
|
||||
if strings.TrimSpace(os.Getenv(p.AutogenRefreshEnv())) == "" {
|
||||
manifest, fresh, err := readFreshAutogenManifestCache(cachePath, p.AutogenCacheMaxAge())
|
||||
@@ -344,12 +350,12 @@ func resolveReleasedAutogenManifestEntries(p *project.Project, consumer project.
|
||||
if progress != nil {
|
||||
progress(fmt.Sprintf("Using cached released autogen manifest %s (remote check failed: %v)...", cachePath, err))
|
||||
}
|
||||
return manifest.Entries, nil
|
||||
return manifest, nil
|
||||
} else if current {
|
||||
if progress != nil {
|
||||
progress(fmt.Sprintf("Using cached released autogen manifest %s...", cachePath))
|
||||
}
|
||||
return manifest.Entries, nil
|
||||
return manifest, nil
|
||||
} else if progress != nil {
|
||||
progress(fmt.Sprintf("Refreshing released autogen manifest %s; remote asset changed at %s.", consumer.Manifest.CacheName, remoteTime.Format(time.RFC3339)))
|
||||
}
|
||||
@@ -383,6 +389,14 @@ func resolveReleasedAutogenManifestEntries(p *project.Project, consumer project.
|
||||
if err := writeAutogenManifestCache(cachePath, manifest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return manifest, nil
|
||||
}
|
||||
|
||||
func resolveReleasedAutogenManifestEntries(p *project.Project, consumer project.AutogenConsumerConfig, progress func(string)) ([]autogenManifestEntry, error) {
|
||||
manifest, err := resolveReleasedAutogenManifest(p, consumer, progress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return manifest.Entries, nil
|
||||
}
|
||||
|
||||
@@ -660,12 +674,12 @@ func augmentWithAutogeneratedCachedModels(collected []nativeCollectedDataset, en
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func augmentWithAutogeneratedHeadVisualeffects(collected []nativeCollectedDataset, entries []autogenManifestEntry, consumer project.AutogenConsumerConfig) ([]nativeCollectedDataset, error) {
|
||||
func augmentWithAutogeneratedHeadVisualeffects(collected []nativeCollectedDataset, entries []autogenManifestEntry, consumer project.AutogenConsumerConfig, manifestPolicy *project.HeadVisualeffectsConfig) ([]nativeCollectedDataset, error) {
|
||||
if len(entries) == 0 {
|
||||
return collected, nil
|
||||
}
|
||||
|
||||
policy := resolveHeadVisualeffectsPolicy(consumer)
|
||||
policy := resolveHeadVisualeffectsPolicy(consumer, manifestPolicy)
|
||||
result := append([]nativeCollectedDataset(nil), collected...)
|
||||
for i, dataset := range result {
|
||||
if dataset.Dataset.Name != "visualeffects" {
|
||||
@@ -771,20 +785,31 @@ type headVisualeffectsGroupPolicy struct {
|
||||
RowDefaults map[string]string
|
||||
}
|
||||
|
||||
func resolveHeadVisualeffectsPolicy(consumer project.AutogenConsumerConfig) headVisualeffectsPolicy {
|
||||
func resolveHeadVisualeffectsPolicy(consumer project.AutogenConsumerConfig, manifestPolicy *project.HeadVisualeffectsConfig) headVisualeffectsPolicy {
|
||||
policy := defaultHeadVisualeffectsPolicy()
|
||||
cfg := consumer.HeadVisualeffects
|
||||
if manifestPolicy != nil {
|
||||
applyHeadVisualeffectsConfig(&policy, *manifestPolicy)
|
||||
}
|
||||
applyHeadVisualeffectsConfig(&policy, consumer.HeadVisualeffects)
|
||||
return policy
|
||||
}
|
||||
|
||||
func applyHeadVisualeffectsConfig(policy *headVisualeffectsPolicy, cfg project.HeadVisualeffectsConfig) {
|
||||
for group, groupCfg := range cfg.Groups {
|
||||
group = strings.TrimSpace(group)
|
||||
prefix := strings.TrimSpace(groupCfg.Prefix)
|
||||
if group == "" || prefix == "" {
|
||||
continue
|
||||
}
|
||||
groupPolicy := headVisualeffectsGroupPolicy{
|
||||
Prefix: prefix,
|
||||
ModelColumns: normalizeHeadVisualeffectsModelColumns(groupCfg.ModelColumn, groupCfg.ModelColumns),
|
||||
RowDefaults: normalizeHeadVisualeffectsRowDefaults(groupCfg.RowDefaults),
|
||||
groupPolicy := policy.Groups[group]
|
||||
groupPolicy.Prefix = prefix
|
||||
if columns := normalizeHeadVisualeffectsModelColumns(groupCfg.ModelColumn, groupCfg.ModelColumns); len(columns) > 0 {
|
||||
groupPolicy.ModelColumns = columns
|
||||
}
|
||||
if groupPolicy.RowDefaults == nil {
|
||||
groupPolicy.RowDefaults = map[string]string{}
|
||||
}
|
||||
mergeStringMap(groupPolicy.RowDefaults, normalizeHeadVisualeffectsRowDefaults(groupCfg.RowDefaults))
|
||||
policy.Groups[group] = groupPolicy
|
||||
}
|
||||
if len(cfg.StripModelPrefixes) > 0 {
|
||||
@@ -800,7 +825,6 @@ func resolveHeadVisualeffectsPolicy(consumer project.AutogenConsumerConfig) head
|
||||
policy.ModelColumn = strings.TrimSpace(cfg.ModelColumn)
|
||||
}
|
||||
mergeStringMap(policy.RowDefaults, normalizeHeadVisualeffectsRowDefaults(cfg.RowDefaults))
|
||||
return policy
|
||||
}
|
||||
|
||||
func defaultHeadVisualeffectsPolicy() headVisualeffectsPolicy {
|
||||
@@ -964,9 +988,22 @@ func formatAutogenManifest(root string, producer project.AutogenProducerConfig,
|
||||
GeneratedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
Entries: entries,
|
||||
}
|
||||
if autogenHeadVisualeffectsConfigConfigured(producer.HeadVisualeffects) {
|
||||
cfg := producer.HeadVisualeffects
|
||||
manifest.HeadVisualeffects = &cfg
|
||||
}
|
||||
return json.MarshalIndent(manifest, "", " ")
|
||||
}
|
||||
|
||||
func autogenHeadVisualeffectsConfigConfigured(cfg project.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 parseAutogenManifestEntryList(raw []byte) ([]autogenManifestEntry, error) {
|
||||
var manifest autogenManifest
|
||||
if err := json.Unmarshal(raw, &manifest); err != nil {
|
||||
|
||||
@@ -12666,9 +12666,9 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "base_dialog.json"), "{}\n")
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "data", "visualeffects", "base.json"), `{
|
||||
"output": "visualeffects.2da",
|
||||
"columns": ["Label", "Type_FD", "OrientWithGround", "Imp_HeadCon_Node", "OrientWithObject"],
|
||||
"columns": ["Label", "Type_FD", "OrientWithGround", "Imp_HeadCon_Node", "Imp_Root_H_Node", "OrientWithObject"],
|
||||
"rows": [
|
||||
{"key": "visualeffects:existing", "id": 17, "Label": "EXISTING", "Type_FD": "F", "OrientWithGround": "0", "Imp_HeadCon_Node": "****", "OrientWithObject": "0"}
|
||||
{"key": "visualeffects:existing", "id": 17, "Label": "EXISTING", "Type_FD": "F", "OrientWithGround": "0", "Imp_HeadCon_Node": "****", "Imp_Root_H_Node": "****", "OrientWithObject": "0"}
|
||||
]
|
||||
}`+"\n")
|
||||
writeFile(t, filepath.Join(projRoot, "topdata", "data", "visualeffects", "lock.json"), `{
|
||||
@@ -12682,6 +12682,26 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
||||
"repo": "ShadowsOverWestgate/sow-assets",
|
||||
"ref": "test-manifest",
|
||||
"generated_at": "2026-04-25T00:00:00Z",
|
||||
"head_visualeffects": {
|
||||
"groups": {
|
||||
"head_accessories": {
|
||||
"prefix": "headaccessory",
|
||||
"model_columns": ["Imp_HeadCon_Node", "Imp_Root_H_Node"]
|
||||
},
|
||||
"head_features": {
|
||||
"prefix": "headfeature",
|
||||
"model_columns": ["Imp_HeadCon_Node", "Imp_Root_H_Node"]
|
||||
}
|
||||
},
|
||||
"strip_model_prefixes": ["hfx_"],
|
||||
"key_format": "{dataset}:{prefix}_{stem}",
|
||||
"label_format": "{prefix}_{stem_upper}",
|
||||
"row_defaults": {
|
||||
"Type_FD": "D",
|
||||
"OrientWithGround": "0",
|
||||
"OrientWithObject": "1"
|
||||
}
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"group": "head_accessories",
|
||||
@@ -12758,9 +12778,9 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
||||
}
|
||||
text := string(visualeffectsBytes)
|
||||
for _, want := range []string{
|
||||
"0\theadaccessory_BANDANA\tD\t0\thfx_bandana\t1",
|
||||
"1\theadfeature_HAIR_BANGS\tD\t0\thfx_hair_bangs\t1",
|
||||
"17\tEXISTING\tF\t0\t****\t0",
|
||||
"0\theadaccessory_BANDANA\tD\t0\thfx_bandana\thfx_bandana\t1",
|
||||
"1\theadfeature_HAIR_BANGS\tD\t0\thfx_hair_bangs\thfx_hair_bangs\t1",
|
||||
"17\tEXISTING\tF\t0\t****\t****\t0",
|
||||
} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("expected visualeffects output to contain %q, got:\n%s", want, text)
|
||||
|
||||
Reference in New Issue
Block a user