
基於分析的GO Linter,該林格運行動態加載規則。
您編寫規則, ruleguard檢查是否滿意。
ruleguard與GitHub CodeQL有一些相似之處,但它僅專門用於去。
特徵:
它也可以很容易地嵌入其他靜態分析儀中。可以將Go-Critic用作例子。
建議您從最新版本{Linux/AMD64,Linux/ARM64,Darwin/AMD64,Darwin/ARM64,Windows/AMD64,Windows/ARM64}中獲得二進制。
如果要從源中安裝規則守衛,則很簡單:
# Installs a `ruleguard` binary under your `$(go env GOPATH)/bin`
$ go install -v github.com/quasilyte/go-ruleguard/cmd/ruleguard@latest
# Get the DSL package (needed to execute the ruleguard files)
$ go get -v -u github.com/quasilyte/go-ruleguard/dsl@latest如果在GO模塊內部,將為當前模塊安裝
dsl軟件包,否則將其安裝到$ Gopath中,並且將在全球上可用。
如果$GOPATH/bin在您的系統$PATH下,則應該可用ruleguard命令:
$ ruleguard -help
ruleguard: execute dynamic gogrep-based rules
Usage: ruleguard [-flag] [package]
Flags:
-rules string
comma-separated list of ruleguard file paths
-e string
execute a single rule from a given string
-fix
apply all suggested fixes
-c int
display offending line with this many lines of context (default -1)
-json
emit JSON output創建一個測試rules.go文件:
//go:build ruleguard
// +build ruleguard
package gorules
import "github.com/quasilyte/go-ruleguard/dsl"
func dupSubExpr ( m dsl. Matcher ) {
m . Match ( `$x || $x` ,
`$x && $x` ,
`$x | $x` ,
`$x & $x` ).
Where ( m [ "x" ]. Pure ).
Report ( `suspicious identical LHS and RHS` )
}
func boolExprSimplify ( m dsl. Matcher ) {
m . Match ( `!($x != $y)` ). Suggest ( `$x == $y` )
m . Match ( `!($x == $y)` ). Suggest ( `$x != $y` )
}
func exposedMutex ( m dsl. Matcher ) {
isExported := func ( v dsl. Var ) bool {
return v . Text . Matches ( `^p{Lu}` )
}
m . Match ( `type $name struct { $*_; sync.Mutex; $*_ }` ).
Where ( isExported ( m [ "name" ])).
Report ( "do not embed sync.Mutex" )
m . Match ( `type $name struct { $*_; sync.RWMutex; $*_ }` ).
Where ( isExported ( m [ "name" ])).
Report ( "do not embed sync.RWMutex" )
}創建一個測試example.go 。 go目標文件:
package main
import "sync"
type EmbedsMutex struct {
key int
sync. Mutex
}
func main () {
var v1 , v2 int
println ( ! ( v1 != v2 ))
println ( ! ( v1 == v2 ))
if v1 == 0 && v1 == 0 {
println ( "hello, world!" )
}
}在該目標文件上運行ruleguard :
$ ruleguard -rules rules.go -fix example.go
example.go:5:1: exposedMutex: do not embed sync.Mutex (rules.go:24)
example.go:12:10: boolExprSimplify: suggestion: v1 == v2 (rules.go:15)
example.go:13:10: boolExprSimplify: suggestion: v1 ! = v2 (rules.go:16)
example.go:14:5: dupSubExpr: suspicious identical LHS and RHS (rules.go:7)由於我們使用-fix參數運行ruleguard ,因此兩個建議的更改都應用於example.go 。
在模式調試過程中,還有一個-e模式很有用:
$ ruleguard -e ' m.Match(`!($x != $y)`) ' example.go
example.go:12:10: ! (v1 ! = v2)它會自動將Report("$$")插入指定模式。
您可以使用-debug-group <name>標誌來查看有關某些規則為何拒絕匹配的說明(例如, Where()條件失敗)。
-e生成的規則將具有e名稱,因此也可以進行調試。
首先,它在開始加載規則集的過程中解析了Ruleguard文件(例如rules.go )。
然後,加載規則用於檢查指定的目標(GO文件,軟件包)。
rules.go文件是根據dsl API編寫的。 Ruleguard文件包含一組用作規則組的功能。每個這樣的功能都接受單個dsl.Matcher參數,然後將其用於定義和配置組內的規則。
規則定義始終以Match(patterns...)方法調用開始,並以Report(message)方法調用結束。
這兩個之間可能會有其他電話。例如,某個Where(cond)調用在匹配項中應用約束以決定是被接受還是拒絕。因此,即使有一個模式匹配,它也不會產生報告消息,除非它滿足Where()條件。
為了使Rulegar可以使用dsl軟件包,必須在運行時可用。如果不是,您將看到一個錯誤:
$ ruleguard -rules rules.go .
ruleguard: load rules: parse rules file: typechecker error: rules.go:6:8: could not import github.com/quasilyte/go-ruleguard/dsl (can't find import: "github.com/quasilyte/go-ruleguard/dsl")
通過將DSL軟件包添加到模塊中來修復:
$ ruleguard-test go get github.com/quasilyte/go-ruleguard/dsl
go: downloading github.com/quasilyte/go-ruleguard v0.3.18
go: downloading github.com/quasilyte/go-ruleguard/dsl v0.3.21
go: added github.com/quasilyte/go-ruleguard/dsl v0.3.21
$ ruleguard-test ruleguard -rules rules.go .
.../test.go:6:5: boolExprSimplify: suggestion: 1 == 0 (rules.go:9)
如果您遵循了過去的建議,請在規則中使用構建約束。 go文件,例如:
$ ruleguard-test head -4 rules.go
//go:build ignore
// +build ignore
package gorules
您將注意到go.mod文件將DSL列為間接依賴性:
$ grep dsl go.mod
require github.com/quasilyte/go-ruleguard/dsl v0.3.21 // indirect
如果您現在運行go mod tidy ,您將注意到DSL軟件包從go.mod文件中消失:
$ go mod tidy
$ grep dsl go.mod
$
這是因為go mod tidy行為就像所有構建約束都在生效一樣,除了ignore 。這是在GO網站上記錄的。
通過使用不同的構建約束(例如ruleguard或rules來修復這一點。
注意: go-critic和go-perfguard使用IR預兼容功能嵌入了規則。