diff --git a/data/datasource.go b/data/datasource.go index 2e52c9e8..147ba013 100644 --- a/data/datasource.go +++ b/data/datasource.go @@ -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: diff --git a/data/datasource_test.go b/data/datasource_test.go index 3a71de14..003d7731 100644 --- a/data/datasource_test.go +++ b/data/datasource_test.go @@ -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") diff --git a/docs-src/content/functions/data.yml b/docs-src/content/functions/data.yml index a512c078..15106372 100644 --- a/docs-src/content/functions/data.yml +++ b/docs-src/content/functions/data.yml @@ -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. @@ -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. @@ -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). @@ -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 @@ -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) @@ -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 diff --git a/docs/content/datasources.md b/docs/content/datasources.md index 67959b25..65f107e4 100644 --- a/docs/content/datasources.md +++ b/docs/content/datasources.md @@ -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 | diff --git a/docs/content/functions/data.md b/docs/content/functions/data.md index b09200e8..4845de60 100644 --- a/docs/content/functions/data.md +++ b/docs/content/functions/data.md @@ -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. @@ -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. @@ -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). @@ -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. @@ -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 @@ -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) @@ -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