Merge pull request #2232 from mitchellh/f-build-name
core: add build_name and build_type functions
This commit is contained in:
commit
723b91ccf3
|
@ -106,6 +106,8 @@ func Decode(target interface{}, config *DecodeOpts, raws ...interface{}) error {
|
||||||
// detecting things like user variables from the raw configuration params.
|
// detecting things like user variables from the raw configuration params.
|
||||||
func DetectContext(raws ...interface{}) (*interpolate.Context, error) {
|
func DetectContext(raws ...interface{}) (*interpolate.Context, error) {
|
||||||
var s struct {
|
var s struct {
|
||||||
|
BuildName string `mapstructure:"packer_build_name"`
|
||||||
|
BuildType string `mapstructure:"packer_builder_type"`
|
||||||
TemplatePath string `mapstructure:"packer_template_path"`
|
TemplatePath string `mapstructure:"packer_template_path"`
|
||||||
Vars map[string]string `mapstructure:"packer_user_variables"`
|
Vars map[string]string `mapstructure:"packer_user_variables"`
|
||||||
}
|
}
|
||||||
|
@ -117,6 +119,8 @@ func DetectContext(raws ...interface{}) (*interpolate.Context, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &interpolate.Context{
|
return &interpolate.Context{
|
||||||
|
BuildName: s.BuildName,
|
||||||
|
BuildType: s.BuildType,
|
||||||
TemplatePath: s.TemplatePath,
|
TemplatePath: s.TemplatePath,
|
||||||
UserVariables: s.Vars,
|
UserVariables: s.Vars,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -142,6 +142,64 @@ func TestCoreBuild_env(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCoreBuild_buildNameVar(t *testing.T) {
|
||||||
|
config := TestCoreConfig(t)
|
||||||
|
testCoreTemplate(t, config, fixtureDir("build-var-build-name.json"))
|
||||||
|
b := TestBuilder(t, config, "test")
|
||||||
|
core := TestCore(t, config)
|
||||||
|
|
||||||
|
b.ArtifactId = "hello"
|
||||||
|
|
||||||
|
build, err := core.Build("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := build.Prepare(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interpolate the config
|
||||||
|
var result map[string]interface{}
|
||||||
|
err = configHelper.Decode(&result, nil, b.PrepareConfig...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result["value"] != "test" {
|
||||||
|
t.Fatalf("bad: %#v", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCoreBuild_buildTypeVar(t *testing.T) {
|
||||||
|
config := TestCoreConfig(t)
|
||||||
|
testCoreTemplate(t, config, fixtureDir("build-var-build-type.json"))
|
||||||
|
b := TestBuilder(t, config, "test")
|
||||||
|
core := TestCore(t, config)
|
||||||
|
|
||||||
|
b.ArtifactId = "hello"
|
||||||
|
|
||||||
|
build, err := core.Build("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := build.Prepare(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interpolate the config
|
||||||
|
var result map[string]interface{}
|
||||||
|
err = configHelper.Decode(&result, nil, b.PrepareConfig...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result["value"] != "test" {
|
||||||
|
t.Fatalf("bad: %#v", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCoreBuild_nonExist(t *testing.T) {
|
func TestCoreBuild_nonExist(t *testing.T) {
|
||||||
config := TestCoreConfig(t)
|
config := TestCoreConfig(t)
|
||||||
testCoreTemplate(t, config, fixtureDir("build-basic.json"))
|
testCoreTemplate(t, config, fixtureDir("build-basic.json"))
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"builders": [{
|
||||||
|
"type": "test",
|
||||||
|
"value": "{{build_name}}"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"builders": [{
|
||||||
|
"type": "test",
|
||||||
|
"value": "{{build_type}}"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -24,6 +24,8 @@ func init() {
|
||||||
|
|
||||||
// Funcs are the interpolation funcs that are available within interpolations.
|
// Funcs are the interpolation funcs that are available within interpolations.
|
||||||
var FuncGens = map[string]FuncGenerator{
|
var FuncGens = map[string]FuncGenerator{
|
||||||
|
"build_name": funcGenBuildName,
|
||||||
|
"build_type": funcGenBuildType,
|
||||||
"env": funcGenEnv,
|
"env": funcGenEnv,
|
||||||
"isotime": funcGenIsotime,
|
"isotime": funcGenIsotime,
|
||||||
"pwd": funcGenPwd,
|
"pwd": funcGenPwd,
|
||||||
|
@ -56,6 +58,26 @@ func Funcs(ctx *Context) template.FuncMap {
|
||||||
return template.FuncMap(result)
|
return template.FuncMap(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func funcGenBuildName(ctx *Context) interface{} {
|
||||||
|
return func() (string, error) {
|
||||||
|
if ctx == nil || ctx.BuildName == "" {
|
||||||
|
return "", errors.New("build_name not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.BuildName, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func funcGenBuildType(ctx *Context) interface{} {
|
||||||
|
return func() (string, error) {
|
||||||
|
if ctx == nil || ctx.BuildType == "" {
|
||||||
|
return "", errors.New("build_name not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.BuildType, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func funcGenEnv(ctx *Context) interface{} {
|
func funcGenEnv(ctx *Context) interface{} {
|
||||||
return func(k string) (string, error) {
|
return func(k string) (string, error) {
|
||||||
if !ctx.EnableEnv {
|
if !ctx.EnableEnv {
|
||||||
|
|
|
@ -8,6 +8,56 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestFuncBuildName(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Input string
|
||||||
|
Output string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`{{build_name}}`,
|
||||||
|
"foo",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := &Context{BuildName: "foo"}
|
||||||
|
for _, tc := range cases {
|
||||||
|
i := &I{Value: tc.Input}
|
||||||
|
result, err := i.Render(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Input: %s\n\nerr: %s", tc.Input, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result != tc.Output {
|
||||||
|
t.Fatalf("Input: %s\n\nGot: %s", tc.Input, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFuncBuildType(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Input string
|
||||||
|
Output string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`{{build_type}}`,
|
||||||
|
"foo",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := &Context{BuildType: "foo"}
|
||||||
|
for _, tc := range cases {
|
||||||
|
i := &I{Value: tc.Input}
|
||||||
|
result, err := i.Render(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Input: %s\n\nerr: %s", tc.Input, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result != tc.Output {
|
||||||
|
t.Fatalf("Input: %s\n\nGot: %s", tc.Input, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFuncEnv(t *testing.T) {
|
func TestFuncEnv(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Input string
|
Input string
|
||||||
|
|
|
@ -14,16 +14,23 @@ type Context struct {
|
||||||
// Funcs are extra functions available in the template
|
// Funcs are extra functions available in the template
|
||||||
Funcs map[string]interface{}
|
Funcs map[string]interface{}
|
||||||
|
|
||||||
// TemplatePath is the path to the template that this is being
|
|
||||||
// rendered within.
|
|
||||||
TemplatePath string
|
|
||||||
|
|
||||||
// UserVariables is the mapping of user variables that the
|
// UserVariables is the mapping of user variables that the
|
||||||
// "user" function reads from.
|
// "user" function reads from.
|
||||||
UserVariables map[string]string
|
UserVariables map[string]string
|
||||||
|
|
||||||
// EnableEnv enables the env function
|
// EnableEnv enables the env function
|
||||||
EnableEnv bool
|
EnableEnv bool
|
||||||
|
|
||||||
|
// All the fields below are used for built-in functions.
|
||||||
|
//
|
||||||
|
// BuildName and BuildType are the name and type, respectively,
|
||||||
|
// of the builder being used.
|
||||||
|
//
|
||||||
|
// TemplatePath is the path to the template that this is being
|
||||||
|
// rendered within.
|
||||||
|
BuildName string
|
||||||
|
BuildType string
|
||||||
|
TemplatePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render is shorthand for constructing an I and calling Render.
|
// Render is shorthand for constructing an I and calling Render.
|
||||||
|
|
|
@ -55,6 +55,8 @@ While some configuration settings have local variables specific to only that
|
||||||
configuration, a set of functions are available globally for use in _any string_
|
configuration, a set of functions are available globally for use in _any string_
|
||||||
in Packer templates. These are listed below for reference.
|
in Packer templates. These are listed below for reference.
|
||||||
|
|
||||||
|
* `build_name` - The name of the build being run.
|
||||||
|
* `build_type` - The type of the builder being used currently.
|
||||||
* `isotime [FORMAT]` - UTC time, which can be [formatted](http://golang.org/pkg/time/#example_Time_Format).
|
* `isotime [FORMAT]` - UTC time, which can be [formatted](http://golang.org/pkg/time/#example_Time_Format).
|
||||||
See more examples below.
|
See more examples below.
|
||||||
* `lower` - Lowercases the string.
|
* `lower` - Lowercases the string.
|
||||||
|
|
Loading…
Reference in New Issue