Skip to content

Commit

Permalink
Pipeline: add template functions to serialize DOM to various formats
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Kosegi <richard.kosegi@gmail.com>
  • Loading branch information
rkosegi committed Aug 22, 2024
1 parent c31bdc2 commit 79d1ebb
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 18 deletions.
2 changes: 1 addition & 1 deletion pipeline/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (ac actContext) Executor() Executor { return ac.e }
func (ac actContext) TemplateEngine() TemplateEngine { return ac.t }
func (ac actContext) Logger() Logger { return ac.l }
func (ac actContext) Snapshot() map[string]interface{} {
return dom.DefaultNodeMappingFn(ac.Data()).(map[string]interface{})
return dom.DefaultNodeEncoderFn(ac.Data()).(map[string]interface{})
}

func (p *exec) newCtx(a Action) *actContext {
Expand Down
2 changes: 1 addition & 1 deletion pipeline/export_op.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (e *ExportOp) Do(ctx ActionContext) (err error) {
}
return enc(f, d.(dom.Leaf).Value())
}
return enc(f, dom.DefaultNodeMappingFn(d.(dom.Container)))
return enc(f, dom.DefaultNodeEncoderFn(d.(dom.Container)))
}

func (e *ExportOp) CloneWith(ctx ActionContext) Action {
Expand Down
19 changes: 11 additions & 8 deletions pipeline/template_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@ type templateEngine struct {
func renderTemplate(tmplStr string, data interface{}, fm template.FuncMap) (string, error) {
tmpl := template.New("tmpl").Funcs(fm)
tmpl.Funcs(template.FuncMap{
"tpl": tplFunc(tmpl),
"toYaml": toYamlFunc,
"isEmpty": isEmptyFunc,
"unflatten": unflattenFunc,
"fileExists": fileExistsFunc,
"mergeFiles": mergeFilesFunc,
"isDir": isDirFunc,
"glob": globFunc,
"tpl": tplFunc(tmpl),
"toYaml": toYamlFunc,
"isEmpty": isEmptyFunc,
"unflatten": unflattenFunc,
"fileExists": fileExistsFunc,
"mergeFiles": mergeFilesFunc,
"isDir": isDirFunc,
"glob": globFunc,
"dom2yaml": dom2yamlFunc,
"dom2json": dom2jsonFunc,
"dom2properties": dom2propertiesFunc,
})
_, err := tmpl.Parse(tmplStr)
if err != nil {
Expand Down
30 changes: 22 additions & 8 deletions pipeline/template_engine_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ limitations under the License.
package pipeline

import (
"fmt"
"github.com/rkosegi/yaml-toolkit/analytics"
"github.com/rkosegi/yaml-toolkit/dom"
"github.com/rkosegi/yaml-toolkit/props"
"github.com/rkosegi/yaml-toolkit/utils"
"os"
"path/filepath"
Expand Down Expand Up @@ -89,18 +89,32 @@ func globFunc(pattern string) ([]string, error) {
return filepath.Glob(pattern)
}

// mergeFilesFunc merges 0 or more files into single map[string]interface{}
func mergeFilesFunc(files []string) (map[string]interface{}, error) {
// mergeFilesFunc merges 0 or more files into dom.Container
func mergeFilesFunc(files []string) (dom.Container, error) {
ds := analytics.NewDocumentSet()
result := make(map[string]interface{})
for _, f := range files {
err := ds.AddDocumentFromFile(f, analytics.DefaultFileDecoderProvider(f))
if err != nil {
return nil, err
}
}
for k, v := range ds.AsOne().Merged(dom.ListsMergeAppend()).Flatten() {
result[k] = fmt.Sprintf("%v", v.Value())
}
return result, nil
return ds.AsOne().Merged(dom.ListsMergeAppend()), nil
}

func dom2str(c dom.Container, encFn dom.EncoderFunc) (string, error) {
var buf strings.Builder
err := c.Serialize(&buf, dom.DefaultNodeEncoderFn, encFn)
return buf.String(), err
}

func dom2yamlFunc(c dom.Container) (string, error) {
return dom2str(c, dom.DefaultYamlEncoder)
}

func dom2jsonFunc(c dom.Container) (string, error) {
return dom2str(c, dom.DefaultJsonEncoder)
}

func dom2propertiesFunc(c dom.Container) (string, error) {
return dom2str(c, props.EncoderFn)
}
42 changes: 42 additions & 0 deletions pipeline/template_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,45 @@ func TestTemplateFuncGlob(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, 1, len(files))
}

func TestTemplateFuncDom2Yaml(t *testing.T) {
type testCase struct {
format string
exp string
}
d, err := os.MkdirTemp("", "yt*")
assert.NoError(t, err)
removeDirsLater(t, d)
f1, err := os.CreateTemp(d, "yt*.yaml")
assert.NoError(t, err)
f2, err := os.CreateTemp(d, "yt*.yaml")
assert.NoError(t, err)
_, err = f1.Write([]byte("a: 1"))
assert.NoError(t, err)
_, err = f2.Write([]byte("b: 2\n"))
assert.NoError(t, err)
for _, tc := range []testCase{
{
format: "properties",
exp: "a=1",
},
{
format: "yaml",
exp: "a: 1",
},
{
format: "json",
exp: `"a": 1`,
},
} {
var res string
res, err = renderTemplate(`{{ mergeFiles ( glob ( printf "%s/*.yaml" .Temp ) ) | dom2`+tc.format+` | trim }}`,
map[string]interface{}{
"Temp": d,
}, sprig.HermeticTxtFuncMap())
t.Logf("Merged content using format '%s':\n%s", tc.format, res)
assert.NoError(t, err)
assert.Contains(t, res, tc.exp)
}
removeFilesLater(t, f1, f2)
}

0 comments on commit 79d1ebb

Please sign in to comment.