Skip to content

Commit d69301d

Browse files
authored
Merge pull request #3101 from crazy-max/bake-validation-fixes
bake: check condition and error_message are set during validation
2 parents ee77cdb + 77139da commit d69301d

File tree

2 files changed

+104
-6
lines changed

2 files changed

+104
-6
lines changed

bake/bake_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,6 +2142,73 @@ target "app" {
21422142
})
21432143
}
21442144

2145+
func TestVariableValidationConditionNull(t *testing.T) {
2146+
fp := File{
2147+
Name: "docker-bake.hcl",
2148+
Data: []byte(`
2149+
variable "PORT" {
2150+
default = 3000
2151+
validation {}
2152+
}
2153+
target "app" {
2154+
args = {
2155+
PORT = PORT
2156+
}
2157+
}
2158+
`),
2159+
}
2160+
2161+
_, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"app"}, nil, nil, &EntitlementConf{})
2162+
require.Error(t, err)
2163+
require.Contains(t, err.Error(), "Condition expression must return either true or false, not null")
2164+
}
2165+
2166+
func TestVariableValidationConditionUnknownValue(t *testing.T) {
2167+
fp := File{
2168+
Name: "docker-bake.hcl",
2169+
Data: []byte(`
2170+
variable "PORT" {
2171+
default = 3000
2172+
validation {
2173+
condition = "foo"
2174+
}
2175+
}
2176+
target "app" {
2177+
args = {
2178+
PORT = PORT
2179+
}
2180+
}
2181+
`),
2182+
}
2183+
2184+
_, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"app"}, nil, nil, &EntitlementConf{})
2185+
require.Error(t, err)
2186+
require.Contains(t, err.Error(), "Invalid condition result value: a bool is required")
2187+
}
2188+
2189+
func TestVariableValidationInvalidErrorMessage(t *testing.T) {
2190+
fp := File{
2191+
Name: "docker-bake.hcl",
2192+
Data: []byte(`
2193+
variable "FOO" {
2194+
default = 0
2195+
validation {
2196+
condition = FOO > 5
2197+
}
2198+
}
2199+
target "app" {
2200+
args = {
2201+
FOO = FOO
2202+
}
2203+
}
2204+
`),
2205+
}
2206+
2207+
_, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"app"}, nil, nil, &EntitlementConf{})
2208+
require.Error(t, err)
2209+
require.Contains(t, err.Error(), "This check failed, but has an invalid error message")
2210+
}
2211+
21452212
// https://github.com/docker/buildx/issues/2822
21462213
func TestVariableEmpty(t *testing.T) {
21472214
fp := File{

bake/hclparser/hclparser.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/hashicorp/hcl/v2"
1717
"github.com/pkg/errors"
1818
"github.com/zclconf/go-cty/cty"
19+
"github.com/zclconf/go-cty/cty/convert"
1920
)
2021

2122
type Opt struct {
@@ -555,27 +556,57 @@ func (p *parser) resolveBlockNames(block *hcl.Block) ([]string, error) {
555556
func (p *parser) validateVariables(vars map[string]*variable, ectx *hcl.EvalContext) hcl.Diagnostics {
556557
var diags hcl.Diagnostics
557558
for _, v := range vars {
558-
for _, validation := range v.Validations {
559-
condition, condDiags := validation.Condition.Value(ectx)
559+
for _, rule := range v.Validations {
560+
resultVal, condDiags := rule.Condition.Value(ectx)
560561
if condDiags.HasErrors() {
561562
diags = append(diags, condDiags...)
562563
continue
563564
}
564-
if !condition.True() {
565-
message, msgDiags := validation.ErrorMessage.Value(ectx)
565+
566+
if resultVal.IsNull() {
567+
diags = append(diags, &hcl.Diagnostic{
568+
Severity: hcl.DiagError,
569+
Summary: "Invalid condition result",
570+
Detail: "Condition expression must return either true or false, not null.",
571+
Subject: rule.Condition.Range().Ptr(),
572+
Expression: rule.Condition,
573+
})
574+
continue
575+
}
576+
577+
var err error
578+
resultVal, err = convert.Convert(resultVal, cty.Bool)
579+
if err != nil {
580+
diags = append(diags, &hcl.Diagnostic{
581+
Severity: hcl.DiagError,
582+
Summary: "Invalid condition result",
583+
Detail: fmt.Sprintf("Invalid condition result value: %s", err),
584+
Subject: rule.Condition.Range().Ptr(),
585+
Expression: rule.Condition,
586+
})
587+
continue
588+
}
589+
590+
if !resultVal.True() {
591+
message, msgDiags := rule.ErrorMessage.Value(ectx)
566592
if msgDiags.HasErrors() {
567593
diags = append(diags, msgDiags...)
568594
continue
569595
}
596+
errorMessage := "This check failed, but has an invalid error message."
597+
if !message.IsNull() {
598+
errorMessage = message.AsString()
599+
}
570600
diags = append(diags, &hcl.Diagnostic{
571601
Severity: hcl.DiagError,
572602
Summary: "Validation failed",
573-
Detail: message.AsString(),
574-
Subject: validation.Condition.Range().Ptr(),
603+
Detail: errorMessage,
604+
Subject: rule.Condition.Range().Ptr(),
575605
})
576606
}
577607
}
578608
}
609+
579610
return diags
580611
}
581612

0 commit comments

Comments
 (0)