Skip to content

Commit

Permalink
go(feat): Testing adding the dry-run option to gomplate (hairyhenders…
Browse files Browse the repository at this point in the history
  • Loading branch information
mihkels committed Jan 16, 2025
1 parent a97ddf1 commit 783009b
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 18 deletions.
8 changes: 8 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type Config struct {

ExecPipe bool `yaml:"execPipe,omitempty"`
Experimental bool `yaml:"experimental,omitempty"`
DryRun bool `yaml:"dryRun,omitempty"`
}

// TODO: remove when we remove the deprecated array format for templates
Expand Down Expand Up @@ -107,6 +108,7 @@ type rawConfig struct {

ExecPipe bool `yaml:"execPipe,omitempty"`
Experimental bool `yaml:"experimental,omitempty"`
DryRun bool `yaml:"dryRun,omitempty"`
}

// TODO: remove when we remove the deprecated array format for templates
Expand Down Expand Up @@ -140,6 +142,7 @@ func (c *Config) UnmarshalYAML(value *yaml.Node) error {
PluginTimeout: r.PluginTimeout,
ExecPipe: r.ExecPipe,
Experimental: r.Experimental,
DryRun: r.DryRun,
}

return nil
Expand Down Expand Up @@ -170,6 +173,7 @@ func (c Config) MarshalYAML() (interface{}, error) {
PluginTimeout: c.PluginTimeout,
ExecPipe: c.ExecPipe,
Experimental: c.Experimental,
DryRun: c.DryRun,
}

return aux, nil
Expand Down Expand Up @@ -274,6 +278,10 @@ func (c *Config) MergeFrom(o *Config) *Config {
}
}

if !isZero(o.DryRun) {
c.DryRun = true
}

if !isZero(o.OutputMap) {
c.OutputDir = ""
c.OutputFiles = nil
Expand Down
12 changes: 12 additions & 0 deletions gomplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ func Run(ctx context.Context, cfg *Config) error {
}
Metrics.TemplatesGathered = len(tmpl)

// Check for dry-run flag
slog.InfoContext(ctx, "dry-run", "value", cfg.DryRun)
if cfg.DryRun {
err = tr.RenderTemplatesToBuffer(ctx, cfg, namer, tmpl)
if err != nil {
return fmt.Errorf("failed to render templates: %w", err)
}

return nil
}

err = tr.RenderTemplates(ctx, tmpl)
if err != nil {
return err
Expand Down Expand Up @@ -133,6 +144,7 @@ func mappingNamer(outMap string, tr *renderer) outputNamer {
return "", fmt.Errorf("failed to render outputMap with ctx %+v and inPath %s: %w", tctx, inPath, err)
}

slog.Info("outputMap rendered", "in", inPath, "out", out.String())
return filepath.Clean(strings.TrimSpace(out.String())), nil
})
}
6 changes: 6 additions & 0 deletions internal/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ func cobraConfig(cmd *cobra.Command, args []string) (cfg *gomplate.Config, err e
if err != nil {
return nil, err
}

cfg.DryRun, err = getBool(cmd, "dry-run")
if err != nil {
return nil, err
}

return cfg, nil
}

Expand Down
2 changes: 2 additions & 0 deletions internal/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ func InitFlags(command *cobra.Command) {
command.Flags().BoolP("verbose", "V", false, "output extra information about what gomplate is doing")

command.Flags().String("config", defaultConfigFile, "config file (overridden by commandline flags)")

command.Flags().Bool("dry-run", false, "render the templates without writing the output files")
}

// Main -
Expand Down
88 changes: 70 additions & 18 deletions render.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gomplate

