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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
package main
import (
"encoding/json"
"io"
"github.com/hashicorp/hcl/v2"
)
type jsonDiagWriter struct {
w io.Writer
diags hcl.Diagnostics
}
var _ hcl.DiagnosticWriter = &jsonDiagWriter{}
func (wr *jsonDiagWriter) WriteDiagnostic(diag *hcl.Diagnostic) error {
wr.diags = append(wr.diags, diag)
return nil
}
func (wr *jsonDiagWriter) WriteDiagnostics(diags hcl.Diagnostics) error {
wr.diags = append(wr.diags, diags...)
return nil
}
func (wr *jsonDiagWriter) Flush() error {
if len(wr.diags) == 0 {
return nil
}
type PosJSON struct {
Line int `json:"line"`
Column int `json:"column"`
Byte int `json:"byte"`
}
type RangeJSON struct {
Filename string `json:"filename"`
Start PosJSON `json:"start"`
End PosJSON `json:"end"`
}
type DiagnosticJSON struct {
Severity string `json:"severity"`
Summary string `json:"summary"`
Detail string `json:"detail,omitempty"`
Subject *RangeJSON `json:"subject,omitempty"`
}
type DiagnosticsJSON struct {
Diagnostics []DiagnosticJSON `json:"diagnostics"`
}
diagsJSON := make([]DiagnosticJSON, 0, len(wr.diags))
for _, diag := range wr.diags {
var diagJSON DiagnosticJSON
switch diag.Severity {
case hcl.DiagError:
diagJSON.Severity = "error"
case hcl.DiagWarning:
diagJSON.Severity = "warning"
default:
diagJSON.Severity = "(unknown)" // should never happen
}
diagJSON.Summary = diag.Summary
diagJSON.Detail = diag.Detail
if diag.Subject != nil {
diagJSON.Subject = &RangeJSON{}
sJSON := diagJSON.Subject
rng := diag.Subject
sJSON.Filename = rng.Filename
sJSON.Start.Line = rng.Start.Line
sJSON.Start.Column = rng.Start.Column
sJSON.Start.Byte = rng.Start.Byte
sJSON.End.Line = rng.End.Line
sJSON.End.Column = rng.End.Column
sJSON.End.Byte = rng.End.Byte
}
diagsJSON = append(diagsJSON, diagJSON)
}
src, err := json.MarshalIndent(DiagnosticsJSON{diagsJSON}, "", " ")
if err != nil {
return err
}
_, err = wr.w.Write(src)
wr.w.Write([]byte{'\n'})
return err
}
type flusher interface {
Flush() error
}
func flush(maybeFlusher interface{}) error {
if f, ok := maybeFlusher.(flusher); ok {
return f.Flush()
}
return nil
}
|