Home  >  Article  >  Backend Development  >  Code automation inspection that Gopher must know

Code automation inspection that Gopher must know

Go语言进阶学习
Go语言进阶学习forward
2023-07-25 15:20:291499browse

This article explains how to implement Go using git hooks through the two major frameworks of golangci-lint and pre-commit Automated code review for language git commits.

##Static code inspection

Static code inspection is a common problem, which can ensure code quality to a large extent. The Go language comes with a suite that provides us with the static code analysis tool vet, which can be used to check code in the Go project that can be compiled but may still contain errors. Readers who do not understand can check the introduction of the previous article . In addition to go vet<span style="font-size: 15px;letter-spacing: 1px;"></span>, many Gophers may also know goimports<span style="font-size: 15px;letter-spacing: 1px;"></span> for automatically importing packages. Tools, gofmt<span style="font-size: 15px;letter-spacing: 1px;"></span> for formatting code, and ## that has stopped updating for checking code command errors, etc. #golint<span style="font-size: 15px;letter-spacing: 1px;"></span> Tools.

The tools mentioned above can be called

linter<span style="font-size: 15px;letter-spacing: 1px;"></span>. Here, we first need to know what lint is. In Wikipedia, lint is defined as follows:

In computer science, lint is the name of a tool program, which is used to mark some suspicious and unstructured (may cause bugs) in the source code. paragraph. It is a static program analysis tool, first adapted to C language and developed on the UNIX platform. It later became a general term that can be used to describe a tool used in any computer programming language to mark questionable passages in source code.

In the field of Go language, golangci-lint is a comprehensive linter framework. It integrates a lot of linters, including several mentioned above. Proper use of it can help us analyze and inspect Go code more comprehensively. The linter items supported by golangci-lint can be viewed on the pagehttps://golangci-lint.run/usage/linters/#golint

Use golangci-lint

##Download
1go get github.com/golangci/golangci-lint/cmd/golangci-lint@latest
Check installation success
1$ golangci-lint version
2golangci-lint has version v1.41.1 built from (unknown, mod sum: "h1:KH28pTSqRu6DTXIAANl1sPXNCmqg4VEH21z6G9Wj4SM=") on (unknown)
View help document
1$ golangci-lint help linters
  • Default linters

Code automation inspection that Gopher must know


  • ##linters are not effective by default


  • linters 的分类

Code automation inspection that Gopher must know

可以看出,golangci-lint 框架支持的 linter 非常全面,它包括了 bugs、error、format、unused、module 等常见类别的分析 linter。

实例

下面来展示使用示例,现有以下项目结构代码

1.
2├── go.mod
3├── main.go
4└── typecheck
5    └── typecheckDemo.go

其中 <span style="font-size: 15px;letter-spacing: 1px;">main.go</span> 中的代码如下

 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}

<span style="font-size: 15px;letter-spacing: 1px;">typecheckDemo.go</span> 中的代码

 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 工具来对源码文件进行检查

Code automation inspection that Gopher must know

可以看到,我们在程序根目录中执行 <span style="font-size: 15px;letter-spacing: 1px;">golangci-lint run</span> 命令,它等效于 <span style="font-size: 15px;letter-spacing: 1px;">golangci-lint run ./...</span> 。此时,它将 <span style="font-size: 15px;letter-spacing: 1px;">main.go</span><span style="font-size: 15px;letter-spacing: 1px;">typecheckDemo.go</span> 中存在的潜在问题都检测到了,并标记了是何种 linter 检测(这里是 typecheck 和 govet 两种)到的。

当然,也可以通过命令 <span style="font-size: 15px;letter-spacing: 1px;">golangci-lint run dir1 dir2/... dir3/file1.go</span> 对某特定的文件或文件夹进行分析。

灵活运用命令选项
  • golangci-lint 可以通过 <span style="font-size: 15px;">-E/--enable</span> 去开启指定 linter,或者 <span style="font-size: 15px;">-D/--disable</span> 禁止指定 linter。

1golangci-lint run --disable-all -E errcheck

如上命令代表的就是除了 <span style="font-size: 15px;letter-spacing: 1px;">errcheck</span> 的 linter,禁止其他所有的 linter 生效。

  • golangci-lint 还可以通过 <span style="font-size: 15px;">-p/--preset</span> 指定一系列 linter 开启。

1golangci-lint run -p bugs -p error

如上命令代表的就是所有属于 <span style="font-size: 15px;letter-spacing: 1px;">bugs</span><span style="font-size: 15px;letter-spacing: 1px;">error</span> 分类的 linter 生效。

  • 更多命令选项,可以通过 <span style="font-size: 15px;">golangci-lint run -h</span> 查看

