
GO Linter berbasis analisis yang menjalankan aturan yang dimuat secara dinamis.
Anda menulis aturannya, ruleguard memeriksa apakah mereka puas.
ruleguard memiliki beberapa kesamaan dengan Github CodeQL, tetapi hanya didedikasikan untuk pergi.
Fitur:
Ini juga dapat dengan mudah tertanam ke analisis statis lainnya. Go-Critic dapat digunakan sebagai contoh.
Disarankan agar Anda mendapatkan biner dari rilis terbaru {Linux/AMD64, Linux/ARM64, Darwin/AMD64, Darwin/ARMD64, Windows/AMD64, Windows/ARM64}.
Jika Anda ingin menginstal RuleGuard dari sumber, itu sesederhana:
# 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@latestJika di dalam modul GO, paket
dslakan diinstal untuk modul saat ini, jika tidak ia menginstal paket ke $ gopath dan itu akan tersedia secara global.
Jika $GOPATH/bin berada di bawah sistem Anda $PATH , perintah ruleguard harus tersedia setelah itu:
$ 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 Buat file rules.go tes.
//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" )
} Buat file tes example.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!" )
}
} Jalankan ruleguard pada file target itu:
$ 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) Karena kami menjalankan ruleguard dengan argumen -fix , keduanya perubahan yang disarankan diterapkan pada example.go .
Ada juga mode -e yang berguna selama debugging pola:
$ ruleguard -e ' m.Match(`!($x != $y)`) ' example.go
example.go:12:10: ! (v1 ! = v2) Ini secara otomatis menyisipkan Report("$$") ke dalam pola yang ditentukan.
Anda dapat menggunakan -debug-group <name> flag untuk melihat penjelasan tentang mengapa beberapa aturan menolak pertandingan (misalnya kondisi Where() kondisi gagal).
Aturan yang dihasilkan -e akan memiliki nama e , sehingga dapat didebug juga.
Pertama, ini mem -parsing file aturan (misalnya rules.go ) selama awal untuk memuat set aturan.
Aturan yang dimuat kemudian digunakan untuk memeriksa target yang ditentukan (file GO, paket).
File rules.go ditulis dalam hal dsl API. File RuleGuard berisi serangkaian fungsi yang berfungsi sebagai grup aturan. Setiap fungsi tersebut menerima argumen dsl.Matcher .
Definisi aturan selalu dimulai dengan Match(patterns...) Panggilan metode dan berakhir dengan Report(message) Metode Panggilan.
Mungkin ada panggilan tambahan di antara keduanya. Misalnya, panggilan Where(cond) menerapkan kendala untuk kecocokan untuk memutuskan apakah itu diterima atau ditolak. Jadi, bahkan jika ada kecocokan untuk suatu pola, itu tidak akan menghasilkan pesan laporan kecuali jika memenuhi kondisi Where() .
Agar RuleGuard bekerja, paket dsl harus tersedia saat runtime . Jika tidak, Anda akan melihat kesalahan seperti:
$ 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")
Ini diperbaiki dengan menambahkan paket DSL ke modul:
$ 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)
Jika Anda telah mengikuti saran masa lalu menggunakan kendala build dalam file aturan. GO, seperti ini:
$ ruleguard-test head -4 rules.go
//go:build ignore
// +build ignore
package gorules
Anda akan melihat bahwa file go.mod mencantumkan DSL sebagai ketergantungan tidak langsung:
$ grep dsl go.mod
require github.com/quasilyte/go-ruleguard/dsl v0.3.21 // indirect
Jika Anda menjalankan go mod tidy sekarang, Anda akan melihat paket DSL menghilang dari file go.mod :
$ go mod tidy
$ grep dsl go.mod
$
Ini karena go mod tidy berperilaku seolah -olah semua kendala build berlaku, dengan pengecualian ignore . Ini didokumentasikan di situs web GO.
Ini diperbaiki dengan menggunakan kendala build yang berbeda, seperti ruleguard atau rules .
Catatan: go-critic dan go-perfguard menanamkan aturan menggunakan fitur prekompilasi IR.