Skip to content

Hello-World-DSL

Die kleinstmögliche eigene CodeCharter-Regel. Schritt für Schritt erklärt.

Verhältnis zu anderen Seiten: dieses Tutorial führt Sie Schritt für Schritt durch das Schreiben Ihrer ersten Regel. Syntax-Übersicht ist die kompakte Alltagsreferenz; DSL-Grammatik ist der formale Anhang.

Die einfachste sinnvolle CodeCharter-Regel hat neun Zeilen. Hier ist sie:

@name "Class must not be named Manager"
@severity warn
@category "Naming"
@description "Classes called *Manager are vague, name them after what they actually do"
@recommendation "Pick a verb-based name: OrderProcessor, EmailDispatcher, PriceCalculator"

from t in Types
where t.Kind == "Class"
where t.Name.EndsWith("Manager")
select t

Speichern Sie das als rules/no-manager-suffix.ccr in Ihrem Repo. Wenn Sie nicht bei null anfangen möchten: codecharter init legt das rules/-Verzeichnis mit zwei Beispielregeln für Sie an. Starten Sie die Analyse dann aus dem Repo-Root. analyze erwartet den Pfad zu einer .sln-, .slnx- oder .csproj-Datei:

codecharter analyze MySolution.sln

Das rules/-Verzeichnis im aktuellen Arbeitsverzeichnis wird automatisch verwendet. Wenn Sie eine Klasse mit Manager-Suffix haben, taucht sie als Finding auf. Solange Ihr Projekt noch keine Plattform-Profile nutzt, gibt die CLI zusätzlich einen Deprecation-Hinweis auf stderr aus; er stoppt die Analyse nicht und lässt sich mit CODECHARTER_SUPPRESS_DEPRECATION_WARNING=1 unterdrücken.

Was passiert hier

Fünf Zeilen Metadaten und vier Zeilen Query. Gehen wir das durch.

Metadaten

Alle Direktiven sind optional und haben sinnvolle Defaults. Der Regel-Slug kommt aus dem Dateinamen (no-manager-suffix), nicht aus @name. @name ist der menschenlesbare Titel, der im CI-Log und den Output-Formaten erscheint; wenn er fehlt, wird der Dateiname verwendet. @severity hat den Default warn. Auch unbekannte @severity-Werte fallen auf warn zurück; achten Sie also auf Tippfehler.

@name "Class must not be named Manager"
@severity warn
@category "Naming"
@description "..."
@recommendation "..."
Direktive Pflicht Default Beschreibung
@name nein Dateiname Menschenlesbarer Titel
@severity nein warn info, warn oder error
@category nein General Frei wählbar, gruppiert verwandte Regeln
@description nein -- Was die Regel prüft
@recommendation nein -- Wie man es fixt

Alle sind optional, aber @name, @description und @recommendation auszufüllen macht Findings deutlich hilfreicher.

Query

Der Body ist eine LINQ-Query gegen das Code-Modell:

from t in Types                    // alle Typen
where t.Kind == "Class"            // nur Klassen
where t.Name.EndsWith("Manager")   // mit Manager-Suffix
select t                           // gibt alle Treffer als Findings zurück

Kommentare in .ccr-Dateien nutzen //. select t ist der Pflicht-Abschluss. Was Sie selektieren, wird zum Finding. t ist ein TypeModel, also zeigt das Finding auf die Datei und Zeile, wo t deklariert ist.

Variante: Mehrere Suffixe verbieten

@name "No vague class suffixes"
@severity warn

from t in Types
where t.Kind == "Class"
where t.Name.EndsWith("Manager")
    || t.Name.EndsWith("Helper")
    || t.Name.EndsWith("Util")
select t

Bedingungen lassen sich mit && und || kombinieren. Die Query-Sprache unterstützt eine feste Auswahl an LINQ-artigen Methoden wie Where, Any, OrderBy und Count; die Syntax-Übersicht listet, was verfügbar ist.

Variante: Mehrere Bedingungen kombinieren

Eine Regel, die nur Klassen findet, die zu groß sind und zu viele Felder haben:

@name "Large class with many fields, split candidate"
@severity warn
@category "Design"

from t in Types
where t.Kind == "Class"
where t.LinesOfCode > 400
where t.Fields.Count > 15
select t

Die Regel testen

codecharter test rules/no-manager-suffix.ccr --scaffold legt eine Starter-Spec-Datei rules/no-manager-suffix.spec.md neben der Regel an. Tragen Sie dort Code-Schnipsel ein, die die Regel treffen bzw. nicht treffen soll, und prüfen Sie die Regel anschließend mit codecharter test rules/ dagegen.

Weitere Beispiele

Die Seite Regel-Beispiele enthält eine Galerie fertiger Regeln nach Kategorie, darunter das vollständige Manager-Suffix- und Async/CancellationToken-Beispiel. Dort weiterlesen, sobald die Grundlagen sitzen.

Wo geht's weiter