package main import ( "bytes" "encoding/json" "fmt" "html" "html/template" "io/ioutil" "os" "strings" "gopkg.in/yaml.v2" "code.senomas.com/go/util" ) // Variables struct type Variables struct { Env map[string]string } func parseYAML(text string) map[string]interface{} { val := make(map[string]interface{}) err := yaml.Unmarshal([]byte(text), &val) util.Check("Invalid yaml [%s] %v", text, err) return val } func parseJSON(text string) map[string]interface{} { val := make(map[string]interface{}) err := json.Unmarshal([]byte(text), &val) util.Check("Invalid json [%s] %v", text, err) return val } func value(vs ...interface{}) interface{} { for _, v := range vs { if v != nil { return v } } return nil } func cat(spacer string, va ...interface{}) string { var bb bytes.Buffer for k, v := range va { if k > 0 { bb.WriteString(spacer) } fmt.Fprintf(&bb, "%v", v) } return bb.String() } func split(v string, sep string) []string { return strings.Split(v, sep) } func ift(test bool, vt, vf interface{}) interface{} { if test { return vt } return vf } func get(v map[string]interface{}, key string) interface{} { return v[key] } func getMap(v map[string]interface{}, keys ...string) interface{} { var ok bool for _, kk := range keys { v, ok = v[kk].(map[string]interface{}) if !ok { return nil } } return v } func main() { funcMap := template.FuncMap{ "parseYAML": parseYAML, "parseJSON": parseJSON, "value": value, "cat": cat, "ift": ift, "split": split, "get": get, "getMap": getMap, } var text []byte var err error text, err = ioutil.ReadFile(os.Args[1]) util.Check("Error open file %s %v", os.Args[1], err) tmpl, err := template.New("config").Option("missingkey=zero").Funcs(funcMap).Parse(string(text)) util.Check("Error %v", err) env := make(map[string]string) for _, v := range os.Environ() { splits := strings.Split(v, "=") env[splits[0]] = strings.Join(splits[1:], "=") } var bb bytes.Buffer err = tmpl.Execute(&bb, &Variables{env}) util.Check("Execute error %v", err) fmt.Println(html.UnescapeString(bb.String())) }