背景
开发团队代码,保持一个统一的风格和规范,有利于团队协作和交流。
对代码进行质量检查,能达到以下作用:
-
提高代码质量:代码质量检查可以帮助团队发现潜在的错误和问题,从而提高代码的稳定性和可靠性。
-
统一编码规范:通过代码质量检查,可以确保团队成员遵循统一的编码规范,提高代码的可读性和可维护性。
-
减少技术债务:及时发现并修复代码中的问题,可以减少技术债务的积累,降低未来的维护成本。
-
提高开发效率:通过自动化的代码检查,可以减少人工审查的时间,让开发人员专注于更重要的任务。
-
促进团队协作:代码质量检查可以作为团队协作的一部分,帮助新成员快速了解项目规范,促进团队成员之间的协作。
所以,需要借助一个工具对团队代码进行统一标准的质量检查。
认识 golangci-lint
golangci-lint
是一个针对 Go 语言的代码质量检查工具,它集成了多个 linter(代码检查工具)和静态分析工具,可以帮助团队检查代码中的各种问题。
以下是 golangci-lint
的一些主要特性和作用:
-
多工具集成:集成了多个 Go 语言的 linter 和静态分析工具,如
gofmt
、go vet
、errcheck
等。 -
自定义配置:支持自定义配置文件,可以根据团队的需求配置不同的检查规则。
-
快速反馈:在代码提交之前进行快速检查,及时发现问题,减少代码合并时的冲突。
-
易于集成:可以轻松集成到现有的 CI/CD 流程中,自动化代码质量检查。
-
丰富的检查规则:提供了丰富的检查规则,包括但不限于死代码、错误处理、代码复杂度、性能问题等。
-
跨平台支持:支持多个操作系统,可以在不同的开发环境中使用。
利用 golangci-lint
期望达到的效果:
-
提高代码质量:通过自动化检查,及时发现并修复代码中的错误和潜在问题。
-
统一编码规范:确保团队成员遵循统一的编码规范,提高代码的一致性和可读性。
-
减少技术债务:通过定期检查,减少技术债务的积累,降低未来的维护成本。
-
提高开发效率:自动化的代码检查可以减少人工审查的时间,让开发人员有更多的时间专注于开发。
-
促进团队协作:代码质量检查可以作为团队协作的一部分,帮助新成员快速了解项目规范,促进团队成员之间的协作。
-
提高项目成功率:高质量的代码是成功项目的基石,通过代码质量检查,可以提高项目的成功率。
安装和使用
- 安装 golangci-lint
可以通过两种方式安装 golangci-lint
:
- 使用
go install
命令:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
注意:注意要和当前 golang 环境的版本匹配。如果 Golang 版本过低,也要降低 golangci-lint 的版本,具体有哪些版本可以参考 https://github.com/golangci/golangci-lint/releases。比如安装版本 v1.46.1,安装命令变为:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.46.1
- 使用官方提供的二进制文件进行安装,适用于不同平台:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s latest
安装完成后,执行以下命令检查是否安装成功:
golangci-lint --version
执行以下命令,可以查看 golangci-lint
的帮助文档,了解不同版本支持的命令和选项:
golangci-lint help linters
2. 基本使用
在项目的根目录中运行以下命令,golangci-lint
会自动检查当前目录及子目录下的 Go 代码:
golangci-lint run
这将自动运行一系列内置的 linter 来分析代码。如果有问题,它会输出错误和警告。常见的 lint 检查包括:
-
代码风格(如变量命名)
-
不必要的类型转换
-
未使用的变量和导入包
-
潜在的空指针访问
-
性能优化建议
3. 常用选项
- 只检查特定文件: 如果只想检查某个文件或目录,可以指定路径:
golangci-lint run ./path/to/yourfile.go
- 检查并修复(自动修复部分问题): 可以尝试自动修复代码中的部分问题:
golangci-lint run --fix
- 跳过特定的文件或目录: 使用
--skip-files
跳过某些文件的检查,例如测试文件或第三方代码:
golangci-lint run --skip-files usecase_test.go
- 列出支持的所有 linter:
golangci-lint
内置了多种 linter,使用以下命令可以列出所有可用的 linter:
golangci-lint linters
- 指定要启用或禁用的 linter: 可以通过配置来启用或禁用特定的 linter。如下示例只启用
govet
和golint
,并禁用errcheck
:
golangci-lint run --enable=govet --enable=golint --disable=errcheck
4. 配置文件
为了方便管理 lint 规则,可以在项目根目录创建 .golangci.yml
配置文件,进行更细粒度的控制。
以下是一个典型的配置示例:
linters:
enable: # 设置允许使用的 linter
- govet
- golint
- staticcheck
disable: # 禁止使用的 linter
- errcheck
run:
timeout: 2m # 设置运行超时时间
skip-dirs:
- vendor # 跳过 vendor 目录
skip-files:
- .*_test\.go # 跳过测试文件
issues:
exclude-rules:
- linters:
- golint
text: "don't use underscores in Go names" # 忽略 golint 的特定规则
5. CI/CD 集成
可以将 golangci-lint
集成到 CI/CD 流水线中,确保每次提交的代码都经过严格的 lint 检查。
以 GitLab CI 为例:
lint:
stage: test
script:
- golangci-lint run
allow_failure: false # 如果 lint 失败则阻止代码合并
Goland + golangci-lint
很多 IDE(如 VSCode、GoLand)都可以通过插件集成 golangci-lint
,从而在开发过程中实时显示 lint 问题,极大地提高代码编写的质量和效率。
在 GoLand 中集成 golangci-lint
可以让你在开发过程中实时检查代码质量,并在编写代码时提示错误或警告。以下是如何在 GoLand 中集成 golangci-lint
的详细步骤:
1. 安装 golangci-lint
如果还没有安装 golangci-lint
,请首先在终端中安装:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
或者通过其他方式安装(如使用二进制文件),确保能够从终端运行 golangci-lint
。
2. 配置 GoLand
步骤 1:打开 GoLand 的设置
在 GoLand 界面中,依次点击:File -> Settings -> Tools -> External Tools
步骤 2:添加一个新的 External Tool
-
点击右上角的
+
按钮,创建一个新的外部工具。 -
填写以下配置项:
-
Name:
golangci-lint
-
Group:可以选择不填,或者自定义为
Go Tools
-
Program:填写
golangci-lint
的安装路径,通常为:-
如果通过
go install
安装,路径是$GOPATH/bin/golangci-lint
,在 Unix 系统上可能是$HOME/go/bin/golangci-lint
。 -
在 Windows 系统上可能是
C:\Users\<your-username>\go\bin\golangci-lint.exe
。
-
-
Arguments:填写
run
,也可以根据需要添加更多参数,如run --fix
(自动修复部分问题)。 -
Working directory:填入
$ProjectFileDir$
,确保命令在项目的根目录下运行。 -
示例如下:
-
Program:
$HOME/go/bin/golangci-lint
(在 Linux/macOS 中) -
Arguments:
run
-
Working directory:
$ProjectFileDir$
-
点击 OK
保存设置。
步骤 3:运行 golangci-lint
-
配置完成后,打开你想要检查的 Go 项目。
-
右键点击项目的根目录,选择:
External Tools -> golangci-lint
- GoLand 将会运行
golangci-lint
,并在终端中输出检查结果。
3. 配置 golangci-lint
检查结果高亮
要让 GoLand 直接在代码中显示 golangci-lint
的检查结果,可以借助 GoLand 的 File Watchers 插件,或者结合 GoLand 的 File Watcher
功能来自动运行。
步骤 1:安装 File Watchers 插件
-
打开
Settings
->Plugins
。 -
搜索
File Watchers
,并点击Install
。 -
安装完成后,重启 GoLand。
步骤 2:配置 File Watchers 运行 golangci-lint
-
打开
Settings
->Tools
->File Watchers
。 -
点击右上角的
+
按钮,选择Custom
,为golangci-lint
配置一个新的文件监视器。 -
配置如下:
-
File Type:选择
Go
。 -
Scope:选择
Current File
或Whole Project
,根据你的需要配置范围。 -
Program:填写
golangci-lint
的路径。 -
Arguments:填写
run --out-format=colored-line-number --issues-exit-code=0 $FilePathRelativeToProjectRoot$
。 -
Output paths:可以为空。
步骤 3:保存并启用
保存配置后,File Watchers 将会在你修改 Go 文件时自动运行 golangci-lint
,并在编辑器中高亮显示 lint 问题。
AI 分析测试结果
分析单个文件,一般规范问题不会过多,手动处理即可。
但如果在 CI/CD 流程中集成质量检查,一次性提交的代码可能规范性问题过多,人工读取信息,可能会有遗漏,且不熟悉 golangci-lint
的开发人员也不太会用。
所以,这种情况下,可以利用 AI 分析,如下提示词:
golang代码检查测试如下,请总结解释以及给出具体文件、代码行对应的修改建议:
PS D:\develop\go\regionService> golangci-lint run
test\other\sync\main.go:48:6: `request` is unused (deadcode)
func request(host, uri string) {
^
bll\model\0_response.go:251:6: `callers` is unused (deadcode)
func callers() string {
^
bll\service\device.go:269:5: `deviceNameRegion` is unused (deadcode)
var deviceNameRegion = map[string]string{
^
http\router.go:101:6: `runRouter` is unused (deadcode)
func runRouter(r *gin.Engine) {
^
bll\service\cmd.go:152:24: Error return value is not checked (errcheck)
go ActionAliDeviceCmd(v)
^
……
AI 识别一一罗列检测出来代码的具体问题:
这些是使用 `golangci-lint` 工具在 Go 代码中检测到的一系列问题。下面是每个问题的总结和修改建议:
1. **未使用的变量(deadcode)**:
- `test\other\sync\main.go:48`、`bll\model\0_response.go:251`、`bll\service\device.go:269`、`http\router.go:101`:这些文件中定义了变量或函数,但它们没有在代码中被使用。建议检查这些变量或函数是否必要,如果不使用,应该删除它们。
2. **错误返回值未检查(errcheck)**:
- `bll\service\cmd.go:152`、`bll\service\cmd.go:186`、`bll\service\cmd_func.go:23`、`bll\service\device.go:67`、`bll\service\smart_2_control.go:172`、`bll\service\smart_2_control.go:572`、`bll\service\user.go:99`、`bll\service\user.go:136`、`test\bll\service\smart_test.go:9`:这些行中的函数调用返回了错误值,但没有进行检查。建议添加错误检查逻辑,例如 `if err != nil { return err }`。
3. **多余的返回语句(gosimple)**:
- `dao\redis\google_home_status.go:42`:在函数的末尾有多余的 `return` 语句。建议删除多余的 `return`。
4. **简化的返回语句(gosimple)**:
- `bll\validate\product_id.go:10`、`bll\validate\user.go:36`、`bll\validate\user.go:61`:这些地方的代码可以通过直接返回条件表达式的结果来简化。
……
这些修改建议可以帮助你清理代码,提高代码质量和可维护性。
如上的输出,什么问题,哪个文件,哪一行,都有标注。
把错误信息输出,开发人员看到 CI 流程失败后,直接就可以看到具体指向性的错误信息,能极大提高团队整体规范性的建设过程,也能让程序开发人员快速培养代码规范能力。