
GO 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 قم بإنشاء ملف 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" )
} قم بإنشاء ملف Test 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!" )
}
} تشغيل 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 ، بحيث يمكن تصحيحها أيضًا.
أولاً ، تقوم بتوزيع ملفات RuleGuard (على سبيل المثال rules.go ) أثناء البدء في تحميل مجموعة القواعد.
ثم يتم استخدام القواعد المحملة للتحقق من الأهداف المحددة (ملفات GO ، الحزم).
يتم كتابة ملف rules.go من حيث dsl API. تحتوي ملفات RuleGuard على مجموعة من الوظائف التي تعمل كمجموعات قواعد. تقبل كل وظيفة من هذا القبيل وسيطة واحدة dsl.Matcher التي يتم استخدامها بعد ذلك لتحديد وتكوين القواعد داخل المجموعة.
يبدأ تعريف القاعدة دائمًا مع استدعاء طريقة Match(patterns...) وينتهي مع استدعاء طريقة Report(message) .
يمكن أن تكون هناك مكالمات إضافية بين هذين. على سبيل المثال ، يطبق مكالمة Where(cond) قيودًا على مباراة لتحديد ما إذا كانت مقبولة أو رفضها. لذلك حتى لو كان هناك تطابق لنمط ما ، فلن ينتج رسالة تقرير ما لم تفي بشرط Where() .
لكي تعمل RuleGuard ، يجب أن تكون حزمة 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 premompilation.