Skip to content

Commit c23c379

Browse files
committed
feat: add extra diagnostic block for coder metadata
Only `code` is present right now.
1 parent 5aa2069 commit c23c379

File tree

2 files changed

+79
-3
lines changed

2 files changed

+79
-3
lines changed

types/diagnostics.go

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,43 @@ import (
66
"github.com/hashicorp/hcl/v2"
77
)
88

9+
type DiagnosticExtra struct {
10+
Code string `json:"code"`
11+
12+
// If there was a previous extra, store it here for unwrapping.
13+
wrapped any
14+
}
15+
16+
var _ hcl.DiagnosticExtraUnwrapper = DiagnosticExtra{}
17+
18+
func (e DiagnosticExtra) UnwrapDiagnosticExtra() interface{} {
19+
return e.wrapped
20+
}
21+
22+
func ExtractDiagnosticExtra(diag *hcl.Diagnostic) DiagnosticExtra {
23+
// Zero values for a missing extra field is fine.
24+
extra, _ := hcl.DiagnosticExtra[DiagnosticExtra](diag)
25+
return extra
26+
}
27+
28+
func SetDiagnosticExtra(diag *hcl.Diagnostic, extra DiagnosticExtra) {
29+
existing, ok := hcl.DiagnosticExtra[DiagnosticExtra](diag)
30+
if ok {
31+
// If an existing extra is present, we will keep the underlying
32+
// wrapped. This is not perfect, as any parents are lost.
33+
// So try to avoid calling 'SetDiagnosticExtra' more than once.
34+
extra.wrapped = existing.wrapped
35+
diag.Extra = extra
36+
return
37+
}
38+
39+
// Maintain any existing extra fields.
40+
if diag.Extra != nil {
41+
extra.wrapped = diag.Extra
42+
}
43+
diag.Extra = extra
44+
}
45+
946
// Diagnostics is a JSON friendly form of hcl.Diagnostics.
1047
// Data is lost when doing a json marshal.
1148
type Diagnostics hcl.Diagnostics
@@ -23,11 +60,15 @@ func (d *Diagnostics) UnmarshalJSON(data []byte) error {
2360
severity = hcl.DiagWarning
2461
}
2562

26-
*d = append(*d, &hcl.Diagnostic{
63+
hclDiag := &hcl.Diagnostic{
2764
Severity: severity,
2865
Summary: diag.Summary,
2966
Detail: diag.Detail,
30-
})
67+
}
68+
69+
SetDiagnosticExtra(hclDiag, diag.Extra)
70+
71+
*d = append(*d, hclDiag)
3172
}
3273
return nil
3374
}
@@ -40,10 +81,13 @@ func (d Diagnostics) MarshalJSON() ([]byte, error) {
4081
severity = DiagnosticSeverityWarning
4182
}
4283

84+
extra := ExtractDiagnosticExtra(diag)
85+
4386
cpy = append(cpy, FriendlyDiagnostic{
4487
Severity: severity,
4588
Summary: diag.Summary,
4689
Detail: diag.Detail,
90+
Extra: extra,
4791
})
4892
}
4993
return json.Marshal(cpy)
@@ -60,4 +104,6 @@ type FriendlyDiagnostic struct {
60104
Severity DiagnosticSeverityString `json:"severity"`
61105
Summary string `json:"summary"`
62106
Detail string `json:"detail"`
107+
108+
Extra DiagnosticExtra `json:"extra"`
63109
}

types/diagnostics_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,48 @@ import (
1010
"github.com/coder/preview/types"
1111
)
1212

13-
func TestDiagnosticsJSON(t *testing.T) {
13+
func TestDiagnosticExtra(t *testing.T) {
14+
diag := &hcl.Diagnostic{
15+
Severity: hcl.DiagWarning,
16+
Summary: "Some summary",
17+
Detail: "Some detail",
18+
}
19+
20+
extra := types.ExtractDiagnosticExtra(diag)
21+
require.Empty(t, extra.Code)
22+
23+
// Set it
24+
extra.Code = "foobar"
25+
types.SetDiagnosticExtra(diag, extra)
26+
27+
extra = types.ExtractDiagnosticExtra(diag)
28+
require.Equal(t, "foobar", extra.Code)
1429

30+
// Set it again
31+
extra.Code = "bazz"
32+
types.SetDiagnosticExtra(diag, extra)
33+
34+
extra = types.ExtractDiagnosticExtra(diag)
35+
require.Equal(t, "bazz", extra.Code)
36+
}
37+
38+
func TestDiagnosticsJSON(t *testing.T) {
1539
diags := types.Diagnostics{
1640
{
1741
Severity: hcl.DiagWarning,
1842
Summary: "Some summary",
1943
Detail: "Some detail",
44+
Extra: types.DiagnosticExtra{
45+
Code: "foobar",
46+
},
2047
},
2148
{
2249
Severity: hcl.DiagError,
2350
Summary: "Some summary",
2451
Detail: "Some detail",
52+
Extra: types.DiagnosticExtra{
53+
Code: "",
54+
},
2555
},
2656
}
2757

0 commit comments

Comments
 (0)