diff options
author | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
---|---|---|
committer | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
commit | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go | |
parent | 07971ca38143c5faf951d152fba370ddcbe26ad5 (diff) | |
download | terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip |
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go')
-rw-r--r-- | vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go b/vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go new file mode 100644 index 0000000..dfa473a --- /dev/null +++ b/vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go | |||
@@ -0,0 +1,168 @@ | |||
1 | package hcl | ||
2 | |||
3 | import ( | ||
4 | "bufio" | ||
5 | "errors" | ||
6 | "fmt" | ||
7 | "io" | ||
8 | |||
9 | wordwrap "github.com/mitchellh/go-wordwrap" | ||
10 | ) | ||
11 | |||
12 | type diagnosticTextWriter struct { | ||
13 | files map[string]*File | ||
14 | wr io.Writer | ||
15 | width uint | ||
16 | color bool | ||
17 | } | ||
18 | |||
19 | // NewDiagnosticTextWriter creates a DiagnosticWriter that writes diagnostics | ||
20 | // to the given writer as formatted text. | ||
21 | // | ||
22 | // It is designed to produce text appropriate to print in a monospaced font | ||
23 | // in a terminal of a particular width, or optionally with no width limit. | ||
24 | // | ||
25 | // The given width may be zero to disable word-wrapping of the detail text | ||
26 | // and truncation of source code snippets. | ||
27 | // | ||
28 | // If color is set to true, the output will include VT100 escape sequences to | ||
29 | // color-code the severity indicators. It is suggested to turn this off if | ||
30 | // the target writer is not a terminal. | ||
31 | func NewDiagnosticTextWriter(wr io.Writer, files map[string]*File, width uint, color bool) DiagnosticWriter { | ||
32 | return &diagnosticTextWriter{ | ||
33 | files: files, | ||
34 | wr: wr, | ||
35 | width: width, | ||
36 | color: color, | ||
37 | } | ||
38 | } | ||
39 | |||
40 | func (w *diagnosticTextWriter) WriteDiagnostic(diag *Diagnostic) error { | ||
41 | if diag == nil { | ||
42 | return errors.New("nil diagnostic") | ||
43 | } | ||
44 | |||
45 | var colorCode, highlightCode, resetCode string | ||
46 | if w.color { | ||
47 | switch diag.Severity { | ||
48 | case DiagError: | ||
49 | colorCode = "\x1b[31m" | ||
50 | case DiagWarning: | ||
51 | colorCode = "\x1b[33m" | ||
52 | } | ||
53 | resetCode = "\x1b[0m" | ||
54 | highlightCode = "\x1b[1;4m" | ||
55 | } | ||
56 | |||
57 | var severityStr string | ||
58 | switch diag.Severity { | ||
59 | case DiagError: | ||
60 | severityStr = "Error" | ||
61 | case DiagWarning: | ||
62 | severityStr = "Warning" | ||
63 | default: | ||
64 | // should never happen | ||
65 | severityStr = "???????" | ||
66 | } | ||
67 | |||
68 | fmt.Fprintf(w.wr, "%s%s%s: %s\n\n", colorCode, severityStr, resetCode, diag.Summary) | ||
69 | |||
70 | if diag.Subject != nil { | ||
71 | snipRange := *diag.Subject | ||
72 | highlightRange := snipRange | ||
73 | if diag.Context != nil { | ||
74 | // Show enough of the source code to include both the subject | ||
75 | // and context ranges, which overlap in all reasonable | ||
76 | // situations. | ||
77 | snipRange = RangeOver(snipRange, *diag.Context) | ||
78 | } | ||
79 | // We can't illustrate an empty range, so we'll turn such ranges into | ||
80 | // single-character ranges, which might not be totally valid (may point | ||
81 | // off the end of a line, or off the end of the file) but are good | ||
82 | // enough for the bounds checks we do below. | ||
83 | if snipRange.Empty() { | ||
84 | snipRange.End.Byte++ | ||
85 | snipRange.End.Column++ | ||
86 | } | ||
87 | if highlightRange.Empty() { | ||
88 | highlightRange.End.Byte++ | ||
89 | highlightRange.End.Column++ | ||
90 | } | ||
91 | |||
92 | file := w.files[diag.Subject.Filename] | ||
93 | if file == nil || file.Bytes == nil { | ||
94 | fmt.Fprintf(w.wr, " on %s line %d:\n (source code not available)\n\n", diag.Subject.Filename, diag.Subject.Start.Line) | ||
95 | } else { | ||
96 | |||
97 | var contextLine string | ||
98 | if diag.Subject != nil { | ||
99 | contextLine = contextString(file, diag.Subject.Start.Byte) | ||
100 | if contextLine != "" { | ||
101 | contextLine = ", in " + contextLine | ||
102 | } | ||
103 | } | ||
104 | |||
105 | fmt.Fprintf(w.wr, " on %s line %d%s:\n", diag.Subject.Filename, diag.Subject.Start.Line, contextLine) | ||
106 | |||
107 | src := file.Bytes | ||
108 | sc := NewRangeScanner(src, diag.Subject.Filename, bufio.ScanLines) | ||
109 | |||
110 | for sc.Scan() { | ||
111 | lineRange := sc.Range() | ||
112 | if !lineRange.Overlaps(snipRange) { | ||
113 | continue | ||
114 | } | ||
115 | |||
116 | beforeRange, highlightedRange, afterRange := lineRange.PartitionAround(highlightRange) | ||
117 | if highlightedRange.Empty() { | ||
118 | fmt.Fprintf(w.wr, "%4d: %s\n", lineRange.Start.Line, sc.Bytes()) | ||
119 | } else { | ||
120 | before := beforeRange.SliceBytes(src) | ||
121 | highlighted := highlightedRange.SliceBytes(src) | ||
122 | after := afterRange.SliceBytes(src) | ||
123 | fmt.Fprintf( | ||
124 | w.wr, "%4d: %s%s%s%s%s\n", | ||
125 | lineRange.Start.Line, | ||
126 | before, | ||
127 | highlightCode, highlighted, resetCode, | ||
128 | after, | ||
129 | ) | ||
130 | } | ||
131 | |||
132 | } | ||
133 | |||
134 | w.wr.Write([]byte{'\n'}) | ||
135 | } | ||
136 | } | ||
137 | |||
138 | if diag.Detail != "" { | ||
139 | detail := diag.Detail | ||
140 | if w.width != 0 { | ||
141 | detail = wordwrap.WrapString(detail, w.width) | ||
142 | } | ||
143 | fmt.Fprintf(w.wr, "%s\n\n", detail) | ||
144 | } | ||
145 | |||
146 | return nil | ||
147 | } | ||
148 | |||
149 | func (w *diagnosticTextWriter) WriteDiagnostics(diags Diagnostics) error { | ||
150 | for _, diag := range diags { | ||
151 | err := w.WriteDiagnostic(diag) | ||
152 | if err != nil { | ||
153 | return err | ||
154 | } | ||
155 | } | ||
156 | return nil | ||
157 | } | ||
158 | |||
159 | func contextString(file *File, offset int) string { | ||
160 | type contextStringer interface { | ||
161 | ContextString(offset int) string | ||
162 | } | ||
163 | |||
164 | if cser, ok := file.Nav.(contextStringer); ok { | ||
165 | return cser.ContextString(offset) | ||
166 | } | ||
167 | return "" | ||
168 | } | ||