initial commit
This commit is contained in:
commit
b730aca6cf
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.yaml
|
||||||
|
templates
|
||||||
|
target
|
7
config_file.go
Normal file
7
config_file.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Globals map[interface{}]interface{} `yaml:"globals"`
|
||||||
|
TemplateDir string `yaml:"templates"`
|
||||||
|
TargetDir string `yaml:"target"`
|
||||||
|
}
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module git.milar.in/milarin/cfgen
|
||||||
|
|
||||||
|
go 1.19
|
||||||
|
|
||||||
|
require gopkg.in/yaml.v2 v2.4.0
|
4
go.sum
Normal file
4
go.sum
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
42
handle_template.go
Normal file
42
handle_template.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HandleTemplate(tmpl *template.Template) error {
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
if err := tmpl.Execute(b, ConfigFile.Globals); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(strings.TrimSpace(b.String())) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tmplPath := filepath.Join(ConfigFile.TargetDir, tmpl.Name())
|
||||||
|
|
||||||
|
if err := os.MkdirAll(filepath.Dir(tmplPath), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(tmplPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if _, err := io.Copy(file, b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(tmplPath)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
81
main.go
Normal file
81
main.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ConfigFile = &Config{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if err := ReadConfigFile(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmplMap, err := ParseTemplates(template.New("template"), ConfigFile.TemplateDir)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(ConfigFile.TargetDir, 0755); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tmpl := range tmplMap {
|
||||||
|
if err := HandleTemplate(tmpl); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadConfigFile() error {
|
||||||
|
filename := flag.Arg(0)
|
||||||
|
if filename == "" {
|
||||||
|
return errors.New("no config file provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if err := yaml.NewDecoder(file).Decode(ConfigFile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
RecursiveEnvLookupForMap(ConfigFile.Globals)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RecursiveEnvLookupForMap(m map[interface{}]interface{}) {
|
||||||
|
for k, v := range m {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
m[k] = os.ExpandEnv(str)
|
||||||
|
} else if m2, ok := v.(map[interface{}]interface{}); ok {
|
||||||
|
RecursiveEnvLookupForMap(m2)
|
||||||
|
} else if arr, ok := v.([]interface{}); ok {
|
||||||
|
RecursiveEnvLookupForSlice(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RecursiveEnvLookupForSlice(s []interface{}) {
|
||||||
|
for i, v := range s {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
s[i] = os.ExpandEnv(str)
|
||||||
|
} else if m, ok := v.(map[interface{}]interface{}); ok {
|
||||||
|
RecursiveEnvLookupForMap(m)
|
||||||
|
} else if arr, ok := v.([]interface{}); ok {
|
||||||
|
RecursiveEnvLookupForSlice(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
parse_templates.go
Normal file
58
parse_templates.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseTemplates(tmpl *template.Template, path string) (map[string]*template.Template, error) {
|
||||||
|
tmplMap := map[string]*template.Template{}
|
||||||
|
|
||||||
|
err := parseTemplates(tmpl, tmplMap, path, path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmplMap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTemplates(tmpl *template.Template, tmplMap map[string]*template.Template, path string, trimPrefix string) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
dirEntries, err := os.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dirEntry := range dirEntries {
|
||||||
|
entryPath := filepath.Join(path, dirEntry.Name())
|
||||||
|
if dirEntry.IsDir() {
|
||||||
|
err = parseTemplates(tmpl, tmplMap, entryPath, trimPrefix)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ReadFileString(entryPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmplName := filepath.Clean(strings.TrimPrefix(entryPath, trimPrefix))
|
||||||
|
if tmplName[0] == '/' {
|
||||||
|
tmplName = tmplName[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err = tmpl.New(tmplName).Parse(string(data))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmplMap[tmplName] = tmpl
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
20
utils.go
Normal file
20
utils.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ReadFile(path string) ([]byte, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
return io.ReadAll(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadFileString(path string) (string, error) {
|
||||||
|
data, err := ReadFile(path)
|
||||||
|
return string(data), err
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user