parent
a57bc83d70
commit
7d51954355
@ -31,3 +31,4 @@ linters:
|
|||||||
- maligned
|
- maligned
|
||||||
- prealloc
|
- prealloc
|
||||||
- gosec
|
- 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]
|
prealloc: Finds slice declarations that could potentially be preallocated [fast: true]
|
||||||
scopelint: Scopelint checks for unpinned variables in go programs [fast: true]
|
scopelint: Scopelint checks for unpinned variables in go programs [fast: true]
|
||||||
gocritic: The most opinionated Go source code linter [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:
|
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
|
- [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
|
- [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
|
- [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
|
## Configuration
|
||||||
|
|
||||||
@ -745,6 +749,7 @@ linters:
|
|||||||
- maligned
|
- maligned
|
||||||
- prealloc
|
- prealloc
|
||||||
- gosec
|
- gosec
|
||||||
|
- gochecknoglobals
|
||||||
```
|
```
|
||||||
|
|
||||||
## False Positives
|
## False Positives
|
||||||
@ -828,6 +833,7 @@ Thanks to developers and authors of used linters:
|
|||||||
- [alexkohler](https://github.com/alexkohler)
|
- [alexkohler](https://github.com/alexkohler)
|
||||||
- [kyoh86](https://github.com/kyoh86)
|
- [kyoh86](https://github.com/kyoh86)
|
||||||
- [go-critic](https://github.com/go-critic)
|
- [go-critic](https://github.com/go-critic)
|
||||||
|
- [leighmcculloch](https://github.com/leighmcculloch)
|
||||||
|
|
||||||
## Changelog
|
## 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).
|
WithSpeed(5).
|
||||||
WithTypeInfo().
|
WithTypeInfo().
|
||||||
WithURL("https://github.com/go-critic/go-critic"),
|
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") == ""
|
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