mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	bake: check condition and error_message are set during validation
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
		@@ -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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user