command/format: Fix rendering of attribute-agnostic diagnostics

This commit is contained in:
Radek Simko 2018-11-23 16:08:27 +00:00
parent 8f6d525c56
commit 4f2868a019
No known key found for this signature in database
GPG Key ID: 1F1C84FE689A88D7
1 changed files with 19 additions and 18 deletions

View File

@ -58,23 +58,11 @@ func Diagnostic(diag tfdiags.Diagnostic, sources map[string][]byte, color *color
if sourceRefs.Context != nil { if sourceRefs.Context != nil {
snippetRange = sourceRefs.Context.ToHCL() snippetRange = sourceRefs.Context.ToHCL()
} }
// Make sure the snippet includes the highlight. This should be true // Make sure the snippet includes the highlight. This should be true
// for any reasonable diagnostic, but we'll make sure. // for any reasonable diagnostic, but we'll make sure.
snippetRange = hcl.RangeOver(snippetRange, highlightRange) snippetRange = hcl.RangeOver(snippetRange, highlightRange)
// We can't illustrate an empty range, so we'll turn such ranges into
// single-character ranges, which might not be totally valid (may point
// off the end of a line, or off the end of the file) but are good
// enough for the bounds checks we do below.
if snippetRange.Empty() {
snippetRange.End.Byte++
snippetRange.End.Column++
}
if highlightRange.Empty() {
highlightRange.End.Byte++
highlightRange.End.Column++
}
var src []byte var src []byte
if sources != nil { if sources != nil {
src = sources[snippetRange.Filename] src = sources[snippetRange.Filename]
@ -86,12 +74,25 @@ func Diagnostic(diag tfdiags.Diagnostic, sources map[string][]byte, color *color
// a not-so-helpful error message. // a not-so-helpful error message.
fmt.Fprintf(&buf, " on %s line %d:\n (source code not available)\n", highlightRange.Filename, highlightRange.Start.Line) fmt.Fprintf(&buf, " on %s line %d:\n (source code not available)\n", highlightRange.Filename, highlightRange.Start.Line)
} else { } else {
contextStr := sourceCodeContextStr(src, highlightRange) file, offset := parseRange(src, highlightRange)
headerRange := highlightRange
if snippetRange.Empty() {
// We assume that empty range signals diagnostic
// related to the whole body, so we lookup the definition
// instead of attempting to render empty range
snippetRange = hcled.ContextDefRange(file, offset-1)
headerRange = snippetRange
}
contextStr := hcled.ContextString(file, offset-1)
if contextStr != "" { if contextStr != "" {
contextStr = ", in " + contextStr contextStr = ", in " + contextStr
} }
fmt.Fprintf(&buf, " on %s line %d%s:\n", highlightRange.Filename, highlightRange.Start.Line, contextStr)
fmt.Fprintf(&buf, " on %s line %d%s:\n", headerRange.Filename, headerRange.Start.Line, contextStr)
// Config snippet rendering
sc := hcl.NewRangeScanner(src, highlightRange.Filename, bufio.ScanLines) sc := hcl.NewRangeScanner(src, highlightRange.Filename, bufio.ScanLines)
for sc.Scan() { for sc.Scan() {
lineRange := sc.Range() lineRange := sc.Range()
@ -185,7 +186,7 @@ func Diagnostic(diag tfdiags.Diagnostic, sources map[string][]byte, color *color
// An empty string is returned if no suitable description is available, e.g. // An empty string is returned if no suitable description is available, e.g.
// because the source is invalid, or because the offset is not inside any sort // because the source is invalid, or because the offset is not inside any sort
// of identifiable container. // of identifiable container.
func sourceCodeContextStr(src []byte, rng hcl.Range) string { func parseRange(src []byte, rng hcl.Range) (*hcl.File, int) {
filename := rng.Filename filename := rng.Filename
offset := rng.Start.Byte offset := rng.Start.Byte
@ -203,10 +204,10 @@ func sourceCodeContextStr(src []byte, rng hcl.Range) string {
file, diags = parser.ParseHCL(src, filename) file, diags = parser.ParseHCL(src, filename)
} }
if diags.HasErrors() { if diags.HasErrors() {
return "" return file, offset
} }
return hcled.ContextString(file, offset) return file, offset
} }
// traversalStr produces a representation of an HCL traversal that is compact, // traversalStr produces a representation of an HCL traversal that is compact,