aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go
diff options
context:
space:
mode:
authorAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
committerAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
commit15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/hashicorp/hcl2/hcl/diagnostic_text.go
parent07971ca38143c5faf951d152fba370ddcbe26ad5 (diff)
downloadterraform-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.go168
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 @@
1package hcl
2
3import (
4 "bufio"
5 "errors"
6 "fmt"
7 "io"
8
9 wordwrap "github.com/mitchellh/go-wordwrap"
10)
11
12type 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.
31func 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
40func (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
149func (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
159func 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}