Merge pull request #1029 from kaka19ace/master
feat: [gocritic] support disabled-tags
This commit is contained in:
commit
aed4806aae
@ -117,6 +117,8 @@ linters-settings:
|
|||||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||||
enabled-tags:
|
enabled-tags:
|
||||||
- performance
|
- performance
|
||||||
|
disabled-tags:
|
||||||
|
- experimental
|
||||||
|
|
||||||
settings: # settings passed to gocritic
|
settings: # settings passed to gocritic
|
||||||
captLocal: # must be valid enabled check name
|
captLocal: # must be valid enabled check name
|
||||||
|
@ -729,6 +729,8 @@ linters-settings:
|
|||||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||||
enabled-tags:
|
enabled-tags:
|
||||||
- performance
|
- performance
|
||||||
|
disabled-tags:
|
||||||
|
- experimental
|
||||||
|
|
||||||
settings: # settings passed to gocritic
|
settings: # settings passed to gocritic
|
||||||
captLocal: # must be valid enabled check name
|
captLocal: # must be valid enabled check name
|
||||||
|
@ -15,10 +15,18 @@ import (
|
|||||||
|
|
||||||
const gocriticDebugKey = "gocritic"
|
const gocriticDebugKey = "gocritic"
|
||||||
|
|
||||||
var gocriticDebugf = logutils.Debug(gocriticDebugKey)
|
var (
|
||||||
var isGocriticDebug = logutils.HaveDebugTag(gocriticDebugKey)
|
gocriticDebugf = logutils.Debug(gocriticDebugKey)
|
||||||
|
isGocriticDebug = logutils.HaveDebugTag(gocriticDebugKey)
|
||||||
var allGocriticCheckers = lintpack.GetCheckersInfo()
|
allGocriticCheckers = lintpack.GetCheckersInfo()
|
||||||
|
allGocriticCheckerMap = func() map[string]*lintpack.CheckerInfo {
|
||||||
|
checkInfoMap := make(map[string]*lintpack.CheckerInfo)
|
||||||
|
for _, checkInfo := range allGocriticCheckers {
|
||||||
|
checkInfoMap[checkInfo.Name] = checkInfo
|
||||||
|
}
|
||||||
|
return checkInfoMap
|
||||||
|
}()
|
||||||
|
)
|
||||||
|
|
||||||
type GocriticCheckSettings map[string]interface{}
|
type GocriticCheckSettings map[string]interface{}
|
||||||
|
|
||||||
@ -26,6 +34,7 @@ type GocriticSettings struct {
|
|||||||
EnabledChecks []string `mapstructure:"enabled-checks"`
|
EnabledChecks []string `mapstructure:"enabled-checks"`
|
||||||
DisabledChecks []string `mapstructure:"disabled-checks"`
|
DisabledChecks []string `mapstructure:"disabled-checks"`
|
||||||
EnabledTags []string `mapstructure:"enabled-tags"`
|
EnabledTags []string `mapstructure:"enabled-tags"`
|
||||||
|
DisabledTags []string `mapstructure:"disabled-tags"`
|
||||||
SettingsPerCheck map[string]GocriticCheckSettings `mapstructure:"settings"`
|
SettingsPerCheck map[string]GocriticCheckSettings `mapstructure:"settings"`
|
||||||
|
|
||||||
inferredEnabledChecks map[string]bool
|
inferredEnabledChecks map[string]bool
|
||||||
@ -107,6 +116,8 @@ func (s *GocriticSettings) InferEnabledChecks(log logutils.Log) {
|
|||||||
debugChecksListf(disabledByDefaultChecks, "Disabled by default")
|
debugChecksListf(disabledByDefaultChecks, "Disabled by default")
|
||||||
|
|
||||||
var enabledChecks []string
|
var enabledChecks []string
|
||||||
|
|
||||||
|
// EnabledTags
|
||||||
if len(s.EnabledTags) != 0 {
|
if len(s.EnabledTags) != 0 {
|
||||||
tagToCheckers := buildGocriticTagToCheckersMap()
|
tagToCheckers := buildGocriticTagToCheckersMap()
|
||||||
for _, tag := range s.EnabledTags {
|
for _, tag := range s.EnabledTags {
|
||||||
@ -120,6 +131,12 @@ func (s *GocriticSettings) InferEnabledChecks(log logutils.Log) {
|
|||||||
enabledChecks = append(enabledChecks, enabledByDefaultChecks...)
|
enabledChecks = append(enabledChecks, enabledByDefaultChecks...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DisabledTags
|
||||||
|
if len(s.DisabledTags) != 0 {
|
||||||
|
enabledChecks = filterByDisableTags(enabledChecks, s.DisabledTags, log)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnabledChecks
|
||||||
if len(s.EnabledChecks) != 0 {
|
if len(s.EnabledChecks) != 0 {
|
||||||
debugChecksListf(s.EnabledChecks, "Enabled by config")
|
debugChecksListf(s.EnabledChecks, "Enabled by config")
|
||||||
|
|
||||||
@ -133,6 +150,7 @@ func (s *GocriticSettings) InferEnabledChecks(log logutils.Log) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DisabledChecks
|
||||||
if len(s.DisabledChecks) != 0 {
|
if len(s.DisabledChecks) != 0 {
|
||||||
debugChecksListf(s.DisabledChecks, "Disabled by config")
|
debugChecksListf(s.DisabledChecks, "Disabled by config")
|
||||||
|
|
||||||
@ -174,6 +192,22 @@ func validateStringsUniq(ss []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func intersectStringSlice(s1, s2 []string) []string {
|
||||||
|
s1Map := make(map[string]struct{})
|
||||||
|
for _, s := range s1 {
|
||||||
|
s1Map[s] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]string, 0)
|
||||||
|
for _, s := range s2 {
|
||||||
|
if _, exists := s1Map[s]; exists {
|
||||||
|
result = append(result, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GocriticSettings) Validate(log logutils.Log) error {
|
func (s *GocriticSettings) Validate(log logutils.Log) error {
|
||||||
if len(s.EnabledTags) == 0 {
|
if len(s.EnabledTags) == 0 {
|
||||||
if len(s.EnabledChecks) != 0 && len(s.DisabledChecks) != 0 {
|
if len(s.EnabledChecks) != 0 && len(s.DisabledChecks) != 0 {
|
||||||
@ -187,7 +221,16 @@ func (s *GocriticSettings) Validate(log logutils.Log) error {
|
|||||||
tagToCheckers := buildGocriticTagToCheckersMap()
|
tagToCheckers := buildGocriticTagToCheckersMap()
|
||||||
for _, tag := range s.EnabledTags {
|
for _, tag := range s.EnabledTags {
|
||||||
if _, ok := tagToCheckers[tag]; !ok {
|
if _, ok := tagToCheckers[tag]; !ok {
|
||||||
return fmt.Errorf("gocritic tag %q doesn't exist", tag)
|
return fmt.Errorf("gocritic [enabled]tag %q doesn't exist", tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.DisabledTags) > 0 {
|
||||||
|
tagToCheckers := buildGocriticTagToCheckersMap()
|
||||||
|
for _, tag := range s.EnabledTags {
|
||||||
|
if _, ok := tagToCheckers[tag]; !ok {
|
||||||
|
return fmt.Errorf("gocritic [disabled]tag %q doesn't exist", tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,3 +344,24 @@ func (s *GocriticSettings) GetLowercasedParams() map[string]GocriticCheckSetting
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filterByDisableTags(enabledChecks, disableTags []string, log logutils.Log) []string {
|
||||||
|
enabledChecksSet := stringsSliceToSet(enabledChecks)
|
||||||
|
for _, enabledCheck := range enabledChecks {
|
||||||
|
checkInfo, checkInfoExists := allGocriticCheckerMap[enabledCheck]
|
||||||
|
if !checkInfoExists {
|
||||||
|
log.Warnf("Gocritic check %q was not exists via filtering disabled tags", enabledCheck)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hitTags := intersectStringSlice(checkInfo.Tags, disableTags)
|
||||||
|
if len(hitTags) != 0 {
|
||||||
|
delete(enabledChecksSet, enabledCheck)
|
||||||
|
}
|
||||||
|
debugChecksListf(enabledChecks, "Disabled by config tags %s", sprintStrings(disableTags))
|
||||||
|
}
|
||||||
|
enabledChecks = nil
|
||||||
|
for enabledCheck := range enabledChecksSet {
|
||||||
|
enabledChecks = append(enabledChecks, enabledCheck)
|
||||||
|
}
|
||||||
|
return enabledChecks
|
||||||
|
}
|
||||||
|
54
pkg/config/config_gocritic_test.go
Normal file
54
pkg/config/config_gocritic_test.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/logutils"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUtils(t *testing.T) {
|
||||||
|
s1 := []string{"diagnostic", "experimental", "opinionated"}
|
||||||
|
s2 := []string{"opinionated", "experimental"}
|
||||||
|
s3 := intersectStringSlice(s1, s2)
|
||||||
|
sort.Strings(s3)
|
||||||
|
assert.Equal(t, s3, []string{"experimental", "opinionated"})
|
||||||
|
}
|
||||||
|
|
||||||
|
type tLog struct{}
|
||||||
|
|
||||||
|
func (l *tLog) Fatalf(format string, args ...interface{}) {
|
||||||
|
fmt.Printf(fmt.Sprintf(format, args...) + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tLog) Panicf(format string, args ...interface{}) {
|
||||||
|
fmt.Printf(fmt.Sprintf(format, args...) + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tLog) Errorf(format string, args ...interface{}) {
|
||||||
|
fmt.Printf(fmt.Sprintf(format, args...) + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tLog) Warnf(format string, args ...interface{}) {
|
||||||
|
fmt.Printf(fmt.Sprintf(format, args...) + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tLog) Infof(format string, args ...interface{}) {
|
||||||
|
fmt.Printf(fmt.Sprintf(format, args...) + "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tLog) Child(name string) logutils.Log { return nil }
|
||||||
|
|
||||||
|
func (l *tLog) SetLevel(level logutils.LogLevel) {}
|
||||||
|
|
||||||
|
func TestFilterByDisableTags(t *testing.T) {
|
||||||
|
testLog := &tLog{}
|
||||||
|
disabledTags := []string{"experimental", "opinionated"}
|
||||||
|
enabledChecks := []string{"appendAssign", "argOrder", "caseOrder", "codegenComment"}
|
||||||
|
filterEnabledChecks := filterByDisableTags(enabledChecks, disabledTags, testLog)
|
||||||
|
sort.Strings(filterEnabledChecks)
|
||||||
|
assert.Equal(t, []string{"appendAssign", "caseOrder"}, filterEnabledChecks)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user