diff --git a/command/format/diagnostic.go b/command/format/diagnostic.go index 6b8232650e..dc1dfe5bf7 100644 --- a/command/format/diagnostic.go +++ b/command/format/diagnostic.go @@ -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), + ) + } } } diff --git a/command/format/diagnostic_test.go b/command/format/diagnostic_test.go index 18812089ca..8848e4b295 100644 --- a/command/format/diagnostic_test.go +++ b/command/format/diagnostic_test.go @@ -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) + } +}