Autogen categories
This commit is contained in:
@@ -419,11 +419,9 @@ mapping, model stem prefixes to strip, key/label formats, model column, and
|
|||||||
default row values. `group_token_source: folder_name` uses the manifest folder
|
default row values. `group_token_source: folder_name` uses the manifest folder
|
||||||
group directly instead of a prefix mapping, and `category_from:
|
group directly instead of a prefix mapping, and `category_from:
|
||||||
immediate_parent` can expose the model's category folder in keys and labels.
|
immediate_parent` can expose the model's category folder in keys and labels.
|
||||||
`legacy_groups` maps released manifest group names to current folder groups,
|
Individual groups can override the model column with `model_column` or write
|
||||||
and `legacy_key_format` preserves row IDs when migrating older generated lock
|
the discovered model stem to several columns with `model_columns`, which is
|
||||||
keys. Individual groups can override the model column with `model_column` or
|
useful for root-node visualeffects. Supported format tokens are `{dataset}`,
|
||||||
write the discovered model stem to several columns with `model_columns`, which
|
|
||||||
is useful for root-node visualeffects. Supported format tokens are `{dataset}`,
|
|
||||||
`{group}`, `{group_raw}`, `{prefix}`, `{category}`, `{category_upper}`,
|
`{group}`, `{group_raw}`, `{prefix}`, `{category}`, `{category_upper}`,
|
||||||
`{category_segment}`, `{category_segment_upper}`, `{subgroup}`, `{stem}`,
|
`{category_segment}`, `{category_segment_upper}`, `{subgroup}`, `{stem}`,
|
||||||
`{stem_upper}`, `{model_stem}`, and `{delimiter}`.
|
`{stem_upper}`, `{model_stem}`, and `{delimiter}`.
|
||||||
|
|||||||
@@ -395,8 +395,6 @@ type HeadVisualeffectsConfig struct {
|
|||||||
StripModelPrefixes []string `json:"strip_model_prefixes,omitempty" yaml:"strip_model_prefixes"`
|
StripModelPrefixes []string `json:"strip_model_prefixes,omitempty" yaml:"strip_model_prefixes"`
|
||||||
KeyFormat string `json:"key_format,omitempty" yaml:"key_format"`
|
KeyFormat string `json:"key_format,omitempty" yaml:"key_format"`
|
||||||
LabelFormat string `json:"label_format,omitempty" yaml:"label_format"`
|
LabelFormat string `json:"label_format,omitempty" yaml:"label_format"`
|
||||||
LegacyGroups map[string]string `json:"legacy_groups,omitempty" yaml:"legacy_groups"`
|
|
||||||
LegacyKeyFormat string `json:"legacy_key_format,omitempty" yaml:"legacy_key_format"`
|
|
||||||
ModelColumn string `json:"model_column,omitempty" yaml:"model_column"`
|
ModelColumn string `json:"model_column,omitempty" yaml:"model_column"`
|
||||||
RowDefaults map[string]string `json:"row_defaults,omitempty" yaml:"row_defaults"`
|
RowDefaults map[string]string `json:"row_defaults,omitempty" yaml:"row_defaults"`
|
||||||
}
|
}
|
||||||
@@ -1820,8 +1818,6 @@ func headVisualeffectsConfigConfigured(cfg HeadVisualeffectsConfig) bool {
|
|||||||
len(cfg.StripModelPrefixes) > 0 ||
|
len(cfg.StripModelPrefixes) > 0 ||
|
||||||
strings.TrimSpace(cfg.KeyFormat) != "" ||
|
strings.TrimSpace(cfg.KeyFormat) != "" ||
|
||||||
strings.TrimSpace(cfg.LabelFormat) != "" ||
|
strings.TrimSpace(cfg.LabelFormat) != "" ||
|
||||||
len(cfg.LegacyGroups) > 0 ||
|
|
||||||
strings.TrimSpace(cfg.LegacyKeyFormat) != "" ||
|
|
||||||
strings.TrimSpace(cfg.ModelColumn) != "" ||
|
strings.TrimSpace(cfg.ModelColumn) != "" ||
|
||||||
len(cfg.RowDefaults) > 0
|
len(cfg.RowDefaults) > 0
|
||||||
}
|
}
|
||||||
@@ -1888,21 +1884,6 @@ func validateHeadVisualeffectsConfig(fieldPrefix string, cfg HeadVisualeffectsCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for legacyGroup, group := range cfg.LegacyGroups {
|
|
||||||
legacyGroup = strings.TrimSpace(legacyGroup)
|
|
||||||
group = strings.TrimSpace(group)
|
|
||||||
if legacyGroup == "" {
|
|
||||||
failures = append(failures, fmt.Errorf("%s.legacy_groups contains an empty legacy group key", fieldPrefix))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if group == "" {
|
|
||||||
failures = append(failures, fmt.Errorf("%s.legacy_groups[%s] must not be empty", fieldPrefix, legacyGroup))
|
|
||||||
}
|
|
||||||
failures = append(failures, validateTreeRootPath(fieldPrefix+".legacy_groups["+legacyGroup+"]", legacyGroup)...)
|
|
||||||
if group != "" {
|
|
||||||
failures = append(failures, validateTreeRootPath(fieldPrefix+".legacy_groups["+legacyGroup+"]", group)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for index, prefix := range cfg.StripModelPrefixes {
|
for index, prefix := range cfg.StripModelPrefixes {
|
||||||
if strings.TrimSpace(prefix) == "" {
|
if strings.TrimSpace(prefix) == "" {
|
||||||
failures = append(failures, fmt.Errorf("%s.strip_model_prefixes[%d] must not be empty", fieldPrefix, index))
|
failures = append(failures, fmt.Errorf("%s.strip_model_prefixes[%d] must not be empty", fieldPrefix, index))
|
||||||
|
|||||||
@@ -1449,9 +1449,6 @@ func TestValidateLayoutRejectsInvalidHeadVisualeffectsNamingConfig(t *testing.T)
|
|||||||
CategoryFrom: "unsupported",
|
CategoryFrom: "unsupported",
|
||||||
Delimiter: " ",
|
Delimiter: " ",
|
||||||
Case: "unsupported",
|
Case: "unsupported",
|
||||||
LegacyGroups: map[string]string{
|
|
||||||
"head_features": "",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1468,7 +1465,6 @@ func TestValidateLayoutRejectsInvalidHeadVisualeffectsNamingConfig(t *testing.T)
|
|||||||
"autogen.consumers[0].head_visualeffects.category_from",
|
"autogen.consumers[0].head_visualeffects.category_from",
|
||||||
"autogen.consumers[0].head_visualeffects.delimiter",
|
"autogen.consumers[0].head_visualeffects.delimiter",
|
||||||
"autogen.consumers[0].head_visualeffects.case",
|
"autogen.consumers[0].head_visualeffects.case",
|
||||||
"autogen.consumers[0].head_visualeffects.legacy_groups[head_features]",
|
|
||||||
} {
|
} {
|
||||||
if !strings.Contains(err.Error(), needle) {
|
if !strings.Contains(err.Error(), needle) {
|
||||||
t.Fatalf("expected validation error to mention %s, got %v", needle, err)
|
t.Fatalf("expected validation error to mention %s, got %v", needle, err)
|
||||||
@@ -1476,6 +1472,47 @@ func TestValidateLayoutRejectsInvalidHeadVisualeffectsNamingConfig(t *testing.T)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadRejectsLegacyHeadVisualeffectsNamingFields(t *testing.T) {
|
||||||
|
root := t.TempDir()
|
||||||
|
writeProjectFile(t, filepath.Join(root, ConfigFile), `
|
||||||
|
module:
|
||||||
|
name: Test Module
|
||||||
|
resref: testmod
|
||||||
|
paths:
|
||||||
|
source: src
|
||||||
|
autogen:
|
||||||
|
consumers:
|
||||||
|
- id: head_visualeffects
|
||||||
|
producer: head_visualeffects
|
||||||
|
dataset: visualeffects
|
||||||
|
mode: head_visualeffects
|
||||||
|
root: vfxs
|
||||||
|
include:
|
||||||
|
- headfeature/**/*.mdl
|
||||||
|
derive:
|
||||||
|
kind: model_stem
|
||||||
|
group_from: first_path_segment
|
||||||
|
head_visualeffects:
|
||||||
|
groups:
|
||||||
|
headfeature:
|
||||||
|
model_columns:
|
||||||
|
- Imp_HeadCon_Node
|
||||||
|
group_token_source: folder_name
|
||||||
|
category_from: immediate_parent
|
||||||
|
legacy_groups:
|
||||||
|
head_features: headfeature
|
||||||
|
legacy_key_format: "{dataset}:{group}_{stem}"
|
||||||
|
`)
|
||||||
|
|
||||||
|
_, err := Load(root)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected legacy head visualeffects naming fields to be rejected")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "legacy_groups") {
|
||||||
|
t.Fatalf("expected legacy_groups unknown field error, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidateLayoutAcceptsGeneratedTopData2DAConfig(t *testing.T) {
|
func TestValidateLayoutAcceptsGeneratedTopData2DAConfig(t *testing.T) {
|
||||||
root := t.TempDir()
|
root := t.TempDir()
|
||||||
mkdirAll(t, filepath.Join(root, "assets"))
|
mkdirAll(t, filepath.Join(root, "assets"))
|
||||||
|
|||||||
+13
-85
@@ -742,25 +742,10 @@ func augmentWithAutogeneratedHeadVisualeffects(collected []nativeCollectedDatase
|
|||||||
|
|
||||||
rowID, ok := lockData[key]
|
rowID, ok := lockData[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
var migratedLegacyKey string
|
|
||||||
if preservedRowID, preserved := historicalLockData[key]; preserved {
|
if preservedRowID, preserved := historicalLockData[key]; preserved {
|
||||||
rowID = preservedRowID
|
rowID = preservedRowID
|
||||||
} else {
|
} else {
|
||||||
preservedLegacyID := false
|
rowID = allocateNextID()
|
||||||
for _, legacyKey := range headVisualeffectLegacyKeys(dataset.Dataset.Name, entry, policy) {
|
|
||||||
if preservedRowID, preserved := historicalLockData[legacyKey]; preserved {
|
|
||||||
rowID = preservedRowID
|
|
||||||
preservedLegacyID = true
|
|
||||||
migratedLegacyKey = legacyKey
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !preservedLegacyID {
|
|
||||||
rowID = allocateNextID()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if migratedLegacyKey != "" && migratedLegacyKey != key {
|
|
||||||
delete(lockData, migratedLegacyKey)
|
|
||||||
}
|
}
|
||||||
lockData[key] = rowID
|
lockData[key] = rowID
|
||||||
}
|
}
|
||||||
@@ -796,8 +781,6 @@ type headVisualeffectsPolicy struct {
|
|||||||
StripModelPrefixes []string
|
StripModelPrefixes []string
|
||||||
KeyFormat string
|
KeyFormat string
|
||||||
LabelFormat string
|
LabelFormat string
|
||||||
LegacyGroups map[string]string
|
|
||||||
LegacyKeyFormat string
|
|
||||||
ModelColumn string
|
ModelColumn string
|
||||||
RowDefaults map[string]string
|
RowDefaults map[string]string
|
||||||
}
|
}
|
||||||
@@ -858,22 +841,6 @@ func applyHeadVisualeffectsConfig(policy *headVisualeffectsPolicy, cfg project.H
|
|||||||
if strings.TrimSpace(cfg.LabelFormat) != "" {
|
if strings.TrimSpace(cfg.LabelFormat) != "" {
|
||||||
policy.LabelFormat = strings.TrimSpace(cfg.LabelFormat)
|
policy.LabelFormat = strings.TrimSpace(cfg.LabelFormat)
|
||||||
}
|
}
|
||||||
if len(cfg.LegacyGroups) > 0 {
|
|
||||||
if policy.LegacyGroups == nil {
|
|
||||||
policy.LegacyGroups = map[string]string{}
|
|
||||||
}
|
|
||||||
for legacyGroup, group := range cfg.LegacyGroups {
|
|
||||||
legacyGroup = strings.TrimSpace(legacyGroup)
|
|
||||||
group = strings.TrimSpace(group)
|
|
||||||
if legacyGroup == "" || group == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
policy.LegacyGroups[legacyGroup] = group
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(cfg.LegacyKeyFormat) != "" {
|
|
||||||
policy.LegacyKeyFormat = strings.TrimSpace(cfg.LegacyKeyFormat)
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(cfg.ModelColumn) != "" {
|
if strings.TrimSpace(cfg.ModelColumn) != "" {
|
||||||
policy.ModelColumn = strings.TrimSpace(cfg.ModelColumn)
|
policy.ModelColumn = strings.TrimSpace(cfg.ModelColumn)
|
||||||
}
|
}
|
||||||
@@ -883,17 +850,18 @@ func applyHeadVisualeffectsConfig(policy *headVisualeffectsPolicy, cfg project.H
|
|||||||
func defaultHeadVisualeffectsPolicy() headVisualeffectsPolicy {
|
func defaultHeadVisualeffectsPolicy() headVisualeffectsPolicy {
|
||||||
return headVisualeffectsPolicy{
|
return headVisualeffectsPolicy{
|
||||||
Groups: map[string]headVisualeffectsGroupPolicy{
|
Groups: map[string]headVisualeffectsGroupPolicy{
|
||||||
"head_accessories": {Prefix: "headaccessory"},
|
"chestaccessory": {},
|
||||||
"head_decorations": {Prefix: "headdecoration"},
|
"headaccessory": {},
|
||||||
"head_features": {Prefix: "headfeature"},
|
"headdecoration": {},
|
||||||
|
"headfeature": {},
|
||||||
},
|
},
|
||||||
GroupTokenSource: "prefix",
|
GroupTokenSource: "folder_name",
|
||||||
CategoryFrom: "none",
|
CategoryFrom: "immediate_parent",
|
||||||
Delimiter: "_",
|
Delimiter: "/",
|
||||||
Case: "preserve",
|
Case: "preserve",
|
||||||
StripModelPrefixes: []string{"hfx_", "vfx_"},
|
StripModelPrefixes: []string{"hfx_", "tfx_", "vfx_", "cfx_"},
|
||||||
KeyFormat: "{dataset}:{prefix}_{stem}",
|
KeyFormat: "{dataset}:{group}{delimiter}{category_segment}{stem}",
|
||||||
LabelFormat: "{prefix}_{stem_upper}",
|
LabelFormat: "{group}{delimiter}{category_segment}{stem}",
|
||||||
ModelColumn: "Imp_HeadCon_Node",
|
ModelColumn: "Imp_HeadCon_Node",
|
||||||
RowDefaults: map[string]string{
|
RowDefaults: map[string]string{
|
||||||
"Type_FD": "D",
|
"Type_FD": "D",
|
||||||
@@ -939,7 +907,7 @@ func mergeStringMap(target map[string]string, source map[string]string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func headVisualeffectIdentity(dataset string, entry autogenManifestEntry, policy headVisualeffectsPolicy) (string, string, string, headVisualeffectsGroupPolicy, bool) {
|
func headVisualeffectIdentity(dataset string, entry autogenManifestEntry, policy headVisualeffectsPolicy) (string, string, string, headVisualeffectsGroupPolicy, bool) {
|
||||||
entry = normalizeHeadVisualeffectEntry(entry, policy)
|
entry = normalizeHeadVisualeffectEntry(entry)
|
||||||
group, ok := policy.Groups[entry.Group]
|
group, ok := policy.Groups[entry.Group]
|
||||||
if !ok || strings.TrimSpace(entry.ModelStem) == "" {
|
if !ok || strings.TrimSpace(entry.ModelStem) == "" {
|
||||||
return "", "", "", headVisualeffectsGroupPolicy{}, false
|
return "", "", "", headVisualeffectsGroupPolicy{}, false
|
||||||
@@ -975,50 +943,12 @@ func headVisualeffectIdentity(dataset string, entry autogenManifestEntry, policy
|
|||||||
return key, label, modelStem, group, true
|
return key, label, modelStem, group, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func headVisualeffectLegacyKeys(dataset string, entry autogenManifestEntry, policy headVisualeffectsPolicy) []string {
|
func normalizeHeadVisualeffectEntry(entry autogenManifestEntry) autogenManifestEntry {
|
||||||
if strings.TrimSpace(policy.LegacyKeyFormat) == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
entry = normalizeHeadVisualeffectEntry(entry, policy)
|
|
||||||
group, ok := policy.Groups[entry.Group]
|
|
||||||
if !ok || strings.TrimSpace(entry.ModelStem) == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
modelStem := strings.TrimSpace(entry.ModelStem)
|
|
||||||
stem := strings.TrimSpace(stripHeadVisualeffectModelPrefix(modelStem, policy))
|
|
||||||
if stem == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
groupToken := headVisualeffectGroupToken(entry.Group, group, policy)
|
|
||||||
values := map[string]string{
|
|
||||||
"dataset": dataset,
|
|
||||||
"group": applyHeadVisualeffectCase(groupToken, policy),
|
|
||||||
"group_raw": entry.Group,
|
|
||||||
"prefix": applyHeadVisualeffectCase(group.Prefix, policy),
|
|
||||||
"stem": applyHeadVisualeffectCase(stem, policy),
|
|
||||||
"stem_upper": strings.ToUpper(stem),
|
|
||||||
"model_stem": modelStem,
|
|
||||||
"delimiter": policy.Delimiter,
|
|
||||||
}
|
|
||||||
legacyKey := strings.TrimSpace(expandHeadVisualeffectsFormat(policy.LegacyKeyFormat, values))
|
|
||||||
if legacyKey == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return []string{legacyKey}
|
|
||||||
}
|
|
||||||
|
|
||||||
func normalizeHeadVisualeffectEntry(entry autogenManifestEntry, policy headVisualeffectsPolicy) autogenManifestEntry {
|
|
||||||
entry.Group = strings.TrimSpace(entry.Group)
|
entry.Group = strings.TrimSpace(entry.Group)
|
||||||
if mapped, ok := policy.LegacyGroups[entry.Group]; ok && strings.TrimSpace(mapped) != "" {
|
|
||||||
entry.Group = strings.TrimSpace(mapped)
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(entry.Group) == "" && strings.TrimSpace(entry.Source) != "" {
|
if strings.TrimSpace(entry.Group) == "" && strings.TrimSpace(entry.Source) != "" {
|
||||||
parts := strings.Split(filepath.ToSlash(entry.Source), "/")
|
parts := strings.Split(filepath.ToSlash(entry.Source), "/")
|
||||||
if len(parts) > 1 {
|
if len(parts) > 1 {
|
||||||
entry.Group = parts[0]
|
entry.Group = parts[0]
|
||||||
if mapped, ok := policy.LegacyGroups[entry.Group]; ok && strings.TrimSpace(mapped) != "" {
|
|
||||||
entry.Group = strings.TrimSpace(mapped)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(entry.Subgroup) == "" && strings.TrimSpace(entry.Source) != "" {
|
if strings.TrimSpace(entry.Subgroup) == "" && strings.TrimSpace(entry.Source) != "" {
|
||||||
@@ -1176,8 +1106,6 @@ func autogenHeadVisualeffectsConfigConfigured(cfg project.HeadVisualeffectsConfi
|
|||||||
len(cfg.StripModelPrefixes) > 0 ||
|
len(cfg.StripModelPrefixes) > 0 ||
|
||||||
strings.TrimSpace(cfg.KeyFormat) != "" ||
|
strings.TrimSpace(cfg.KeyFormat) != "" ||
|
||||||
strings.TrimSpace(cfg.LabelFormat) != "" ||
|
strings.TrimSpace(cfg.LabelFormat) != "" ||
|
||||||
len(cfg.LegacyGroups) > 0 ||
|
|
||||||
strings.TrimSpace(cfg.LegacyKeyFormat) != "" ||
|
|
||||||
strings.TrimSpace(cfg.ModelColumn) != "" ||
|
strings.TrimSpace(cfg.ModelColumn) != "" ||
|
||||||
len(cfg.RowDefaults) > 0
|
len(cfg.RowDefaults) > 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7328,12 +7328,12 @@ func TestApplyAutogenConsumersAugmentsPartsFromLocalOverride(t *testing.T) {
|
|||||||
func TestApplyAutogenConsumersAugmentsHeadVisualeffectsFromLocalOverride(t *testing.T) {
|
func TestApplyAutogenConsumersAugmentsHeadVisualeffectsFromLocalOverride(t *testing.T) {
|
||||||
root := testProjectRoot(t)
|
root := testProjectRoot(t)
|
||||||
overrideRoot := filepath.Join(root, "autogen-assets")
|
overrideRoot := filepath.Join(root, "autogen-assets")
|
||||||
mkdirAll(t, filepath.Join(overrideRoot, "vfxs", "head_accessories"))
|
mkdirAll(t, filepath.Join(overrideRoot, "vfxs", "headaccessory", "hat"))
|
||||||
mkdirAll(t, filepath.Join(overrideRoot, "vfxs", "head_decorations"))
|
mkdirAll(t, filepath.Join(overrideRoot, "vfxs", "headdecoration", "laurel"))
|
||||||
mkdirAll(t, filepath.Join(overrideRoot, "vfxs", "head_features", "hair"))
|
mkdirAll(t, filepath.Join(overrideRoot, "vfxs", "headfeature", "hair"))
|
||||||
writeFile(t, filepath.Join(overrideRoot, "vfxs", "head_accessories", "hfx_bandana.mdl"), "mdl\n")
|
writeFile(t, filepath.Join(overrideRoot, "vfxs", "headaccessory", "hat", "hfx_bandana.mdl"), "mdl\n")
|
||||||
writeFile(t, filepath.Join(overrideRoot, "vfxs", "head_decorations", "hfx_laurel.mdl"), "mdl\n")
|
writeFile(t, filepath.Join(overrideRoot, "vfxs", "headdecoration", "laurel", "hfx_laurel.mdl"), "mdl\n")
|
||||||
writeFile(t, filepath.Join(overrideRoot, "vfxs", "head_features", "hair", "hfx_hair_bangs.mdl"), "mdl\n")
|
writeFile(t, filepath.Join(overrideRoot, "vfxs", "headfeature", "hair", "hfx_hair_bangs.mdl"), "mdl\n")
|
||||||
|
|
||||||
p := testProject(root)
|
p := testProject(root)
|
||||||
p.Config.Autogen.Consumers = []project.AutogenConsumerConfig{
|
p.Config.Autogen.Consumers = []project.AutogenConsumerConfig{
|
||||||
@@ -7343,7 +7343,7 @@ func TestApplyAutogenConsumersAugmentsHeadVisualeffectsFromLocalOverride(t *test
|
|||||||
Dataset: "visualeffects",
|
Dataset: "visualeffects",
|
||||||
Mode: "head_visualeffects",
|
Mode: "head_visualeffects",
|
||||||
Root: "vfxs",
|
Root: "vfxs",
|
||||||
Include: []string{"head_accessories/**/*.mdl", "head_decorations/**/*.mdl", "head_features/**/*.mdl"},
|
Include: []string{"headaccessory/**/*.mdl", "headdecoration/**/*.mdl", "headfeature/**/*.mdl"},
|
||||||
Derive: project.AutogenDeriveConfig{Kind: "model_stem", GroupFrom: "first_path_segment"},
|
Derive: project.AutogenDeriveConfig{Kind: "model_stem", GroupFrom: "first_path_segment"},
|
||||||
Manifest: project.AutogenManifestConfig{ReleaseTag: "head-vfx-manifest-current", AssetName: "sow-head-vfx-manifest.json", CacheName: "sow-head-vfx-manifest.json"},
|
Manifest: project.AutogenManifestConfig{ReleaseTag: "head-vfx-manifest-current", AssetName: "sow-head-vfx-manifest.json", CacheName: "sow-head-vfx-manifest.json"},
|
||||||
LocalOverrideRoot: "autogen-assets",
|
LocalOverrideRoot: "autogen-assets",
|
||||||
@@ -7374,37 +7374,37 @@ func TestApplyAutogenConsumersAugmentsHeadVisualeffectsFromLocalOverride(t *test
|
|||||||
rowByKey[row["key"].(string)] = row
|
rowByKey[row["key"].(string)] = row
|
||||||
}
|
}
|
||||||
|
|
||||||
bandana := rowByKey["visualeffects:headaccessory_bandana"]
|
bandana := rowByKey["visualeffects:headaccessory/hat/bandana"]
|
||||||
if bandana == nil {
|
if bandana == nil {
|
||||||
t.Fatalf("expected head accessory row, got %#v", got[0].Rows)
|
t.Fatalf("expected head accessory row, got %#v", got[0].Rows)
|
||||||
}
|
}
|
||||||
if bandana["Label"] != "headaccessory_BANDANA" || bandana["Imp_HeadCon_Node"] != "hfx_bandana" || bandana["OrientWithObject"] != "1" {
|
if bandana["Label"] != "headaccessory/hat/bandana" || bandana["Imp_HeadCon_Node"] != "hfx_bandana" || bandana["OrientWithObject"] != "1" {
|
||||||
t.Fatalf("unexpected head accessory defaults: %#v", bandana)
|
t.Fatalf("unexpected head accessory defaults: %#v", bandana)
|
||||||
}
|
}
|
||||||
|
|
||||||
laurel := rowByKey["visualeffects:headdecoration_laurel"]
|
laurel := rowByKey["visualeffects:headdecoration/laurel/laurel"]
|
||||||
if laurel == nil {
|
if laurel == nil {
|
||||||
t.Fatalf("expected head decoration row, got %#v", got[0].Rows)
|
t.Fatalf("expected head decoration row, got %#v", got[0].Rows)
|
||||||
}
|
}
|
||||||
if laurel["Label"] != "headdecoration_LAUREL" || laurel["Imp_HeadCon_Node"] != "hfx_laurel" || laurel["Type_FD"] != "D" {
|
if laurel["Label"] != "headdecoration/laurel/laurel" || laurel["Imp_HeadCon_Node"] != "hfx_laurel" || laurel["Type_FD"] != "D" {
|
||||||
t.Fatalf("unexpected head decoration defaults: %#v", laurel)
|
t.Fatalf("unexpected head decoration defaults: %#v", laurel)
|
||||||
}
|
}
|
||||||
|
|
||||||
hair := rowByKey["visualeffects:headfeature_hair_bangs"]
|
hair := rowByKey["visualeffects:headfeature/hair/hair_bangs"]
|
||||||
if hair == nil {
|
if hair == nil {
|
||||||
t.Fatalf("expected head feature row, got %#v", got[0].Rows)
|
t.Fatalf("expected head feature row, got %#v", got[0].Rows)
|
||||||
}
|
}
|
||||||
if hair["Label"] != "headfeature_HAIR_BANGS" || hair["Imp_HeadCon_Node"] != "hfx_hair_bangs" || hair["Type_FD"] != "D" {
|
if hair["Label"] != "headfeature/hair/hair_bangs" || hair["Imp_HeadCon_Node"] != "hfx_hair_bangs" || hair["Type_FD"] != "D" {
|
||||||
t.Fatalf("unexpected head feature defaults: %#v", hair)
|
t.Fatalf("unexpected head feature defaults: %#v", hair)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := got[0].LockData["visualeffects:headaccessory_bandana"]; !ok {
|
if _, ok := got[0].LockData["visualeffects:headaccessory/hat/bandana"]; !ok {
|
||||||
t.Fatalf("expected head accessory lock id, got %#v", got[0].LockData)
|
t.Fatalf("expected head accessory lock id, got %#v", got[0].LockData)
|
||||||
}
|
}
|
||||||
if _, ok := got[0].LockData["visualeffects:headdecoration_laurel"]; !ok {
|
if _, ok := got[0].LockData["visualeffects:headdecoration/laurel/laurel"]; !ok {
|
||||||
t.Fatalf("expected head decoration lock id, got %#v", got[0].LockData)
|
t.Fatalf("expected head decoration lock id, got %#v", got[0].LockData)
|
||||||
}
|
}
|
||||||
if _, ok := got[0].LockData["visualeffects:headfeature_hair_bangs"]; !ok {
|
if _, ok := got[0].LockData["visualeffects:headfeature/hair/hair_bangs"]; !ok {
|
||||||
t.Fatalf("expected head feature lock id, got %#v", got[0].LockData)
|
t.Fatalf("expected head feature lock id, got %#v", got[0].LockData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7440,7 +7440,6 @@ func TestApplyAutogenConsumersUsesFolderDrivenSlashHeadVisualeffectsNames(t *tes
|
|||||||
StripModelPrefixes: []string{"hfx_"},
|
StripModelPrefixes: []string{"hfx_"},
|
||||||
KeyFormat: "{dataset}:{group}{delimiter}{category_segment}{stem}",
|
KeyFormat: "{dataset}:{group}{delimiter}{category_segment}{stem}",
|
||||||
LabelFormat: "{group}{delimiter}{category_segment}{stem}",
|
LabelFormat: "{group}{delimiter}{category_segment}{stem}",
|
||||||
LegacyKeyFormat: "{dataset}:{group}_{stem}",
|
|
||||||
RowDefaults: map[string]string{
|
RowDefaults: map[string]string{
|
||||||
"Type_FD": "D",
|
"Type_FD": "D",
|
||||||
"OrientWithGround": "0",
|
"OrientWithGround": "0",
|
||||||
@@ -7456,7 +7455,7 @@ func TestApplyAutogenConsumersUsesFolderDrivenSlashHeadVisualeffectsNames(t *tes
|
|||||||
Columns: []string{"Label", "Type_FD", "OrientWithGround", "Imp_HeadCon_Node", "Imp_Root_H_Node", "OrientWithObject"},
|
Columns: []string{"Label", "Type_FD", "OrientWithGround", "Imp_HeadCon_Node", "Imp_Root_H_Node", "OrientWithObject"},
|
||||||
Rows: nil,
|
Rows: nil,
|
||||||
LockData: map[string]int{
|
LockData: map[string]int{
|
||||||
"visualeffects:headfeature_Ear_EL_L": 11030,
|
"visualeffects:headfeature/ears_plt/Ear_EL_L": 11030,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -7473,7 +7472,7 @@ func TestApplyAutogenConsumersUsesFolderDrivenSlashHeadVisualeffectsNames(t *tes
|
|||||||
t.Fatalf("expected folder-driven key, got %#v", row)
|
t.Fatalf("expected folder-driven key, got %#v", row)
|
||||||
}
|
}
|
||||||
if row["id"] != 11030 {
|
if row["id"] != 11030 {
|
||||||
t.Fatalf("expected legacy lock id to be preserved, got %#v", row)
|
t.Fatalf("expected existing lock id to be preserved, got %#v", row)
|
||||||
}
|
}
|
||||||
if row["Label"] != "headfeature/ears_plt/Ear_EL_L" {
|
if row["Label"] != "headfeature/ears_plt/Ear_EL_L" {
|
||||||
t.Fatalf("expected preserve-case slash label, got %#v", row)
|
t.Fatalf("expected preserve-case slash label, got %#v", row)
|
||||||
@@ -7483,70 +7482,6 @@ func TestApplyAutogenConsumersUsesFolderDrivenSlashHeadVisualeffectsNames(t *tes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHeadVisualeffectsConsumerMapsLegacyManifestGroupsToFolderDrivenNames(t *testing.T) {
|
|
||||||
collected := []nativeCollectedDataset{
|
|
||||||
{
|
|
||||||
Dataset: nativeDataset{Name: "visualeffects", Kind: nativeDatasetBase},
|
|
||||||
Columns: []string{"Label", "Type_FD", "OrientWithGround", "Imp_HeadCon_Node", "Imp_Root_H_Node", "OrientWithObject"},
|
|
||||||
Rows: nil,
|
|
||||||
LockData: map[string]int{
|
|
||||||
"visualeffects:headfeature_ear_el_l": 11030,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
entries := []autogenManifestEntry{
|
|
||||||
{
|
|
||||||
Group: "head_features",
|
|
||||||
Source: "head_features/sinfar/ears_plt/hfx_ear_el_l.mdl",
|
|
||||||
ModelStem: "hfx_ear_el_l",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
consumer := project.AutogenConsumerConfig{
|
|
||||||
Dataset: "visualeffects",
|
|
||||||
HeadVisualeffects: project.HeadVisualeffectsConfig{
|
|
||||||
Groups: map[string]project.HeadVisualeffectGroupConfig{
|
|
||||||
"headfeature": {
|
|
||||||
ModelColumns: []string{"Imp_HeadCon_Node", "Imp_Root_H_Node"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
GroupTokenSource: "folder_name",
|
|
||||||
CategoryFrom: "immediate_parent",
|
|
||||||
Delimiter: "/",
|
|
||||||
Case: "preserve",
|
|
||||||
StripModelPrefixes: []string{
|
|
||||||
"hfx_",
|
|
||||||
},
|
|
||||||
KeyFormat: "{dataset}:{group}{delimiter}{category_segment}{stem}",
|
|
||||||
LabelFormat: "{group}{delimiter}{category_segment}{stem}",
|
|
||||||
LegacyGroups: map[string]string{"head_features": "headfeature"},
|
|
||||||
LegacyKeyFormat: "{dataset}:{group}_{stem}",
|
|
||||||
RowDefaults: map[string]string{
|
|
||||||
"Type_FD": "D",
|
|
||||||
"OrientWithGround": "0",
|
|
||||||
"OrientWithObject": "1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := augmentWithAutogeneratedHeadVisualeffects(collected, entries, consumer, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("augmentWithAutogeneratedHeadVisualeffects failed: %v", err)
|
|
||||||
}
|
|
||||||
if len(got) != 1 || len(got[0].Rows) != 1 {
|
|
||||||
t.Fatalf("expected one autogenerated row, got %#v", got)
|
|
||||||
}
|
|
||||||
row := got[0].Rows[0]
|
|
||||||
if row["key"] != "visualeffects:headfeature/ears_plt/ear_el_l" || row["id"] != 11030 {
|
|
||||||
t.Fatalf("expected migrated slash key with preserved ID, got %#v", row)
|
|
||||||
}
|
|
||||||
if _, exists := got[0].LockData["visualeffects:headfeature/ears_plt/ear_el_l"]; !exists {
|
|
||||||
t.Fatalf("expected new slash key in lock data, got %#v", got[0].LockData)
|
|
||||||
}
|
|
||||||
if _, exists := got[0].LockData["visualeffects:headfeature_ear_el_l"]; exists {
|
|
||||||
t.Fatalf("expected legacy key to be removed from active lock data, got %#v", got[0].LockData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuildNativeUsesConfiguredHeadVisualeffectsGroups(t *testing.T) {
|
func TestBuildNativeUsesConfiguredHeadVisualeffectsGroups(t *testing.T) {
|
||||||
root := t.TempDir()
|
root := t.TempDir()
|
||||||
mkdirAll(t, filepath.Join(root, "src"))
|
mkdirAll(t, filepath.Join(root, "src"))
|
||||||
@@ -12873,18 +12808,20 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
|||||||
"generated_at": "2026-04-25T00:00:00Z",
|
"generated_at": "2026-04-25T00:00:00Z",
|
||||||
"head_visualeffects": {
|
"head_visualeffects": {
|
||||||
"groups": {
|
"groups": {
|
||||||
"head_accessories": {
|
"headaccessory": {
|
||||||
"prefix": "headaccessory",
|
|
||||||
"model_columns": ["Imp_HeadCon_Node", "Imp_Root_H_Node"]
|
"model_columns": ["Imp_HeadCon_Node", "Imp_Root_H_Node"]
|
||||||
},
|
},
|
||||||
"head_features": {
|
"headfeature": {
|
||||||
"prefix": "headfeature",
|
|
||||||
"model_columns": ["Imp_HeadCon_Node", "Imp_Root_H_Node"]
|
"model_columns": ["Imp_HeadCon_Node", "Imp_Root_H_Node"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"group_token_source": "folder_name",
|
||||||
|
"category_from": "immediate_parent",
|
||||||
|
"delimiter": "/",
|
||||||
|
"case": "preserve",
|
||||||
"strip_model_prefixes": ["hfx_"],
|
"strip_model_prefixes": ["hfx_"],
|
||||||
"key_format": "{dataset}:{prefix}_{stem}",
|
"key_format": "{dataset}:{group}{delimiter}{category_segment}{stem}",
|
||||||
"label_format": "{prefix}_{stem_upper}",
|
"label_format": "{group}{delimiter}{category_segment}{stem}",
|
||||||
"row_defaults": {
|
"row_defaults": {
|
||||||
"Type_FD": "D",
|
"Type_FD": "D",
|
||||||
"OrientWithGround": "0",
|
"OrientWithGround": "0",
|
||||||
@@ -12893,14 +12830,14 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"group": "head_accessories",
|
"group": "headaccessory",
|
||||||
"model_stem": "hfx_bandana",
|
"model_stem": "hfx_bandana",
|
||||||
"source": "head_accessories/hfx_bandana.mdl"
|
"source": "headaccessory/hfx_bandana.mdl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "head_features",
|
"group": "headfeature",
|
||||||
"model_stem": "hfx_hair_bangs",
|
"model_stem": "hfx_hair_bangs",
|
||||||
"source": "head_features/hair/hfx_hair_bangs.mdl"
|
"source": "headfeature/hair/hfx_hair_bangs.mdl"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}` + "\n"
|
}` + "\n"
|
||||||
@@ -12940,7 +12877,7 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
|||||||
Dataset: "visualeffects",
|
Dataset: "visualeffects",
|
||||||
Mode: "head_visualeffects",
|
Mode: "head_visualeffects",
|
||||||
Root: "vfxs",
|
Root: "vfxs",
|
||||||
Include: []string{"head_accessories/**/*.mdl", "head_features/**/*.mdl"},
|
Include: []string{"headaccessory/**/*.mdl", "headfeature/**/*.mdl"},
|
||||||
Derive: project.AutogenDeriveConfig{
|
Derive: project.AutogenDeriveConfig{
|
||||||
Kind: "model_stem",
|
Kind: "model_stem",
|
||||||
GroupFrom: "first_path_segment",
|
GroupFrom: "first_path_segment",
|
||||||
@@ -12967,8 +12904,8 @@ func TestBuildNativeWithReleasedHeadVisualeffectsManifest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
text := string(visualeffectsBytes)
|
text := string(visualeffectsBytes)
|
||||||
for _, want := range []string{
|
for _, want := range []string{
|
||||||
"0\theadaccessory_BANDANA\tD\t0\thfx_bandana\thfx_bandana\t1",
|
"0\theadaccessory/bandana\tD\t0\thfx_bandana\thfx_bandana\t1",
|
||||||
"1\theadfeature_HAIR_BANGS\tD\t0\thfx_hair_bangs\thfx_hair_bangs\t1",
|
"1\theadfeature/hair/hair_bangs\tD\t0\thfx_hair_bangs\thfx_hair_bangs\t1",
|
||||||
"17\tEXISTING\tF\t0\t****\t****\t0",
|
"17\tEXISTING\tF\t0\t****\t****\t0",
|
||||||
} {
|
} {
|
||||||
if !strings.Contains(text, want) {
|
if !strings.Contains(text, want) {
|
||||||
@@ -12995,7 +12932,7 @@ func TestBuildNativePrefersRemoteReleasedHeadVisualeffectsManifestOverFreshCache
|
|||||||
}`+"\n")
|
}`+"\n")
|
||||||
writeFile(t, filepath.Join(projRoot, "topdata", "data", "visualeffects", "lock.json"), `{
|
writeFile(t, filepath.Join(projRoot, "topdata", "data", "visualeffects", "lock.json"), `{
|
||||||
"visualeffects:existing": 17,
|
"visualeffects:existing": 17,
|
||||||
"visualeffects:headaccessory_bandana": 42
|
"visualeffects:headaccessory/bandana": 42
|
||||||
}`+"\n")
|
}`+"\n")
|
||||||
mkdirAll(t, filepath.Join(projRoot, "reference"))
|
mkdirAll(t, filepath.Join(projRoot, "reference"))
|
||||||
writeFile(t, filepath.Join(projRoot, "reference", "build.py"), "print('ok')\n")
|
writeFile(t, filepath.Join(projRoot, "reference", "build.py"), "print('ok')\n")
|
||||||
@@ -13006,9 +12943,9 @@ func TestBuildNativePrefersRemoteReleasedHeadVisualeffectsManifestOverFreshCache
|
|||||||
"generated_at": "2026-04-25T00:00:00Z",
|
"generated_at": "2026-04-25T00:00:00Z",
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"group": "head_features",
|
"group": "headfeature",
|
||||||
"model_stem": "hfx_hair_bangs",
|
"model_stem": "hfx_hair_bangs",
|
||||||
"source": "head_features/hair/hfx_hair_bangs.mdl"
|
"source": "headfeature/hair/hfx_hair_bangs.mdl"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}`+"\n")
|
}`+"\n")
|
||||||
@@ -13022,9 +12959,9 @@ func TestBuildNativePrefersRemoteReleasedHeadVisualeffectsManifestOverFreshCache
|
|||||||
"generated_at": "2026-04-25T12:00:00Z",
|
"generated_at": "2026-04-25T12:00:00Z",
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"group": "head_accessories",
|
"group": "headaccessory",
|
||||||
"model_stem": "hfx_bandana",
|
"model_stem": "hfx_bandana",
|
||||||
"source": "head_accessories/hfx_bandana.mdl"
|
"source": "headaccessory/hfx_bandana.mdl"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}` + "\n"
|
}` + "\n"
|
||||||
@@ -13064,7 +13001,7 @@ func TestBuildNativePrefersRemoteReleasedHeadVisualeffectsManifestOverFreshCache
|
|||||||
Dataset: "visualeffects",
|
Dataset: "visualeffects",
|
||||||
Mode: "head_visualeffects",
|
Mode: "head_visualeffects",
|
||||||
Root: "vfxs",
|
Root: "vfxs",
|
||||||
Include: []string{"head_accessories/**/*.mdl", "head_features/**/*.mdl"},
|
Include: []string{"headaccessory/**/*.mdl", "headfeature/**/*.mdl"},
|
||||||
Derive: project.AutogenDeriveConfig{
|
Derive: project.AutogenDeriveConfig{
|
||||||
Kind: "model_stem",
|
Kind: "model_stem",
|
||||||
GroupFrom: "first_path_segment",
|
GroupFrom: "first_path_segment",
|
||||||
@@ -13090,7 +13027,7 @@ func TestBuildNativePrefersRemoteReleasedHeadVisualeffectsManifestOverFreshCache
|
|||||||
t.Fatalf("read visualeffects.2da: %v", err)
|
t.Fatalf("read visualeffects.2da: %v", err)
|
||||||
}
|
}
|
||||||
text := string(visualeffectsBytes)
|
text := string(visualeffectsBytes)
|
||||||
if !strings.Contains(text, "42\theadaccessory_BANDANA\tD\t0\thfx_bandana\t1") {
|
if !strings.Contains(text, "42\theadaccessory/bandana\tD\t0\thfx_bandana\t1") {
|
||||||
t.Fatalf("expected remote manifest entry with preserved lock id, got:\n%s", text)
|
t.Fatalf("expected remote manifest entry with preserved lock id, got:\n%s", text)
|
||||||
}
|
}
|
||||||
if strings.Contains(text, "HAIR_BANGS") {
|
if strings.Contains(text, "HAIR_BANGS") {
|
||||||
@@ -13115,7 +13052,7 @@ func TestBuildPackageInvalidatesFreshAutogenCacheWhenReleaseAssetIsNewer(t *test
|
|||||||
setCompiledOutputTimes(t, result, outputTime)
|
setCompiledOutputTimes(t, result, outputTime)
|
||||||
|
|
||||||
cachePath := filepath.Join(root, ".cache", "sow-head-vfx-manifest.json")
|
cachePath := filepath.Join(root, ".cache", "sow-head-vfx-manifest.json")
|
||||||
writeFile(t, cachePath, `{"id":"head_visualeffects","generated_at":"2026-04-25T10:00:00Z","entries":[{"group":"head_accessories","model_stem":"hfx_bandana","source":"head_accessories/hfx_bandana.mdl"}]}`+"\n")
|
writeFile(t, cachePath, `{"id":"head_visualeffects","generated_at":"2026-04-25T10:00:00Z","entries":[{"group":"headaccessory","model_stem":"hfx_bandana","source":"headaccessory/hfx_bandana.mdl"}]}`+"\n")
|
||||||
setFileTime(t, cachePath, time.Now())
|
setFileTime(t, cachePath, time.Now())
|
||||||
|
|
||||||
var server *httptest.Server
|
var server *httptest.Server
|
||||||
@@ -13126,7 +13063,7 @@ func TestBuildPackageInvalidatesFreshAutogenCacheWhenReleaseAssetIsNewer(t *test
|
|||||||
_, _ = w.Write([]byte(`{"assets":[{"name":"sow-head-vfx-manifest.json","updated_at":"3026-04-25T12:00:00Z","browser_download_url":"` + server.URL + `/downloads/sow-head-vfx-manifest.json"}]}`))
|
_, _ = w.Write([]byte(`{"assets":[{"name":"sow-head-vfx-manifest.json","updated_at":"3026-04-25T12:00:00Z","browser_download_url":"` + server.URL + `/downloads/sow-head-vfx-manifest.json"}]}`))
|
||||||
case "/downloads/sow-head-vfx-manifest.json":
|
case "/downloads/sow-head-vfx-manifest.json":
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
_, _ = w.Write([]byte(`{"id":"head_visualeffects","entries":[{"group":"head_accessories","model_stem":"hfx_bandana","source":"head_accessories/hfx_bandana.mdl"}]}`))
|
_, _ = w.Write([]byte(`{"id":"head_visualeffects","entries":[{"group":"headaccessory","model_stem":"hfx_bandana","source":"headaccessory/hfx_bandana.mdl"}]}`))
|
||||||
default:
|
default:
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
}
|
}
|
||||||
@@ -13144,7 +13081,7 @@ func TestBuildPackageInvalidatesFreshAutogenCacheWhenReleaseAssetIsNewer(t *test
|
|||||||
Mode: "head_visualeffects",
|
Mode: "head_visualeffects",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Root: "vfxs",
|
Root: "vfxs",
|
||||||
Include: []string{"head_accessories/**/*.mdl", "head_features/**/*.mdl"},
|
Include: []string{"headaccessory/**/*.mdl", "headfeature/**/*.mdl"},
|
||||||
Derive: project.AutogenDeriveConfig{
|
Derive: project.AutogenDeriveConfig{
|
||||||
Kind: "model_stem",
|
Kind: "model_stem",
|
||||||
GroupFrom: "first_path_segment",
|
GroupFrom: "first_path_segment",
|
||||||
@@ -13469,7 +13406,7 @@ func TestBuildPackageFailsWhenAutogenManifestCacheIsStale(t *testing.T) {
|
|||||||
Mode: "head_visualeffects",
|
Mode: "head_visualeffects",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Root: "vfxs",
|
Root: "vfxs",
|
||||||
Include: []string{"head_accessories/**/*.mdl", "head_features/**/*.mdl"},
|
Include: []string{"headaccessory/**/*.mdl", "headfeature/**/*.mdl"},
|
||||||
Derive: project.AutogenDeriveConfig{
|
Derive: project.AutogenDeriveConfig{
|
||||||
Kind: "model_stem",
|
Kind: "model_stem",
|
||||||
GroupFrom: "first_path_segment",
|
GroupFrom: "first_path_segment",
|
||||||
@@ -13482,7 +13419,7 @@ func TestBuildPackageFailsWhenAutogenManifestCacheIsStale(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
cachePath := filepath.Join(root, ".cache", "sow-head-vfx-manifest.json")
|
cachePath := filepath.Join(root, ".cache", "sow-head-vfx-manifest.json")
|
||||||
writeFile(t, cachePath, `{"id":"head_visualeffects","entries":[{"group":"head_accessories","model_stem":"hfx_bandana","source":"head_accessories/hfx_bandana.mdl"}]}`+"\n")
|
writeFile(t, cachePath, `{"id":"head_visualeffects","entries":[{"group":"headaccessory","model_stem":"hfx_bandana","source":"headaccessory/hfx_bandana.mdl"}]}`+"\n")
|
||||||
setFileTime(t, cachePath, time.Now().Add(-2*autogenManifestCacheMaxAge))
|
setFileTime(t, cachePath, time.Now().Add(-2*autogenManifestCacheMaxAge))
|
||||||
|
|
||||||
if _, err := BuildPackage(proj, nil); err == nil || !strings.Contains(err.Error(), "older than source file") {
|
if _, err := BuildPackage(proj, nil); err == nil || !strings.Contains(err.Error(), "older than source file") {
|
||||||
@@ -14417,7 +14354,7 @@ func testProject(root string) *project.Project {
|
|||||||
Mode: "head_visualeffects",
|
Mode: "head_visualeffects",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Root: "vfxs",
|
Root: "vfxs",
|
||||||
Include: []string{"head_accessories/**/*.mdl", "head_features/**/*.mdl"},
|
Include: []string{"headaccessory/**/*.mdl", "headfeature/**/*.mdl"},
|
||||||
Derive: project.AutogenDeriveConfig{
|
Derive: project.AutogenDeriveConfig{
|
||||||
Kind: "model_stem",
|
Kind: "model_stem",
|
||||||
GroupFrom: "first_path_segment",
|
GroupFrom: "first_path_segment",
|
||||||
|
|||||||
Reference in New Issue
Block a user