mirror of
https://github.com/mgechev/revive.git
synced 2025-05-21 22:13:14 +02:00
Implement severity
This commit is contained in:
parent
b2e276ddf8
commit
4f31c1639f
@ -20,30 +20,32 @@ type CLIFormatter struct {
|
|||||||
Metadata linter.FormatterMetadata
|
Metadata linter.FormatterMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatFailure(failure linter.Failure) []string {
|
func formatFailure(failure linter.Failure, severity linter.Severity) []string {
|
||||||
fString := color.BlueString(failure.Failure)
|
fString := color.BlueString(failure.Failure)
|
||||||
fTypeStr := string(failure.Type)
|
fTypeStr := string(severity)
|
||||||
fType := color.RedString(fTypeStr)
|
fType := color.RedString(fTypeStr)
|
||||||
lineColumn := failure.Position
|
lineColumn := failure.Position
|
||||||
pos := fmt.Sprintf("(%d, %d)", lineColumn.Start.Line, lineColumn.Start.Column)
|
pos := fmt.Sprintf("(%d, %d)", lineColumn.Start.Line, lineColumn.Start.Column)
|
||||||
if failure.Type == linter.FailureTypeWarning {
|
if severity == linter.SeverityWarning {
|
||||||
fType = color.YellowString(fTypeStr)
|
fType = color.YellowString(fTypeStr)
|
||||||
}
|
}
|
||||||
return []string{failure.GetFilename(), pos, fType, fString}
|
return []string{failure.GetFilename(), pos, fType, fString}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format formats the failures gotten from the linter.
|
// Format formats the failures gotten from the linter.
|
||||||
func (f *CLIFormatter) Format(failures <-chan linter.Failure) (string, error) {
|
func (f *CLIFormatter) Format(failures <-chan linter.Failure, config linter.RulesConfig) (string, error) {
|
||||||
var result [][]string
|
var result [][]string
|
||||||
var totalErrors = 0
|
var totalErrors = 0
|
||||||
var total = 0
|
var total = 0
|
||||||
|
|
||||||
for f := range failures {
|
for f := range failures {
|
||||||
result = append(result, formatFailure(f))
|
|
||||||
total++
|
total++
|
||||||
if f.Type == linter.FailureTypeError {
|
currentType := linter.SeverityWarning
|
||||||
|
if config, ok := config[f.RuleName]; ok && config.Severity == linter.SeverityError {
|
||||||
|
currentType = linter.SeverityError
|
||||||
totalErrors++
|
totalErrors++
|
||||||
}
|
}
|
||||||
|
result = append(result, formatFailure(f, linter.Severity(currentType)))
|
||||||
}
|
}
|
||||||
ps := "problems"
|
ps := "problems"
|
||||||
if total == 1 {
|
if total == 1 {
|
||||||
|
@ -13,7 +13,7 @@ type JSONFormatter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Format formats the failures gotten from the linter.
|
// Format formats the failures gotten from the linter.
|
||||||
func (f *JSONFormatter) Format(failures <-chan linter.Failure) (string, error) {
|
func (f *JSONFormatter) Format(failures <-chan linter.Failure, config linter.RulesConfig) (string, error) {
|
||||||
var slice []linter.Failure
|
var slice []linter.Failure
|
||||||
for failure := range failures {
|
for failure := range failures {
|
||||||
slice = append(slice, failure)
|
slice = append(slice, failure)
|
||||||
|
@ -91,7 +91,7 @@ func (f *File) lint(rules []Rule, rulesConfig RulesConfig, failures chan Failure
|
|||||||
disabledIntervals := f.disabledIntervals(rules)
|
disabledIntervals := f.disabledIntervals(rules)
|
||||||
for _, currentRule := range rules {
|
for _, currentRule := range rules {
|
||||||
config := rulesConfig[currentRule.Name()]
|
config := rulesConfig[currentRule.Name()]
|
||||||
currentFailures := currentRule.Apply(f, config)
|
currentFailures := currentRule.Apply(f, config.Arguments)
|
||||||
for idx, failure := range currentFailures {
|
for idx, failure := range currentFailures {
|
||||||
if failure.RuleName == "" {
|
if failure.RuleName == "" {
|
||||||
failure.RuleName = currentRule.Name()
|
failure.RuleName = currentRule.Name()
|
||||||
|
@ -9,5 +9,5 @@ type FormatterMetadata struct {
|
|||||||
|
|
||||||
// Formatter defines an interface for failure formatters
|
// Formatter defines an interface for failure formatters
|
||||||
type Formatter interface {
|
type Formatter interface {
|
||||||
Format(<-chan Failure, <-chan string, int) string
|
Format(<-chan Failure, RulesConfig) string
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// FailureTypeWarning declares failures of type warning
|
// SeverityWarning declares failures of type warning
|
||||||
FailureTypeWarning = "warning"
|
SeverityWarning = "warning"
|
||||||
// FailureTypeError declares failures of type error.
|
// SeverityError declares failures of type error.
|
||||||
FailureTypeError = "error"
|
SeverityError = "error"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FailureType is the type for the failure types.
|
// Severity is the type for the failure types.
|
||||||
type FailureType string
|
type Severity string
|
||||||
|
|
||||||
// FailurePosition returns the failure position
|
// FailurePosition returns the failure position
|
||||||
type FailurePosition struct {
|
type FailurePosition struct {
|
||||||
@ -26,7 +26,6 @@ type Failure struct {
|
|||||||
Failure string
|
Failure string
|
||||||
RuleName string
|
RuleName string
|
||||||
Category string
|
Category string
|
||||||
Type FailureType
|
|
||||||
Position FailurePosition
|
Position FailurePosition
|
||||||
Node ast.Node `json:"-"`
|
Node ast.Node `json:"-"`
|
||||||
Confidence float64
|
Confidence float64
|
||||||
@ -48,16 +47,16 @@ type DisabledInterval struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Arguments is type used for the arguments of a rule.
|
// Arguments is type used for the arguments of a rule.
|
||||||
type Arguments []string
|
type Arguments = []string
|
||||||
|
|
||||||
// Config contains the rule configuration.
|
// RuleConfig is type used for the rule configuration.
|
||||||
type Config struct {
|
type RuleConfig struct {
|
||||||
Name string
|
|
||||||
Arguments Arguments
|
Arguments Arguments
|
||||||
|
Severity Severity
|
||||||
}
|
}
|
||||||
|
|
||||||
// RulesConfig defiles the config for all rules.
|
// RulesConfig defiles the config for all rules.
|
||||||
type RulesConfig = map[string]Arguments
|
type RulesConfig = map[string]RuleConfig
|
||||||
|
|
||||||
// Rule defines an abstract rule interaface
|
// Rule defines an abstract rule interaface
|
||||||
type Rule interface {
|
type Rule interface {
|
||||||
|
38
main.go
38
main.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/mgechev/revive/formatter"
|
"github.com/mgechev/revive/formatter"
|
||||||
"github.com/mgechev/revive/linter"
|
"github.com/mgechev/revive/linter"
|
||||||
@ -20,7 +21,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func foobar(a int, b int, c int, d int) {
|
func foo_bar(a int, b int, c int, d int) {
|
||||||
return a + b + c;
|
return a + b + c;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@ -29,10 +30,13 @@ func main() {
|
|||||||
return []byte(src), nil
|
return []byte(src), nil
|
||||||
})
|
})
|
||||||
var result []linter.Rule
|
var result []linter.Rule
|
||||||
result = append(result, &rule.LintElseRule{}, &rule.ArgumentsLimitRule{})
|
result = append(result, &rule.LintElseRule{}, &rule.ArgumentsLimitRule{}, &rule.NamesRule{})
|
||||||
|
|
||||||
var config = linter.RulesConfig{
|
var config = linter.RulesConfig{
|
||||||
"argument-limit": []string{"3"},
|
"argument-limit": linter.RuleConfig{
|
||||||
|
Arguments: []string{"3"},
|
||||||
|
Severity: linter.SeverityWarning,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
failures, err := revive.Lint([]string{"foo.go", "bar.go", "baz.go"}, result, config)
|
failures, err := revive.Lint([]string{"foo.go", "bar.go", "baz.go"}, result, config)
|
||||||
@ -40,11 +44,29 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var formatter formatter.CLIFormatter
|
formatChan := make(chan linter.Failure)
|
||||||
output, err := formatter.Format(failures)
|
exitChan := make(chan bool)
|
||||||
if err != nil {
|
var output string
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
go (func() {
|
||||||
|
var formatter formatter.CLIFormatter
|
||||||
|
output, err = formatter.Format(formatChan, config)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
exitChan <- true
|
||||||
|
})()
|
||||||
|
|
||||||
|
exitCode := 0
|
||||||
|
for f := range failures {
|
||||||
|
if c, ok := config[f.RuleName]; ok && c.Severity == linter.SeverityError {
|
||||||
|
exitCode = 1
|
||||||
|
}
|
||||||
|
formatChan <- f
|
||||||
|
}
|
||||||
|
close(formatChan)
|
||||||
|
<-exitChan
|
||||||
fmt.Println(output)
|
fmt.Println(output)
|
||||||
|
|
||||||
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,6 @@ func (w lintArgsNum) Visit(n ast.Node) ast.Visitor {
|
|||||||
if num > w.total {
|
if num > w.total {
|
||||||
w.onFailure(linter.Failure{
|
w.onFailure(linter.Failure{
|
||||||
Failure: fmt.Sprintf("maximum number of arguments per function exceeded; max %d but got %d", w.total, num),
|
Failure: fmt.Sprintf("maximum number of arguments per function exceeded; max %d but got %d", w.total, num),
|
||||||
Type: linter.FailureTypeWarning,
|
|
||||||
Node: node.Type,
|
Node: node.Type,
|
||||||
})
|
})
|
||||||
return w
|
return w
|
||||||
|
@ -66,7 +66,6 @@ func (w lintElse) Visit(node ast.Node) ast.Visitor {
|
|||||||
}
|
}
|
||||||
w.onFailure(linter.Failure{
|
w.onFailure(linter.Failure{
|
||||||
Failure: "if block ends with a return statement, so drop this else and outdent its block" + extra,
|
Failure: "if block ends with a return statement, so drop this else and outdent its block" + extra,
|
||||||
Type: linter.FailureTypeWarning,
|
|
||||||
Node: ifStmt.Else,
|
Node: ifStmt.Else,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user