Files
helmfile/tmpl/file.go
T
David Genest 7bfb58c0e4 feat: double render the helmfile (#308)
This allows using the environment values defined in the environments: section of helmfile.yaml to be used from other sections of the file.

This works by having two template renderers, the first-pass and the second-pass renderer.

The first-pass render renders a helmfile.yaml template with replacing template functions has side-effects with noop. So, use only funcs that don't have side-effects to compose your environment values.

Then the second-pass renderer renders the same helmfile.yaml template, but with the environment values loaded by the first-pass renderer.

The implementation uses a buffer instead of re-reading the file twice.

Resolves #297
2018-09-12 08:55:42 +09:00

64 lines
1.4 KiB
Go

package tmpl
import (
"bytes"
"io/ioutil"
"github.com/roboll/helmfile/environment"
)
type templateFileRenderer struct {
ReadFile func(string) ([]byte, error)
Context *Context
Data TemplateData
}
type TemplateData struct {
// Environment is accessible as `.Environment` from any template executed by the renderer
Environment environment.Environment
}
type FileRenderer interface {
RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error)
}
func NewFileRenderer(readFile func(filename string) ([]byte, error), basePath string, env environment.Environment) *templateFileRenderer {
return &templateFileRenderer{
ReadFile: readFile,
Context: &Context{
basePath: basePath,
readFile: readFile,
},
Data: TemplateData{
Environment: env,
},
}
}
func NewFirstPassRenderer(env environment.Environment) *templateFileRenderer {
return &templateFileRenderer{
ReadFile: ioutil.ReadFile,
Context: &Context{
preRender: true,
basePath: "",
readFile: ioutil.ReadFile,
},
Data: TemplateData{
Environment: env,
},
}
}
func (r *templateFileRenderer) RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error) {
content, err := r.ReadFile(file)
if err != nil {
return nil, err
}
return r.RenderTemplateContentToBuffer(content)
}
func (r *templateFileRenderer) RenderTemplateContentToBuffer(content []byte) (*bytes.Buffer, error) {
return r.Context.RenderTemplateToBuffer(string(content), r.Data)
}