Skip to content

Commit ba84329

Browse files
feat: introduce problem severity levels
1 parent 15657fd commit ba84329

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

lint/problem.go

+41-6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,32 @@ import (
2121
"github.com/jhump/protoreflect/desc"
2222
)
2323

24+
type SeverityLevel int
25+
26+
// Different levels of problem severity.
27+
const (
28+
UnknownSeverity SeverityLevel = 0
29+
LowSeverity SeverityLevel = 100
30+
ModerateSeverity SeverityLevel = 200
31+
MajorSeverity SeverityLevel = 300
32+
CriticalSeverity SeverityLevel = 400
33+
)
34+
35+
func (sv SeverityLevel) String() string {
36+
severity := "UNKNOWN"
37+
switch sv {
38+
case LowSeverity:
39+
severity = "LOW"
40+
case ModerateSeverity:
41+
severity = "MODERATE"
42+
case MajorSeverity:
43+
severity = "MAJOR"
44+
case CriticalSeverity:
45+
severity = "CRITICAL"
46+
}
47+
return severity
48+
}
49+
2450
// Problem contains information about a result produced by an API Linter.
2551
//
2652
// All rules return []Problem. Most lint rules return 0 or 1 problems, but
@@ -61,6 +87,13 @@ type Problem struct {
6187

6288
// nolint:structcheck,unused
6389
noPositional struct{}
90+
91+
// Severity represents the criticality level of the problem. The higher
92+
// the severity, the more critical the violation and the need of fixing it.
93+
//
94+
// It can be used to categorize problems and decide which of them are
95+
// "no-gos" and which are simply informational and can be tolerated.
96+
Severity SeverityLevel
6497
}
6598

6699
// MarshalJSON defines how to represent a Problem in JSON.
@@ -84,19 +117,21 @@ func (p Problem) marshal() interface{} {
84117

85118
// Return a marshal-able structure.
86119
return struct {
87-
Message string `json:"message" yaml:"message"`
88-
Suggestion string `json:"suggestion,omitempty" yaml:"suggestion,omitempty"`
89-
Location fileLocation `json:"location" yaml:"location"`
90-
RuleID RuleName `json:"rule_id" yaml:"rule_id"`
91-
RuleDocURI string `json:"rule_doc_uri" yaml:"rule_doc_uri"`
92-
Category string `json:"category,omitempty" yaml:"category,omitempty"`
120+
Message string `json:"message" yaml:"message"`
121+
Suggestion string `json:"suggestion,omitempty" yaml:"suggestion,omitempty"`
122+
Location fileLocation `json:"location" yaml:"location"`
123+
RuleID RuleName `json:"rule_id" yaml:"rule_id"`
124+
RuleDocURI string `json:"rule_doc_uri" yaml:"rule_doc_uri"`
125+
Category string `json:"category,omitempty" yaml:"category,omitempty"`
126+
Severity SeverityLevel `json:"severity,omitempty" yaml:"severity,omitempty"`
93127
}{
94128
p.Message,
95129
p.Suggestion,
96130
fileLocationFromPBLocation(loc),
97131
p.RuleID,
98132
getRuleURL(string(p.RuleID), ruleURLMappings),
99133
p.category,
134+
p.Severity,
100135
}
101136
}
102137

lint/problem_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func TestProblemJSON(t *testing.T) {
2929
Message: "foo bar",
3030
Location: &dpb.SourceCodeInfo_Location{Span: []int32{2, 0, 42}},
3131
RuleID: "core::0131",
32+
Severity: LowSeverity,
3233
}
3334
serialized, err := json.Marshal(problem)
3435
if err != nil {
@@ -43,6 +44,7 @@ func TestProblemJSON(t *testing.T) {
4344
{"ColumnNumberStart", `"column_number":1`},
4445
{"ColumnNumberEnd", `"column_number":42`},
4546
{"RuleID", `"rule_id":"core::0131"`},
47+
{"Severity", `"severity":100`},
4648
}
4749
for _, test := range tests {
4850
t.Run(test.testName, func(t *testing.T) {
@@ -58,6 +60,7 @@ func TestProblemYAML(t *testing.T) {
5860
Message: "foo bar",
5961
Location: &dpb.SourceCodeInfo_Location{Span: []int32{2, 0, 5, 70}},
6062
RuleID: "core::0131",
63+
Severity: LowSeverity,
6164
}
6265
serialized, err := yaml.Marshal(problem)
6366
if err != nil {
@@ -73,6 +76,7 @@ func TestProblemYAML(t *testing.T) {
7376
{"ColumnNumberStart", `column_number: 1`},
7477
{"ColumnNumberEnd", `column_number: 70`},
7578
{"RuleID", `rule_id: core::0131`},
79+
{"Severity", `severity: 100`},
7680
}
7781
for _, test := range tests {
7882
t.Run(test.testName, func(t *testing.T) {
@@ -93,6 +97,7 @@ func TestProblemDescriptor(t *testing.T) {
9397
Message: "foo bar",
9498
Descriptor: m,
9599
RuleID: "core::0131",
100+
Severity: LowSeverity,
96101
}
97102
serialized, err := yaml.Marshal(problem)
98103
if err != nil {
@@ -107,6 +112,7 @@ func TestProblemDescriptor(t *testing.T) {
107112
{"ColumnNumberStart", `column_number: 1`},
108113
{"ColumnNumberEnd", `column_number: 79`},
109114
{"RuleID", `rule_id: core::0131`},
115+
{"Severity", `severity: 100`},
110116
}
111117
for _, test := range tests {
112118
t.Run(test.testName, func(t *testing.T) {

0 commit comments

Comments
 (0)