import (
"bytes"
"context"
"fmt"
"io"
Expand Down Expand Up @@ -173,13 +174,7 @@ type Template struct {
}

func (r *renderer) RenderTemplates(ctx context.Context, templates []Template) error {
if datafs.FSProviderFromContext(ctx) == nil {
ctx = datafs.ContextWithFSProvider(ctx, DefaultFSProvider)
}

// configure the template context with the refreshed Data value
// only done here because the data context may have changed
tmplctx, err := createTmplContext(ctx, r.tctxAliases, r.sr)
ctx, tmplctx, err := r.initializeTemplateContext(ctx)
if err != nil {
return err
}
Expand All @@ -188,28 +183,33 @@ func (r *renderer) RenderTemplates(ctx context.Context, templates []Template) er
}

func (r *renderer) renderTemplatesWithData(ctx context.Context, templates []Template, tmplctx interface{}) error {
// update funcs with the current context
// only done here to ensure the context is properly set in func namespaces
f := CreateFuncs(ctx)

// add datasource funcs here because they need to share the source reader
addToMap(f, funcs.CreateDataSourceFuncs(ctx, r.sr))

// add user-defined funcs last so they override the built-in funcs
addToMap(f, r.funcs)
f := r.initializeTemplateFuncs(ctx)

// track some metrics for debug output
start := time.Now()
defer func() { Metrics.TotalRenderDuration = time.Since(start) }()
for _, template := range templates {
err := r.renderTemplate(ctx, template, f, tmplctx)
for _, t := range templates {
err := r.renderTemplate(ctx, t, f, tmplctx)
if err != nil {
return fmt.Errorf("renderTemplate: %w", err)
}
}
return nil
}

func (r *renderer) initializeTemplateFuncs(ctx context.Context) template.FuncMap {
// update funcs with the current context
// only done here to ensure the context is properly set in func namespaces
f := CreateFuncs(ctx)

// add datasource funcs here because they need to share the source reader
addToMap(f, funcs.CreateDataSourceFuncs(ctx, r.sr))

// add user-defined funcs last so they override the built-in funcs
addToMap(f, r.funcs)
return f
}

func (r *renderer) renderTemplate(ctx context.Context, template Template, f template.FuncMap, tmplctx interface{}) error {
if template.Writer != nil {
if wr, ok := template.Writer.(io.Closer); ok {
Expand Down Expand Up @@ -335,6 +335,58 @@ func (r *renderer) parseNestedTemplates(ctx context.Context, tmpl *template.Temp
return nil
}

func (r *renderer) RenderTemplatesToBuffer(ctx context.Context, cfg *Config, namer outputNamer, tmpl []Template) error {
ctx, tmplctx, err := r.initializeTemplateContext(ctx)
if err != nil {
return err
}

f := r.initializeTemplateFuncs(ctx)

// track some metrics for debug output
start := time.Now()
defer func() { Metrics.TotalRenderDuration = time.Since(start) }()
for _, t := range tmpl {
inFile := t.Name
if cfg.InputDir != "" {
inFile = strings.Replace(inFile, cfg.InputDir, "", 1)
}

outFile, err := namer.Name(ctx, inFile)
fmt.Println("---")
fmt.Println("##::gomplate::output::file", outFile)
fmt.Println("##::gomplate::template::file", t.Name)
fmt.Println("---")
var buf bytes.Buffer
// Set the template's writer to the buffer
t.Writer = &buf
err = r.renderTemplate(ctx, t, f, tmplctx)
if err != nil {
return fmt.Errorf("renderTemplate: %w", err)
}

// Print the rendered content to the console
fmt.Println(buf.String() + "\n")
}

return nil
}

func (r *renderer) initializeTemplateContext(ctx context.Context) (context.Context, interface{}, error) {
if datafs.FSProviderFromContext(ctx) == nil {
ctx = datafs.ContextWithFSProvider(ctx, DefaultFSProvider)
}

// configure the template context with the refreshed Data value
// only done here because the data context may have changed
tmplctx, err := createTmplContext(ctx, r.tctxAliases, r.sr)
if err != nil {
return nil, nil, err
}

return ctx, tmplctx, nil
}

func parseNestedTemplateDir(ctx context.Context, fsys fs.FS, alias, fname string, tmpl *template.Template) error {
files, err := fs.ReadDir(fsys, fname)
if err != nil {
Expand Down

0 comments on commit 783009b

Please sign in to comment.