Skip to content

Commit 9cef155

Browse files
feat: introduce problem severity levels
1 parent 7204040 commit 9cef155

2 files changed

Lines changed: 48 additions & 6 deletions

File tree

lint/problem.go

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,33 @@ import (
2121
"github.com/jhump/protoreflect/desc"
2222
)
2323

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

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

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

85119
// Return a marshal-able structure.
86120
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"`
121+
Message string `json:"message" yaml:"message"`
122+
Suggestion string `json:"suggestion,omitempty" yaml:"suggestion,omitempty"`
123+
Location fileLocation `json:"location" yaml:"location"`
124+
RuleID RuleName `json:"rule_id" yaml:"rule_id"`
125+
RuleDocURI string `json:"rule_doc_uri" yaml:"rule_doc_uri"`
126+
Category string `json:"category,omitempty" yaml:"category,omitempty"`
127+
Severity SeverityLevel `json:"severity,omitempty" yaml:"severity,omitempty"`
93128
}{
94129
p.Message,
95130
p.Suggestion,
96131
fileLocationFromPBLocation(loc),
97132
p.RuleID,
98133
getRuleURL(string(p.RuleID), ruleURLMappings),
99134
p.category,
135+
p.Severity,
100136
}
101137
}
102138

lint/problem_test.go

Lines changed: 6 additions & 0 deletions
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)