mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-01-18 16:47:42 +01:00
takes over the "Order" validation of scripts/ini, and also re-orders the "Sections" section according to "Order". Used instead of copying config-base.yaml into the executable's data.
122 lines
2.7 KiB
Go
122 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/goccy/go-yaml"
|
|
"github.com/hrfee/jfa-go/common"
|
|
)
|
|
|
|
func flattenOrder(c common.Config) (sections []string) {
|
|
var traverseGroup func(groupName string) []string
|
|
traverseGroup = func(groupName string) []string {
|
|
out := []string{}
|
|
for _, group := range c.Groups {
|
|
if group.Group == groupName {
|
|
for _, groupMember := range group.Members {
|
|
if groupMember.Group != "" {
|
|
out = append(out, traverseGroup(groupMember.Group)...)
|
|
} else if groupMember.Section != "" {
|
|
out = append(out, groupMember.Section)
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
sections = make([]string, 0, len(c.Sections))
|
|
for _, member := range c.Order {
|
|
if member.Group != "" {
|
|
sections = append(sections, traverseGroup(member.Group)...)
|
|
} else if member.Section != "" {
|
|
sections = append(sections, member.Section)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func validateOrderCompleteness(c common.Config, sectOrder []string) (missing []string) {
|
|
listedSects := map[string]bool{}
|
|
for _, sect := range sectOrder {
|
|
listedSects[sect] = true
|
|
}
|
|
|
|
for _, section := range c.Sections {
|
|
if _, ok := listedSects[section.Section]; !ok {
|
|
missing = append(missing, section.Section)
|
|
}
|
|
}
|
|
return missing
|
|
}
|
|
|
|
func main() {
|
|
var inPath string
|
|
var outPath string
|
|
flag.StringVar(&inPath, "in", "", "Input of the config base in yaml.")
|
|
flag.StringVar(&outPath, "out", "", "Output of the checked and processed")
|
|
|
|
flag.Parse()
|
|
|
|
if inPath == "" {
|
|
panic(errors.New("invalid input path"))
|
|
}
|
|
if outPath == "" {
|
|
panic(errors.New("invalid output path"))
|
|
}
|
|
|
|
yamlFile, err := os.ReadFile(inPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
info, err := os.Stat(inPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
configBase := common.Config{}
|
|
err = yaml.Unmarshal(yamlFile, &configBase)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
red := color.New(color.FgRed)
|
|
|
|
if len(configBase.Order) > 0 {
|
|
sectOrder := flattenOrder(configBase)
|
|
missing := validateOrderCompleteness(configBase, sectOrder)
|
|
if len(missing) > 0 {
|
|
red.Fprintln(os.Stderr, "ERROR: Root order specified but the following sections were not listed, directly or indirectly:")
|
|
for _, section := range missing {
|
|
red.Fprintln(os.Stderr, "\t"+section)
|
|
}
|
|
os.Exit(1)
|
|
}
|
|
|
|
sectionMap := map[string]common.Section{}
|
|
for _, sect := range configBase.Sections {
|
|
sectionMap[sect.Section] = sect
|
|
}
|
|
|
|
for i, sect := range sectOrder {
|
|
configBase.Sections[i] = sectionMap[sect]
|
|
}
|
|
|
|
fmt.Println("Re-ordered sections to follow root order.")
|
|
}
|
|
|
|
bytes, err := yaml.Marshal(&configBase)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = os.WriteFile(outPath, bytes, info.Mode())
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|