Skip to content

Commit

Permalink
Adding support for stdin: scheme for datasources
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Henderson <[email protected]>
  • Loading branch information
hairyhenderson authored and Gman98ish committed Nov 27, 2017
1 parent 8d12188 commit 50d4ab2
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
20 changes: 20 additions & 0 deletions data/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package data
import (
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"mime"
Expand All @@ -22,6 +23,9 @@ import (
// logFatal is defined so log.Fatal calls can be overridden for testing
var logFatalf = log.Fatalf

// stdin - for overriding in tests
var stdin io.Reader

func regExtension(ext, typ string) {
err := mime.AddExtensionType(ext, typ)
if err != nil {
Expand All @@ -43,6 +47,7 @@ func init() {
addSourceReader("http", readHTTP)
addSourceReader("https", readHTTP)
addSourceReader("file", readFile)
addSourceReader("stdin", readStdin)
addSourceReader("vault", readVault)
addSourceReader("consul", readConsul)
addSourceReader("consul+http", readConsul)
Expand Down Expand Up @@ -157,6 +162,9 @@ func ParseSource(value string) (*Source, error) {
srcURL = absURL(f)
} else if len(parts) == 2 {
alias = parts[0]
if parts[1] == "-" {
parts[1] = "stdin://"
}
var err error
srcURL, err = url.Parse(parts[1])
if err != nil {
Expand Down Expand Up @@ -296,6 +304,18 @@ func readFile(source *Source, args ...string) ([]byte, error) {
return b, nil
}

func readStdin(source *Source, args ...string) ([]byte, error) {
if stdin == nil {
stdin = os.Stdin
}
b, err := ioutil.ReadAll(stdin)
if err != nil {
log.Printf("Can't read %v: %#v", stdin, err)
return nil, err
}
return b, nil
}

func readHTTP(source *Source, args ...string) ([]byte, error) {
if source.HC == nil {
source.HC = &http.Client{Timeout: time.Second * 5}
Expand Down
21 changes: 21 additions & 0 deletions data/datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

"github.com/blang/vfs"
Expand Down Expand Up @@ -307,3 +308,23 @@ func TestInclude(t *testing.T) {
actual := data.Include("foo")
assert.Equal(t, contents, actual)
}

type errorReader struct{}

func (e errorReader) Read(p []byte) (n int, err error) {
return 0, fmt.Errorf("error")
}

func TestReadStdin(t *testing.T) {
defer func() {
stdin = nil
}()
stdin = strings.NewReader("foo")
out, err := readStdin(nil)
assert.NoError(t, err)
assert.Equal(t, []byte("foo"), out)

stdin = errorReader{}
_, err = readStdin(nil)
assert.Error(t, err)
}
21 changes: 20 additions & 1 deletion 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.

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

Currently, `file://`, `http://`, `https://`, and `vault://` URLs are supported.
Currently, `file://`, `stdin://`, `http://`, `https://`, and `vault://` URLs are supported.

Currently-supported formats are JSON, YAML, TOML, and CSV.

Expand All @@ -34,6 +34,25 @@ $ gomplate -d person.json < input.tmpl
Hello Dave
```

### Providing datasources on standard input (`stdin`)

Normally `stdin` is used as the input for the template, but it can also be used
to provide datasources. To do this, specify a URL with the `stdin:` scheme:

```console
$ echo 'foo: bar' | gomplate -i '{{(ds "data").foo}}' -d data=stdin:///foo.yaml
bar
```

Note that the URL must have a file name with a supported extension in order for
the input to be correctly parsed. If no parsing is required (i.e. if the data
is being included verbatim with the include function), just `stdin:` is enough:

```console
$ echo 'foo' | gomplate -i '{{ include "data" }}' -d data=stdin:
foo
```

### Usage with HTTP data

```console
Expand Down

0 comments on commit 50d4ab2

Please sign in to comment.