Skip to content

Commit

Permalink
feat: add ability to fill a Golang template from a Starlark transformer
Browse files Browse the repository at this point in the history
Signed-off-by: Harikrishnan Balagopal <harikrishmenon@gmail.com>
  • Loading branch information
HarikrishnanBalagopal committed Jun 21, 2023
1 parent 7304a4f commit 66331cb
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
8 changes: 3 additions & 5 deletions common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,12 +641,10 @@ func GetStringFromTemplate(tpl string, config interface{}) (string, error) {
var tplbuffer bytes.Buffer
packageTemplate, err := template.New("").Funcs(sprig.TxtFuncMap()).Parse(tpl)
if err != nil {
logrus.Errorf("Unable to parse template : %s", err)
return "", err
return "", fmt.Errorf("failed to parse the template. Error: %w", err)
}
err = packageTemplate.Execute(&tplbuffer, config)
if err != nil {
return "", fmt.Errorf("unable to transform template to string using the data. Error: %q . Data: %+v Template: %q", err, config, tpl)
if err := packageTemplate.Execute(&tplbuffer, config); err != nil {
return "", fmt.Errorf("failed to transform the template to string using the data. Error: %w . Data: %+v Template: '%s'", err, config, tpl)
}
return tplbuffer.String(), nil
}
Expand Down
48 changes: 48 additions & 0 deletions transformer/external/starlarktransformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const (
// Function names
qaFnName = "query"
// fs package
evalTemplate = "eval_template"
fsExistsFnName = "exists"
fsReadAsStringFnName = "read_as_string"
fsReadAsBinaryFnName = "read_as_binary"
Expand Down Expand Up @@ -330,6 +331,7 @@ func (t *Starlark) setDefaultGlobals() {
t.StarGlobals = starlark.StringDict{}
t.addStarlibModules()
t.addFSModules()
t.addTemplateModules()
t.addAppModules()
t.addCryptoModules()
t.addArchiveModules()
Expand Down Expand Up @@ -377,6 +379,15 @@ func (t *Starlark) addFSModules() {
}
}

func (t *Starlark) addTemplateModules() {
t.StarGlobals["template"] = &starlarkstruct.Module{
Name: "template",
Members: starlark.StringDict{
evalTemplate: t.getStarlarkEvalTemplate(),
},
}
}

func (t *Starlark) addCryptoModules() {
t.StarGlobals["crypto"] = &starlarkstruct.Module{
Name: "crypto",
Expand Down Expand Up @@ -557,6 +568,43 @@ func (t *Starlark) getStarlarkFSWrite() *starlark.Builtin {
})
}

func (t *Starlark) getStarlarkEvalTemplate() *starlark.Builtin {
return starlark.NewBuiltin(evalTemplate, func(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
templateContents := ""
data := starlark.NewDict(16)
if err := starlark.UnpackPositionalArgs(fsExistsFnName, args, kwargs, 2, &templateContents, &data); err != nil {
return nil, fmt.Errorf("failed to unpack the positional arguments. Error: %w", err)
}
logrus.Debugf("templateContents:\n%s\n---------------\n", templateContents)
dataMap := map[string]interface{}{}
for _, x := range data.Items() {
k, err := starutil.Unmarshal(x[0])
if err != nil {
logrus.Errorf("failed to unmarshal the Starlark value %#v as a Golang interface{} . Error: %q", x[0], err)
continue
}
v, err := starutil.Unmarshal(x[1])
if err != nil {
logrus.Errorf("failed to unmarshal the Starlark value %#v as a Golang interface{} . Error: %q", x[1], err)
continue
}
kStr, ok := k.(string)
if !ok {
logrus.Errorf("expected the key to be a string. actual type is %T and value is %#v", k, k)
continue
}
dataMap[kStr] = v
}
logrus.Debugf("dataMap:\n%#v\n---------------\n", dataMap)
filledTemplate, err := common.GetStringFromTemplate(templateContents, dataMap)
if err != nil {
return starlark.String(""), fmt.Errorf("failed to fill the template '%s' using the data %#v . Error: %w", templateContents, data, err)
}
logrus.Debugf("filledTemplate:\n%s\n---------------\n", filledTemplate)
return starlark.String(filledTemplate), nil
})
}

func (t *Starlark) getStarlarkFSExists() *starlark.Builtin {
return starlark.NewBuiltin(fsExistsFnName, func(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var path string
Expand Down

0 comments on commit 66331cb

Please sign in to comment.