mirror of https://github.com/databricks/cli.git
Add map and pair helper functions for bundle templates (#665)
## Changes Go text templates allows only specifying one input argument for invocations of associated templates (ie `{{template ...}}`). This PR introduces the map and pair functions which allow template authors to work around this limitation by passing multiple arguments as key value pairs in a map. This PR is based on feedback from the mlops stacks migration where otherwise a bunch of duplicate code is required for computed values and fixtures. ## Tests Unit test
This commit is contained in:
parent
61b103318f
commit
6c644e159c
|
@ -15,6 +15,11 @@ func (err ErrFail) Error() string {
|
||||||
return err.msg
|
return err.msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type pair struct {
|
||||||
|
k string
|
||||||
|
v any
|
||||||
|
}
|
||||||
|
|
||||||
var helperFuncs = template.FuncMap{
|
var helperFuncs = template.FuncMap{
|
||||||
"fail": func(format string, args ...any) (any, error) {
|
"fail": func(format string, args ...any) (any, error) {
|
||||||
return nil, ErrFail{fmt.Sprintf(format, args...)}
|
return nil, ErrFail{fmt.Sprintf(format, args...)}
|
||||||
|
@ -27,4 +32,23 @@ var helperFuncs = template.FuncMap{
|
||||||
"regexp": func(expr string) (*regexp.Regexp, error) {
|
"regexp": func(expr string) (*regexp.Regexp, error) {
|
||||||
return regexp.Compile(expr)
|
return regexp.Compile(expr)
|
||||||
},
|
},
|
||||||
|
// A key value pair. This is used with the map function to generate maps
|
||||||
|
// to use inside a template
|
||||||
|
"pair": func(k string, v any) pair {
|
||||||
|
return pair{k, v}
|
||||||
|
},
|
||||||
|
// map converts a list of pairs to a map object. This is useful to pass multiple
|
||||||
|
// objects to templates defined in the library directory. Go text template
|
||||||
|
// syntax for invoking a template only allows specifying a single argument,
|
||||||
|
// this function can be used to workaround that limitation.
|
||||||
|
//
|
||||||
|
// For example: {{template "my_template" (map (pair "foo" $arg1) (pair "bar" $arg2))}}
|
||||||
|
// $arg1 and $arg2 can be referred from inside "my_template" as ".foo" and ".bar"
|
||||||
|
"map": func(pairs ...pair) map[string]any {
|
||||||
|
result := make(map[string]any, 0)
|
||||||
|
for _, p := range pairs {
|
||||||
|
result[p.k] = p.v
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,3 +54,18 @@ func TestTemplateUrlFunction(t *testing.T) {
|
||||||
assert.Len(t, r.files, 1)
|
assert.Len(t, r.files, 1)
|
||||||
assert.Equal(t, "https://www.databricks.com", string(r.files[0].(*inMemoryFile).content))
|
assert.Equal(t, "https://www.databricks.com", string(r.files[0].(*inMemoryFile).content))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTemplateMapPairFunction(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
|
r, err := newRenderer(ctx, nil, "./testdata/map-pair/template", "./testdata/map-pair/library", tmpDir)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = r.walk()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, r.files, 1)
|
||||||
|
assert.Equal(t, "false 123 hello 12.3", string(r.files[0].(*inMemoryFile).content))
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{{- define "my_template" -}}
|
||||||
|
{{- .foo}} {{.bar}} {{.abc}} {{.def -}}
|
||||||
|
{{- end -}}
|
|
@ -0,0 +1 @@
|
||||||
|
{{template "my_template" (map (pair "foo" false) (pair "bar" 123) (pair "abc" "hello") (pair "def" 12.3)) -}}
|
Loading…
Reference in New Issue