From e6a4ce0b055b339bf645f6a00750ff29b552ed04 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Tue, 4 Jun 2024 12:11:03 +0200 Subject: [PATCH 1/5] backfill sprig functions in liquid templating --- .gitignore | 3 +++ template/liquid.go | 23 ++++++++-------------- template/utils.go | 49 ---------------------------------------------- 3 files changed, 11 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index 66fd13c..a7b61e8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +# IDE +.idea diff --git a/template/liquid.go b/template/liquid.go index 5a11211..1847354 100644 --- a/template/liquid.go +++ b/template/liquid.go @@ -1,38 +1,31 @@ package template import ( - "strings" - "github.com/Masterminds/sprig/v3" "github.com/osteele/liquid" ) var ( - liquidEngine = liquid.NewEngine() - sprigFunctions = map[string]string{ + liquidEngine = liquid.NewEngine() + sprigFunctionNameMap = map[string]string{ "toJson": "to_json", "fromJson": "from_json", - "b64enc": "b64enc", - "b64dec": "b64dec", "semverCompare": "semver_compare", "sha256sum": "sha26sum", - "quote": "quote", - "squote": "squote", - "replace": "replace", - "coalesce": "coalesce", } ) func init() { fncs := sprig.TxtFuncMap() - for key, name := range sprigFunctions { + + for name, fnc := range fncs { + liquidEngine.RegisterFilter(name, fnc) + } + + for key, name := range sprigFunctionNameMap { liquidEngine.RegisterFilter(name, fncs[key]) } - liquidEngine.RegisterFilter("indent", indent) - liquidEngine.RegisterFilter("nindent", nindent) - liquidEngine.RegisterFilter("replace", strings.ReplaceAll) - liquidEngine.RegisterFilter("default", dfault) liquidEngine.RegisterFilter("ternary", ternary) } diff --git a/template/utils.go b/template/utils.go index 963ea1a..33d2d2c 100644 --- a/template/utils.go +++ b/template/utils.go @@ -1,19 +1,5 @@ package template -import ( - "reflect" - "strings" -) - -func indent(v string, spaces int) string { - pad := strings.Repeat(" ", spaces) - return pad + strings.ReplaceAll(v, "\n", "\n"+pad) -} - -func nindent(v string, spaces int) string { - return "\n" + indent(v, spaces) -} - func ternary(v bool, vt interface{}, vf interface{}) interface{} { if v { return vt @@ -21,38 +7,3 @@ func ternary(v bool, vt interface{}, vf interface{}) interface{} { return vf } - -func dfault(v1, v2 interface{}) interface{} { - if empty(v1) { - return v2 - } - - return v1 -} - -func empty(given interface{}) bool { - g := reflect.ValueOf(given) - if !g.IsValid() { - return true - } - - // Basically adapted from text/template.isTrue - switch g.Kind() { - default: - return g.IsNil() - case reflect.Array, reflect.Slice, reflect.Map, reflect.String: - return g.Len() == 0 - case reflect.Bool: - return !g.Bool() - case reflect.Complex64, reflect.Complex128: - return g.Complex() == 0 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return g.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return g.Uint() == 0 - case reflect.Float32, reflect.Float64: - return g.Float() == 0 - case reflect.Struct: - return false - } -} From 9d660189c21487fc3b2e30fe456cb1e13280c589 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Tue, 4 Jun 2024 16:54:40 +0200 Subject: [PATCH 2/5] exclude funcs without params --- template/liquid.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/template/liquid.go b/template/liquid.go index 1847354..2779122 100644 --- a/template/liquid.go +++ b/template/liquid.go @@ -3,11 +3,13 @@ package template import ( "github.com/Masterminds/sprig/v3" "github.com/osteele/liquid" + "github.com/pluralsh/polly/algorithms" ) var ( - liquidEngine = liquid.NewEngine() - sprigFunctionNameMap = map[string]string{ + liquidEngine = liquid.NewEngine() + excludedSprigFunctions = []string{"hello", "now", "uuidv4"} + sprigFunctionNameMap = map[string]string{ "toJson": "to_json", "fromJson": "from_json", "semverCompare": "semver_compare", @@ -19,7 +21,9 @@ func init() { fncs := sprig.TxtFuncMap() for name, fnc := range fncs { - liquidEngine.RegisterFilter(name, fnc) + if algorithms.Index(excludedSprigFunctions, func(s string) bool { return s == name }) < 0 { + liquidEngine.RegisterFilter(name, fnc) + } } for key, name := range sprigFunctionNameMap { From c31528f74f3b740bcc541bb74f7444acae3f8045 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 5 Jun 2024 17:49:39 +0200 Subject: [PATCH 3/5] restore internal functions --- template/liquid.go | 32 +++++++++++++++++++++++++----- template/utils.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/template/liquid.go b/template/liquid.go index 2779122..43d8f04 100644 --- a/template/liquid.go +++ b/template/liquid.go @@ -1,36 +1,58 @@ package template import ( + "strings" + "github.com/Masterminds/sprig/v3" "github.com/osteele/liquid" "github.com/pluralsh/polly/algorithms" ) var ( - liquidEngine = liquid.NewEngine() + liquidEngine = liquid.NewEngine() + + // excludedSprigFunctions contains names of Spring functions that will be excluded. excludedSprigFunctions = []string{"hello", "now", "uuidv4"} - sprigFunctionNameMap = map[string]string{ + + // sprigFunctionNameAliases contains additional aliases for Sprig functions. + sprigFunctionNameAliases = map[string]string{ "toJson": "to_json", "fromJson": "from_json", "semverCompare": "semver_compare", "sha256sum": "sha26sum", } + + // internalFunctions to register. These will override Sprig functions. + internalFunctions = map[string]any{ + "indent": indent, + "nindent": nindent, + "replace": strings.ReplaceAll, + "default": dfault, + "ternary": ternary, + } ) func init() { fncs := sprig.TxtFuncMap() + excludedFunctions := excludedSprigFunctions + for k := range internalFunctions { + excludedFunctions = append(excludedFunctions, k) + } + for name, fnc := range fncs { - if algorithms.Index(excludedSprigFunctions, func(s string) bool { return s == name }) < 0 { + if algorithms.Index(excludedFunctions, func(s string) bool { return s == name }) < 0 { liquidEngine.RegisterFilter(name, fnc) } } - for key, name := range sprigFunctionNameMap { + for key, name := range sprigFunctionNameAliases { liquidEngine.RegisterFilter(name, fncs[key]) } - liquidEngine.RegisterFilter("ternary", ternary) + for name, fnc := range internalFunctions { + liquidEngine.RegisterFilter(name, fnc) + } } func RenderLiquid(input []byte, bindings map[string]interface{}) ([]byte, error) { diff --git a/template/utils.go b/template/utils.go index 33d2d2c..963ea1a 100644 --- a/template/utils.go +++ b/template/utils.go @@ -1,5 +1,19 @@ package template +import ( + "reflect" + "strings" +) + +func indent(v string, spaces int) string { + pad := strings.Repeat(" ", spaces) + return pad + strings.ReplaceAll(v, "\n", "\n"+pad) +} + +func nindent(v string, spaces int) string { + return "\n" + indent(v, spaces) +} + func ternary(v bool, vt interface{}, vf interface{}) interface{} { if v { return vt @@ -7,3 +21,38 @@ func ternary(v bool, vt interface{}, vf interface{}) interface{} { return vf } + +func dfault(v1, v2 interface{}) interface{} { + if empty(v1) { + return v2 + } + + return v1 +} + +func empty(given interface{}) bool { + g := reflect.ValueOf(given) + if !g.IsValid() { + return true + } + + // Basically adapted from text/template.isTrue + switch g.Kind() { + default: + return g.IsNil() + case reflect.Array, reflect.Slice, reflect.Map, reflect.String: + return g.Len() == 0 + case reflect.Bool: + return !g.Bool() + case reflect.Complex64, reflect.Complex128: + return g.Complex() == 0 + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return g.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return g.Uint() == 0 + case reflect.Float32, reflect.Float64: + return g.Float() == 0 + case reflect.Struct: + return false + } +} From a103360ed59f64ad5b9996a76466ead7a28409ca Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 5 Jun 2024 17:55:51 +0200 Subject: [PATCH 4/5] update comment --- template/liquid.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/liquid.go b/template/liquid.go index 43d8f04..2c3ac00 100644 --- a/template/liquid.go +++ b/template/liquid.go @@ -22,7 +22,7 @@ var ( "sha256sum": "sha26sum", } - // internalFunctions to register. These will override Sprig functions. + // internalFunctions to register. These will override Sprig functions if same names are used. internalFunctions = map[string]any{ "indent": indent, "nindent": nindent, From a22b9ffedfa20c86f6cc0bc57885df8ab7f86e12 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 6 Jun 2024 16:07:05 +0200 Subject: [PATCH 5/5] use lo contains function --- template/liquid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/template/liquid.go b/template/liquid.go index 2c3ac00..a7e93ba 100644 --- a/template/liquid.go +++ b/template/liquid.go @@ -5,7 +5,7 @@ import ( "github.com/Masterminds/sprig/v3" "github.com/osteele/liquid" - "github.com/pluralsh/polly/algorithms" + "github.com/samber/lo" ) var ( @@ -41,7 +41,7 @@ func init() { } for name, fnc := range fncs { - if algorithms.Index(excludedFunctions, func(s string) bool { return s == name }) < 0 { + if !lo.Contains(excludedFunctions, name) { liquidEngine.RegisterFilter(name, fnc) } }