
基于分析的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预兼容功能嵌入了规则。