execute_command in powershell wasn't interpolating build vars properly (#8771)

This commit is contained in:
Megan Marsh 2020-03-02 01:20:32 -08:00 committed by GitHub
parent b45ed4c4f1
commit 0cfcbd66ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 32 deletions

View File

@ -164,41 +164,50 @@ func funcGenTemplateDir(ctx *Context) interface{} {
}
}
func funcGenBuild(ctx *Context) interface{} {
return func(s string) (string, error) {
if data, ok := ctx.Data.(map[string]string); ok {
if heldPlace, ok := data[s]; ok {
// If we're in the first interpolation pass, the goal is to
// make sure that we pass the value through.
// TODO match against an actual string constant
if strings.Contains(heldPlace, common.PlaceholderMsg) {
return fmt.Sprintf("{{.%s}}", s), nil
} else {
return heldPlace, nil
}
func passthroughOrInterpolate(data map[interface{}]interface{}, s string) (string, error) {
if heldPlace, ok := data[s]; ok {
if hp, ok := heldPlace.(string); ok {
// If we're in the first interpolation pass, the goal is to
// make sure that we pass the value through.
// TODO match against an actual string constant
if strings.Contains(hp, common.PlaceholderMsg) {
return fmt.Sprintf("{{.%s}}", s), nil
} else {
return hp, nil
}
return "", fmt.Errorf("loaded data, but couldnt find %s in it.", s)
}
if data, ok := ctx.Data.(map[interface{}]interface{}); ok {
// PlaceholderData has been passed into generator, so if the given
// key already exists in data, then we know it's an "allowed" key
if heldPlace, ok := data[s]; ok {
if hp, ok := heldPlace.(string); ok {
// If we're in the first interpolation pass, the goal is to
// make sure that we pass the value through.
// TODO match against an actual string constant
if strings.Contains(hp, common.PlaceholderMsg) {
return fmt.Sprintf("{{.%s}}", s), nil
} else {
return hp, nil
}
}
}
return "", fmt.Errorf("loaded data, but couldnt find %s in it.", s)
}
}
return "", fmt.Errorf("loaded data, but couldnt find %s in it.", s)
return "", fmt.Errorf("Error validating build variable: the given "+
"variable %s will not be passed into your plugin.", s)
}
func funcGenBuild(ctx *Context) interface{} {
// Depending on where the context data is coming from, it could take a few
// different map types. The following switch standardizes the map types
// so we can act on them correctly.
return func(s string) (string, error) {
switch data := ctx.Data.(type) {
case map[interface{}]interface{}:
return passthroughOrInterpolate(data, s)
case map[string]interface{}:
// convert to a map[interface{}]interface{} so we can use same
// parsing on it
passed := make(map[interface{}]interface{}, len(data))
for k, v := range data {
passed[k] = v
}
return passthroughOrInterpolate(passed, s)
case map[string]string:
// convert to a map[interface{}]interface{} so we can use same
// parsing on it
passed := make(map[interface{}]interface{}, len(data))
for k, v := range data {
passed[k] = v
}
return passthroughOrInterpolate(passed, s)
default:
return "", fmt.Errorf("Error validating build variable: the given "+
"variable %s will not be passed into your plugin.", s)
}
}
}

View File

@ -384,6 +384,13 @@ func TestFuncPackerBuild(t *testing.T) {
Template: "{{ build `MissingVar` }}",
OutVal: "",
},
// Data map is a map[string]interface and contains value
{
DataMap: map[string]interface{}{"PartyVar": "PartyVal"},
ErrExpected: false,
Template: "{{ build `PartyVar` }}",
OutVal: "PartyVal",
},
}
for _, tc := range testCases {