本文简要介绍go实现lint和golangci-lint使用。
what
linter为静态代码检查、分析工具,golang常见的有govet\golint\errcheck 等。通过工具其一,可以提前发现一些语法问题,比如变量作用域问题、数组下标越界、内存泄露等;其二可以根据团队规范定制lint规则,提升可读性,可维护性。
golang的linters比较多,比如 awesome-go-linters中 golint检查变量、函数名、注释等。errcheck为未检查错误等。golangci-lint是一个 Go linters 聚合器,通过配置来选择需要的linters。其特征如下:
- ⚡非常快:并行运行linters,重用Go构建缓存和缓存分析结果。
- ⚙️基于yaml的配置
- 🖥集成VS Code, Sublime Text, GoLand, GNU Emacs, Vim, Atom, GitHub动作。
- 🥇包含了很多linters,不需要安装它们。
- 📈由于调优的默认设置导致的最小误报数。
- 🔥漂亮的输出颜色,源代码行和标记的标识符。
install
mac
macOS你可以使用brew在macOS上安装二进制版本:
brew install golangci-lint
brew upgrade golangci-lint
Install from Source
源码安装:
> go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.1
查看安装是否成功:
>golangci-lint --version
>golangci-lint has version v1.50.1 built from (unknown, mod sum: "h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY=") on (unknown)
how
GolangCI-Lint 可以零配置使用。默认情况下启用以下 linters
>golangci-lint help linters
>Enabled by default linters:
errcheck: Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases [fast: false, auto-fix: false]
gosimple (megacheck): Linter for Go source code that specializes in simplifying code [fast: false, auto-fix: false]
govet (vet, vetshadow): Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string [fast: false, auto-fix: false]
ineffassign: Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
staticcheck (megacheck): It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint. [fast: false, auto-fix: false]
typecheck: Like the front-end of a Go compiler, parses and type-checks Go code [fast: false, auto-fix: false]
unused (megacheck): Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]
如何执行golangci-lint呢?在需要执行的项目目录下:
golangci-lint run
这相当于执行
golangci-lint run ./...
您可以选择要分析的目录和文件:
golangci-lint run dir1 dir2/... dir3/file1.go
接着,我们创建一个Example代码:linter_example.go
package main
import "fmt"
type People struct {
Name string
}
func (p *People) String() string {
return fmt.Sprintf("print: %v", p)
}
func main() {
p := &People{}
p.String()
}
执行lint,如果没有相关的配置文件,会走默认的lint配置
> golangci-lint run
level=warning msg="[runner] The linter 'golint' is deprecated (since v1.41.0) due to: The repository of the linter has been archived b
y the owner. Replaced by revive."
linter_example.go:5:6: exported type `People` should have comment or be unexported (golint)
type People struct {
^
linter_example.go:10:9: printf: fmt.Sprintf format %v with arg p causes recursive (*demos/linter-demo.People).String method call (gove
t)
return fmt.Sprintf("print: %v", p)
^
linter_example.go:15:10: unusedresult: result of (*demos/linter-demo.People).String call not used (govet)
p.String()
^
我们可以根据lint提示修改
printf: fmt。Sprintf格式%v与arg p导致递归( demos/ lininter -demo. people)。字符串方法调用(govet)。
在使⽤ fmt 包中的打印⽅法时,如果类型实现了这个接⼝,会直接调⽤。⽽中打印 p 的时候会直接调⽤ p 实现的 String() ⽅法,然后就产⽣了循环调⽤。
Custom Configuration
GolangCI-Lint 通过当前工作目录的以下路径中增加配置文件:
- .golangci.yml
- .golangci.yaml
- .golangci.toml
- .golangci.json
来实现自定义linters
例如我们添加了.golangci.yml
run:
timeout: 5m
modules-download-mode: readonly
linters:
disable-all: true
enable: # 下面是开启的lint列表
- errcheck
- goimports
- golint
# - govet 为了测试是否生效,关闭
- staticcheck
linters-settings:
golint:
# minimal confidence for issues, default is 0.8
min-confidence: 0.8
issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
这里我们把govet 关闭了,在执行run
golangci-lint run
level=warning msg="[runner] The linter 'golint' is deprecated (since v1.41.0) due to: The repository of the linter has been archived b
y the owner. Replaced by revive."
linter_example.go:5:6: exported type `People` should have comment or be unexported (golint)
type People struct {
^
可见关闭govet生效了。
reference
- golangci-lint https://github.com/golangci/golangci-lint
- golangci-lint doc https://golangci-lint.run/
- lint https://github.com/golang/lint
- awesome-go-linters https://github.com/golangci/awesome-go-linters
- bolg gocn https://mp.weixin.qq.com/s/kNh0TP59fCFJhbmr-YMz4Q