mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 09:17:49 +08:00
bake: avoid nesting error diagnostics
With changes to the lazy evaluation, the evaluation order is no longer fixed - this means that we can follow long and confusing paths to get to an error. Because of the co-recursive nature of the lazy evaluation, we need to take special care that the original HCL diagnostics are not discarded and are preserved so that the original source of the error can be detected. Preserving the full trace is not necessary, and probably not useful to the user - all of the file that is not lazily loaded will be eagerly loaded after all struct blocks are loaded - so the error would be found regardless. Signed-off-by: Justin Chadwell <me@jedevc.com> (cherry picked from commit fbb4f4dec86541dd243e99816ef84b3a4d4741c2)
This commit is contained in:
parent
661af29d46
commit
0fad89c3b9
@ -14,15 +14,7 @@ func funcCalls(exp hcl.Expression) ([]string, hcl.Diagnostics) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
fns, err := jsonFuncCallsRecursive(exp)
|
fns, err := jsonFuncCallsRecursive(exp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, hcl.Diagnostics{
|
return nil, wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid expression",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: exp.Range().Ptr(),
|
|
||||||
Context: exp.Range().Ptr(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return fns, nil
|
return fns, nil
|
||||||
}
|
}
|
||||||
|
@ -75,15 +75,7 @@ func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}, allow
|
|||||||
if allowMissing && errors.Is(err, errUndefined) {
|
if allowMissing && errors.Is(err, errUndefined) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid expression",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: exp.Range().Ptr(),
|
|
||||||
Context: exp.Range().Ptr(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,30 +128,14 @@ func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}, allow
|
|||||||
if allowMissing && errors.Is(err, errUndefined) {
|
if allowMissing && errors.Is(err, errUndefined) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid expression",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: v.SourceRange().Ptr(),
|
|
||||||
Context: v.SourceRange().Ptr(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := p.resolveValue(v.RootName()); err != nil {
|
if err := p.resolveValue(v.RootName()); err != nil {
|
||||||
if allowMissing && errors.Is(err, errUndefined) {
|
if allowMissing && errors.Is(err, errUndefined) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid expression",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: v.SourceRange().Ptr(),
|
|
||||||
Context: v.SourceRange().Ptr(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,14 +301,7 @@ func (p *parser) resolveValue(name string) (err error) {
|
|||||||
func (p *parser) resolveBlock(block *hcl.Block, target *hcl.BodySchema) (err error) {
|
func (p *parser) resolveBlock(block *hcl.Block, target *hcl.BodySchema) (err error) {
|
||||||
name := block.Labels[0]
|
name := block.Labels[0]
|
||||||
if err := p.opt.ValidateLabel(name); err != nil {
|
if err := p.opt.ValidateLabel(name); err != nil {
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid name", err, &block.LabelRanges[0], &block.LabelRanges[0])
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid name",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: &block.LabelRanges[0],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := p.doneB[block]; !ok {
|
if _, ok := p.doneB[block]; !ok {
|
||||||
@ -584,15 +553,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
r := p.vars[k].Body.MissingItemRange()
|
r := p.vars[k].Body.MissingItemRange()
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid value", err, &r, &r)
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid value",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: &r,
|
|
||||||
Context: &r,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,15 +576,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid function", err, subject, context)
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid function",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: subject,
|
|
||||||
Context: context,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,15 +637,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid block", err, &b.LabelRanges[0], &b.DefRange)
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid attribute",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: &b.LabelRanges[0],
|
|
||||||
Context: &b.DefRange,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,21 +682,34 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
|
|||||||
if diags, ok := err.(hcl.Diagnostics); ok {
|
if diags, ok := err.(hcl.Diagnostics); ok {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
return hcl.Diagnostics{
|
return wrapErrorDiagnostic("Invalid attribute", err, &p.attrs[k].Range, &p.attrs[k].Range)
|
||||||
&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Invalid attribute",
|
|
||||||
Detail: err.Error(),
|
|
||||||
Subject: &p.attrs[k].Range,
|
|
||||||
Context: &p.attrs[k].Range,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wrapErrorDiagnostic wraps an error into a hcl.Diagnostics object.
|
||||||
|
// If the error is already an hcl.Diagnostics object, it is returned as is.
|
||||||
|
func wrapErrorDiagnostic(message string, err error, subject *hcl.Range, context *hcl.Range) hcl.Diagnostics {
|
||||||
|
switch err := err.(type) {
|
||||||
|
case *hcl.Diagnostic:
|
||||||
|
return hcl.Diagnostics{err}
|
||||||
|
case hcl.Diagnostics:
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
return hcl.Diagnostics{
|
||||||
|
&hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: message,
|
||||||
|
Detail: err.Error(),
|
||||||
|
Subject: subject,
|
||||||
|
Context: context,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setLabel(v reflect.Value, lbl string) int {
|
func setLabel(v reflect.Value, lbl string) int {
|
||||||
// cache field index?
|
// cache field index?
|
||||||
numFields := v.Elem().Type().NumField()
|
numFields := v.Elem().Type().NumField()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user