Head Accessories AutoGen Configuration
This commit is contained in:
@@ -34,6 +34,7 @@ type Config struct {
|
||||
HAKs []HAKConfig `json:"haks"`
|
||||
TopData TopDataConfig `json:"topdata"`
|
||||
Extract ExtractConfig `json:"extract"`
|
||||
Autogen AutogenConfig `json:"autogen"`
|
||||
}
|
||||
|
||||
type ModuleConfig struct {
|
||||
@@ -72,6 +73,43 @@ type ExtractConfig struct {
|
||||
DeleteModuleArchiveAfterSuccess bool `json:"delete_module_archive_after_success,omitempty"`
|
||||
}
|
||||
|
||||
type AutogenConfig struct {
|
||||
Producers []AutogenProducerConfig `json:"producers"`
|
||||
Consumers []AutogenConsumerConfig `json:"consumers"`
|
||||
}
|
||||
|
||||
type AutogenProducerConfig struct {
|
||||
ID string `json:"id"`
|
||||
Root string `json:"root"`
|
||||
Include []string `json:"include"`
|
||||
Derive AutogenDeriveConfig `json:"derive"`
|
||||
Manifest AutogenManifestConfig `json:"manifest"`
|
||||
}
|
||||
|
||||
type AutogenConsumerConfig struct {
|
||||
ID string `json:"id"`
|
||||
Producer string `json:"producer"`
|
||||
Dataset string `json:"dataset"`
|
||||
Mode string `json:"mode"`
|
||||
Optional bool `json:"optional,omitempty"`
|
||||
Root string `json:"root"`
|
||||
Include []string `json:"include"`
|
||||
Derive AutogenDeriveConfig `json:"derive"`
|
||||
Manifest AutogenManifestConfig `json:"manifest"`
|
||||
LocalOverrideRoot string `json:"local_override_root,omitempty"`
|
||||
}
|
||||
|
||||
type AutogenDeriveConfig struct {
|
||||
Kind string `json:"kind"`
|
||||
GroupFrom string `json:"group_from,omitempty"`
|
||||
}
|
||||
|
||||
type AutogenManifestConfig struct {
|
||||
ReleaseTag string `json:"release_tag"`
|
||||
AssetName string `json:"asset_name"`
|
||||
CacheName string `json:"cache_name"`
|
||||
}
|
||||
|
||||
type Inventory struct {
|
||||
SourceFiles []string
|
||||
ScriptFiles []string
|
||||
@@ -141,6 +179,7 @@ func (p *Project) ValidateLayout() error {
|
||||
failures = append(failures, err)
|
||||
}
|
||||
}
|
||||
failures = append(failures, validateAutogenConfig(p.Config.Autogen)...)
|
||||
|
||||
for index, hak := range p.Config.HAKs {
|
||||
if strings.TrimSpace(hak.Name) == "" {
|
||||
@@ -447,6 +486,100 @@ func defaultConfig() Config {
|
||||
}
|
||||
}
|
||||
|
||||
func validateAutogenConfig(cfg AutogenConfig) []error {
|
||||
var failures []error
|
||||
producerIDs := map[string]struct{}{}
|
||||
consumerIDs := map[string]struct{}{}
|
||||
|
||||
for index, producer := range cfg.Producers {
|
||||
fieldPrefix := fmt.Sprintf("autogen.producers[%d]", index)
|
||||
id := strings.TrimSpace(producer.ID)
|
||||
if id == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.id is required", fieldPrefix))
|
||||
} else {
|
||||
if _, exists := producerIDs[id]; exists {
|
||||
failures = append(failures, fmt.Errorf("%s.id %q is duplicated", fieldPrefix, id))
|
||||
}
|
||||
producerIDs[id] = struct{}{}
|
||||
}
|
||||
if strings.TrimSpace(producer.Root) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.root is required", fieldPrefix))
|
||||
}
|
||||
if len(producer.Include) == 0 {
|
||||
failures = append(failures, fmt.Errorf("%s.include must contain at least one glob", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateAutogenDeriveConfig(fieldPrefix+".derive", producer.Derive)...)
|
||||
failures = append(failures, validateAutogenManifestConfig(fieldPrefix+".manifest", producer.Manifest)...)
|
||||
}
|
||||
|
||||
for index, consumer := range cfg.Consumers {
|
||||
fieldPrefix := fmt.Sprintf("autogen.consumers[%d]", index)
|
||||
id := strings.TrimSpace(consumer.ID)
|
||||
if id == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.id is required", fieldPrefix))
|
||||
} else {
|
||||
if _, exists := consumerIDs[id]; exists {
|
||||
failures = append(failures, fmt.Errorf("%s.id %q is duplicated", fieldPrefix, id))
|
||||
}
|
||||
consumerIDs[id] = struct{}{}
|
||||
}
|
||||
if strings.TrimSpace(consumer.Producer) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.producer is required", fieldPrefix))
|
||||
}
|
||||
if strings.TrimSpace(consumer.Dataset) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.dataset is required", fieldPrefix))
|
||||
}
|
||||
switch strings.TrimSpace(consumer.Mode) {
|
||||
case "parts_rows", "head_visualeffects":
|
||||
case "":
|
||||
failures = append(failures, fmt.Errorf("%s.mode is required", fieldPrefix))
|
||||
default:
|
||||
failures = append(failures, fmt.Errorf("%s.mode %q is not supported", fieldPrefix, consumer.Mode))
|
||||
}
|
||||
if strings.TrimSpace(consumer.Root) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.root is required", fieldPrefix))
|
||||
}
|
||||
if len(consumer.Include) == 0 {
|
||||
failures = append(failures, fmt.Errorf("%s.include must contain at least one glob", fieldPrefix))
|
||||
}
|
||||
failures = append(failures, validateAutogenDeriveConfig(fieldPrefix+".derive", consumer.Derive)...)
|
||||
failures = append(failures, validateAutogenManifestConfig(fieldPrefix+".manifest", consumer.Manifest)...)
|
||||
}
|
||||
|
||||
return failures
|
||||
}
|
||||
|
||||
func validateAutogenDeriveConfig(fieldPrefix string, cfg AutogenDeriveConfig) []error {
|
||||
var failures []error
|
||||
switch strings.TrimSpace(cfg.Kind) {
|
||||
case "trailing_numeric_suffix", "model_stem":
|
||||
case "":
|
||||
failures = append(failures, fmt.Errorf("%s.kind is required", fieldPrefix))
|
||||
default:
|
||||
failures = append(failures, fmt.Errorf("%s.kind %q is not supported", fieldPrefix, cfg.Kind))
|
||||
}
|
||||
switch strings.TrimSpace(cfg.GroupFrom) {
|
||||
case "", "first_path_segment":
|
||||
default:
|
||||
failures = append(failures, fmt.Errorf("%s.group_from %q is not supported", fieldPrefix, cfg.GroupFrom))
|
||||
}
|
||||
return failures
|
||||
}
|
||||
|
||||
func validateAutogenManifestConfig(fieldPrefix string, cfg AutogenManifestConfig) []error {
|
||||
var failures []error
|
||||
if strings.TrimSpace(cfg.ReleaseTag) == "" {
|
||||
failures = append(failures, fmt.Errorf("%s.release_tag is required", fieldPrefix))
|
||||
}
|
||||
if err := validateOutputFileName(fieldPrefix+".asset_name", cfg.AssetName, ".json"); err != nil {
|
||||
failures = append(failures, err)
|
||||
}
|
||||
if err := validateOutputFileName(fieldPrefix+".cache_name", cfg.CacheName, ".json"); err != nil {
|
||||
failures = append(failures, err)
|
||||
}
|
||||
return failures
|
||||
}
|
||||
|
||||
func scanDir(root string, include func(path string) bool) ([]string, []string, error) {
|
||||
var files []string
|
||||
extSet := map[string]struct{}{}
|
||||
|
||||
@@ -196,6 +196,52 @@ func TestValidateLayoutRejectsInvalidTopDataPackageOutputNames(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLayoutRejectsInvalidAutogenConsumerConfig(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: "unsupported",
|
||||
Root: "vfxs",
|
||||
Include: []string{"head_accessories/**/*.mdl"},
|
||||
Derive: AutogenDeriveConfig{Kind: "model_stem", GroupFrom: "first_path_segment"},
|
||||
Manifest: AutogenManifestConfig{
|
||||
ReleaseTag: "head-vfx-manifest-current",
|
||||
AssetName: "nested/sow-head-vfx-manifest.json",
|
||||
CacheName: "sow-head-vfx-manifest.txt",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := proj.ValidateLayout()
|
||||
if err == nil {
|
||||
t.Fatal("expected autogen validation error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "autogen.consumers[0].mode") {
|
||||
t.Fatalf("expected autogen mode validation error, got %v", err)
|
||||
}
|
||||
if !strings.Contains(err.Error(), "autogen.consumers[0].manifest.asset_name") {
|
||||
t.Fatalf("expected autogen asset_name validation error, got %v", err)
|
||||
}
|
||||
if !strings.Contains(err.Error(), "autogen.consumers[0].manifest.cache_name") {
|
||||
t.Fatalf("expected autogen cache_name validation error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanAllowsMissingAssetsDir(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
mkdirAll(t, filepath.Join(root, "src"))
|
||||
|
||||
Reference in New Issue
Block a user