
GO basé sur l'analyse qui exécute des règles chargées dynamiquement.
Vous écrivez les règles, ruleguard vérifie s'ils sont satisfaits.
ruleguard a quelques similitudes avec GitHub CodeQL, mais il est dédié à aller uniquement.
Caractéristiques:
Il peut également être facilement intégré dans d'autres analyseurs statiques. Le go-critique peut être utilisé comme exemple.
Il est conseillé d'obtenir un binaire de la dernière version {Linux / AMD64, Linux / Arm64, Darwin / AMD64, DARWIN / ARM64, Windows / AMD64, Windows / Arm64}.
Si vous souhaitez installer le RuleGuard de Source, c'est aussi simple que:
# 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@latestSi à l'intérieur d'un module GO, le package
dslsera installé pour le module actuel, sinon il installe le package dans le $ GOPATH et il sera disponible à l'échelle mondiale.
Si $GOPATH/bin est sous votre système $PATH , la commande ruleguard doit être disponible après cela:
$ 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 Créer un fichier de tests de 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" )
} Créer un example.go de test.go Fichier cible:
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!" )
}
} Exécutez ruleguard sur ce fichier cible:
$ 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) Puisque nous avons exécuté ruleguard avec un argument -fix , les deux modifications suggérées sont appliquées à example.go .
Il existe également un mode -e qui est utile pendant le débogage du modèle:
$ ruleguard -e ' m.Match(`!($x != $y)`) ' example.go
example.go:12:10: ! (v1 ! = v2) Il insère automatiquement Report("$$") dans le modèle spécifié.
Vous pouvez utiliser le drapeau -debug-group <name> pour voir les explications sur les raisons pour lesquelles certaines règles ont rejeté la correspondance (par exemple Where() a échoué).
La règle générée -e aura un nom e , donc il peut également être débogué.
Tout d'abord, il analyse les fichiers de règles de règles (par exemple, rules.go ) pendant le début à charger l'ensemble de règles.
Les règles chargées sont ensuite utilisées pour vérifier les cibles spécifiées (fichiers Go, Packages).
Le fichier rules.go est écrit en termes d'API dsl . Les fichiers de règlements contiennent un ensemble de fonctions qui servent de groupes de règles. Toute fonction de ce type accepte un seul argument dsl.Matcher qui est ensuite utilisé pour définir et configurer des règles à l'intérieur du groupe.
Une définition de règle commence toujours par l'appel de méthode Match(patterns...) et se termine par l'appel de méthode Report(message) .
Il peut y avoir des appels supplémentaires entre ces deux. Par exemple, un appel Where(cond) applique des contraintes à une correspondance pour décider si elle est acceptée ou rejetée. Donc, même s'il y a une correspondance pour un modèle, il ne produira pas de message de rapport à moins qu'il ne satisfait à une condition Where() .
Pour que RuleGuard fonctionne, le package dsl doit être disponible au moment de l'exécution . Si ce n'est pas le cas, vous allez voir une erreur comme:
$ 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")
Ceci est corrigé en ajoutant le package DSL au module:
$ 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)
Si vous avez suivi le conseil passé de l'utilisation d'une contrainte de construction dans le fichier règne.go, comme ceci:
$ ruleguard-test head -4 rules.go
//go:build ignore
// +build ignore
package gorules
Vous allez remarquer que go.mod le fichier répertorie le DSL en tant que dépendance indirecte:
$ grep dsl go.mod
require github.com/quasilyte/go-ruleguard/dsl v0.3.21 // indirect
Si vous exécutez go mod tidy maintenant, vous allez remarquer que le package DSL disparaît du fichier go.mod :
$ go mod tidy
$ grep dsl go.mod
$
En effet, go mod tidy se comporte comme si toutes les contraintes de construction étaient en vigueur, à l'exception de ignore . Ceci est documenté sur le site Web Go.
Ceci est corrigé en utilisant une contrainte de construction différente, comme ruleguard ou rules .
Remarque: go-critic et go-perfguard Integment les règles à l'aide de la fonction de précompilation IR.