packer: render build names

This commit is contained in:
Mitchell Hashimoto 2015-05-23 16:12:32 -07:00
parent 47b570a2d2
commit 3ebfe06ec8
5 changed files with 87 additions and 0 deletions

View File

@ -3,9 +3,11 @@ package packer
import ( import (
"fmt" "fmt"
"os" "os"
"sort"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/mitchellh/packer/template" "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 // Core is the main executor of Packer. If Packer is being used as a
@ -16,6 +18,7 @@ type Core struct {
ui Ui ui Ui
template *template.Template template *template.Template
variables map[string]string variables map[string]string
builds map[string]*template.Builder
} }
// CoreConfig is the structure for initializing a new Core. Once a CoreConfig // 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{ return &Core{
cache: c.Cache, cache: c.Cache,
components: c.Components, components: c.Components,
ui: c.Ui, ui: c.Ui,
template: c.Template, template: c.Template,
variables: c.Variables, variables: c.Variables,
builds: builds,
}, nil }, 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. // Build returns the Build object for the given name.
func (c *Core) Build(n string) (Build, error) { func (c *Core) Build(n string) (Build, error) {
// Setup the builder // Setup the builder

View File

@ -2,11 +2,52 @@ package packer
import ( import (
"os" "os"
"reflect"
"testing" "testing"
"github.com/mitchellh/packer/template" "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) { func TestCoreValidate(t *testing.T) {
cases := []struct { cases := []struct {
File string File string

View File

@ -0,0 +1,5 @@
{
"builders": [
{"type": "something"}
]
}

View File

@ -0,0 +1,5 @@
{
"builders": [
{"type": "{{upper `tubes`}}"}
]
}

View File

@ -19,6 +19,11 @@ type Context struct {
EnableEnv bool 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 // I stands for "interpolation" and is the main interpolation struct
// in order to render values. // in order to render values.
type I struct { type I struct {