From c3d531f8f28e8b69a7ab91c6e9c96ef0db1d0287 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Thu, 18 May 2017 13:59:09 -0400 Subject: [PATCH] add-json-support: added support for both YAML and JSON values for input to a template --- tpl.go | 51 +++++++++++++++++++++++++++++++++++++++------------ tpl_test.go | 28 ++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/tpl.go b/tpl.go index 563d847..497eb70 100644 --- a/tpl.go +++ b/tpl.go @@ -2,6 +2,8 @@ package main import ( "bytes" + "encoding/json" + "flag" "fmt" "io" "log" @@ -14,33 +16,58 @@ import ( // Reads a YAML document from the values_in stream, uses it as values // for the tpl_files templates and writes the executed templates to // the out stream. -func ExecuteTemplates(values_in io.Reader, out io.Writer, tpl_files ...string) error { +func ExecuteTemplates(values map[string]interface{}, out io.Writer, tpl_files ...string) error { tpl, err := template.ParseFiles(tpl_files...) if err != nil { return fmt.Errorf("Error parsing template(s): %v", err) } - buf := bytes.NewBuffer(nil) - _, err = io.Copy(buf, values_in) + err = tpl.Execute(out, values) if err != nil { - return fmt.Errorf("Failed to read standard input: %v", err) + return fmt.Errorf("Failed to parse standard input: %v", err) } + return nil +} - var values map[string]interface{} - err = yaml.Unmarshal(buf.Bytes(), &values) +func ParseValues(values_in io.Reader, format string) (map[string]interface{}, error) { + buf := bytes.NewBuffer(nil) + _, err := io.Copy(buf, values_in) if err != nil { - return fmt.Errorf("Failed to parse standard input: %v", err) + return nil, fmt.Errorf("Failed to read standard input: %v", err) } - err = tpl.Execute(out, values) - if err != nil { - return fmt.Errorf("Failed to parse standard input: %v", err) + var values map[string]interface{} + + switch format { + case "json": + err = json.Unmarshal(buf.Bytes(), &values) + if err != nil { + return nil, fmt.Errorf("Failed to parse standard input: %v", err) + } + case "yaml": + err = yaml.Unmarshal(buf.Bytes(), &values) + if err != nil { + return nil, fmt.Errorf("Failed to parse standard input: %v", err) + } + default: + return nil, fmt.Errorf("Unknown format: %s", format) } - return nil + + return values, nil + } func main() { - err := ExecuteTemplates(os.Stdin, os.Stdout, os.Args[1:]...) + format := flag.String("format", "yaml", "format of input values: yaml or json") + flag.Parse() + + values, err := ParseValues(os.Stdin, *format) + if err != nil { + log.Println(err) + os.Exit(1) + } + + err = ExecuteTemplates(values, os.Stdout, flag.Args()...) if err != nil { log.Println(err) os.Exit(1) diff --git a/tpl_test.go b/tpl_test.go index e08291e..b9aee0b 100644 --- a/tpl_test.go +++ b/tpl_test.go @@ -10,11 +10,12 @@ import ( "github.com/stretchr/testify/assert" ) -func TestYamlTemplate(t *testing.T) { +func TestTemplate(t *testing.T) { type io struct { Input string Template string Output string + Format string } tests := []io{ @@ -22,16 +23,37 @@ func TestYamlTemplate(t *testing.T) { Input: "test: value", Template: "{{.test}}", Output: "value", + Format: "yaml", }, io{ Input: "name: Max\nage: 15", Template: "Hello {{.name}}, of {{.age}} years old", Output: "Hello Max, of 15 years old", + Format: "yaml", }, io{ Input: "legumes:\n - potato\n - onion\n - cabbage", Template: "Legumes:{{ range $index, $el := .legumes}}{{if $index}},{{end}} {{$el}}{{end}}", Output: "Legumes: potato, onion, cabbage", + Format: "yaml", + }, + io{ + Input: "{\"test\": \"value\"}", + Template: "{{.test}}", + Output: "value", + Format: "json", + }, + io{ + Input: "{\"name\": \"Max\", \"age\": 15}", + Template: "Hello {{.name}}, of {{.age}} years old", + Output: "Hello Max, of 15 years old", + Format: "json", + }, + io{ + Input: "{\"legumes\": [\"potato\", \"onion\", \"cabbage\"]}", + Template: "Legumes:{{ range $index, $el := .legumes}}{{if $index}},{{end}} {{$el}}{{end}}", + Output: "Legumes: potato, onion, cabbage", + Format: "json", }, } @@ -45,7 +67,9 @@ func TestYamlTemplate(t *testing.T) { tpl_file.Close() output := bytes.NewBuffer(nil) - err = ExecuteTemplates(strings.NewReader(test.Input), output, + values, err := ParseValues(strings.NewReader(test.Input), test.Format) + assert.Nil(t, err) + err = ExecuteTemplates(values, output, tpl_file.Name()) assert.Nil(t, err)