Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce problem severity levels #966

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions lint/problem.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,32 @@ import (
"github.com/jhump/protoreflect/desc"
)

type SeverityLevel int

// Different levels of problem severity.
const (
UnknownSeverity SeverityLevel = 0
LowSeverity SeverityLevel = 100
ModerateSeverity SeverityLevel = 200
MajorSeverity SeverityLevel = 300
CriticalSeverity SeverityLevel = 400
)

func (sv SeverityLevel) String() string {
severity := "UNKNOWN"
switch sv {
case LowSeverity:
severity = "LOW"
case ModerateSeverity:
severity = "MODERATE"
case MajorSeverity:
severity = "MAJOR"
case CriticalSeverity:
severity = "CRITICAL"
}
return severity
}

// Problem contains information about a result produced by an API Linter.
//
// All rules return []Problem. Most lint rules return 0 or 1 problems, but
Expand Down Expand Up @@ -61,6 +87,12 @@ type Problem struct {

// nolint:structcheck,unused
noPositional struct{}

// Severity level of the problem. The higher the numeric value, the higher the severity.
//
// It can be used to categorize problems and decide which of them are
// "no-gos" and which are simply informational and can be tolerated.
Severity SeverityLevel
}

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

// Return a marshal-able structure.
return struct {
Message string `json:"message" yaml:"message"`
Suggestion string `json:"suggestion,omitempty" yaml:"suggestion,omitempty"`
Location fileLocation `json:"location" yaml:"location"`
RuleID RuleName `json:"rule_id" yaml:"rule_id"`
RuleDocURI string `json:"rule_doc_uri" yaml:"rule_doc_uri"`
Category string `json:"category,omitempty" yaml:"category,omitempty"`
Message string `json:"message" yaml:"message"`
Suggestion string `json:"suggestion,omitempty" yaml:"suggestion,omitempty"`
Location fileLocation `json:"location" yaml:"location"`
RuleID RuleName `json:"rule_id" yaml:"rule_id"`
RuleDocURI string `json:"rule_doc_uri" yaml:"rule_doc_uri"`
Category string `json:"category,omitempty" yaml:"category,omitempty"`
Severity SeverityLevel `json:"severity,omitempty" yaml:"severity,omitempty"`
}{
p.Message,
p.Suggestion,
fileLocationFromPBLocation(loc),
p.RuleID,
getRuleURL(string(p.RuleID), ruleURLMappings),
p.category,
p.Severity,
}
}

Expand Down
6 changes: 6 additions & 0 deletions lint/problem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestProblemJSON(t *testing.T) {
Message: "foo bar",
Location: &dpb.SourceCodeInfo_Location{Span: []int32{2, 0, 42}},
RuleID: "core::0131",
Severity: LowSeverity,
}
serialized, err := json.Marshal(problem)
if err != nil {
Expand All @@ -43,6 +44,7 @@ func TestProblemJSON(t *testing.T) {
{"ColumnNumberStart", `"column_number":1`},
{"ColumnNumberEnd", `"column_number":42`},
{"RuleID", `"rule_id":"core::0131"`},
{"Severity", `"severity":100`},
}
for _, test := range tests {
t.Run(test.testName, func(t *testing.T) {
Expand All @@ -58,6 +60,7 @@ func TestProblemYAML(t *testing.T) {
Message: "foo bar",
Location: &dpb.SourceCodeInfo_Location{Span: []int32{2, 0, 5, 70}},
RuleID: "core::0131",
Severity: LowSeverity,
}
serialized, err := yaml.Marshal(problem)
if err != nil {
Expand All @@ -73,6 +76,7 @@ func TestProblemYAML(t *testing.T) {
{"ColumnNumberStart", `column_number: 1`},
{"ColumnNumberEnd", `column_number: 70`},
{"RuleID", `rule_id: core::0131`},
{"Severity", `severity: 100`},
}
for _, test := range tests {
t.Run(test.testName, func(t *testing.T) {
Expand All @@ -93,6 +97,7 @@ func TestProblemDescriptor(t *testing.T) {
Message: "foo bar",
Descriptor: m,
RuleID: "core::0131",
Severity: LowSeverity,
}
serialized, err := yaml.Marshal(problem)
if err != nil {
Expand All @@ -107,6 +112,7 @@ func TestProblemDescriptor(t *testing.T) {
{"ColumnNumberStart", `column_number: 1`},
{"ColumnNumberEnd", `column_number: 79`},
{"RuleID", `rule_id: core::0131`},
{"Severity", `severity: 100`},
}
for _, test := range tests {
t.Run(test.testName, func(t *testing.T) {
Expand Down