
Основанный на анализе Linter, который запускает динамически загруженные правила.
Вы пишете правила, ruleguard , удовлетворены ли они.
ruleguard имеет некоторое сходство с GitHub CodeQL, но он посвящен только.
Функции:
Его также можно легко встроить в другие статические анализаторы. Go-критический может быть использован в качестве примера.
Рекомендуется получить двоичный файл от последнего выпуска {linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64, windows/arm64}.
Если вы хотите установить Gual Guard из Source, это так же просто, как:
# 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 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 Создайте файл Test 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) Поскольку мы управляли ruleguard с аргументом -fix , оба предлагаемых изменения применяются к example.go .
Существует также режим -e , который полезен во время отладки шаблона:
$ ruleguard -e ' m.Match(`!($x != $y)`) ' example.go
example.go:12:10: ! (v1 ! = v2) Он автоматически вставляет Report("$$") в указанный шаблон.
Вы можете использовать -debug-group <name> флаг, чтобы увидеть объяснения того, почему некоторые правила отклонили совпадение (например, Where() не удалось).
Правило -e , сгенерированное, будет иметь имя e , поэтому его можно отладить.
Во -первых, он анализирует файлы правил правил (например, rules.go ) во время начала загрузки набора правил.
Загруженные правила затем используются для проверки указанных целей (файлы GO, пакеты).
Файл rules.go записан с точки зрения dsl API. Файлы правилгарда содержат набор функций, которые служат группами правил. Каждая такая функция принимает один аргумент dsl.Matcher , который затем используется для определения и настройки правил внутри группы.
Определение правила всегда начинается с вызова метода Match(patterns...) и заканчивается вызовом метода Report(message) .
Между этими двумя могут быть дополнительные звонки. Например, вызов Where(cond) применяет ограничения на совпадение, чтобы решить, принят ли он или отклонен. Таким образом, даже если есть совпадение с шаблоном, он не будет создавать сообщение отчета, если не удовлетворяет условие, Where() .
Для того, чтобы Gual Guard для работы пакет 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)
Если вы следили за прошлым советом об использовании ограничения сборки в файле правил.
$ 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.