Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gocognit linter #756

Merged
merged 7 commits into from
Oct 3, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .golangci.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ linters-settings:
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 10
gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 10
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ dupl: Tool for code clone detection [fast: true, auto-fix: false]
funlen: Tool for detection of long functions [fast: true, auto-fix: false]
gochecknoglobals: Checks that no globals are present in Go code [fast: true, auto-fix: false]
gochecknoinits: Checks that no init functions are present in Go code [fast: true, auto-fix: false]
gocognit: Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
goconst: Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
gocritic: The most opinionated Go source code linter [fast: true, auto-fix: false]
gocyclo: Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
Expand Down Expand Up @@ -449,6 +450,7 @@ golangci-lint help linters
- [dupl](https://github.com/mibk/dupl) - Tool for code clone detection
- [goconst](https://github.com/jgautheron/goconst) - Finds repeated strings that could be replaced by a constant
- [gocyclo](https://github.com/alecthomas/gocyclo) - Computes and checks the cyclomatic complexity of functions
- [gocognit](https://github.com/uudashr/gocognit) - Computes and checks the cognitive complexity of functions
- [gofmt](https://golang.org/cmd/gofmt/) - Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification
- [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) - Goimports does everything that gofmt does. Additionally it checks unused imports
- [maligned](https://github.com/mdempsky/maligned) - Tool to detect Go structs that would take less memory if their fields were sorted
Expand Down Expand Up @@ -703,6 +705,9 @@ linters-settings:
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 10
gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 10
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
Expand Down Expand Up @@ -1108,6 +1113,7 @@ Thanks to developers and authors of used linters:
- [jgautheron](https://github.com/jgautheron)
- [remyoudompheng](https://github.com/remyoudompheng)
- [alecthomas](https://github.com/alecthomas)
- [uudashr](https://github.com/uudashr)
- [OpenPeeDeeP](https://github.com/OpenPeeDeeP)
- [client9](https://github.com/client9)
- [walle](https://github.com/walle)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ require (
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e
github.com/ultraware/funlen v0.0.2
github.com/ultraware/whitespace v0.0.3
github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517
github.com/valyala/quicktemplate v1.2.0
golang.org/x/tools v0.0.0-20190912215617-3720d1ec3678
gopkg.in/yaml.v2 v2.2.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbd
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.3 h1:S5BCRRB5sttNy0bSOhbpw+0mb+cHiCmWfrvxpEzuUk0=
github.com/ultraware/whitespace v0.0.3/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517 h1:ChMKTho2hWKpks/nD/FL2KqM1wuVt62oJeiE8+eFpGs=
github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
Expand Down
3 changes: 3 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ type LintersSettings struct {
Gocyclo struct {
MinComplexity int `mapstructure:"min-complexity"`
}
Gocognit struct {
MinComplexity int `mapstructure:"min-complexity"`
}
Varcheck struct {
CheckExportedFields bool `mapstructure:"exported-fields"`
}
Expand Down
54 changes: 54 additions & 0 deletions pkg/golinters/gocognit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// nolint:dupl
package golinters

import (
"context"
"fmt"
"sort"

"github.com/uudashr/gocognit"

"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/result"
)

type Gocognit struct{}

func (Gocognit) Name() string {
return "gocognit"
}

func (Gocognit) Desc() string {
return "Computes and checks the cognitive complexity of functions"
}

func (g Gocognit) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
var stats []gocognit.Stat
for _, f := range lintCtx.ASTCache.GetAllValidFiles() {
uudashr marked this conversation as resolved.
Show resolved Hide resolved
stats = gocognit.ComplexityStats(f.F, f.Fset, stats)
}

if len(stats) == 0 {
return nil, nil
}

sort.Slice(stats, func(i, j int) bool {
return stats[i].Complexity > stats[j].Complexity
})

res := make([]result.Issue, 0, len(stats))
for _, s := range stats {
if s.Complexity <= lintCtx.Settings().Gocognit.MinComplexity {
break // Break as the stats is already sorted from greatest to least
}

res = append(res, result.Issue{
Pos: s.Pos,
Text: fmt.Sprintf("cognitive complexity %d of func %s is high (> %d)",
s.Complexity, formatCode(s.FuncName, lintCtx.Cfg), lintCtx.Settings().Gocognit.MinComplexity),
FromLinter: g.Name(),
})
}

return res, nil
}
1 change: 1 addition & 0 deletions pkg/golinters/gocyclo.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// nolint:dupl
package golinters

import (
Expand Down
4 changes: 4 additions & 0 deletions pkg/lint/lintersdb/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
linter.NewConfig(golinters.NewGocyclo()).
WithPresets(linter.PresetComplexity).
WithURL("https://github.com/alecthomas/gocyclo"),
linter.NewConfig(golinters.Gocognit{}).
WithPresets(linter.PresetComplexity).
WithSpeed(8).
uudashr marked this conversation as resolved.
Show resolved Hide resolved
WithURL("https://github.com/uudashr/gocognit"),
linter.NewConfig(golinters.NewTypecheck()).
WithLoadForGoAnalysis().
WithPresets(linter.PresetBugs).
Expand Down
23 changes: 23 additions & 0 deletions test/testdata/gocognit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//args: -Egocognit
//config: linters-settings.gocognit.min-complexity=2
package testdata

func GocognitGetWords(number int) string { // ERROR "cognitive complexity 4 of func .* is high .*"
if number == 1 { // +1
return "one"
} else if number == 2 { // +1
return "a couple"
} else if number == 3 { // +1
return "a few"
} else { // +1
return "lots"
}
} // total complexity = 4

func GoCognitFact(n int) int { // ERROR "cognitive complexity 3 of func .* is high .*"
if n <= 1 { // +1
return 1
} else { // +1
return n + GoCognitFact(n-1) // +1
}
} // total complexity = 3
21 changes: 21 additions & 0 deletions vendor/github.com/uudashr/gocognit/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

185 changes: 185 additions & 0 deletions vendor/github.com/uudashr/gocognit/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vendor/github.com/uudashr/gocognit/go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading