Skip to content

Commit

Permalink
feat: add support for jinja2 like templates
Browse files Browse the repository at this point in the history
  • Loading branch information
gchiesa committed Aug 9, 2024
1 parent 51eb60c commit e82f9f7
Show file tree
Hide file tree
Showing 15 changed files with 161 additions and 45 deletions.
4 changes: 3 additions & 1 deletion cmd/create.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"github.com/gchiesa/ska/pkg/skaffolder"
)

Expand All @@ -11,9 +12,10 @@ type CreateCmd struct {
NonInteractive bool `arg:"-n,--non-interactive" help:"Run in non-interactive mode"`
}

func (c *CreateCmd) Execute() error {
func (c *CreateCmd) Execute(ctx context.Context) error {
options := &skaffolder.SkaOptions{
NonInteractive: c.NonInteractive,
Engine: ctx.Value("engine").(string),
}
ska := skaffolder.NewSkaCreate(
c.TemplateURI,
Expand Down
12 changes: 10 additions & 2 deletions cmd/entrypoint.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"fmt"
"github.com/alexflint/go-arg"
"github.com/apex/log"
Expand All @@ -19,6 +20,7 @@ type arguments struct {
UpdateCmd *UpdateCmd `arg:"subcommand:update"`
Debug bool `arg:"-d"`
JSONOutput bool `arg:"-j,--json" help:"Enable JSON output for logging"`
Engine string `arg:"--engine" default:"sprig" help:"Template engine to use (sprig or jinja)"`
}

func (arguments) Version() string {
Expand Down Expand Up @@ -54,13 +56,19 @@ func Execute(version string) error {
log.SetHandler(json.New(os.Stderr))
}

if args.Engine != "sprig" && args.Engine != "jinja" {
log.Fatalf("invalid template engine: %s", args.Engine)
}

ctx := context.TODO()
ctx = context.WithValue(ctx, "engine", args.Engine)

Check warning on line 64 in cmd/entrypoint.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

context-keys-type: should not use basic type string as key in context.WithValue (revive)

Check warning on line 64 in cmd/entrypoint.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

context-keys-type: should not use basic type string as key in context.WithValue (revive)
switch {
case args.CreateCmd != nil:
if err := args.CreateCmd.Execute(); err != nil {
if err := args.CreateCmd.Execute(ctx); err != nil {
log.Fatalf("error executing create command: %v", err)
}
case args.UpdateCmd != nil:
if err := args.UpdateCmd.Execute(); err != nil {
if err := args.UpdateCmd.Execute(ctx); err != nil {
log.Fatalf("error executing update command: %v", err)
}
default:
Expand Down
4 changes: 3 additions & 1 deletion cmd/update.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"github.com/gchiesa/ska/pkg/skaffolder"
)

Expand All @@ -10,9 +11,10 @@ type UpdateCmd struct {
NonInteractive bool `arg:"-n,--non-interactive" help:"Run in non-interactive mode"`
}

func (c *UpdateCmd) Execute() error {
func (c *UpdateCmd) Execute(ctx context.Context) error {
options := &skaffolder.SkaOptions{
NonInteractive: c.NonInteractive,
Engine: ctx.Value("engine").(string),
}
ska := skaffolder.NewSkaUpdate(
c.FolderPath,
Expand Down
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ require (
github.com/charmbracelet/bubbletea v0.26.4
github.com/charmbracelet/lipgloss v0.12.1
github.com/daixiang0/gci v0.13.4
github.com/flosch/pongo2/v6 v6.0.0
github.com/go-critic/go-critic v0.11.3
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572
github.com/golangci/golangci-lint v1.58.1
github.com/gotesttools/gotestfmt/v2 v2.5.0
github.com/huandu/xstrings v1.5.0
github.com/otiai10/copy v1.14.0
github.com/palantir/stacktrace v0.0.0-20161112013806-78658fd2d177
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/stretchr/testify v1.9.0
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
Expand Down Expand Up @@ -147,12 +149,10 @@ require (
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/nishanths/exhaustive v0.12.0 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/nunnatsa/ginkgolinter v0.16.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/palantir/stacktrace v0.0.0-20161112013806-78658fd2d177 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand Down Expand Up @@ -225,7 +225,6 @@ require (
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/firefart/nonamedreturns v1.0.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA=
github.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw=
github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU=
github.com/flosch/pongo2/v6 v6.0.0/go.mod h1:CuDpFm47R0uGGE7z13/tTlt1Y6zdxvr2RLT5LJhsHEU=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
Expand Down Expand Up @@ -463,8 +465,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=
github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
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/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg=
github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
Expand Down Expand Up @@ -1050,8 +1050,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
Expand Down
14 changes: 4 additions & 10 deletions internal/processor/filetreeprocessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package processor

import (
"github.com/apex/log"
"github.com/gchiesa/ska/internal/templateservice"
ts "github.com/gchiesa/ska/internal/templateprovider"
"os"
)

Expand All @@ -15,7 +15,7 @@ func NewFileTreeProcessor(sourcePath, destinationPathRoot string, options ...fun
sourcePath: sourcePath,
destinationPathRoot: destinationPathRoot,
workingDir: "",
templateService: templateservice.NewSprigTemplate("default"),
template: nil,
log: logCtx,
}
// configure options
Expand Down Expand Up @@ -72,15 +72,9 @@ func (tp *FileTreeProcessor) Render(withVariables map[string]interface{}) error
return nil
}

func WithTemplateService(templateService *templateservice.SprigTemplate) func(tp *FileTreeProcessor) {
func WithTemplateService(ts ts.TemplateService) func(tp *FileTreeProcessor) {

Check failure on line 75 in internal/processor/filetreeprocessor.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

importShadow: shadow of imported from 'github.com/gchiesa/ska/internal/templateprovider' package 'ts' (gocritic)

Check failure on line 75 in internal/processor/filetreeprocessor.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

importShadow: shadow of imported from 'github.com/gchiesa/ska/internal/templateprovider' package 'ts' (gocritic)
return func(tp *FileTreeProcessor) {
tp.templateService = templateService
}
}

func WithErrorOnMissingKey(errorOnMissingKey bool) func(tp *FileTreeProcessor) {
return func(tp *FileTreeProcessor) {
tp.templateService.WithErrorOnMissingKey(errorOnMissingKey)
tp.template = ts
}
}

Expand Down
12 changes: 6 additions & 6 deletions internal/processor/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ func (tp *FileTreeProcessor) buildStagingFileTree(withVariables map[string]inter
}

// create a template from the file name as it was a template
if err := tp.templateService.FromString(sRelPath); err != nil {
if err := tp.template.FromString(sRelPath); err != nil {
return err
}

// render the template
buff := bytes.NewBufferString("")
if err := tp.templateService.Execute(buff, withVariables); err != nil {
if tp.templateService.IsMissingKeyError(err) {
if err := tp.template.Execute(buff, withVariables); err != nil {
if tp.template.IsMissingKeyError(err) {
logger.WithFields(log.Fields{"path": sRelPath}).Errorf("missing variable while rendering file path: %s", sRelPath)
}
return err
Expand Down Expand Up @@ -158,14 +158,14 @@ func (tp *FileTreeProcessor) renderStagingFileTree(withVariables map[string]inte
return nil
}

if err := tp.templateService.FromFile(absPath); err != nil {
if err := tp.template.FromFile(absPath); err != nil {
return err
}

// render the template
buff := bytes.NewBufferString("")
if err := tp.templateService.Execute(buff, withVariables); err != nil {
if tp.templateService.IsMissingKeyError(err) {
if err := tp.template.Execute(buff, withVariables); err != nil {
if tp.template.IsMissingKeyError(err) {
logger.WithFields(log.Fields{"path": relPath}).Errorf("missing variable while rendering file: %s", relPath)
}
return err
Expand Down
4 changes: 2 additions & 2 deletions internal/processor/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package processor
import (
"github.com/apex/log"
"github.com/gchiesa/ska/internal/multipart"
"github.com/gchiesa/ska/internal/templateservice"
"github.com/gchiesa/ska/internal/templateprovider"
)

type FileTreeProcessor struct {
Expand All @@ -13,6 +13,6 @@ type FileTreeProcessor struct {
destinationIgnorePaths []string
workingDir string
multiparts []*multipart.Multipart
templateService *templateservice.SprigTemplate
template templateprovider.TemplateService
log *log.Entry
}
62 changes: 62 additions & 0 deletions internal/templateprovider/jinjatemplate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package templateprovider

import (
"github.com/flosch/pongo2/v6"
"github.com/palantir/stacktrace"
"io"
)

type JinjaTemplate struct {
templateFilePath string

Check failure on line 10 in internal/templateprovider/jinjatemplate.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

field `templateFilePath` is unused (unused)

Check failure on line 10 in internal/templateprovider/jinjatemplate.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

field `templateFilePath` is unused (unused)
templateContent string
variables map[string]interface{}
pongo2Template *pongo2.Template
}

func NewJinjaTemplate(name string) *JinjaTemplate {

Check warning on line 16 in internal/templateprovider/jinjatemplate.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)

Check warning on line 16 in internal/templateprovider/jinjatemplate.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

unused-parameter: parameter 'name' seems to be unused, consider removing or renaming it as _ (revive)
return &JinjaTemplate{}
}

func (t *JinjaTemplate) FromString(templateContent string) error {
t.templateContent = templateContent
tpl, err := pongo2.FromString(t.templateContent)
if err != nil {
return stacktrace.Propagate(err, "failed to parse template")
}
t.pongo2Template = tpl
return nil
}

func (t *JinjaTemplate) FromFile(templateFilePath string) error {
tpl, err := pongo2.FromFile(templateFilePath)
if err != nil {
return err
}
t.pongo2Template = tpl
return nil
}

func (t *JinjaTemplate) Execute(fp io.Writer, withVariables map[string]interface{}) error {
t.variables = withVariables
var context = make(pongo2.Context)
for k, v := range t.variables {
context[k] = v.(any)

Check failure on line 43 in internal/templateprovider/jinjatemplate.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

sloppyTypeAssert: type assertion from/to types are identical (gocritic)

Check failure on line 43 in internal/templateprovider/jinjatemplate.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

sloppyTypeAssert: type assertion from/to types are identical (gocritic)
}
renderedContent, err := t.pongo2Template.Execute(context)
if err != nil {
return err
}

_, err = fp.Write([]byte(renderedContent))
if err != nil {
return err
}
return nil
}

func (t *JinjaTemplate) WithErrorOnMissingKey(_ bool) {
}

func (t *JinjaTemplate) IsMissingKeyError(err error) bool {
return err.Error() == "TokenError"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package templateservice
package templateprovider

import (
sprig "github.com/go-task/slim-sprig"
Expand All @@ -24,13 +24,12 @@ func NewSprigTemplate(name string) *SprigTemplate {
}
}

func (t *SprigTemplate) WithErrorOnMissingKey(state bool) *SprigTemplate {
func (t *SprigTemplate) WithErrorOnMissingKey(state bool) {
if state {
t.textTemplate.Option("missingkey=error")
} else {
t.textTemplate.Option("missingkey=default")
}
return t
}

func (t *SprigTemplate) FromString(templateContent string) error {
Expand Down
12 changes: 12 additions & 0 deletions internal/templateprovider/templateservice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package templateprovider

func ByType(templateType TemplateType, name string) TemplateService {
var ts TemplateService
switch templateType {
case SprigTemplateService:
ts = NewSprigTemplate(name)
case JinjaTemplateService:
ts = NewJinjaTemplate(name)
}
return ts
}
24 changes: 24 additions & 0 deletions internal/templateprovider/type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package templateprovider

import (
"io"
)

type TemplateService interface {
// FromFile Load template from file
FromFile(path string) error
// FromString Load template from string
FromString(templateContent string) error
// Execute Execute the template
Execute(fp io.Writer, withVariables map[string]interface{}) error
// WithErrorOnMissingKey Set error on missing key
WithErrorOnMissingKey(key bool)
IsMissingKeyError(err error) bool
}

type TemplateType int

const (
SprigTemplateService TemplateType = iota
JinjaTemplateService
)
11 changes: 0 additions & 11 deletions internal/templateservice/type.go

This file was deleted.

Loading

0 comments on commit e82f9f7

Please sign in to comment.