From 585ed5e7b56e56b4fd4c38e5c102a4fa33a93846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Svoboda?= Date: Mon, 13 Feb 2017 09:27:44 +0100 Subject: [PATCH] feat: Added Sprig - useful template functions for Go templates Added Sprig (useful template functions for Go templates) BREAKING CHAGE: - **`{{ .NonExistsent }}` resolves to empty string** Before `{{ .NonExistsent }}` => `` After `{{ .NonExistsent }}` => `` - **function `default` is used from `Sprig` and has another params** Before: `default (env "VAR") "10"` After `env "VAR" | default "10"` --- README.md | 5 ++--- debian/changelog | 17 +++++++++++++++++ debian/control | 4 +++- debian/rules | 4 ++-- glide.lock | 10 ++++++++-- glide.yaml | 2 ++ template.go | 41 ++++------------------------------------- template_test.go | 18 ++++++++++++++---- tests/fixtures.env | 1 + 9 files changed, 53 insertions(+), 49 deletions(-) create mode 100644 tests/fixtures.env diff --git a/README.md b/README.md index 084f016..8a90296 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,9 @@ goenvtemplator -env-file myenvfile -exec sh -c 'echo $D' ``` ## Using Templates -Templates use Golang [text/template](http://golang.org/pkg/text/template/). +Templates use Golang [html/template](http://golang.org/pkg/html/template/) +and [Sprig](https://github.com/Masterminds/sprig) library. ### Built-in functions There are a few built in functions as well: - * `env "ENV_NAME"` - Accesses environment variables. If it does not exist return empty string. `{{ env "TIMEOUT_MS }}` * `require (env "ENV_NAME")` - Renders an error if environments variable does not exists. If it is equal to empty string, returns empty string. `{{ require (env "TIMEOUT_MS) }}` - * `default $default_1 $default_2 $default_3` - Returns a first argument that exists. If none is valid it generates error `{{ default (env "SPECIFIC_TIMEOUT_MS") (env "GENERAL_TIMEOUT_MS") "1000" }}` diff --git a/debian/changelog b/debian/changelog index 8f6af37..5c67eaa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,20 @@ +goenvtemplator (2.0.0~rc1) Seznam; urgency=medium + + * Added Sprig (useful template functions for Go templates) + * Breaking chages + - **`{{ .NonExistsent }}` resolves to empty string** + Before + `{{ .NonExistsent }}` => `` + After + `{{ .NonExistsent }}` => `` + - **function `default` is used from `Sprig` and has another params** + Before: + `default (env "VAR") "10"` + After + `env "VAR" | default "10"` + + -- Lukas Svoboda Fri, 10 Feb 2017 16:02:47 +0100 + goenvtemplator (1.1.0) Seznam; urgency=medium * Table driven tests. diff --git a/debian/control b/debian/control index ccf74cc..4c1b23b 100644 --- a/debian/control +++ b/debian/control @@ -3,8 +3,10 @@ Maintainer: https://github.com/seznam/goenvtemplator Section: admin Priority: optional Build-Depends: debhelper (>= 9), golang (>= 2:1.5), git +Replaces: goenvtemplator +Breaks: goenvtemplator -Package: goenvtemplator +Package: goenvtemplator2 Architecture: amd64 Description: Tool to template configuration files by environment variables. goenvtemplator is a simple app, that can template your config files by diff --git a/debian/rules b/debian/rules index cc342ff..f917823 100755 --- a/debian/rules +++ b/debian/rules @@ -4,5 +4,5 @@ +dh $@ --parallel override_dh_auto_install: - mkdir -p ./debian/goenvtemplator/usr/bin - install -m 0755 goenvtemplator ./debian/goenvtemplator/usr/bin + mkdir -p ./debian/goenvtemplator2/usr/bin + install -m 0755 goenvtemplator ./debian/goenvtemplator2/usr/bin diff --git a/glide.lock b/glide.lock index d52aa61..55a5d52 100644 --- a/glide.lock +++ b/glide.lock @@ -1,6 +1,12 @@ -hash: 2e49700d65abd2ec5287560ff1c0eb932322e097aef96cae137da9cb4f5b0b0f -updated: 2016-11-23T16:52:10.769828004+01:00 +hash: 425d244bf3bbb2e65ea63d5503c543fcc67e21d946b70801e9b38f9b78aaaa31 +updated: 2017-02-09T12:45:47.121193027+01:00 imports: +- name: github.com/aokoli/goutils + version: 9c37978a95bd5c709a15883b6242714ea6709e64 - name: github.com/joho/godotenv version: a01a834e1654b4c9ca5b3ad05159445cc9c7ad08 +- name: github.com/Masterminds/sprig + version: 69011c0cd9b4d2e0733c4d9e2c8e2a5a0d0a2f2f +- name: github.com/satori/go.uuid + version: 879c5887cd475cd7864858769793b2ceb0d44feb testImports: [] diff --git a/glide.yaml b/glide.yaml index 308aaa5..ee67828 100644 --- a/glide.yaml +++ b/glide.yaml @@ -2,3 +2,5 @@ package: github.com/seznam/goenvtemplator import: - package: github.com/joho/godotenv version: v1 +- package: github.com/Masterminds/sprig + version: 2.8.0 diff --git a/template.go b/template.go index 626fcd0..c631744 100644 --- a/template.go +++ b/template.go @@ -3,11 +3,11 @@ package main import ( "errors" "fmt" - "os" "path/filepath" - "text/template" // "io/ioutil" "bytes" + "github.com/Masterminds/sprig" + "html/template" "io/ioutil" "log" ) @@ -23,38 +23,6 @@ func (s OptionalString) String() string { return *s.ptr } -func Env(key string) OptionalString { - value, ok := os.LookupEnv(key) - if !ok { - return OptionalString{nil} - } - return OptionalString{&value} -} - -func Default(args ...interface{}) (string, error) { - for _, arg := range args { - if arg == nil { - continue - } - switch v := arg.(type) { - case string: - return v, nil - case *string: - if v != nil { - return *v, nil - } - case OptionalString: - if v.ptr != nil { - return *v.ptr, nil - } - default: - return "", fmt.Errorf("Default: unsupported type '%T'!", v) - } - } - - return "", errors.New("Default: all arguments are nil!") -} - func Require(arg interface{}) (string, error) { if arg == nil { return "", errors.New("Required argument is missing!") @@ -77,15 +45,14 @@ func Require(arg interface{}) (string, error) { } var funcMap = template.FuncMap{ - "env": Env, - "default": Default, "require": Require, } func generateTemplate(source, name string) (string, error) { var t *template.Template var err error - if t, err = template.New(name).Funcs(funcMap).Parse(source); err != nil { + t, err = template.New(name).Funcs(funcMap).Funcs(sprig.FuncMap()).Parse(source) + if err != nil { return "", err } var buffer bytes.Buffer diff --git a/template_test.go b/template_test.go index 7138551..950e317 100644 --- a/template_test.go +++ b/template_test.go @@ -1,6 +1,7 @@ package main import ( + "github.com/joho/godotenv" "os" "testing" ) @@ -12,17 +13,26 @@ func TestGenerateTemplate(t *testing.T) { err error }{ {`K={{ env "GOENVTEMPLATOR_DEFINED_VAR" }}`, `K=foo`, nil}, + {`K={{ env "GOENVTEMPLATOR_DEFINED_FILE_VAR" }}`, `K=bar`, nil}, {`K={{ env "NONEXISTING" }}`, `K=`, nil}, - {`K={{ .NONEXISTING }}`, `K=`, nil}, - {`K={{ default .NonExisting "default value" }}`, `K=default value`, nil}, - {`K={{ default (env "GOENVTEMPLATOR_DEFINED_VAR") }}`, `K=foo`, nil}, - {`K={{ default (env "NONEXISTING") "default value" }}`, `K=default value`, nil}, + {`K={{ .NONEXISTING }}`, `K=`, nil}, + {`K={{ .NonExisting | default "default value" }}`, `K=default value`, nil}, + {`K={{ env "GOENVTEMPLATOR_DEFINED_VAR" | default "xxx" }}`, `K=foo`, nil}, + {`K={{ env "GOENVTEMPLATOR_DEFINED_FILE_VAR" | default "xxx" }}`, `K=bar`, nil}, + {`K={{ env "NONEXISTING"| default "default value" }}`, `K=default value`, nil}, + {`{{ "hi!" | upper | repeat 3 }}`, `HI!HI!HI!`, nil}, + {`{{$v := "foo/bar/baz" | split "/"}}{{$v._1}}`, `bar`, nil}, } templateName := "test" os.Setenv("GOENVTEMPLATOR_DEFINED_VAR", "foo") + err := godotenv.Load("./tests/fixtures.env") + if err != nil { + t.Errorf("Cannot load env file: %q", err) + } + for _, tt := range tests { got, gotErr := generateTemplate(tt.in, templateName) diff --git a/tests/fixtures.env b/tests/fixtures.env new file mode 100644 index 0000000..bbb0d31 --- /dev/null +++ b/tests/fixtures.env @@ -0,0 +1 @@ +GOENVTEMPLATOR_DEFINED_FILE_VAR=bar