mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 00:47:48 +08:00
Merge pull request #3101 from crazy-max/bake-validation-fixes
bake: check condition and error_message are set during validation
This commit is contained in:
commit
d69301d57b
@ -2142,6 +2142,73 @@ target "app" {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVariableValidationConditionNull(t *testing.T) {
|
||||||
|
fp := File{
|
||||||
|
Name: "docker-bake.hcl",
|
||||||
|
Data: []byte(`
|
||||||
|
variable "PORT" {
|
||||||
|
default = 3000
|
||||||
|
validation {}
|
||||||
|
}
|
||||||
|
target "app" {
|
||||||
|
args = {
|
||||||
|
PORT = PORT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"app"}, nil, nil, &EntitlementConf{})
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "Condition expression must return either true or false, not null")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVariableValidationConditionUnknownValue(t *testing.T) {
|
||||||
|
fp := File{
|
||||||
|
Name: "docker-bake.hcl",
|
||||||
|
Data: []byte(`
|
||||||
|
variable "PORT" {
|
||||||
|
default = 3000
|
||||||
|
validation {
|
||||||
|
condition = "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target "app" {
|
||||||
|
args = {
|
||||||
|
PORT = PORT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"app"}, nil, nil, &EntitlementConf{})
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "Invalid condition result value: a bool is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVariableValidationInvalidErrorMessage(t *testing.T) {
|
||||||
|
fp := File{
|
||||||
|
Name: "docker-bake.hcl",
|
||||||
|
Data: []byte(`
|
||||||
|
variable "FOO" {
|
||||||
|
default = 0
|
||||||
|
validation {
|
||||||
|
condition = FOO > 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target "app" {
|
||||||
|
args = {
|
||||||
|
FOO = FOO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"app"}, nil, nil, &EntitlementConf{})
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "This check failed, but has an invalid error message")
|
||||||
|
}
|
||||||
|
|
||||||
// https://github.com/docker/buildx/issues/2822
|
// https://github.com/docker/buildx/issues/2822
|
||||||
func TestVariableEmpty(t *testing.T) {
|
func TestVariableEmpty(t *testing.T) {
|
||||||
fp := File{
|
fp := File{
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Opt struct {
|
type Opt struct {
|
||||||
@ -555,27 +556,57 @@ func (p *parser) resolveBlockNames(block *hcl.Block) ([]string, error) {
|
|||||||
func (p *parser) validateVariables(vars map[string]*variable, ectx *hcl.EvalContext) hcl.Diagnostics {
|
func (p *parser) validateVariables(vars map[string]*variable, ectx *hcl.EvalContext) hcl.Diagnostics {
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
for _, v := range vars {
|
for _, v := range vars {
|
||||||
for _, validation := range v.Validations {
|
for _, rule := range v.Validations {
|
||||||
condition, condDiags := validation.Condition.Value(ectx)
|
resultVal, condDiags := rule.Condition.Value(ectx)
|
||||||
if condDiags.HasErrors() {
|
if condDiags.HasErrors() {
|
||||||
diags = append(diags, condDiags...)
|
diags = append(diags, condDiags...)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !condition.True() {
|
|
||||||
message, msgDiags := validation.ErrorMessage.Value(ectx)
|
if resultVal.IsNull() {
|
||||||
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: "Invalid condition result",
|
||||||
|
Detail: "Condition expression must return either true or false, not null.",
|
||||||
|
Subject: rule.Condition.Range().Ptr(),
|
||||||
|
Expression: rule.Condition,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
resultVal, err = convert.Convert(resultVal, cty.Bool)
|
||||||
|
if err != nil {
|
||||||
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: "Invalid condition result",
|
||||||
|
Detail: fmt.Sprintf("Invalid condition result value: %s", err),
|
||||||
|
Subject: rule.Condition.Range().Ptr(),
|
||||||
|
Expression: rule.Condition,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !resultVal.True() {
|
||||||
|
message, msgDiags := rule.ErrorMessage.Value(ectx)
|
||||||
if msgDiags.HasErrors() {
|
if msgDiags.HasErrors() {
|
||||||
diags = append(diags, msgDiags...)
|
diags = append(diags, msgDiags...)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
errorMessage := "This check failed, but has an invalid error message."
|
||||||
|
if !message.IsNull() {
|
||||||
|
errorMessage = message.AsString()
|
||||||
|
}
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Validation failed",
|
Summary: "Validation failed",
|
||||||
Detail: message.AsString(),
|
Detail: errorMessage,
|
||||||
Subject: validation.Condition.Range().Ptr(),
|
Subject: rule.Condition.Range().Ptr(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user