command/format: Fix multi-line diagnostic output
Previously, if a diagnostic context spanned multiple lines, any lines which did not overlap with the highlight range would be displayed as blank. This commit fixes the bug. The problem was caused by the unconditional use of `PartitionAround` to split the line into before/highlighted/after ranges. When two ranges don't overlap, this method returns empty ranges, which results in a blank line. Instead, we first check if the ranges do overlap, and if not we print the entire line from the context.
This commit is contained in:
parent
537c1bedcf
commit
a23c3e3c81
|
@ -100,15 +100,23 @@ func Diagnostic(diag tfdiags.Diagnostic, sources map[string][]byte, color *color
|
|||
if !lineRange.Overlaps(snippetRange) {
|
||||
continue
|
||||
}
|
||||
beforeRange, highlightedRange, afterRange := lineRange.PartitionAround(highlightRange)
|
||||
before := beforeRange.SliceBytes(src)
|
||||
highlighted := highlightedRange.SliceBytes(src)
|
||||
after := afterRange.SliceBytes(src)
|
||||
fmt.Fprintf(
|
||||
&buf, color.Color("%4d: %s[underline]%s[reset]%s\n"),
|
||||
lineRange.Start.Line,
|
||||
before, highlighted, after,
|
||||
)
|
||||
if lineRange.Overlaps(highlightRange) {
|
||||
beforeRange, highlightedRange, afterRange := lineRange.PartitionAround(highlightRange)
|
||||
before := beforeRange.SliceBytes(src)
|
||||
highlighted := highlightedRange.SliceBytes(src)
|
||||
after := afterRange.SliceBytes(src)
|
||||
fmt.Fprintf(
|
||||
&buf, color.Color("%4d: %s[underline]%s[reset]%s\n"),
|
||||
lineRange.Start.Line,
|
||||
before, highlighted, after,
|
||||
)
|
||||
} else {
|
||||
fmt.Fprintf(
|
||||
&buf, "%4d: %s\n",
|
||||
lineRange.Start.Line,
|
||||
lineRange.SliceBytes(src),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,3 +71,52 @@ func TestDiagnosticWarningsCompact(t *testing.T) {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Test case via https://github.com/hashicorp/terraform/issues/21359
|
||||
func TestDiagnostic_nonOverlappingHighlightContext(t *testing.T) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Some error",
|
||||
Detail: "...",
|
||||
Subject: &hcl.Range{
|
||||
Filename: "source.tf",
|
||||
Start: hcl.Pos{Line: 1, Column: 5, Byte: 5},
|
||||
End: hcl.Pos{Line: 1, Column: 5, Byte: 5},
|
||||
},
|
||||
Context: &hcl.Range{
|
||||
Filename: "source.tf",
|
||||
Start: hcl.Pos{Line: 1, Column: 5, Byte: 5},
|
||||
End: hcl.Pos{Line: 4, Column: 2, Byte: 60},
|
||||
},
|
||||
})
|
||||
sources := map[string][]byte{
|
||||
"source.tf": []byte(`x = somefunc("testing", {
|
||||
alpha = "foo"
|
||||
beta = "bar"
|
||||
})
|
||||
`),
|
||||
}
|
||||
color := &colorstring.Colorize{
|
||||
Colors: colorstring.DefaultColors,
|
||||
Reset: true,
|
||||
Disable: true,
|
||||
}
|
||||
expected := `
|
||||
Error: Some error
|
||||
|
||||
on source.tf line 1:
|
||||
1: x = somefunc("testing", {
|
||||
2: alpha = "foo"
|
||||
3: beta = "bar"
|
||||
4: })
|
||||
|
||||
...
|
||||
`
|
||||
output := Diagnostic(diags[0], sources, color, 80)
|
||||
|
||||
if output != expected {
|
||||
t.Fatalf("unexpected output: got:\n%s\nwant\n%s\n", output, expected)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue