Skip to content

Commit

Permalink
Deprecate most of "templatelib" in favor of Sprig
Browse files Browse the repository at this point in the history
It implements many of the same functions like `first`, `last`, `ternary`, etc, some just with a different name like `toJson` vs `json`, and gives us *many* more useful functions.
  • Loading branch information
tianon committed Dec 22, 2020
1 parent 8e42901 commit 750da3b
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 54 deletions.
2 changes: 1 addition & 1 deletion cmd/bashbrew/cmd-cat.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func cmdCat(c *cli.Context) error {
}

var i int
tmpl, err := template.New(templateName).Funcs(templatelib.FuncMap).Funcs(template.FuncMap{
tmpl, err := template.New(templateName).Funcs(templatelib.FuncMap()).Funcs(template.FuncMap{
"i": func() int {
return i
},
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module github.com/docker-library/bashbrew
go 1.13

require (
github.com/Masterminds/sprig/v3 v3.2.0
github.com/containerd/containerd v1.4.0
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/go-git/go-git/v5 v5.1.0
github.com/imdario/mergo v0.3.11 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1
github.com/pkg/errors v0.9.1 // indirect
Expand Down
22 changes: 21 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.2.0 h1:P1ekkbuU73Ui/wS0nK1HOM37hh4xdfZo485UPf8rc+Y=
github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
Expand Down Expand Up @@ -45,6 +51,10 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
Expand All @@ -61,8 +71,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
Expand All @@ -79,15 +93,20 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
Expand All @@ -97,6 +116,7 @@ golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
Expand Down
69 changes: 28 additions & 41 deletions pkg/templatelib/lib.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package templatelib

import (
"encoding/json"
"fmt"
"os"
"reflect"
"strings"
"text/template"

"github.com/Masterminds/sprig/v3"
)

func swapStringsFuncBoolArgsOrder(a func(string, string) bool) func(string, string) bool {
Expand Down Expand Up @@ -68,55 +69,33 @@ func stringsModifierActionFactory(a func(string, string) string) func([]string,
}
}

var FuncMap = template.FuncMap{
// {{- $isGitHub := hasPrefix "https://github.com/" $url -}}
// {{- $isHtml := hasSuffix ".html" $url -}}
"hasPrefix": swapStringsFuncBoolArgsOrder(strings.HasPrefix),
"hasSuffix": swapStringsFuncBoolArgsOrder(strings.HasSuffix),

// {{- $hugeIfTrue := .SomeValue | ternary "HUGE" "not so huge" -}}
// if .SomeValue is truthy, $hugeIfTrue will be "HUGE"
// (otherwise, "not so huge")
"ternary": func(truthy interface{}, falsey interface{}, val interface{}) interface{} {
if t, ok := template.IsTrue(val); !ok {
panic(fmt.Sprintf(`template.IsTrue(%+v) says things are NOT OK`, val))
} else if t {
return truthy
} else {
return falsey
func FuncMap() template.FuncMap {
funcMap := sprig.TxtFuncMap()

// https://github.com/Masterminds/sprig/pull/276
funcMap["ternary"] = func(vt interface{}, vf interface{}, v interface{}) interface{} {
if truth, ok := template.IsTrue(v); !ok {
panic(fmt.Sprintf(`template.IsTrue(%+v) says things are NOT OK`, v))
} else if truth {
return vt
}
},
return vf
}

// First Tag: {{- .Tags | first -}}
// Last Tag: {{- .Tags | last -}}
"first": thingsActionFactory("first", true, func(args []interface{}, arg interface{}) interface{} { return arg }),
"last": thingsActionFactory("last", false, func(args []interface{}, arg interface{}) interface{} { return arg }),
// Everybody: {{- join ", " .Names -}}
// Concat: {{- join "/" "https://github.com" "jsmith" "some-repo" -}}
funcMap["join"] = stringsActionFactory("join", true, strings.Join)
// (this differs slightly from the Sprig "join" in that it accepts either a list of strings or multiple arguments - Sprig instead has an explicit "list" function which can create a list of strings *from* a list of arguments so that multiple-signature usability like this is not necessary)

// JSON data dump: {{ json . }}
// (especially nice for taking data and piping it to "jq")
// (ie "some-tool inspect --format '{{ json . }}' some-things | jq .")
"json": func(v interface{}) (string, error) {
j, err := json.Marshal(v)
return string(j), err
},

// Everybody: {{- join ", " .Names -}}
// Concat: {{- join "/" "https://github.com" "jsmith" "some-repo" -}}
"join": stringsActionFactory("join", true, strings.Join),

// {{- $mungedUrl := $url | replace "git://" "https://" | trimSuffixes ".git" -}}
// turns: git://github.com/jsmith/some-repo.git
// into: https://github.com/jsmith/some-repo
"trimPrefixes": stringsActionFactory("trimPrefixes", false, stringsModifierActionFactory(strings.TrimPrefix)),
"trimSuffixes": stringsActionFactory("trimSuffixes", false, stringsModifierActionFactory(strings.TrimSuffix)),
"replace": stringsActionFactory("replace", false, func(strs []string, str string) string {
return strings.NewReplacer(strs...).Replace(str)
}),
funcMap["json"] = funcMap["toJson"]

// {{- getenv "PATH" -}}
// {{- getenv "HOME" "no HOME set" -}}
// {{- getenv "HOME" "is set" "is NOT set (or is empty)" -}}
"getenv": thingsActionFactory("getenv", true, func(args []interface{}, arg interface{}) interface{} {
funcMap["getenv"] = thingsActionFactory("getenv", true, func(args []interface{}, arg interface{}) interface{} {
var (
val = os.Getenv(arg.(string))
setVal interface{} = val
Expand All @@ -134,5 +113,13 @@ var FuncMap = template.FuncMap{
} else {
return unsetVal
}
}),
})

// {{- $mungedUrl := $url | replace "git://" "https://" | trimSuffixes ".git" -}}
// turns: git://github.com/jsmith/some-repo.git
// into: https://github.com/jsmith/some-repo
funcMap["trimPrefixes"] = stringsActionFactory("trimPrefixes", false, stringsModifierActionFactory(strings.TrimPrefix))
funcMap["trimSuffixes"] = stringsActionFactory("trimSuffixes", false, stringsModifierActionFactory(strings.TrimSuffix))

return funcMap
}
16 changes: 8 additions & 8 deletions pkg/templatelib/lib_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func Example_prefixSuffix() {
tmpl, err := template.New("github-or-html").Funcs(templatelib.FuncMap).Parse(`
tmpl, err := template.New("github-or-html").Funcs(templatelib.FuncMap()).Parse(`
{{- . -}}
{{- if hasPrefix "https://github.com/" . -}}
Expand Down Expand Up @@ -53,7 +53,7 @@ func Example_prefixSuffix() {
}

func Example_ternary() {
tmpl, err := template.New("huge-if-true").Funcs(templatelib.FuncMap).Parse(`
tmpl, err := template.New("huge-if-true").Funcs(templatelib.FuncMap()).Parse(`
{{- range $a := . -}}
{{ printf "%#v: %s\n" $a (ternary "HUGE" "not so huge" $a) }}
{{- end -}}
Expand Down Expand Up @@ -91,7 +91,7 @@ func Example_ternary() {
}

func Example_firstLast() {
tmpl, err := template.New("first-and-last").Funcs(templatelib.FuncMap).Parse(`First: {{ . | first }}, Last: {{ . | last }}`)
tmpl, err := template.New("first-and-last").Funcs(templatelib.FuncMap()).Parse(`First: {{ . | first }}, Last: {{ . | last }}`)

err = tmpl.Execute(os.Stdout, []interface{}{
"a",
Expand All @@ -107,7 +107,7 @@ func Example_firstLast() {
}

func Example_json() {
tmpl, err := template.New("json").Funcs(templatelib.FuncMap).Parse(`
tmpl, err := template.New("json").Funcs(templatelib.FuncMap()).Parse(`
{{- json . -}}
`)

Expand All @@ -125,7 +125,7 @@ func Example_json() {
}

func Example_join() {
tmpl, err := template.New("join").Funcs(templatelib.FuncMap).Parse(`
tmpl, err := template.New("join").Funcs(templatelib.FuncMap()).Parse(`
Array: {{ . | join ", " }}{{ "\n" -}}
Args: {{ join ", " "a" "b" "c" -}}
`)
Expand All @@ -145,7 +145,7 @@ func Example_join() {
}

func Example_trimReplaceGitToHttps() {
tmpl, err := template.New("git-to-https").Funcs(templatelib.FuncMap).Parse(`
tmpl, err := template.New("git-to-https").Funcs(templatelib.FuncMap()).Parse(`
{{- range . -}}
{{- . | replace "git://" "https://" | trimSuffixes ".git" }}{{ "\n" -}}
{{- end -}}
Expand All @@ -167,7 +167,7 @@ func Example_trimReplaceGitToHttps() {
}

func Example_trimReplaceGitToGo() {
tmpl, err := template.New("git-to-go").Funcs(templatelib.FuncMap).Parse(`
tmpl, err := template.New("git-to-go").Funcs(templatelib.FuncMap()).Parse(`
{{- range . -}}
{{- . | trimPrefixes "git://" "http://" "https://" "ssh://" | trimSuffixes ".git" }}{{ "\n" -}}
{{- end -}}
Expand All @@ -193,7 +193,7 @@ func Example_trimReplaceGitToGo() {
}

func Example_getenv() {
tmpl, err := template.New("getenv").Funcs(templatelib.FuncMap).Parse(`
tmpl, err := template.New("getenv").Funcs(templatelib.FuncMap()).Parse(`
The FOO environment variable {{ getenv "FOO" "is set" "is not set" }}. {{- "\n" -}}
BAR: {{ getenv "BAR" "not set" }} {{- "\n" -}}
BAZ: {{ getenv "BAZ" "not set" }} {{- "\n" -}}
Expand Down
4 changes: 2 additions & 2 deletions pkg/templatelib/lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func TestTernaryPanic(t *testing.T) {
// one of the only places template.IsTrue will return "false" for the "ok" value is an UnsafePointer (hence this test)

tmpl, err := template.New("unsafe-pointer").Funcs(templatelib.FuncMap).Parse(`{{ ternary "true" "false" . }}`)
tmpl, err := template.New("unsafe-pointer").Funcs(templatelib.FuncMap()).Parse(`{{ ternary "true" "false" . }}`)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -27,7 +27,7 @@ func TestTernaryPanic(t *testing.T) {
}

func TestJoinPanic(t *testing.T) {
tmpl, err := template.New("join-no-arg").Funcs(templatelib.FuncMap).Parse(`{{ join }}`)
tmpl, err := template.New("join-no-arg").Funcs(templatelib.FuncMap()).Parse(`{{ join }}`)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand Down

0 comments on commit 750da3b

Please sign in to comment.