deduplicate files and don't use values files as templates

This commit is contained in:
Diego Fernando Carrión 2023-10-13 14:01:12 +02:00
parent 5f76bca8a3
commit b0a3501b00
Signed by: CRThaze
GPG Key ID: 0F647F8A6A3AF588

72
main.go
View File

@ -18,6 +18,27 @@ import (
yaml "gopkg.in/yaml.v3"
)
type StrSet map[string]struct{}
func (s *StrSet) Add(str string) {
(*s)[str] = struct{}{}
}
func (s *StrSet) Has(str string) bool {
if _, ok := (*s)[str]; ok {
return true
}
return false
}
func (s *StrSet) AddHas(str string) bool {
if ok := s.Has(str); ok {
return ok
}
s.Add(str)
return false
}
type valFileSlice []string
func (v *valFileSlice) String() string {
@ -72,11 +93,39 @@ func checkErr(err error) {
func expandFiles(files []string) (expFiles []string) {
expFiles = []string{}
fileSet := StrSet{}
directories := []string{}
// Ensure we don't process any provided values files as templates.
for _, path := range flags.valuesFiles {
abs, err := filepath.Abs(path)
if err != nil {
fileSet.Add(path)
break
}
fileSet.Add(abs)
}
for _, path := range files {
fileInfo, err := os.Stat(path)
checkErr(err)
if fileInfo.IsDir() {
// When provided path is a directory, defer loading files from it.
directories = append(directories, path)
} else {
abs, err := filepath.Abs(path)
if err != nil {
// On failure to find the absolute path, just use the provided path.
abs = path
}
// Deduplicate files.
if ok := fileSet.AddHas(abs); !ok {
expFiles = append(expFiles, path)
}
}
// Walk each provided directory to find templates.
for _, path := range directories {
filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: %+v", err)
@ -85,11 +134,17 @@ func expandFiles(files []string) (expFiles []string) {
if d.IsDir() {
return nil
}
expFiles = append(expFiles, path)
abs, err := filepath.Abs(path)
if err != nil {
// On failure to find the absolute path, just use the provided path.
abs = path
}
// Deduplicate files.
if ok := fileSet.AddHas(abs); !ok {
expFiles = append(expFiles, path)
}
return nil
})
} else {
expFiles = append(expFiles, path)
}
}
return
@ -111,14 +166,12 @@ func mergeValues() (result map[string]interface{}) {
for _, v := range flags.values {
valueMap := map[string]interface{}{}
subMap := valueMap
// fmt.Fprintf(os.Stderr, "113: %+v\n", subMap)
for i, node := range v.address {
if i == len(v.address)-1 {
subMap[node] = v.v
break
}
subMap[node] = map[string]interface{}{}
// fmt.Fprintf(os.Stderr, "120: %+v\n", subMap)
subMap = subMap[node].(map[string]interface{})
}
mergemap.Merge(result, valueMap)
@ -129,7 +182,10 @@ func mergeValues() (result map[string]interface{}) {
func main() {
var err error
tpl := template.New("base").Funcs(sprig.FuncMap())
if len(flag.Args()) == 0 {
// With no provided arguments read from STDIN if anything is immediately available through it.
// otherwise print the usage and exit.
ch := make(chan struct{})
go func() {
select {
@ -142,20 +198,24 @@ func main() {
}()
var data []byte
data, err = io.ReadAll(os.Stdin)
// Tell the waiting routine that we got input on STDIN.
ch <- struct{}{}
checkErr(err)
tpl, err = tpl.Parse(string(data))
checkErr(err)
} else if len(flag.Args()) == 1 && flag.Args()[0] == "-" {
// If only a single non-flag argument is provided and it's a -, wait for STDIN indefinitely.
var data []byte
data, err = io.ReadAll(os.Stdin)
checkErr(err)
tpl, err = tpl.Parse(string(data))
checkErr(err)
} else {
// Otherwise use the provided files/directories for templates to render.
// fmt.Fprintf(os.Stderr, "%+v\n", expandFiles(flag.Args()))
tpl, err = tpl.ParseFiles(expandFiles(flag.Args())...)
checkErr(err)
}
fmt.Fprintf(os.Stderr, "%+v\n", mergeValues())
// fmt.Fprintf(os.Stderr, "%+v\n", mergeValues())
tpl.Execute(os.Stdout, mergeValues())
}