Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 39 additions & 20 deletions pkg/cli/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,7 @@ func (c *Context) Funcs() []template.Function {

// loadBackend determines the backend to use for executing the rendered template text (e.g. run in shell).
// During this phase, the template delimiters are changed to =% %= so put this in the comment {{/* */}}
func (c *Context) loadBackends() error {
t, err := template.NewTemplate(c.src, template.Options{
DelimLeft: "=%",
DelimRight: "%=",
})
if err != nil {
return err
}
func (c *Context) loadBackends(t *template.Template) error {
t.AddFunc("print",
func() string {
c.run = func(script string) error {
Expand Down Expand Up @@ -567,35 +560,61 @@ func (c *Context) loadBackends() error {
return ""
})

_, err = t.Render(c)
_, err := t.Render(c)

// clean up after we rendered... remove the functions
t.RemoveFunc("sh", "print", "instanceProvision", "managerCommit")
return err
}

func (c *Context) getTemplate() (*template.Template, error) {
if c.template == nil {
t, err := template.NewTemplate(c.src, template.Options{})
if err != nil {
return nil, err
}
c.template = t
}
return c.template, nil
}

// BuildFlags from parsing the body which is a template
func (c *Context) BuildFlags() error {
t, err := template.NewTemplate(c.src, template.Options{})
func (c *Context) BuildFlags() (err error) {
var t *template.Template

t, err = c.getTemplate()
if err != nil {
return err
return
}

t.SetOptions(template.Options{})
_, err = configureTemplate(t, c.plugins).Render(c)
return err
return
}

// Execute runs the command
func (c *Context) Execute() error {
func (c *Context) Execute() (err error) {
var t *template.Template

if err := c.loadBackends(); err != nil {
return err
t, err = c.getTemplate()
if err != nil {
return
}

t, err := template.NewTemplate(c.src, template.Options{
Stderr: func() io.Writer { return os.Stderr },
// First pass to get the backends
t.SetOptions(template.Options{
DelimLeft: "=%",
DelimRight: "%=",
})
if err != nil {

if err := c.loadBackends(t); err != nil {
return err
}

// Now regular processing
t.SetOptions(template.Options{
Stderr: func() io.Writer { return os.Stderr },
})

c.exec = true
c.template = t
script, err := configureTemplate(t, c.plugins).Render(c)
Expand Down
23 changes: 19 additions & 4 deletions pkg/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ func NewTemplateFromBytes(buff []byte, contextURL string, opt Options) (*Templat
}, nil
}

// NewFromTemplate creates a new template from existing, without any fetches (hence network calls)
func NewFromTemplate(from *Template, opt Options) *Template {
return &Template{
options: opt,
url: from.url,
body: from.body,
}
}

// SetOptions sets the runtime flags for the engine
func (t *Template) SetOptions(opt Options) *Template {
t.lock.Lock()
Expand All @@ -167,6 +176,16 @@ func (t *Template) AddFunc(name string, f interface{}) *Template {
return t
}

// RemoveFunc remove the functions
func (t *Template) RemoveFunc(name ...string) *Template {
t.lock.Lock()
defer t.lock.Unlock()
for _, n := range name {
delete(t.funcs, n)
}
return t
}

// Ref returns the value keyed by name in the context of this template. See 'ref' template function.
func (t *Template) Ref(name string) interface{} {
if found, has := t.globals[name]; has {
Expand Down Expand Up @@ -275,10 +294,6 @@ func (t *Template) build(context Context) error {
t.lock.Lock()
defer t.lock.Unlock()

if t.parsed != nil {
return nil
}

registered := []Function{}
fm := map[string]interface{}{}

Expand Down