Merge pull request #3464 from rrjjvv/typed-vars-as-null
Ensure typed variables with no value still carry type
This commit is contained in:
@@ -480,6 +480,79 @@ func TestHCLTypedValuelessVariables(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHCLTypedValuelessVariablesUsedAsNull(t *testing.T) {
|
||||
// Omitting complex types since they can't (shouldn't) be used as direct build arg values.
|
||||
// Complex types can be used directly for other bake attributes, but that'll conflate HCL
|
||||
// evaluation with whether the attribute accepts null in lieu of empty list/object, etc.
|
||||
// This usage probably hits the 80/20 rule for usage of null variables.
|
||||
types := []string{
|
||||
"any",
|
||||
"string", "number", "bool",
|
||||
}
|
||||
|
||||
t.Run("assignment", func(t *testing.T) {
|
||||
for _, varType := range types {
|
||||
tName := fmt.Sprintf("value-less var typed %q", varType)
|
||||
t.Run(tName, func(t *testing.T) {
|
||||
dt := fmt.Sprintf(`
|
||||
variable "FOO" {
|
||||
type = %s
|
||||
}
|
||||
|
||||
target "default" {
|
||||
args = {
|
||||
foo = FOO
|
||||
}
|
||||
}`, varType)
|
||||
c, err := ParseFile([]byte(dt), "docker-bake.hcl")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(c.Targets))
|
||||
require.Nil(t, c.Targets[0].Args["foo"])
|
||||
})
|
||||
}
|
||||
})
|
||||
t.Run("ternary", func(t *testing.T) {
|
||||
for _, varType := range types {
|
||||
tName := fmt.Sprintf("value-less var of %q on 'false' branch", varType)
|
||||
t.Run(tName, func(t *testing.T) {
|
||||
dt := fmt.Sprintf(`
|
||||
variable "FOO" {
|
||||
type = %s
|
||||
}
|
||||
|
||||
target "default" {
|
||||
args = {
|
||||
foo = FOO == null ? "hi" : FOO
|
||||
}
|
||||
}`, varType)
|
||||
c, err := ParseFile([]byte(dt), "docker-bake.hcl")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(c.Targets))
|
||||
require.Equal(t, "hi", *c.Targets[0].Args["foo"])
|
||||
})
|
||||
}
|
||||
for _, varType := range types {
|
||||
tName := fmt.Sprintf("value-less var of %q on 'true' branch", varType)
|
||||
t.Run(tName, func(t *testing.T) {
|
||||
dt := fmt.Sprintf(`
|
||||
variable "FOO" {
|
||||
type = %s
|
||||
}
|
||||
|
||||
target "default" {
|
||||
args = {
|
||||
foo = FOO == null ? FOO : "hi"
|
||||
}
|
||||
}`, varType)
|
||||
c, err := ParseFile([]byte(dt), "docker-bake.hcl")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(c.Targets))
|
||||
require.Nil(t, c.Targets[0].Args["foo"])
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestJSONNullVariables(t *testing.T) {
|
||||
dt := []byte(`{
|
||||
"variable": {
|
||||
|
||||
@@ -304,17 +304,21 @@ func (p *parser) resolveValue(ectx *hcl.EvalContext, name string) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
var vv cty.Value
|
||||
if def == nil {
|
||||
// Lack of specified value, when untyped is considered to have an empty string value.
|
||||
// A typed variable with no value will result in (typed) nil.
|
||||
if _, ok, _ := p.valueHasOverride(name, false); !ok && !typeSpecified {
|
||||
vv := cty.StringVal("")
|
||||
if _, ok, _ := p.valueHasOverride(name, false); !ok {
|
||||
if typeSpecified {
|
||||
vv = cty.NullVal(varType)
|
||||
} else {
|
||||
vv = cty.StringVal("")
|
||||
}
|
||||
v = &vv
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var vv cty.Value
|
||||
if def != nil {
|
||||
if diags := p.loadDeps(ectx, def.Expr, nil, true); diags.HasErrors() {
|
||||
return diags
|
||||
|
||||
Reference in New Issue
Block a user