1
0
mirror of https://github.com/mgechev/revive.git synced 2025-11-25 22:12:38 +02:00

refactor: rename blacklist to blocklist and whitelist to allowlist (#946)

* refactor: rename blacklist to blocklist and whitelist to allowlist
This commit is contained in:
Marcin Federowicz
2024-01-15 12:16:00 +01:00
committed by GitHub
parent af4f9ea960
commit 9abe06adfa
9 changed files with 159 additions and 24 deletions

View File

@@ -56,6 +56,7 @@ var allRules = append([]lint.Rule{
&rule.ConstantLogicalExprRule{},
&rule.BoolLiteralRule{},
&rule.ImportsBlacklistRule{},
&rule.ImportsBlocklistRule{},
&rule.FunctionResultsLimitRule{},
&rule.MaxPublicStructsRule{},
&rule.RangeValInClosureRule{},

View File

@@ -6,7 +6,7 @@ import (
)
// Name returns a different name if it should be different.
func Name(name string, whitelist, blacklist []string) (should string) {
func Name(name string, allowlist, blocklist []string) (should string) {
// Fast path for simple cases: "_" and all lowercase.
if name == "_" {
return name
@@ -57,12 +57,12 @@ func Name(name string, whitelist, blacklist []string) (should string) {
// [w,i) is a word.
word := string(runes[w:i])
ignoreInitWarnings := map[string]bool{}
for _, i := range whitelist {
for _, i := range allowlist {
ignoreInitWarnings[i] = true
}
extraInits := map[string]bool{}
for _, i := range blacklist {
for _, i := range blocklist {
extraInits[i] = true
}

View File

@@ -18,13 +18,13 @@ const (
kindSTRING = "STRING"
)
type whiteList map[string]map[string]bool
type allowList map[string]map[string]bool
func newWhiteList() whiteList {
func newAllowList() allowList {
return map[string]map[string]bool{kindINT: {}, kindFLOAT: {}, kindSTRING: {}}
}
func (wl whiteList) add(kind, list string) {
func (wl allowList) add(kind, list string) {
elems := strings.Split(list, ",")
for _, e := range elems {
wl[kind][e] = true
@@ -33,7 +33,7 @@ func (wl whiteList) add(kind, list string) {
// AddConstantRule lints unused params in functions.
type AddConstantRule struct {
whiteList whiteList
allowList allowList
ignoreFunctions []*regexp.Regexp
strLitLimit int
sync.Mutex
@@ -53,7 +53,7 @@ func (r *AddConstantRule) Apply(file *lint.File, arguments lint.Arguments) []lin
onFailure: onFailure,
strLits: make(map[string]int),
strLitLimit: r.strLitLimit,
whiteLst: r.whiteList,
allowList: r.allowList,
ignoreFunctions: r.ignoreFunctions,
structTags: make(map[*ast.BasicLit]struct{}),
}
@@ -72,7 +72,7 @@ type lintAddConstantRule struct {
onFailure func(lint.Failure)
strLits map[string]int
strLitLimit int
whiteLst whiteList
allowList allowList
ignoreFunctions []*regexp.Regexp
structTags map[*ast.BasicLit]struct{}
}
@@ -155,7 +155,7 @@ func (w *lintAddConstantRule) isIgnoredFunc(fName string) bool {
}
func (w *lintAddConstantRule) checkStrLit(n *ast.BasicLit) {
if w.whiteLst[kindSTRING][n.Value] {
if w.allowList[kindSTRING][n.Value] {
return
}
@@ -175,7 +175,7 @@ func (w *lintAddConstantRule) checkStrLit(n *ast.BasicLit) {
}
func (w *lintAddConstantRule) checkNumLit(kind string, n *ast.BasicLit) {
if w.whiteLst[kind][n.Value] {
if w.allowList[kind][n.Value] {
return
}
@@ -196,9 +196,9 @@ func (r *AddConstantRule) configure(arguments lint.Arguments) {
r.Lock()
defer r.Unlock()
if r.whiteList == nil {
if r.allowList == nil {
r.strLitLimit = defaultStrLitLimit
r.whiteList = newWhiteList()
r.allowList = newAllowList()
if len(arguments) > 0 {
args, ok := arguments[0].(map[string]any)
if !ok {
@@ -223,7 +223,7 @@ func (r *AddConstantRule) configure(arguments lint.Arguments) {
if !ok {
panic(fmt.Sprintf("Invalid argument to the add-constant rule, string expected. Got '%v' (%T)", v, v))
}
r.whiteList.add(kind, list)
r.allowList.add(kind, list)
case "maxLitCount":
sl, ok := v.(string)
if !ok {

View File

@@ -111,7 +111,7 @@ func checkMethodName(holder string, id *ast.Ident, w *lintConfusingNames) {
pkgm.methods[holder] = make(map[string]*referenceMethod, 1)
}
// update the black list
// update the block list
if pkgm.methods[holder] == nil {
println("no entry for '", holder, "'")
}

73
rule/imports-blocklist.go Normal file
View File

@@ -0,0 +1,73 @@
package rule
import (
"fmt"
"regexp"
"sync"
"github.com/mgechev/revive/lint"
)
// ImportsBlocklistRule lints given else constructs.
type ImportsBlocklistRule struct {
blocklist []*regexp.Regexp
sync.Mutex
}
var replaceImportRegexp = regexp.MustCompile(`/?\*\*/?`)
func (r *ImportsBlocklistRule) configure(arguments lint.Arguments) {
r.Lock()
defer r.Unlock()
if r.blocklist == nil {
r.blocklist = make([]*regexp.Regexp, 0)
for _, arg := range arguments {
argStr, ok := arg.(string)
if !ok {
panic(fmt.Sprintf("Invalid argument to the imports-blocklist rule. Expecting a string, got %T", arg))
}
regStr, err := regexp.Compile(fmt.Sprintf(`(?m)"%s"$`, replaceImportRegexp.ReplaceAllString(argStr, `(\W|\w)*`)))
if err != nil {
panic(fmt.Sprintf("Invalid argument to the imports-blocklist rule. Expecting %q to be a valid regular expression, got: %v", argStr, err))
}
r.blocklist = append(r.blocklist, regStr)
}
}
}
func (r *ImportsBlocklistRule) isBlocklisted(path string) bool {
for _, regex := range r.blocklist {
if regex.MatchString(path) {
return true
}
}
return false
}
// Apply applies the rule to given file.
func (r *ImportsBlocklistRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
r.configure(arguments)
var failures []lint.Failure
for _, is := range file.AST.Imports {
path := is.Path
if path != nil && r.isBlocklisted(path.Value) {
failures = append(failures, lint.Failure{
Confidence: 1,
Failure: "should not use the following blocklisted import: " + path.Value,
Node: is,
Category: "imports",
})
}
}
return failures
}
// Name returns the rule name.
func (*ImportsBlocklistRule) Name() string {
return "imports-blocklist"
}

View File

@@ -19,8 +19,8 @@ var upperCaseConstRE = regexp.MustCompile(`^_?[A-Z][A-Z\d]*(_[A-Z\d]+)*$`)
// VarNamingRule lints given else constructs.
type VarNamingRule struct {
configured bool
whitelist []string
blacklist []string
allowlist []string
blocklist []string
upperCaseConst bool // if true - allows to use UPPER_SOME_NAMES for constants
skipPackageNameChecks bool
sync.Mutex
@@ -35,11 +35,11 @@ func (r *VarNamingRule) configure(arguments lint.Arguments) {
r.configured = true
if len(arguments) >= 1 {
r.whitelist = getList(arguments[0], "whitelist")
r.allowlist = getList(arguments[0], "whitelist")
}
if len(arguments) >= 2 {
r.blacklist = getList(arguments[1], "blacklist")
r.blocklist = getList(arguments[1], "blacklist")
}
if len(arguments) >= 3 {
@@ -93,8 +93,8 @@ func (r *VarNamingRule) Apply(file *lint.File, arguments lint.Arguments) []lint.
walker := lintNames{
file: file,
fileAst: fileAst,
whitelist: r.whitelist,
blacklist: r.blacklist,
allowlist: r.allowlist,
blocklist: r.blocklist,
onFailure: func(failure lint.Failure) {
failures = append(failures, failure)
},
@@ -151,7 +151,7 @@ func (w *lintNames) check(id *ast.Ident, thing string) {
return
}
should := lint.Name(id.Name, w.whitelist, w.blacklist)
should := lint.Name(id.Name, w.allowlist, w.blocklist)
if id.Name == should {
return
}
@@ -177,8 +177,8 @@ type lintNames struct {
file *lint.File
fileAst *ast.File
onFailure func(lint.Failure)
whitelist []string
blacklist []string
allowlist []string
blocklist []string
upperCaseConst bool
}

View File

@@ -0,0 +1,34 @@
package test
import (
"testing"
"github.com/mgechev/revive/lint"
"github.com/mgechev/revive/rule"
)
func TestImportsBlocklistOriginal(t *testing.T) {
args := []any{"crypto/md5", "crypto/sha1"}
testRule(t, "imports-blocklist-original", &rule.ImportsBlocklistRule{}, &lint.RuleConfig{
Arguments: args,
})
}
func TestImportsBlocklist(t *testing.T) {
args := []any{"github.com/full/match", "wildcard/**/between", "wildcard/backward/**", "**/wildcard/forward", "full"}
testRule(t, "imports-blocklist", &rule.ImportsBlocklistRule{}, &lint.RuleConfig{
Arguments: args,
})
}
func BenchmarkImportsBlocklist(b *testing.B) {
args := []any{"github.com/full/match", "wildcard/**/between", "wildcard/backward/**", "**/wildcard/forward", "full"}
var t *testing.T
for i := 0; i <= b.N; i++ {
testRule(t, "imports-blocklist", &rule.ImportsBlocklistRule{}, &lint.RuleConfig{
Arguments: args,
})
}
}

View File

@@ -0,0 +1,8 @@
package fixtures
import (
"crypto/md5" // MATCH /should not use the following blocklisted import: "crypto/md5"/
"crypto/sha1" // MATCH /should not use the following blocklisted import: "crypto/sha1"/
"strings"
)

19
testdata/imports-blocklist.go vendored Normal file
View File

@@ -0,0 +1,19 @@
package fixtures
import (
"github.com/full/match" // MATCH /should not use the following blocklisted import: "github.com/full/match"/
"bithub.com/full/match"
"github.com/full/matche"
"wildcard/between" // MATCH /should not use the following blocklisted import: "wildcard/between"/
"wildcard/pkg1/between" // MATCH /should not use the following blocklisted import: "wildcard/pkg1/between"/
"wildcard/pkg1/pkg2/between" // MATCH /should not use the following blocklisted import: "wildcard/pkg1/pkg2/between"/
"wildcard/backward" // MATCH /should not use the following blocklisted import: "wildcard/backward"/
"wildcard/backward/pkg" // MATCH /should not use the following blocklisted import: "wildcard/backward/pkg"/
"wildcard/backward/pkg/pkg1" // MATCH /should not use the following blocklisted import: "wildcard/backward/pkg/pkg1"/
"wildcard/forward" // MATCH /should not use the following blocklisted import: "wildcard/forward"/
"pkg/wildcard/forward" // MATCH /should not use the following blocklisted import: "pkg/wildcard/forward"/
"pkg/pkg1/wildcard/forward" // MATCH /should not use the following blocklisted import: "pkg/pkg1/wildcard/forward"/
"full" // MATCH /should not use the following blocklisted import: "full"/
"github.com/partical/match/fully"
"strings"
)