Commit 3ebfe06e authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer: render build names

parent 47b570a2
......@@ -3,9 +3,11 @@ package packer
import (
"fmt"
"os"
"sort"
"github.com/hashicorp/go-multierror"
"github.com/mitchellh/packer/template"
"github.com/mitchellh/packer/template/interpolate"
)
// Core is the main executor of Packer. If Packer is being used as a
......@@ -16,6 +18,7 @@ type Core struct {
ui Ui
template *template.Template
variables map[string]string
builds map[string]*template.Builder
}
// CoreConfig is the structure for initializing a new Core. Once a CoreConfig
......@@ -38,15 +41,43 @@ func NewCore(c *CoreConfig) (*Core, error) {
}
}
// Go through and interpolate all the build names. We shuld be able
// to do this at this point with the variables.
builds := make(map[string]*template.Builder)
for _, b := range c.Template.Builders {
v, err := interpolate.Render(b.Name, &interpolate.Context{
UserVariables: c.Variables,
})
if err != nil {
return nil, fmt.Errorf(
"Error interpolating builder '%s': %s",
b.Name, err)
}
builds[v] = b
}
return &Core{
cache: c.Cache,
components: c.Components,
ui: c.Ui,
template: c.Template,
variables: c.Variables,
builds: builds,
}, nil
}
// BuildNames returns the builds that are available in this configured core.
func (c *Core) BuildNames() []string {
r := make([]string, 0, len(c.builds))
for n, _ := range c.builds {
r = append(r, n)
}
sort.Strings(r)
return r
}
// Build returns the Build object for the given name.
func (c *Core) Build(n string) (Build, error) {
// Setup the builder
......
......@@ -2,11 +2,52 @@ package packer
import (
"os"
"reflect"
"testing"
"github.com/mitchellh/packer/template"
)
func TestCoreBuildNames(t *testing.T) {
cases := []struct {
File string
Vars map[string]string
Result []string
}{
{
"build-names-basic.json",
nil,
[]string{"something"},
},
{
"build-names-func.json",
nil,
[]string{"TUBES"},
},
}
for _, tc := range cases {
tpl, err := template.ParseFile(fixtureDir(tc.File))
if err != nil {
t.Fatalf("err: %s\n\n%s", tc.File, err)
}
core, err := NewCore(&CoreConfig{
Template: tpl,
Variables: tc.Vars,
})
if err != nil {
t.Fatalf("err: %s\n\n%s", tc.File, err)
}
names := core.BuildNames()
if !reflect.DeepEqual(names, tc.Result) {
t.Fatalf("err: %s\n\n%#v", tc.File, names)
}
}
}
func TestCoreValidate(t *testing.T) {
cases := []struct {
File string
......
{
"builders": [
{"type": "something"}
]
}
{
"builders": [
{"type": "{{upper `tubes`}}"}
]
}
......@@ -19,6 +19,11 @@ type Context struct {
EnableEnv bool
}
// Render is shorthand for constructing an I and calling Render.
func Render(v string, ctx *Context) (string, error) {
return (&I{Value: v}).Render(ctx)
}
// I stands for "interpolation" and is the main interpolation struct
// in order to render values.
type I struct {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment