134 lines
2.5 KiB
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())
|
|
}
|