diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform-config-inspect/tfconfig/diagnostic.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform-config-inspect/tfconfig/diagnostic.go | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform-config-inspect/tfconfig/diagnostic.go b/vendor/github.com/hashicorp/terraform-config-inspect/tfconfig/diagnostic.go new file mode 100644 index 0000000..8d04ad4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-config-inspect/tfconfig/diagnostic.go | |||
@@ -0,0 +1,138 @@ | |||
1 | package tfconfig | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | |||
6 | legacyhclparser "github.com/hashicorp/hcl/hcl/parser" | ||
7 | "github.com/hashicorp/hcl2/hcl" | ||
8 | ) | ||
9 | |||
10 | // Diagnostic describes a problem (error or warning) encountered during | ||
11 | // configuration loading. | ||
12 | type Diagnostic struct { | ||
13 | Severity DiagSeverity `json:"severity"` | ||
14 | Summary string `json:"summary"` | ||
15 | Detail string `json:"detail,omitempty"` | ||
16 | |||
17 | // Pos is not populated for all diagnostics, but when populated should | ||
18 | // indicate a particular line that the described problem relates to. | ||
19 | Pos *SourcePos `json:"pos,omitempty"` | ||
20 | } | ||
21 | |||
22 | // Diagnostics represents a sequence of diagnostics. This is the type that | ||
23 | // should be returned from a function that might generate diagnostics. | ||
24 | type Diagnostics []Diagnostic | ||
25 | |||
26 | // HasErrors returns true if there is at least one Diagnostic of severity | ||
27 | // DiagError in the receiever. | ||
28 | // | ||
29 | // If a function returns a Diagnostics without errors then the result can | ||
30 | // be assumed to be complete within the "best effort" constraints of this | ||
31 | // library. If errors are present then the caller may wish to employ more | ||
32 | // caution in relying on the result. | ||
33 | func (diags Diagnostics) HasErrors() bool { | ||
34 | for _, diag := range diags { | ||
35 | if diag.Severity == DiagError { | ||
36 | return true | ||
37 | } | ||
38 | } | ||
39 | return false | ||
40 | } | ||
41 | |||
42 | func (diags Diagnostics) Error() string { | ||
43 | switch len(diags) { | ||
44 | case 0: | ||
45 | return "no problems" | ||
46 | case 1: | ||
47 | return fmt.Sprintf("%s: %s", diags[0].Summary, diags[0].Detail) | ||
48 | default: | ||
49 | return fmt.Sprintf("%s: %s (and %d other messages)", diags[0].Summary, diags[0].Detail, len(diags)-1) | ||
50 | } | ||
51 | } | ||
52 | |||
53 | // Err returns an error representing the receiver if the receiver HasErrors, or | ||
54 | // nil otherwise. | ||
55 | // | ||
56 | // The returned error can be type-asserted back to a Diagnostics if needed. | ||
57 | func (diags Diagnostics) Err() error { | ||
58 | if diags.HasErrors() { | ||
59 | return diags | ||
60 | } | ||
61 | return nil | ||
62 | } | ||
63 | |||
64 | // DiagSeverity describes the severity of a Diagnostic. | ||
65 | type DiagSeverity rune | ||
66 | |||
67 | // DiagError indicates a problem that prevented proper processing of the | ||
68 | // configuration. In the precense of DiagError diagnostics the result is | ||
69 | // likely to be incomplete. | ||
70 | const DiagError DiagSeverity = 'E' | ||
71 | |||
72 | // DiagWarning indicates a problem that the user may wish to consider but | ||
73 | // that did not prevent proper processing of the configuration. | ||
74 | const DiagWarning DiagSeverity = 'W' | ||
75 | |||
76 | // MarshalJSON is an implementation of encoding/json.Marshaler | ||
77 | func (s DiagSeverity) MarshalJSON() ([]byte, error) { | ||
78 | switch s { | ||
79 | case DiagError: | ||
80 | return []byte(`"error"`), nil | ||
81 | case DiagWarning: | ||
82 | return []byte(`"warning"`), nil | ||
83 | default: | ||
84 | return []byte(`"invalid"`), nil | ||
85 | } | ||
86 | } | ||
87 | |||
88 | func diagnosticsHCL(diags hcl.Diagnostics) Diagnostics { | ||
89 | if len(diags) == 0 { | ||
90 | return nil | ||
91 | } | ||
92 | ret := make(Diagnostics, len(diags)) | ||
93 | for i, diag := range diags { | ||
94 | ret[i] = Diagnostic{ | ||
95 | Summary: diag.Summary, | ||
96 | Detail: diag.Detail, | ||
97 | } | ||
98 | switch diag.Severity { | ||
99 | case hcl.DiagError: | ||
100 | ret[i].Severity = DiagError | ||
101 | case hcl.DiagWarning: | ||
102 | ret[i].Severity = DiagWarning | ||
103 | } | ||
104 | if diag.Subject != nil { | ||
105 | pos := sourcePosHCL(*diag.Subject) | ||
106 | ret[i].Pos = &pos | ||
107 | } | ||
108 | } | ||
109 | return ret | ||
110 | } | ||
111 | |||
112 | func diagnosticsError(err error) Diagnostics { | ||
113 | if err == nil { | ||
114 | return nil | ||
115 | } | ||
116 | |||
117 | if posErr, ok := err.(*legacyhclparser.PosError); ok { | ||
118 | pos := sourcePosLegacyHCL(posErr.Pos, "") | ||
119 | return Diagnostics{ | ||
120 | Diagnostic{ | ||
121 | Severity: DiagError, | ||
122 | Summary: posErr.Err.Error(), | ||
123 | Pos: &pos, | ||
124 | }, | ||
125 | } | ||
126 | } | ||
127 | |||
128 | return Diagnostics{ | ||
129 | Diagnostic{ | ||
130 | Severity: DiagError, | ||
131 | Summary: err.Error(), | ||
132 | }, | ||
133 | } | ||
134 | } | ||
135 | |||
136 | func diagnosticsErrorf(format string, args ...interface{}) Diagnostics { | ||
137 | return diagnosticsError(fmt.Errorf(format, args...)) | ||
138 | } | ||