Skip to content

Commit

Permalink
feat: Add Sprig template functions (#9005)
Browse files Browse the repository at this point in the history
* feat: Add Sprig template functions

* Render wrapped return value, providing core template error.

Signed-off-by: Brian Topping <[email protected]>

* Don't need the local `default` function if Sprig is available

Signed-off-by: Brian Topping <[email protected]>

* Run linter

Signed-off-by: Brian Topping <[email protected]>

---------

Signed-off-by: Brian Topping <[email protected]>
  • Loading branch information
briantopping authored Aug 10, 2023
1 parent bc41000 commit b4dd9f9
Show file tree
Hide file tree
Showing 61 changed files with 6,947 additions and 51 deletions.
3 changes: 1 addition & 2 deletions docs-v2/content/en/docs/environment/templating.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,5 @@ List of variables that are available for templating:
* `IMAGE_NAME2`, `IMAGE_REPON`, `IMAGE_TAGN`, `IMAGE_DIGESTN` - the Nth artifact's image name, tag, and sha256 digest

### Template functions
Besides the [built-in template functions](https://pkg.go.dev/text/template) in golang, skaffold also provides the following ones:
- `default` : Default values can be specified using the `{{default "bar" .FOO}}` expression syntax, which results in "bar" if .FOO is nil or a zero value.
In addition to the [built-in template functions](https://pkg.go.dev/text/template) in Golang and the [Sprig template functions](http://masterminds.github.io/sprig/), Skaffold also provides the following:
- `cmd`: This allows users to use the result from external commands in template, for example `{{cmd "bash" "-c" "xxx xxx xxx"}}` can be used to execute bash script and get the result into the template.
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ require (
github.com/AlecAivazis/survey/v2 v2.2.15
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.35.1
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.11.1
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/ahmetb/dlog v0.0.0-20170105205344-4fb5f8204f26
github.com/blang/semver v3.5.1+incompatible
Expand Down Expand Up @@ -151,6 +152,7 @@ require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.35.1 // indirect
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Microsoft/hcsshim v0.9.6 // indirect
Expand Down Expand Up @@ -224,6 +226,7 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.8.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand All @@ -239,9 +242,11 @@ require (
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/mount v0.2.0 // indirect
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,14 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapp
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.35.1/go.mod h1:H785fvlgotVZqht+1rHhXSs8EJ8uPVmpBYkTYO3ccpc=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
Expand Down Expand Up @@ -1141,6 +1145,8 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW
github.com/honeycombio/beeline-go v1.10.0 h1:cUDe555oqvw8oD76BQJ8alk7FP0JZ/M/zXpNvOEDLDc=
github.com/honeycombio/libhoney-go v1.16.0 h1:kPpqoz6vbOzgp7jC6SR7SkNj7rua7rgxvznI6M3KdHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
Expand Down Expand Up @@ -1329,6 +1335,8 @@ github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
Expand All @@ -1350,6 +1358,8 @@ github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/buildkit v0.8.0 h1:isPRu9bp8xbMSvs8P6yHAc8vsYPFVNFKrOXHe/tzNXw=
github.com/moby/buildkit v0.8.0/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
Expand Down
2 changes: 1 addition & 1 deletion pkg/skaffold/build/ko/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func expand(dryValues []string) ([]string, error) {
rawValue = strings.ReplaceAll(rawValue, "{{.Env.", "{{.")
expandedValue, err := util.ExpandEnvTemplate(rawValue, nil)
if err != nil {
return nil, fmt.Errorf("could not expand %s", rawValue)
return nil, err
}
expandedValues = append(expandedValues, expandedValue)
}
Expand Down
32 changes: 4 additions & 28 deletions pkg/skaffold/util/env_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ import (
"fmt"
"os"
"os/exec"
"reflect"
"sort"
"strings"
"text/template"

"github.com/Masterminds/sprig"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/output/log"
)

// For testing
var (
OSEnviron = os.Environ
funcsMap = template.FuncMap{
"default": defaultFunc,
"cmd": runCmdFunc,
"cmd": runCmdFunc,
}
)

Expand All @@ -60,7 +60,7 @@ func ExpandEnvTemplateOrFail(s string, envMap map[string]string) (string, error)

// ParseEnvTemplate is a simple wrapper to parse an env template
func ParseEnvTemplate(t string) (*template.Template, error) {
return template.New("envTemplate").Funcs(funcsMap).Parse(t)
return template.New("envTemplate").Funcs(funcsMap).Funcs(sprig.FuncMap()).Parse(t)
}

// ExecuteEnvTemplate executes an envTemplate based on OS environment variables and a custom map
Expand Down Expand Up @@ -139,30 +139,6 @@ func MapToFlag(m map[string]*string, flag string) ([]string, error) {
return kvFlags, nil
}

// defaultFunc is a template function that behaves as sprig's default function.
// See https://masterminds.github.io/sprig/defaults.html#default
func defaultFunc(dflt, value interface{}) interface{} {
if value == nil {
return dflt
}
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.Array, reflect.Slice:
if v.Len() == 0 {
return dflt
}
case reflect.Ptr:
if v.IsNil() {
return dflt
}
default:
if v.IsZero() {
return dflt
}
}
return value
}

func runCmdFunc(name string, args ...string) (string, error) {
cmd := exec.Command(name, args...)
out, err := RunCmdOut(context.TODO(), cmd)
Expand Down
20 changes: 0 additions & 20 deletions pkg/skaffold/util/env_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,26 +180,6 @@ func TestMapToFlag(t *testing.T) {
}
}

func TestDefaultFunc(t *testing.T) {
for _, empty := range []interface{}{nil, false, 0, "", []string{}} {
t.Run(fmt.Sprintf("empties: %v (%T)", empty, empty), func(t *testing.T) {
dflt := "default"
if defaultFunc(dflt, empty) != dflt {
t.Error("did not return default")
}
})
}
s := "string"
for _, nonEmpty := range []interface{}{&s, true, 1, "hoot", []string{"hoot"}} {
t.Run(fmt.Sprintf("non-empty: %v (%T)", nonEmpty, nonEmpty), func(t *testing.T) {
dflt := "default"
if defaultFunc(dflt, nonEmpty) == dflt {
t.Error("should not return default")
}
})
}
}

func TestRunCmdFunc(t *testing.T) {
tests := []struct {
description string
Expand Down
18 changes: 18 additions & 0 deletions vendor/github.com/Masterminds/goutils/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions vendor/github.com/Masterminds/goutils/CHANGELOG.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b4dd9f9

Please sign in to comment.