Ein typischer Fall: Ihr Team hat sich darauf geeinigt, dass Repository-Klassen
mit Repository enden müssen. Bisher wird das im PR-Review nur angemerkt.
Mit CodeCharter wird es vom Build durchgesetzt.
Regelmenge im Repo anlegen
Im Repo-Root:
mkdir -p rules
In dieses Verzeichnis kommen alle .ccr-Dateien. Die CLI findet Regeln
im Verzeichnis rules/ im aktuellen Arbeitsverzeichnis automatisch, ohne
weitere Konfiguration. Liegen Ihre Regeln woanders, geben Sie das
Verzeichnis mit --rules <dir> an.
Die Regel schreiben
rules/repository-naming.ccr:
@name "Repository class must end in 'Repository'"
@severity error
@category "Naming"
@description "Implementations of the Repository pattern must have a 'Repository' suffix for discoverability"
@recommendation "Rename the class to end with 'Repository', e.g. 'UserData' -> 'UserRepository'"
from t in Types
where t.Kind == "Class"
where t.Namespace.FullName.StartsWith("Acme.Infrastructure.Repositories")
where !t.IsAbstract
where !t.Name.EndsWith("Repository")
select t
Anatomie:
@nameist der menschenlesbare Titel im Tooling. Der Slug der Regel (der in Findings und Suppressions erscheint) ist der Dateiname ohne Erweiterung, also für diese Regelrepository-naming.@severityistinfo,warnodererror. Standard istwarn, wenn weggelassen.@categorygruppiert die Regel im Output (optional).@descriptionbeschreibt, was geprüft wird (optional, aber empfohlen).@recommendationsagt, wie man es behebt (optional, aber empfohlen).- Body: eine LINQ-Query gegen das Schema. Hier suchen wir Klassen im Repository-Namespace, die nicht abstrakt sind und deren Name nicht auf "Repository" endet.
Lokal probieren
Prüfen Sie zuerst, ob die Regel parst und typkorrekt ist:
codecharter validate rules/repository-naming.ccr
Dann starten Sie die Analyse. Das Argument von analyze ist der Pfad zu einer
.sln-, .slnx- oder .csproj-Datei:
codecharter analyze MySolution.sln
Wenn Ihre Solution eine Klasse namens UserData im Repository-Namespace
enthält, erscheint sie jetzt als error.
Hinweis: Läuft die Analyse nur mit einem lokalen
rules/-Verzeichnis und ohne Plattform-Profile, erscheint auf stderr ein[DEPRECATION]-Hinweis, der auf Plattform-Profile verweist. Die Analyse läuft trotzdem normal durch.
Ob die Regel wirklich anschlägt, prüfen Sie am besten mit einer Spec aus
Hit- und Miss-Fällen: codecharter test rules/repository-naming.ccr --scaffold
erzeugt eine repository-naming.spec.md neben der Regel, und
codecharter test rules/ führt alle Specs aus.
Was sich noch alles ausdrücken lässt
Die DSL ist eine Untermenge von LINQ. Sie können auf alle Typ-, Methoden-, Property-, Feld-, Event-, Namespace- und Assembly-Eigenschaften zugreifen. Beispiele:
// Methoden ohne CancellationToken finden
from m in Methods
where m.IsAsync
where !m.Parameters.Any(p => p.TypeShortName == "CancellationToken")
where m.AccessModifier == "Public"
select m
// Layer-Verletzung: Domain referenziert Web
from t in Types
where t.Namespace.FullName.StartsWith("Acme.Domain")
where t.UsedTypes.Any(u => u.Namespace.FullName.StartsWith("Acme.Web"))
select t
// Klassen mit zu vielen Methoden
from t in Types
where t.Kind == "Class"
where t.NumberOfMethods > 25
select t
Schema-Übersicht und weitere Details unter Syntax-Übersicht.
Best Practices für eigene Regeln
- Eine Regel pro
.ccr-Datei. Das ist eine Eigenschaft des Formats: jede.ccr-Datei enthält genau eine Query, und der Dateiname wird zur Rule-ID. - Sprechende Dateinamen. Sie tauchen im Build-Log auf.
@recommendationehrlich. Wenn die Empfehlung nichts taugt, deaktivieren die Entwickler die Regel, statt sie zu beheben.- Klein anfangen. Eine Regel, die zu 50 Findings führt, lässt sich
nicht einführen. Stufen Sie sie auf
warnab oder formulieren Sie sie spezifischer.
Mehr unter Best Practices.