目錄
实例" >实例
灵活运用命令选项" >灵活运用命令选项
配置文件" >配置文件
git hooks" >git hooks
pre-commit" >pre-commit
首頁 後端開發 Golang Gopher一定要會的程式碼自動化檢查

Gopher一定要會的程式碼自動化檢查

Jul 25, 2023 pm 03:20 PM
gopher

本文說明如何透過golangci-lintpre-commit 兩大框架,利用git hooks 實作Go語言git commit 的程式碼自動化審查。

#靜態程式碼檢查

靜態程式碼檢查是一個老生常態的問題,它能很大程度保證程式碼品質。 Go 語言自帶套件為我們提供了靜態程式碼分析工具vet,它能用於檢查go 專案中可以透過編譯但仍可能存在錯誤的程式碼,不了解的讀者可以查看先前文章 的介紹。除了<span style="font-size: 15px;letter-spacing: 1px;">go vet</span>,不少Gopher 也許還知道用來自動導包的<span style="font-size: 15px;letter-spacing: 1px;">goimports</span> 工具,用於格式化程式碼的<span style="font-size: 15px;letter-spacing: 1px;">gofmt</span>#,還有已經停止更新的用於檢查程式碼命令錯誤等的 <span style="font-size: 15px;letter-spacing: 1px;">#golint</span> 工具。

以上談到的工具,我們可以稱之為 <span style="font-size: 15px;letter-spacing: 1px;">linter</span>。在這裡,我們首先需要知道什麼是 lint。在維基百科是如下定義 lint 的:

在電腦科學中,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)
    登入後複製

查看說明文件Gopher一定要會的程式碼自動化檢查

1$ golangci-lint help linters
登入後複製
<br/>
    預設生效的linters

Gopher一定要會的程式碼自動化檢查

###############預設不生效linters######### #####################
<br/>
  • linters 的分类

Gopher一定要會的程式碼自動化檢查

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

Gopher一定要會的程式碼自動化檢查

可以看到,我们在程序根目录中执行 <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 是 git 的一種鉤子機制,可以讓使用者在 git 操作的各個階段執行自訂的邏輯。 git hooks  在專案根目錄的 <span style="font-size: 15px;letter-spacing: 1px;">.git/hooks</span> 下面配置,設定檔的名稱是固定的,實質上就是一個個 shell 腳本。根據 git 執行體,鉤子被分為客戶端鉤子和服務端鉤子兩類。

客戶端鉤子包含:<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>##post-commit<span style="font-size: 15px;letter-spacing: 1px;"></span>#等,主要用於控制客戶端git的提交工作流程。服務端鉤子:pre-receive<span style="font-size: 15px;letter-spacing: 1px;"></span>post-receive<span style="font-size: 15px;letter-spacing: 1px;"></span>update<span style="font-size: 15px;letter-spacing: 1px;"></span>,主要在服務端接收提交物件時、推送到伺服器之前呼叫。

注意,以 .sample 結尾的檔案名稱是官方範例,這些範例腳本是不會執行的,只有在重命名後才會生效(去除 .sample 後綴)。

Gopher一定要會的程式碼自動化檢查#

而 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。

Gopher一定要會的程式碼自動化檢查

因此,使用 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 检查

Gopher一定要會的程式碼自動化檢查

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

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

总结

程式碼品質是每位開發者都必須重視的問題,golangci-lint 提供的一系列linter 外掛程式能夠在很大程度上幫助Gopher 及時發現與解決潛在bug。同時,借助 golangci-lint 也能有效規範專案組內的程式碼風格,減輕 code review 的心智負擔,希望 Gopher 們能有效利用它。

git-commit 工具透過設定檔產生git hooks 所需的<span style="font-size: 15px;letter-spacing: 1px;">pre-commit</span> 鉤子腳本,這可以將透過golangci-lint 的靜態程式碼檢查工作,由手動動作轉換為自動化流程。上文關於 git-commit 的介紹比較簡單,想更詳細探究的讀者可以直接去官網 https://pre-commit.com/index.html 學習。其實,這種自動化流程我們可以擴展得更廣,例如我們可以利用golangci-lint 規則防止從專案中拉取不符合標準的程式碼進入本地程式碼庫,這可以在持續整合CI 過程中添加它來實現自動化。鑑於篇幅原因,CI 部分的利用,留待讀者自行探究了。

以上是Gopher一定要會的程式碼自動化檢查的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1322
25
PHP教程
1270
29
C# 教程
1249
24
Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

Golang和C:並發與原始速度 Golang和C:並發與原始速度 Apr 21, 2025 am 12:16 AM

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

Golang的影響:速度,效率和簡單性 Golang的影響:速度,效率和簡單性 Apr 14, 2025 am 12:11 AM

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

開始GO:初學者指南 開始GO:初學者指南 Apr 26, 2025 am 12:21 AM

goisidealforbeginnersandsubableforforcloudnetworkservicesduetoitssimplicity,效率和concurrencyFeatures.1)installgromtheofficialwebsitealwebsiteandverifywith'.2)

Golang vs.C:性能和速度比較 Golang vs.C:性能和速度比較 Apr 21, 2025 am 12:13 AM

Golang適合快速開發和並發場景,C 適用於需要極致性能和低級控制的場景。 1)Golang通過垃圾回收和並發機制提升性能,適合高並發Web服務開發。 2)C 通過手動內存管理和編譯器優化達到極致性能,適用於嵌入式系統開發。

Golang vs. Python:主要差異和相似之處 Golang vs. Python:主要差異和相似之處 Apr 17, 2025 am 12:15 AM

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。Golang以其并发模型和高效性能著称,Python则以简洁语法和丰富库生态系统著称。

Golang和C:性能的權衡 Golang和C:性能的權衡 Apr 17, 2025 am 12:18 AM

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

C和Golang:表演至關重要時 C和Golang:表演至關重要時 Apr 13, 2025 am 12:11 AM

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。

See all articles