配置文件

当然,如果我们要为项目配置 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
<br/>

使用 pre-commit hook

在项目开发中,我们都会使用到 git,因此我们可以将代码静态检查放在一个 git 触发点上,而不用每次写完代码手动去执行 <span style="font-size: 15px;letter-spacing: 1px;">golangci-lint run</span> 命令。这里,我们就需要用到 git hooks。

git hooks

Git hooks is a hook mechanism of git that allows users to execute customized logic at various stages of git operations. Git hooks are configured under <span style="font-size: 15px;letter-spacing: 1px;">.git/hooks</span> in the project root directory. The name of the configuration file is fixed, which is essentially a shell script. According to the git execution body, hooks are divided into two categories: client hooks and server hooks.

Client hooks include: <span style="font-size: 15px;letter-spacing: 1px;">pre-commit</span><span style="font-size: 15px;letter-spacing: 1px;">prepare- commit-msg</span><span style="font-size: 15px;letter-spacing: 1px;">commit-msg</span><span style="font-size: 15px;letter-spacing: 1px;">post-commit</span> , etc., are mainly used to control the submission workflow of client git. Server-side hooks: <span style="font-size: 15px;letter-spacing: 1px;">pre-receive</span>, <span style="font-size: 15px;letter-spacing: 1px;">post-receive</span>, <span style="font-size: 15px;letter-spacing: 1px;">update</span>, mainly called when the server receives the submitted object and before pushing it to the server.

Note that file names ending with .sample are official samples. These sample scripts will not be executed and will only take effect after being renamed (removing the .sample suffix).

Code automation inspection that Gopher must know

而 pre-commit 正如其名一样,它在 <span style="font-size: 15px;letter-spacing: 1px;">git add</span> 提交之后,运行 <span style="font-size: 15px;letter-spacing: 1px;">git commit</span> 时执行,脚本执行没报错就继续提交,反之就驳回提交的操作。

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
  • 编写配置文件

首先我们在项目根目录下新建一个 <span style="font-size: 15px;letter-spacing: 1px;">.pre-commit-config.yaml</span> 文件,这个文件我们可以通过 <span style="font-size: 15px;letter-spacing: 1px;">pre-commit sample-config</span> 得到最基本的配置模板,通过 pre-commit 支持的 hooks 列表 https://pre-commit.com/hooks.html 中,我们找到了 golangci-lint。

Code automation inspection that Gopher must know

因此,使用 golangci-lint 的 <span style="font-size: 15px;letter-spacing: 1px;">.pre-commit-config.yaml</span> 配置内容如下

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 脚本

运行 <span style="font-size: 15px;letter-spacing: 1px;">pre-commit install</span> 命令根据配置文件安装

1$ pre-commit install
2pre-commit installed at .git/hooks/pre-commit

此时,生成了新的 Python 语言编写的 <span style="font-size: 15px;letter-spacing: 1px;">.git/hooks/pre-commit</span> 钩子文件。

  • git commit 触发 golangci-lint 检查

Code automation inspection that Gopher must know

首次运行时,由于 pre-commit 没有 golangci-lint 的环境,会初始化下载安装相关依赖。在下一次 git-commit 的时候,就不会有前三行信息了。

如上图所示,报错内容和我们手动执行 <span style="font-size: 15px;letter-spacing: 1px;">golangci-lint run</span> 命令输出的一样,只有当我们将代码更改正确,才能顺利通过检查,从而 commit 成功。

总结

Code quality is an issue that every developer must pay attention to. Golangci-lint provides a series of The linter plug-in can help Gopher to find and solve potential bugs in a timely manner to a great extent. At the same time, golangci-lint can also effectively standardize the code style within the project team and reduce the mental burden of code review. I hope Gophers can make effective use of it.

The git-commit tool generates the <span style="font-size: 15px;letter-spacing: 1px;">pre-commit</span> hook script required by git hooks through the configuration file. This You can convert static code inspection work through golangci-lint from manual actions into automated processes. The above introduction to git-commit is relatively simple. Readers who want to explore in more detail can go directly to the official website https://pre-commit.com/index.html to learn. In fact, we can expand this automated process more widely. For example, we can use golangci-lint rules to prevent pulling non-standard code from the project into the local code base. This can be added to the continuous integration CI process to achieve automation. . Due to space reasons, the utilization of the CI part is left to the readers to explore by themselves.

The above is the detailed content of Code automation inspection that Gopher must know. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:Go语言进阶学习. If there is any infringement, please contact admin@php.cn delete