parent
a57bc83d70
commit
7d51954355
@ -31,3 +31,4 @@ linters:
|
||||
- maligned
|
||||
- prealloc
|
||||
- gosec
|
||||
- gochecknoglobals
|
||||
|
@ -201,6 +201,8 @@ nakedret: Finds naked returns in functions greater than a specified function len
|
||||
prealloc: Finds slice declarations that could potentially be preallocated [fast: true]
|
||||
scopelint: Scopelint checks for unpinned variables in go programs [fast: true]
|
||||
gocritic: The most opinionated Go source code linter [fast: true]
|
||||
gochecknoinits: Checks that no init functions are present in Go code [fast: true]
|
||||
gochecknoglobals: Checks that no globals are present in Go code [fast: true]
|
||||
```
|
||||
|
||||
Pass `-E/--enable` to enable linter and `-D/--disable` to disable:
|
||||
@ -402,6 +404,8 @@ golangci-lint help linters
|
||||
- [prealloc](https://github.com/alexkohler/prealloc) - Finds slice declarations that could potentially be preallocated
|
||||
- [scopelint](https://github.com/kyoh86/scopelint) - Scopelint checks for unpinned variables in go programs
|
||||
- [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
|
||||
|
||||
## Configuration
|
||||
|
||||
@ -745,6 +749,7 @@ linters:
|
||||
- maligned
|
||||
- prealloc
|
||||
- gosec
|
||||
- gochecknoglobals
|
||||
```
|
||||
|
||||
## False Positives
|
||||
@ -828,6 +833,7 @@ Thanks to developers and authors of used linters:
|
||||
- [alexkohler](https://github.com/alexkohler)
|
||||
- [kyoh86](https://github.com/kyoh86)
|
||||
- [go-critic](https://github.com/go-critic)
|
||||
- [leighmcculloch](https://github.com/leighmcculloch)
|
||||
|
||||
## Changelog
|
||||
|
||||
|
77
pkg/golinters/gochecknoglobals.go
Normal file
77
pkg/golinters/gochecknoglobals.go
Normal file
@ -0,0 +1,77 @@
|
||||
package golinters
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"strings"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/lint/linter"
|
||||
"github.com/golangci/golangci-lint/pkg/result"
|
||||
)
|
||||
|
||||
type Gochecknoglobals struct{}
|
||||
|
||||
func (Gochecknoglobals) Name() string {
|
||||
return "gochecknoglobals"
|
||||
}
|
||||
|
||||
func (Gochecknoglobals) Desc() string {
|
||||
return "Checks that no globals are present in Go code"
|
||||
}
|
||||
|
||||
func (lint Gochecknoglobals) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
|
||||
var res []result.Issue
|
||||
for _, f := range lintCtx.ASTCache.GetAllValidFiles() {
|
||||
res = append(res, lint.checkFile(f.F, f.Fset)...)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (lint Gochecknoglobals) checkFile(f *ast.File, fset *token.FileSet) []result.Issue {
|
||||
var res []result.Issue
|
||||
for _, decl := range f.Decls {
|
||||
genDecl, ok := decl.(*ast.GenDecl)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if genDecl.Tok != token.VAR {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, spec := range genDecl.Specs {
|
||||
valueSpec := spec.(*ast.ValueSpec)
|
||||
for _, vn := range valueSpec.Names {
|
||||
if isWhitelisted(vn) {
|
||||
continue
|
||||
}
|
||||
|
||||
res = append(res, result.Issue{
|
||||
Pos: fset.Position(genDecl.TokPos),
|
||||
Text: fmt.Sprintf("%s is a global variable", formatCode(vn.Name, nil)),
|
||||
FromLinter: lint.Name(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func isWhitelisted(i *ast.Ident) bool {
|
||||
return i.Name == "_" || looksLikeError(i)
|
||||
}
|
||||
|
||||
// looksLikeError returns true if the AST identifier starts
|
||||
// with 'err' or 'Err', or false otherwise.
|
||||
//
|
||||
// TODO: https://github.com/leighmcculloch/gochecknoglobals/issues/5
|
||||
func looksLikeError(i *ast.Ident) bool {
|
||||
prefix := "err"
|
||||
if i.IsExported() {
|
||||
prefix = "Err"
|
||||
}
|
||||
return strings.HasPrefix(i.Name, prefix)
|
||||
}
|
51
pkg/golinters/gochecknoinits.go
Normal file
51
pkg/golinters/gochecknoinits.go
Normal file
@ -0,0 +1,51 @@
|
||||
package golinters
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/lint/linter"
|
||||
"github.com/golangci/golangci-lint/pkg/result"
|
||||
)
|
||||
|
||||
type Gochecknoinits struct{}
|
||||
|
||||
func (Gochecknoinits) Name() string {
|
||||
return "gochecknoinits"
|
||||
}
|
||||
|
||||
func (Gochecknoinits) Desc() string {
|
||||
return "Checks that no init functions are present in Go code"
|
||||
}
|
||||
|
||||
func (lint Gochecknoinits) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
|
||||
var res []result.Issue
|
||||
for _, f := range lintCtx.ASTCache.GetAllValidFiles() {
|
||||
res = append(res, lint.checkFile(f.F, f.Fset)...)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (lint Gochecknoinits) checkFile(f *ast.File, fset *token.FileSet) []result.Issue {
|
||||
var res []result.Issue
|
||||
for _, decl := range f.Decls {
|
||||
funcDecl, ok := decl.(*ast.FuncDecl)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
name := funcDecl.Name.Name
|
||||
if name == "init" && funcDecl.Recv.NumFields() == 0 {
|
||||
res = append(res, result.Issue{
|
||||
Pos: fset.Position(funcDecl.Pos()),
|
||||
Text: fmt.Sprintf("don't use %s function", formatCode(name, nil)),
|
||||
FromLinter: lint.Name(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
@ -196,6 +196,14 @@ func (Manager) GetAllSupportedLinterConfigs() []linter.Config {
|
||||
WithSpeed(5).
|
||||
WithTypeInfo().
|
||||
WithURL("https://github.com/go-critic/go-critic"),
|
||||
linter.NewConfig(golinters.Gochecknoinits{}).
|
||||
WithPresets(linter.PresetStyle).
|
||||
WithSpeed(10).
|
||||
WithURL("https://github.com/leighmcculloch/gochecknoinits"),
|
||||
linter.NewConfig(golinters.Gochecknoglobals{}).
|
||||
WithPresets(linter.PresetStyle).
|
||||
WithSpeed(10).
|
||||
WithURL("https://github.com/leighmcculloch/gochecknoglobals"),
|
||||
}
|
||||
|
||||
isLocalRun := os.Getenv("GOLANGCI_COM_RUN") == ""
|
||||
|
14
test/testdata/gochecknoglobals.go
vendored
Normal file
14
test/testdata/gochecknoglobals.go
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// args: -Egochecknoglobals
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var noGlobalsVar int // ERROR "`noGlobalsVar` is a global variable"
|
||||
var ErrSomeType = errors.New("test that global erorrs aren't warned")
|
||||
|
||||
func NoGlobals() {
|
||||
fmt.Print(noGlobalsVar)
|
||||
}
|
10
test/testdata/gochecknoinits.go
vendored
Normal file
10
test/testdata/gochecknoinits.go
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// args: -Egochecknoinits
|
||||
package testdata
|
||||
|
||||
import "fmt"
|
||||
|
||||
func init() { // ERROR "don't use `init` function"
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func Init() {}
|
21
third_party/gochecknoglobals/LICENSE
vendored
Normal file
21
third_party/gochecknoglobals/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Leigh McCulloch
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
21
third_party/gochecknoinits/LICENSE
vendored
Normal file
21
third_party/gochecknoinits/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Leigh McCulloch
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
Loading…
x
Reference in New Issue
Block a user