spry/main.go

134 lines
2.5 KiB
Go

package main
import (
"encoding/json"
"flag"
"fmt"
"html/template"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"strings"
sprig "github.com/Masterminds/sprig/v3"
)
type valFileSlice []string
func (v *valFileSlice) String() string {
return fmt.Sprintf("%v", *v)
}
func (v *valFileSlice) Set(value string) error {
*v = append(*v, value)
return nil
}
type valEnt struct {
address []string
v string
}
type valSlice []valEnt
func (v *valSlice) String() string {
return fmt.Sprintf("%v", *v)
}
func (v *valSlice) Set(value string) error {
pieces := strings.Split(value, "=")
if len(pieces) < 2 {
return fmt.Errorf("Invalid value setting.")
}
*v = append(*v, valEnt{
strings.Split(pieces[0], "."),
pieces[1],
})
return nil
}
var flags struct {
valuesFiles valFileSlice
values valSlice
}
func init() {
flag.Var(&flags.values, "set", "")
flag.Var(&flags.valuesFiles, "f", "")
flag.Parse()
}
func checkErr(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %+v", err)
os.Exit(1)
}
}
func expandFiles(files []string) (expFiles []string) {
expFiles = []string{}
for _, path := range files {
fileInfo, err := os.Stat(path)
checkErr(err)
if fileInfo.IsDir() {
filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: %+v", err)
return err
}
if d.IsDir() {
return nil
}
expFiles = append(expFiles, path)
return nil
})
} else {
expFiles = append(expFiles, path)
}
}
return
}
func mergeValues() (result map[string]interface{}) {
result = map[string]interface{}{}
for _, vf := range flags.valuesFiles {
vfContent, err := ioutil.ReadFile(vf)
checkErr(err)
err = json.Unmarshal(vfContent, result)
checkErr(err)
}
for i, v := range flags.values {
subMap := result
for _, node := range v.address {
if i == len(v.address)-1 {
subMap[node] = v.v
} else {
if _, ok := subMap[node]; !ok {
subMap[node] = map[string]interface{}{}
}
subMap = subMap[node].(map[string]interface{})
}
}
}
return
}
func main() {
var err error
tpl := template.New("base").Funcs(sprig.FuncMap())
if len(flag.Args()) == 0 || (len(flag.Args()) == 1 && flag.Args()[0] == "-") {
var data []byte
data, err = io.ReadAll(os.Stdin)
checkErr(err)
tpl, err = tpl.Parse(string(data))
checkErr(err)
} else {
tpl, err = tpl.ParseFiles(expandFiles(flag.Args())...)
checkErr(err)
}
tpl.Execute(os.Stdout, mergeValues())
}