Skip to content

Commit

Permalink
Merge pull request #52 from hairyhenderson/support-yaml-datasource-43
Browse files Browse the repository at this point in the history
Adding YAML support
  • Loading branch information
hairyhenderson authored Jul 12, 2016
2 parents be6ce78 + cfb1008 commit eb26fd6
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 1 deletion.
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,47 @@ $ gomplate < input.tmpl
Hello world
```

#### `yaml`

Converts a YAML string into an object. Only works for YAML Objects (not Arrays or other valid YAML types). This can be used to access properties of YAML objects.

##### Example

_`input.tmpl`:_
```
Hello {{ (getenv "FOO" | yaml).hello }}
```

```console
$ export FOO='hello: world'
$ gomplate < input.tmpl
Hello world
```

#### `yamlArray`

Converts a YAML string into a slice. Only works for YAML Arrays.

##### Example

_`input.tmpl`:_
```
Hello {{ index (getenv "FOO" | yamlArray) 1 }}
```

```console
$ export FOO='[ "you", "world" ]'
$ gomplate < input.tmpl
Hello world
```

#### `datasource`

Parses a given datasource (provided by the [`--datasource/-d`](#--datasource-d) argument).

Currently, only `file://` URLs are supported, and only the JSON format can be parsed. More support is coming.
Currently, only `file://` URLs are supported.

Currently-supported formats are JSON and YAML.

##### Example

Expand Down
4 changes: 4 additions & 0 deletions data.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ func (d *Data) Datasource(alias string) map[string]interface{} {
ty := &TypeConv{}
return ty.JSON(string(b))
}
if source.Type == "application/yaml" {
ty := &TypeConv{}
return ty.YAML(string(b))
}
log.Fatalf("Datasources of type %s not yet supported", source.Type)
return nil
}
Expand Down
26 changes: 26 additions & 0 deletions data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,29 @@ func TestDatasource(t *testing.T) {
actual := data.Datasource("foo")
assert.Equal(t, expected["hello"], actual["hello"])
}

func TestYAMLDatasource(t *testing.T) {
fs := memfs.Create()
fs.Mkdir("/tmp", 0777)
f, _ := vfs.Create(fs, "/tmp/foo.yml")
f.Write([]byte(`hello: world`))

sources := make(map[string]*Source)
sources["foo"] = &Source{
Alias: "foo",
URL: &url.URL{
Scheme: "file",
Path: "/tmp/foo.yml",
},
Ext: "yml",
Type: "application/yaml",
FS: fs,
}
data := &Data{
Sources: sources,
}
expected := make(map[string]interface{})
expected["hello"] = "world"
actual := data.Datasource("foo")
assert.Equal(t, expected["hello"], actual["hello"])
}
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func NewGomplate(data *Data) *Gomplate {
"bool": typeconv.Bool,
"json": typeconv.JSON,
"jsonArray": typeconv.JSONArray,
"yaml": typeconv.YAML,
"yamlArray": typeconv.YAMLArray,
"slice": typeconv.Slice,
"join": typeconv.Join,
"ec2meta": ec2meta.Meta,
Expand Down
14 changes: 14 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ func TestJSONArrayTemplates(t *testing.T) {
assert.Equal(t, "bar", testTemplate(g, `{{ index (jsonArray "[\"foo\",\"bar\"]") 1 }}`))
}

func TestYAMLTemplates(t *testing.T) {
ty := new(TypeConv)
g := &Gomplate{
funcMap: template.FuncMap{
"yaml": ty.YAML,
"yamlArray": ty.YAMLArray,
},
}

assert.Equal(t, "bar", testTemplate(g, `{{(yaml "foo: bar").foo}}`))
assert.Equal(t, "[foo bar]", testTemplate(g, `{{yamlArray "- foo\n- bar\n"}}`))
assert.Equal(t, "bar", testTemplate(g, `{{ index (yamlArray "[\"foo\",\"bar\"]") 1 }}`))
}

func TestSliceTemplates(t *testing.T) {
typeconv := &TypeConv{}
g := &Gomplate{
Expand Down
22 changes: 22 additions & 0 deletions typeconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"log"
"strconv"
"strings"

yaml "gopkg.in/yaml.v2"
)

// TypeConv - type conversion function
Expand Down Expand Up @@ -42,6 +44,26 @@ func (t *TypeConv) JSONArray(in string) []interface{} {
return obj
}

// YAML - Unmarshal a YAML Object
func (t *TypeConv) YAML(in string) map[string]interface{} {
obj := make(map[string]interface{})
err := yaml.Unmarshal([]byte(in), &obj)
if err != nil {
log.Fatalf("Unable to unmarshal YAML object %s: %v", in, err)
}
return obj
}

// YAMLArray - Unmarshal a YAML Array
func (t *TypeConv) YAMLArray(in string) []interface{} {
obj := make([]interface{}, 1)
err := yaml.Unmarshal([]byte(in), &obj)
if err != nil {
log.Fatalf("Unable to unmarshal YAML array %s: %v", in, err)
}
return obj
}

// Slice creates a slice from a bunch of arguments
func (t *TypeConv) Slice(args ...interface{}) []interface{} {
return args
Expand Down
28 changes: 28 additions & 0 deletions typeconv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,34 @@ func TestJSONArray(t *testing.T) {
assert.Equal(t, expected[1], actual[1])
}

func TestYAML(t *testing.T) {
ty := new(TypeConv)
expected := make(map[string]interface{})
expected["foo"] = "bar"
expected["one"] = 1.0
expected["true"] = true

actual := ty.YAML(`foo: bar
one: 1.0
true: true
`)
assert.Equal(t, expected["foo"], actual["foo"])
assert.Equal(t, expected["one"], actual["one"])
assert.Equal(t, expected["true"], actual["true"])
}

func TestYAMLArray(t *testing.T) {
ty := new(TypeConv)

expected := []string{"foo", "bar"}
actual := ty.YAMLArray(`
- foo
- bar
`)
assert.Equal(t, expected[0], actual[0])
assert.Equal(t, expected[1], actual[1])
}

func TestSlice(t *testing.T) {
ty := new(TypeConv)
expected := []string{"foo", "bar"}
Expand Down

0 comments on commit eb26fd6

Please sign in to comment.