Head Accessories AutoGen Configuration

This commit is contained in:
2026-04-25 07:40:17 +02:00
parent 831d3b47da
commit b6fff4bed4
6 changed files with 1010 additions and 10 deletions
+133
View File
@@ -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{}{}