Skip to content

Commit

Permalink
Merge pull request #926 from hairyhenderson/fall-back-to-json-array-924
Browse files Browse the repository at this point in the history
Fall back to JSON/YAML arrays when parsing datasources
  • Loading branch information
Dave Henderson authored and GitHub committed Aug 20, 2020
2 parents 6f39778 + ee9947b commit 42805a8
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 19 deletions.
8 changes: 8 additions & 0 deletions data/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,18 @@ func parseData(mimeType, s string) (out interface{}, err error) {
switch mimeAlias(mimeType) {
case jsonMimetype:
out, err = JSON(s)
if err != nil {
// maybe it's a JSON array
out, err = JSONArray(s)
}
case jsonArrayMimetype:
out, err = JSONArray(s)
case yamlMimetype:
out, err = YAML(s)
if err != nil {
// maybe it's a YAML array
out, err = YAMLArray(s)
}
case csvMimetype:
out, err = CSV(s)
case tomlMimetype:
Expand Down
19 changes: 15 additions & 4 deletions data/datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,27 @@ func TestDatasource(t *testing.T) {
}
return &Data{Sources: sources}
}
test := func(ext, mime string, contents []byte) {
test := func(ext, mime string, contents []byte, expected interface{}) {
data := setup(ext, mime, contents)
expected := map[string]interface{}{"hello": map[string]interface{}{"cruel": "world"}}

actual, err := data.Datasource("foo")
assert.NoError(t, err)
assert.Equal(t, expected, actual)
}

test("json", jsonMimetype, []byte(`{"hello":{"cruel":"world"}}`))
test("yml", yamlMimetype, []byte("hello:\n cruel: world\n"))
testObj := func(ext, mime string, contents []byte) {
test(ext, mime, contents,
map[string]interface{}{
"hello": map[string]interface{}{"cruel": "world"},
})
}

testObj("json", jsonMimetype, []byte(`{"hello":{"cruel":"world"}}`))
testObj("yml", yamlMimetype, []byte("hello:\n cruel: world\n"))
test("json", jsonMimetype, []byte(`[1, "two", true]`),
[]interface{}{1, "two", true})
test("yaml", yamlMimetype, []byte("---\n- 1\n- two\n- true\n"),
[]interface{}{1, "two", true})

d := setup("", textMimetype, nil)
actual, err := d.Datasource("foo")
Expand Down
20 changes: 13 additions & 7 deletions docs-src/content/functions/data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ funcs:
- name: datasource
alias: ds
description: |
Parses a given datasource (provided by the [`--datasource/-d`](#--datasource-d) argument or [`defineDatasource`](#definedatasource)).
Parses a given datasource (provided by the [`--datasource/-d`](../../usage/#datasource-d) argument or [`defineDatasource`](#definedatasource)).
If the `alias` is undefined, but is a valid URL, `datasource` will dynamically read from that URL.
Expand All @@ -32,7 +32,7 @@ funcs:
- name: datasourceExists
description: |
Tests whether or not a given datasource was defined on the commandline (with the
[`--datasource/-d`](#--datasource-d) argument). This is intended mainly to allow
[`--datasource/-d`](../../usage/#datasource-d) argument). This is intended mainly to allow
a template to be rendered differently whether or not a given datasource was
defined.
Expand Down Expand Up @@ -64,7 +64,7 @@ funcs:
no worries
- name: defineDatasource
description: |
Define a datasource alias with target URL inside the template. Overridden by the [`--datasource/-d`](#--datasource-d) flag.
Define a datasource alias with target URL inside the template. Overridden by the [`--datasource/-d`](../../usage/#datasource-d) flag.
Note: once a datasource is defined, it can not be redefined (i.e. if this function is called twice with the same alias, only the first applies).
Expand Down Expand Up @@ -94,14 +94,14 @@ funcs:
```
- name: include
description: |
Includes the content of a given datasource (provided by the [`--datasource/-d`](../usage/#datasource-d) argument).
Includes the content of a given datasource (provided by the [`--datasource/-d`](../../usage/#datasource-d) argument).
This is similar to [`datasource`](#datasource), except that the data is not parsed. There is no restriction on the type of data included, except that it should be textual.
pipeline: false
arguments:
- name: alias
required: true
description: the datasource alias, as provided by [`--datasource/-d`](../usage/#datasource-d)
description: the datasource alias, as provided by [`--datasource/-d`](../../usage/#datasource-d)
- name: subpath
required: false
description: the subpath to use, if supported by the datasource
Expand Down Expand Up @@ -132,7 +132,10 @@ funcs:
- name: data.JSON
alias: json
description: |
Converts a JSON string into an object. Only works for JSON Objects (not Arrays or other valid JSON types). This can be used to access properties of JSON objects.
Converts a JSON string into an object. Works for JSON Objects, but will
also parse JSON Arrays. Will not parse other valid JSON types.
For more explict JSON Array support, see [`data.JSONArray`](#data-jsonarray).
#### Encrypted JSON support (EJSON)
Expand Down Expand Up @@ -182,7 +185,10 @@ funcs:
- name: data.YAML
alias: yaml
description: |
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.
Converts a YAML string into an object. Works for YAML Objects but will
also parse YAML Arrays. This can be used to access properties of YAML objects.
For more explict YAML Array support, see [`data.JSONArray`](#data-yamlarray).
pipeline: true
arguments:
- name: in
Expand Down
2 changes: 1 addition & 1 deletion docs/content/datasources.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ These are the supported types:
| Format | MIME Type | Extension(s) | Notes |
|--------|-----------|-------|------|
| CSV | `text/csv` | `.csv` | Uses the [`data.CSV`][] function to present the file as a 2-dimensional row-first string array |
| JSON | `application/json` | `.json` | [JSON][] _objects_ are assumed, and arrays or other values are not parsed with this type. Uses the [`data.JSON`][] function for parsing. [EJSON][] (encrypted JSON) is supported and will be decrypted. |
| JSON | `application/json` | `.json` | [JSON][] _objects_ are assumed, but will support arrays as well. Other values are not parsed with this type. Uses the [`data.JSON`][] function for parsing. [EJSON][] (encrypted JSON) is supported and will be decrypted. |
| JSON Array | `application/array+json` | | A special type for parsing datasources containing just JSON arrays. Uses the [`data.JSONArray`][] function for parsing |
| Plain Text | `text/plain` | | Unstructured, and as such only intended for use with the [`include`][] function |
| TOML | `application/toml` | `.toml` | Parses [TOML][] with the [`data.TOML`][] function |
Expand Down
20 changes: 13 additions & 7 deletions docs/content/functions/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A collection of functions that retrieve, parse, and convert structured data.

**Alias:** `ds`

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

If the `alias` is undefined, but is a valid URL, `datasource` will dynamically read from that URL.

Expand Down Expand Up @@ -45,7 +45,7 @@ Hello Dave
## `datasourceExists`

Tests whether or not a given datasource was defined on the commandline (with the
[`--datasource/-d`](#--datasource-d) argument). This is intended mainly to allow
[`--datasource/-d`](../../usage/#datasource-d) argument). This is intended mainly to allow
a template to be rendered differently whether or not a given datasource was
defined.

Expand Down Expand Up @@ -99,7 +99,7 @@ no worries

## `defineDatasource`

Define a datasource alias with target URL inside the template. Overridden by the [`--datasource/-d`](#--datasource-d) flag.
Define a datasource alias with target URL inside the template. Overridden by the [`--datasource/-d`](../../usage/#datasource-d) flag.

Note: once a datasource is defined, it can not be redefined (i.e. if this function is called twice with the same alias, only the first applies).

Expand Down Expand Up @@ -136,7 +136,7 @@ Hello Daisy

## `include`

Includes the content of a given datasource (provided by the [`--datasource/-d`](../usage/#datasource-d) argument).
Includes the content of a given datasource (provided by the [`--datasource/-d`](../../usage/#datasource-d) argument).

This is similar to [`datasource`](#datasource), except that the data is not parsed. There is no restriction on the type of data included, except that it should be textual.

Expand All @@ -150,7 +150,7 @@ include alias [subpath]

| name | description |
|------|-------------|
| `alias` | _(required)_ the datasource alias, as provided by [`--datasource/-d`](../usage/#datasource-d) |
| `alias` | _(required)_ the datasource alias, as provided by [`--datasource/-d`](../../usage/#datasource-d) |
| `subpath` | _(optional)_ the subpath to use, if supported by the datasource |

### Examples
Expand Down Expand Up @@ -182,7 +182,10 @@ $ gomplate -d person.json -f input.tmpl

**Alias:** `json`

Converts a JSON string into an object. Only works for JSON Objects (not Arrays or other valid JSON types). This can be used to access properties of JSON objects.
Converts a JSON string into an object. Works for JSON Objects, but will
also parse JSON Arrays. Will not parse other valid JSON types.

For more explict JSON Array support, see [`data.JSONArray`](#data-jsonarray).

#### Encrypted JSON support (EJSON)

Expand Down Expand Up @@ -258,7 +261,10 @@ Hello world

**Alias:** `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.
Converts a YAML string into an object. Works for YAML Objects but will
also parse YAML Arrays. This can be used to access properties of YAML objects.

For more explict YAML Array support, see [`data.JSONArray`](#data-yamlarray).

### Usage

Expand Down

0 comments on commit 42805a8

Please sign in to comment.