diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml index 5e79c0c1cfe5..d8ad0046b2e0 100644 --- a/.golangci.next.reference.yml +++ b/.golangci.next.reference.yml @@ -25,6 +25,7 @@ linters: - asciicheck - bidichk - bodyclose + - boolset - canonicalheader - containedctx - contextcheck @@ -139,6 +140,7 @@ linters: - asciicheck - bidichk - bodyclose + - boolset - canonicalheader - containedctx - contextcheck diff --git a/go.mod b/go.mod index 8b060abd2d4b..8c664de1f11a 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/alexkohler/prealloc v1.0.0 github.com/alingse/asasalint v0.0.11 github.com/alingse/nilnesserr v0.2.0 + github.com/arturmelanchyk/boolset v0.1.0 github.com/ashanbrown/forbidigo/v2 v2.1.0 github.com/ashanbrown/makezero/v2 v2.0.1 github.com/bkielbasa/cyclop v1.2.3 diff --git a/go.sum b/go.sum index 81e51769acc7..4d2bc392ccc4 100644 --- a/go.sum +++ b/go.sum @@ -90,6 +90,8 @@ github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQ github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/alingse/nilnesserr v0.2.0 h1:raLem5KG7EFVb4UIDAXgrv3N2JIaffeKNtcEXkEWd/w= github.com/alingse/nilnesserr v0.2.0/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg= +github.com/arturmelanchyk/boolset v0.1.0 h1:h2SsP7fRkQuMa+gehI8TMC8yeGmx3YVVKG7RPd41+ok= +github.com/arturmelanchyk/boolset v0.1.0/go.mod h1:fbNSqEARCo6gKmn3cJoK/G6jaqmqBpeupHgIklA503o= github.com/ashanbrown/forbidigo/v2 v2.1.0 h1:NAxZrWqNUQiDz19FKScQ/xvwzmij6BiOw3S0+QUQ+Hs= github.com/ashanbrown/forbidigo/v2 v2.1.0/go.mod h1:0zZfdNAuZIL7rSComLGthgc/9/n2FqspBOH90xlCHdA= github.com/ashanbrown/makezero/v2 v2.0.1 h1:r8GtKetWOgoJ4sLyUx97UTwyt2dO7WkGFHizn/Lo8TY= diff --git a/pkg/golinters/boolset/boolset.go b/pkg/golinters/boolset/boolset.go new file mode 100644 index 000000000000..017d05fc73d8 --- /dev/null +++ b/pkg/golinters/boolset/boolset.go @@ -0,0 +1,13 @@ +package boolset + +import ( + "github.com/arturmelanchyk/boolset/boolset" + + "github.com/golangci/golangci-lint/v2/pkg/goanalysis" +) + +func New() *goanalysis.Linter { + return goanalysis. + NewLinterFromAnalyzer(boolset.NewAnalyzer()). + WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/golinters/boolset/boolset_integration_test.go b/pkg/golinters/boolset/boolset_integration_test.go new file mode 100644 index 000000000000..69c8ab27df7b --- /dev/null +++ b/pkg/golinters/boolset/boolset_integration_test.go @@ -0,0 +1,11 @@ +package boolset + +import ( + "testing" + + "github.com/golangci/golangci-lint/v2/test/testshared/integration" +) + +func TestFromTestdata(t *testing.T) { + integration.RunTestdata(t) +} diff --git a/pkg/golinters/boolset/testdata/boolset.go b/pkg/golinters/boolset/testdata/boolset.go new file mode 100644 index 000000000000..8f56db12be94 --- /dev/null +++ b/pkg/golinters/boolset/testdata/boolset.go @@ -0,0 +1,23 @@ +//golangcitest:args -Eboolset +package testdata + +import ( + "log" +) + +var allNames = []string{"a", "a", "b", "c", "c", "d"} + +func findDuplicates() []string { + var duplicates []string + uniqueNames := make(map[string]bool) // want "map\\[string\\]bool only stores \"true\" values; consider map\\[string\\]struct\\{\\}" + for _, name := range allNames { + if _, ok := uniqueNames[name]; ok { + duplicates = append(duplicates, name) + log.Println("Duplicate found: ", name) + } else { + uniqueNames[name] = true + } + } + + return duplicates +} diff --git a/pkg/golinters/boolset/testdata/boolset_cgo.go b/pkg/golinters/boolset/testdata/boolset_cgo.go new file mode 100644 index 000000000000..a9de546f5e1c --- /dev/null +++ b/pkg/golinters/boolset/testdata/boolset_cgo.go @@ -0,0 +1,40 @@ +//golangcitest:args -Eboolset +package testdata + +/* + #include + #include + + void myprint(char* s) { + printf("%d\n", s); + } +*/ +import "C" + +import ( + "log" + "unsafe" +) + +func _() { + cs := C.CString("Hello from stdio\n") + C.myprint(cs) + C.free(unsafe.Pointer(cs)) +} + +var allNamesCgo = []string{"a", "a", "b", "c", "c", "d"} + +func findDuplicatesCgo() []string { + var duplicates []string + uniqueNames := make(map[string]bool) // want "map\\[string\\]bool only stores \"true\" values; consider map\\[string\\]struct\\{\\}" + for _, name := range allNamesCgo { + if _, ok := uniqueNames[name]; ok { + duplicates = append(duplicates, name) + log.Println("Duplicate found: ", name) + } else { + uniqueNames[name] = true + } + } + + return duplicates +} diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index 72e02f7a6b3a..f74ee0d0bd18 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -8,6 +8,7 @@ import ( "github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck" "github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk" "github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose" + "github.com/golangci/golangci-lint/v2/pkg/golinters/boolset" "github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader" "github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx" "github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck" @@ -165,6 +166,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithLoadForGoAnalysis(). WithURL("https://github.com/timakin/bodyclose"), + linter.NewConfig(boolset.New()). + WithSince("v2.6.0"). + WithLoadForGoAnalysis(). + WithURL("https://github.com/arturmelanchyk/boolset"), + linter.NewConfig(canonicalheader.New()). WithSince("v1.58.0"). WithLoadForGoAnalysis().