本文讲解如何通过 golangci-lint 和 pre-commit 两大框架,利用 git hooks 实现 Go 语言 git commit 的代码自动化审查。
静态代码检查
go vetgoimportsgofmtgolint
linter
在计算机科学中,lint 是一种工具程序的名称,它用来标记源代码中,某些可疑的、不具结构性(可能造成bug)的段落。它是一种静态程序分析工具,最早适用于C语言,在UNIX平台上开发出来。后来它成为通用术语,可用于描述在任何一种计算机程序语言中,用来标记源代码中有疑义段落的工具。
而在 Go 语言领域, golangci-lint 是一个集大成者的 linter 框架。它集成了非常多的 linter,包括了上文提到的几个,合理使用它可以帮助我们更全面地分析与检查 Go 代码。golangci-lint 所支持的 linter 项可以查看页面 https://golangci-lint.run/usage/linters/#golint
使用 golangci-lint
下载
1go get github.com/golangci/golangci-lint/cmd/golangci-lint@latest
检查安装成功
1$ golangci-lint version
2golangci-lint has version v1.41.1 built from (unknown, mod sum: "h1:KH28pTSqRu6DTXIAANl1sPXNCmqg4VEH21z6G9Wj4SM=") on (unknown)
查看帮助文档
1$ golangci-lint help linters
默认生效的 linters
默认不生效 linters
linters 的分类
可以看出,golangci-lint 框架支持的 linter 非常全面,它包括了 bugs、error、format、unused、module 等常见类别的分析 linter。
实例
下面来展示使用示例,现有以下项目结构代码
1.
2├── go.mod
3├── main.go
4└── typecheck
5 └── typecheckDemo.go
main.go
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 s1 := "this is a string"
9 fmt.Printf("inappropriate formate %s\n", &s1)
10
11 i := 1
12 fmt.Println(i != 0 || i != 1)
13
14 arr := []int{1, 2, 3}
15 for _, i := range arr {
16 go func() {
17 fmt.Println(i)
18 }()
19 }
20}
typecheckDemo.go
1package typecheck
2
3import "fmt"
4
5func check() {
6 t := unexistType{}
7 fmt.Println(t)
8}
9
10func unused() {
11 i := 1
12}
这两个源码文件中的代码都是存在一些问题的。此时,我们通过 golangci-lint 工具来对源码文件进行检查
golangci-lint rungolangci-lint run ./...main.gotypecheckDemo.go
golangci-lint run dir1 dir2/... dir3/file1.go
灵活运用命令选项
-E/--enable-D/--disable
1golangci-lint run --disable-all -E errcheck
errcheck
-p/--preset
1golangci-lint run -p bugs -p error
bugserror
golangci-lint run -h
配置文件
当然,如果我们要为项目配置 golangci-lint,最好的方式还是配置文件。golangci-lint 在当前工作目录按如下顺序搜索配置文件。
.golangci.yml.golangci.yaml.golangci.toml.golangci.json
在 golangci-lint 官方文档 https://golangci-lint.run/usage/configuration/#config-file 中,提供了一个示例配置文件,非常地详细,在这其中包含了所有支持的选项、描述和默认值。
在这里给出一个比较不错的配置示例文档
1linters-settings:
2 errcheck:
3 check-type-assertions: true
4 goconst:
5 min-len: 2
6 min-occurrences: 3
7 gocritic:
8 enabled-tags:
9 - diagnostic
10 - experimental
11 - opinionated
12 - performance
13 - style
14 govet:
15 check-shadowing: true
16 nolintlint:
17 require-explanation: true
18 require-specific: true
19
20linters:
21 disable-all: true
22 enable:
23 - bodyclose
24 - deadcode
25 - depguard
26 - dogsled
27 - dupl
28 - errcheck
29 - exportloopref
30 - exhaustive
31 - goconst
32 - gocritic
33 - gofmt
34 - goimports
35 - gomnd
36 - gocyclo
37 - gosec
38 - gosimple
39 - govet
40 - ineffassign
41 - misspell
42 - nolintlint
43 - nakedret
44 - prealloc
45 - predeclared
46 - revive
47 - staticcheck
48 - structcheck
49 - stylecheck
50 - thelper
51 - tparallel
52 - typecheck
53 - unconvert
54 - unparam
55 - varcheck
56 - whitespace
57 - wsl
58
59run:
60 issues-exit-code: 1
使用 pre-commit hook
golangci-lint run
git hooks
.git/hooks
pre-commitprepare-commit-msgcommit-msgpost-commitpre-receivepost-receiveupdate
注意,以 .sample 结尾的文件名是官方示例,这些示例脚本是不会执行的,只有重命名后才会生效(去除 .sample 后缀)。
git addgit commit
pre-commit
试想,如果我们同时开发多个项目,也许项目的所采用的的编程语言并不一样,那么它们所需要的 git hooks 将不一致,此时我们是否要手动给每个项目都配置一个单独的 pre-commit 脚本呢,或者我们是否要去手动下载每一个钩子脚本呢。
实际上,并不需要这么麻烦。这里就引出了 pre-commit 框架,它是一个与语言无关的用于管理 git hooks 钩子脚本的工具(虽然采用 Python 开发,但不止于 Python )。
安装
1$ pip install pre-commit
2或者
3$ curl https://pre-commit.com/install-local.py | python -
4或者
5$ brew install pre-commit
安装成功
1$ pre-commit --version
2pre-commit 1.20.0
编写配置文件
.pre-commit-config.yamlpre-commit sample-config
.pre-commit-config.yaml
1repos:
2- repo: https://github.com/golangci/golangci-lint
3 rev: v1.41.1 # the current latest version
4 hooks:
5 - id: golangci-lint
安装 git hook 脚本
pre-commit install
1$ pre-commit install
2pre-commit installed at .git/hooks/pre-commit
.git/hooks/pre-commit
git commit 触发 golangci-lint 检查
首次运行时,由于 pre-commit 没有 golangci-lint 的环境,会初始化下载安装相关依赖。在下一次 git-commit 的时候,就不会有前三行信息了。
golangci-lint run
总结
代码质量是每位开发者都必须重视的问题,golangci-lint 提供的一系列 linter 插件能够在很大程度上帮助 Gopher 及时发现与解决潜在 bug。同时,借助 golangci-lint 还可以有效规范项目组内的代码风格,减轻 code review 的心智负担,希望 Gopher 们能有效利用它。
pre-commit
往期推荐
感谢你的点赞和在看哦~