diff --git a/data.go b/data.go index 2acb39ab3..483f141b4 100644 --- a/data.go +++ b/data.go @@ -200,6 +200,19 @@ func (d *Data) Datasource(alias string, args ...string) interface{} { return nil } +// Include - +func (d *Data) include(alias string, args ...string) interface{} { + source, ok := d.Sources[alias] + if !ok { + log.Fatalf("Undefined datasource '%s'", alias) + } + b, err := d.ReadSource(source.FS, source, args...) + if err != nil { + log.Fatalf("Couldn't read datasource '%s': %s", alias, err) + } + return string(b) +} + // ReadSource - func (d *Data) ReadSource(fs vfs.Filesystem, source *Source, args ...string) ([]byte, error) { if d.cache == nil { diff --git a/data_test.go b/data_test.go index 9afb968a5..2301f1d46 100644 --- a/data_test.go +++ b/data_test.go @@ -271,3 +271,28 @@ func TestParseHeaderArgs(t *testing.T) { } assert.Equal(t, expected, parseHeaderArgs(args)) } + +func TestInclude(t *testing.T) { + ext := "txt" + contents := "hello world" + fname := "foo." + ext + fs := memfs.Create() + _ = fs.Mkdir("/tmp", 0777) + f, _ := vfs.Create(fs, "/tmp/"+fname) + _, _ = f.Write([]byte(contents)) + + sources := map[string]*Source{ + "foo": { + Alias: "foo", + URL: &url.URL{Scheme: "file", Path: "/tmp/" + fname}, + Ext: ext, + Type: "text/plain", + FS: fs, + }, + } + data := &Data{ + Sources: sources, + } + actual := data.include("foo") + assert.Equal(t, contents, actual) +} diff --git a/docs/content/functions.md b/docs/content/functions.md index 73d4a3bd8..c8962146f 100644 --- a/docs/content/functions.md +++ b/docs/content/functions.md @@ -704,6 +704,51 @@ no worries Alias to [`datasource`](#datasource) +## `include` + +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. + +### Usage + +```go +include alias [subpath] +``` + +### Arguments + +| name | description | +|--------|-------| +| `alias` | the datasource alias, as provided by [`--datasource/-d`](../usage/#datasource-d) | +| `subpath` | _(optional)_ the subpath to use, if supported by the datasource | + +### Examples + +_`person.json`:_ +```json +{ "name": "Dave" } +``` + +_`input.tmpl`:_ +```go +{ + "people": [ + {{ include "person" }} + ] +} +``` + +```console +$ gomplate -d person.json -f input.tmpl +{ + "people": [ + { "name": "Dave" } + ] +} +``` + ## `ec2meta` Queries AWS [EC2 Instance Metadata](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) for information. This only retrieves data in the `meta-data` path -- for data in the `dynamic` path use `ec2dynamic`. diff --git a/docs/content/usage.md b/docs/content/usage.md index 2296a7b8a..a0b665a5c 100644 --- a/docs/content/usage.md +++ b/docs/content/usage.md @@ -44,7 +44,7 @@ gomplate --input-dir=templates --output-dir=config --datasource config=config.ya ## `--datasource`/`-d` -Add a data source in `name=URL` form. Specify multiple times to add multiple sources. The data can then be used by the [`datasource`](#datasource) function. +Add a data source in `name=URL` form. Specify multiple times to add multiple sources. The data can then be used by the [`datasource`](../functions/#datasource) and [`include`](../functions/#include) functions. A few different forms are valid: - `mydata=file:///tmp/my/file.json` diff --git a/gomplate.go b/gomplate.go index 290069ff3..78317634c 100644 --- a/gomplate.go +++ b/gomplate.go @@ -81,6 +81,7 @@ func NewGomplate(data *Data, leftDelim, rightDelim string) *Gomplate { "datasource": data.Datasource, "ds": data.Datasource, "datasourceExists": data.DatasourceExists, + "include": data.include, }, } } diff --git a/test/integration/datasources_file.bats b/test/integration/datasources_file.bats index 621931c9c..cfabcb65a 100644 --- a/test/integration/datasources_file.bats +++ b/test/integration/datasources_file.bats @@ -40,3 +40,10 @@ function teardown () { [[ "${output}" == "foo\" bar" ]] } + +@test "'include' doesn't parse file" { + echo 'foo: bar' > $tmpdir/config.yml + gomplate -d config=$tmpdir/config.yml -i '{{include "config"}}' + [ "$status" -eq 0 ] + [[ "${output}" == "foo: bar" ]] +}