-
Notifications
You must be signed in to change notification settings - Fork 265
/
decode_result.go
73 lines (64 loc) · 2.66 KB
/
decode_result.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package parse
import (
"fmt"
"github.com/hashicorp/hcl/v2"
"github.com/turbot/go-kit/helpers"
"github.com/turbot/steampipe/steampipeconfig/modconfig"
)
// struct to hold the result of a decoding operation
type decodeResult struct {
Diags hcl.Diagnostics
Depends []*modconfig.ResourceDependency
}
// Merge merges this decode result with another
func (p *decodeResult) Merge(other *decodeResult) *decodeResult {
p.Diags = append(p.Diags, other.Diags...)
p.Depends = append(p.Depends, other.Depends...)
return p
}
// Success :: was the parsing successful - true if there are no errors and no dependencies
func (p *decodeResult) Success() bool {
return !p.Diags.HasErrors() && len(p.Depends) == 0
}
// if the diags containsdependency errors, add dependencies to the result
// otherwise add diags to the result
func (p *decodeResult) handleDecodeDiags(bodyContent *hcl.BodyContent, resource modconfig.HclResource, diags hcl.Diagnostics) {
var allDependencies []*modconfig.ResourceDependency
for _, diag := range diags {
if dependency := isDependencyError(diag); dependency != nil {
allDependencies = append(allDependencies, dependency)
// so it was a dependency error - determine whether this is a RUN TIME dependency
// - if so, do not raise a dependency error but instead store in the resources run time dependencies
if runtimeDependency := dependency.ToRuntimeDependency(bodyContent); runtimeDependency != nil {
// resource must be convertible to a DashboardLeafNode
// - these are the only resources to support runtime dependencies
leafNode, ok := resource.(modconfig.DashboardLeafNode)
if !ok {
p.addDiags(hcl.Diagnostics{&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: fmt.Sprintf("invalid resource type %s declares a runtime depdnency - only ReportLeafNodes may use them", resource.Name()),
Subject: resource.GetDeclRange(),
}})
}
leafNode.AddRuntimeDependencies(runtimeDependency)
} else {
// this is not a runtime dependency - register a normal dependency
p.Depends = append(p.Depends, dependency)
}
}
}
// only register errors if there are NOT any missing variables
if diags.HasErrors() && len(allDependencies) == 0 {
p.addDiags(diags)
}
}
// determine whether the diag is a dependency error, and if so, return a dependency object
func isDependencyError(diag *hcl.Diagnostic) *modconfig.ResourceDependency {
if helpers.StringSliceContains(missingVariableErrors, diag.Summary) {
return &modconfig.ResourceDependency{Range: diag.Expression.Range(), Traversals: diag.Expression.Variables()}
}
return nil
}
func (p *decodeResult) addDiags(diags hcl.Diagnostics) {
p.Diags = append(p.Diags, diags...)
}