envtpl
renders Go templates on the command line using environment variables.
It is directly inspired by the original envtpl, a Python tool for rendering Jinja2 templates.
This port was motivated by the desire to add templating support for template-driven configuration files that needed to be part of a base Docker image without also requiring the installation of Python. For the same reason, I decided not to add variable support to my previous template utility njx, which depends on Node.js.
Despite the difference between Jinja
and Go
templates, an attempt was made
to match the command line syntax of the original envtpl
.
The biggest obvious difference is that Go
template variables represent a path within
a data context, so envtpl
variables will need to be prepended with a leading .
to
match the keys of the internal environment variable map object (see example).
$ go get github.com/subfuzion/envtpl/...
envtpl [-o|--output outfile] [-m|--missingkey option] [template]
- If
template
is not provided,envtpl
reads fromstdin
- If
outfile
is not provided,envtpl
writes tostdout
- If
missingkey
is unset or set to eitherdefault
orinvalid
,envtpl
follows the default behavior of the golang template library and missing keys in the template will be filled in with the string<no value>
. Ifmissingkey
is set tozero
, missing keys will be filled in with the zero value for their data type (ie: an empty string). Ifmissingkey
is set toerror
,envtpl
will fail and an error returned to the caller.
greeting.tpl
Hello {{.USER}}
Render the template (assume the value of $USER
is 'mary')
envtpl greeting.tpl # writes "Hello mary" to stdout
USER=bob envtpl greeting.tpl # overrides "mary" and writes "Hello bob" to stdout
echo "greetings {{.USER}}" | envtpl # writes "greetings mary" to stdout
envtpl < greeting.tpl > out.txt # writes "Hello mary" to out.txt
envtpl > out.txt < greeting.tpl # same thing
cat greeting.tpl | envtpl > out.txt # same thing
unset USER; envtpl greeting.tpl # => "Hello <no value>"
unset USER; envtpl -m zero greeting.tpl # => "Hello "
unset USER; envtpl -m error greeting.tpl # => "map has no entry for key "USER"", aborts
# Use a GitHub gist with curl
curl -s https://gist.githubusercontent.com/subfuzion/d5a6e3b7c2577902408069deb1d8e4d7/raw/2e4c0b894e2983411a20ffa5ee84aeafa5c6ebfb/greeting.tpl | envtpl
# => Hello, Tony
See test/test.tpl
for more examples, including conditional functions and looping over environment variables.
In addition to the standard set of template actions and functions
that come with Go, envtpl
also incorporates sprig for additional, commonly used functions.
For example:
echo "Greetings, {{.USER | title}}" | envtpl # writes "Greetings, Mary" to stdout
In the example, the environment name of the user mary
is converted to Mary
by the title
template function.
For reference, see sprig functions.
To mimic the environment function for the original envtpl, an environment
function allows to filter the environment with a prefix string
{{ range $key, $value := environment "TAG_" }}{{ $key }}="{{ $value }}"{{ end }}
filters all environment variables starting with TAG_.
For example:
$ echo '{{ range $key, $value := environment "GO" }}{{ $key }} => {{ $value }} {{ "\n" }}{{ end }}' | envtpl
GOPATH => /Users/tony/go
GOROOT => /usr/local/go
An image is available on Docker Hub subfuzion/envtpl
You can use run a container like this:
$ echo 'Hello {{ .NAME | title | printf "%s\n" }}' | docker run -i --rm -e NAME=world subfuzion/envtpl
Hello World
# using a gist
$ curl -s https://gist.githubusercontent.com/subfuzion/d5a6e3b7c2577902408069deb1d8e4d7/raw/2e4c0b894e2983411a20ffa5ee84aeafa5c6ebfb/greeting.tpl | docker run -i -e USER=$USER subfuzion/envtpl
Hello, Tony
To build your own local container:
$ make image
The final image is based on scratch
and weighs in at less than 7MB:
$ docker images --format "{{ .Repository }}:{{ .Tag }} => {{ .Size }}" subfuzion/envtpl
subfuzion/envtpl:latest => 6.65MB
The Dockerfile for the image explicitly runs tests, so if the image builds successfully, then the tests passed.
There is an automated build for subfuzion/envtpl on Docker Hub. Docker
Hub runs tests based on the presence of docker-compose.test.yml
, so
there is a docker-compose.test.file
that simply builds the image and
runs envtpl --version
. You can test this yourself:
$ make test
As mentioned above, this tool was inspired by the original envtpl project and motivated to provide something similar without adding a Python dependency to Docker base images.
A search for similar Go-based tools turns up the following:
I haven't spent any time evaluating either yet. However, mattrobenolt/envtpl looks elegantly simple and arschles/envtpl offers tests, glide package management support and more template functionality using sprig.
Neither of these two packages appear to conform to the original envtpl
command line syntax, which was one of my goals, although I don't think this is a big deal since all of these spin-off versions use an entirely different template syntax anyway. However, at first glance at least, this variant does offer more input/output options modeled after the original.
I'm inspired by arschles/envtpl to add sprig support for extended template functions, potentially glide support, and definitely tests. This version now has sprig template support, tests, and uses Go 1.1. modules instead of glide.