Last active
June 2, 2021 13:40
-
-
Save Spazzy757/a3bccb7b23043d211551ea651e819bc3 to your computer and use it in GitHub Desktop.
example code used to take in yaml and template out in a file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
/* | |
* A simple templating cli that takes a yaml file and template | |
* and templates out to stdout | |
* Uses Gotemplating syntax for a more comprehensive | |
* understanding of the different functionalities of go templates | |
* visit: | |
* - https://docs.gomplate.ca/syntax/ | |
* - https://golang.org/pkg/html/template/ | |
*/ | |
import ( | |
"flag" | |
"fmt" | |
"io/ioutil" | |
"log" | |
"os" | |
"path/filepath" | |
"strings" | |
"text/template" | |
"gopkg.in/yaml.v2" | |
) | |
var valuesFiles *string | |
var templateFiles *string | |
func init() { | |
// read flags and set the values accordingly | |
valuesFiles = flag.String("values", "values.yaml", "Yaml with template values") | |
templateFiles = flag.String("templates", "template.tmpl", "Template to inject values into") | |
flag.Parse() | |
} | |
//readValues reads a yaml file and unmarshals it into | |
// a map[string]interface | |
func readValues(path string) (map[string]interface{}, error) { | |
// read content of file | |
content, err := ioutil.ReadFile(path) | |
if err != nil { | |
return nil, fmt.Errorf("unable to read values file") | |
} | |
// initialize empty object for data | |
data := make(map[string]interface{}, 0) | |
// unmarshall file data into empty object | |
if err := yaml.Unmarshal(content, &data); err != nil { | |
return nil, fmt.Errorf("unable decode the values content") | |
} | |
return data, nil | |
} | |
func main() { | |
//read values file data into object | |
// blank data object to load files into | |
data := make(map[string]interface{}) | |
// split files string into slice | |
files := strings.Split(*valuesFiles, ",") | |
// loop through each file and read data | |
for _, file := range files { | |
// get values from current file | |
tmpData, err := readValues(file) | |
if err != nil { | |
log.Fatal(err) | |
} | |
// merge data with previous data | |
// NOTE: will overide keys | |
data = mergeObjects(data, tmpData) | |
} | |
//read template files | |
// split template string into slice | |
tmpls := strings.Split(*templateFiles, ",") | |
// loop through templates and template out each | |
for _, tmpl := range tmpls { | |
// load current template | |
t, err := template.ParseFiles(tmpl) | |
if err != nil { | |
log.Fatal("error Parsing template: ", err) | |
} | |
//template out using values from valuesFile | |
// will create a file corresponding with the template | |
// i.e templates/config.template.xml => config.xml | |
_, filename := filepath.Split(tmpl) | |
filename = strings.ReplaceAll(filename, ".template", "") | |
log.Printf("creating: %v", filename) | |
f, _ := os.Create(filename) | |
err = t.Execute(f, data) | |
if err != nil { | |
log.Fatal("error executing template: ", err) | |
} | |
} | |
} | |
//mergeObjects will take two interfaces | |
//and add them together | |
//NOTE: if keys clash, object two will overwite | |
//object ones key | |
func mergeObjects( | |
objectOne map[string]interface{}, | |
objectTwo map[string]interface{}, | |
) map[string]interface{} { | |
data := make(map[string]interface{}) | |
// loop through first object adding | |
// keys to data | |
for k, v := range objectOne { | |
if _, ok := objectOne[k]; ok { | |
data[k] = v | |
} | |
} | |
// loop through object two adding | |
// object keys to data | |
for k, v := range objectTwo { | |
if _, ok := objectTwo[k]; ok { | |
data[k] = v | |
} | |
} | |
return data | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment