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 funlen linter #603

Merged
merged 2 commits into from Sep 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .golangci.example.yml
Expand Up @@ -78,6 +78,11 @@ linters-settings:
# path to a file containing a list of functions to exclude from checking
# see https://github.com/kisielk/errcheck#excluding-functions for details
exclude: /path/to/file.txt

funlen:
lines: 60
statements: 40

govet:
# report about shadowed variables
check-shadowing: true
Expand Down
1 change: 1 addition & 0 deletions .golangci.yml
Expand Up @@ -46,6 +46,7 @@ linters:
- maligned
- prealloc
- gochecknoglobals
- funlen

run:
skip-dirs:
Expand Down
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -208,6 +208,7 @@ Disabled by default linters:
bodyclose: checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]
depguard: Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
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]
goconst: Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
Expand Down Expand Up @@ -440,6 +441,7 @@ golangci-lint help linters
- [gocritic](https://github.com/go-critic/go-critic) - The most opinionated Go source code linter
- [gochecknoinits](https://github.com/leighmcculloch/gochecknoinits) - Checks that no init functions are present in Go code
- [gochecknoglobals](https://github.com/leighmcculloch/gochecknoglobals) - Checks that no globals are present in Go code
- [funlen](https://github.com/ultraware/funlen) - Tool for detection of long functions

## Configuration

Expand Down Expand Up @@ -629,6 +631,11 @@ linters-settings:
# path to a file containing a list of functions to exclude from checking
# see https://github.com/kisielk/errcheck#excluding-functions for details
exclude: /path/to/file.txt

funlen:
lines: 60
statements: 40

govet:
# report about shadowed variables
check-shadowing: true
Expand Down Expand Up @@ -859,6 +866,7 @@ linters:
- maligned
- prealloc
- gochecknoglobals
- funlen

run:
skip-dirs:
Expand Down Expand Up @@ -999,6 +1007,7 @@ Thanks to developers and authors of used linters:
- [kyoh86](https://github.com/kyoh86)
- [go-critic](https://github.com/go-critic)
- [leighmcculloch](https://github.com/leighmcculloch)
- [ultraware](https://github.com/ultraware)

## Changelog

Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -49,6 +49,7 @@ require (
github.com/spf13/pflag v1.0.1
github.com/spf13/viper v1.0.2
github.com/stretchr/testify v1.2.2
github.com/ultraware/funlen v0.0.1
github.com/timakin/bodyclose v0.0.0-00010101000000-87058b9bfcec
github.com/valyala/quicktemplate v1.1.1
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -164,6 +164,8 @@ github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso=
github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/ultraware/funlen v0.0.1 h1:UeC9tpM4wNWzUJfan8z9sFE4QCzjjzlCZmuJN+aOkH0=
github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/timakin/bodyclose v0.0.0-00010101000000-87058b9bfcec h1:Ha5Eixh5Dgi14hDFFWsxoB/jR95rHjB1biKdK9VKkbQ=
github.com/timakin/bodyclose v0.0.0-00010101000000-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
Expand Down
4 changes: 4 additions & 0 deletions pkg/config/config.go
Expand Up @@ -164,6 +164,10 @@ type LintersSettings struct {
Unused struct {
CheckExported bool `mapstructure:"check-exported"`
}
Funlen struct {
Lines int
Statements int
}

Lll LllSettings
Unparam UnparamSettings
Expand Down
46 changes: 46 additions & 0 deletions pkg/golinters/funlen.go
@@ -0,0 +1,46 @@
package golinters

import (
"context"
"go/token"

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

"github.com/ultraware/funlen"
)

type Funlen struct{}

func (Funlen) Name() string {
return "funlen"
}

func (Funlen) Desc() string {
return "Tool for detection of long functions"
}

func (f Funlen) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
var issues []funlen.Message
for _, file := range lintCtx.ASTCache.GetAllValidFiles() {
issues = append(issues, funlen.Run(file.F, file.Fset, lintCtx.Settings().Funlen.Lines, lintCtx.Settings().Funlen.Statements)...)
}

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

res := make([]result.Issue, len(issues))
for k, i := range issues {
res[k] = result.Issue{
Pos: token.Position{
Filename: i.Pos.Filename,
Line: i.Pos.Line,
},
Text: i.Message,
FromLinter: f.Name(),
}
}

return res, nil
}
4 changes: 4 additions & 0 deletions pkg/lint/lintersdb/manager.go
Expand Up @@ -237,6 +237,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetStyle).
WithSpeed(10).
WithURL("https://github.com/leighmcculloch/gochecknoglobals"),
linter.NewConfig(golinters.Funlen{}).
WithPresets(linter.PresetStyle).
WithSpeed(10).
WithURL("https://github.com/ultraware/funlen"),
}

isLocalRun := os.Getenv("GOLANGCI_COM_RUN") == ""
Expand Down
43 changes: 43 additions & 0 deletions test/testdata/funlen.go
@@ -0,0 +1,43 @@
//args: -Efunlen
//config: linters-settings.funlen.lines=20
//config: linters-settings.funlen.statements=10
package testdata

func TooManyLines() { // ERROR "Function 'TooManyLines' is too long \(22 > 20\)"
t := struct {
A string
B string
C string
D string
E string
F string
G string
H string
I string
}{
`a`,
`b`,
`c`,
`d`,
`e`,
`f`,
`g`,
`h`,
`i`,
}
_ = t
}

func TooManyStatements() { // ERROR "Function 'TooManyStatements' has too many statements \(11 > 10\)"
a := 1
b := a
c := b
d := c
e := d
f := e
g := f
h := g
i := h
j := i
_ = j
}
7 changes: 7 additions & 0 deletions vendor/github.com/ultraware/funlen/LICENSE

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

69 changes: 69 additions & 0 deletions vendor/github.com/ultraware/funlen/README.md

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

98 changes: 98 additions & 0 deletions vendor/github.com/ultraware/funlen/main.go

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

2 changes: 2 additions & 0 deletions vendor/modules.txt
Expand Up @@ -183,6 +183,8 @@ github.com/stretchr/testify/assert
github.com/stretchr/testify/require
# github.com/timakin/bodyclose v0.0.0-00010101000000-87058b9bfcec
github.com/timakin/bodyclose/passes/bodyclose
# github.com/ultraware/funlen v0.0.1
github.com/ultraware/funlen
# github.com/valyala/bytebufferpool v1.0.0
github.com/valyala/bytebufferpool
# github.com/valyala/quicktemplate v1.1.1
Expand Down