feat: [gocritic] support disabled-tags
This commit is contained in:
		
							parent
							
								
									6771beaee6
								
							
						
					
					
						commit
						00cc2336c7
					
				@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -727,6 +727,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