Zum Inhalt springen

Konfigurierbare Regel-Parameter mit @param und config.yml

Wie Sie konfigurierbare @param-Werte in einer Regel deklarieren, im Query-Body nutzen und Repositories sie über config.yml überschreiben lassen.

Bezug zu anderen Seiten: DSL-Grammatik enthält die formale @param-Grammatik. Diese Seite ist die aufgabenorientierte Einführung: warum Sie eine Regel parametrisieren, wie Sie jeden Typ deklarieren, und wie ein Repository den Wert einstellt, ohne die Regeldatei anzufassen.

Ein fest codierter Schwellenwert wie m.LinesOfCode > 60 zwingt jedes Team, das Ihre Regel übernimmt, Ihre Zahl zu akzeptieren. Deklarieren Sie den Schwellenwert stattdessen als @param: Die Logik der Regel bleibt fix, jedes Repository setzt seinen eigenen Wert über .codecharter/config.yml, ganz ohne Fork oder bearbeitete Regeldatei.

Einen Parameter deklarieren

@param steht im Header der Regel, neben @name und @severity:

@param <name>: <typ> [= <default>] [range: a..b] [aliases: a, b] [enum: v1, v2]
@name "Method too long"
@severity warn
@param maxLines: int = 60 [range: 1..500]

Methods.Where(m => m.LinesOfCode > maxLines)

Im Query-Body ist maxLines ein ganz normaler Identifier, der zu seinem konfigurierten Wert auflöst (oder zum Default, wenn nichts ihn überschreibt). Ein Parametername wird von einer gleichnamigen let-Variable oder Schleifenvariable überschattet, verhält sich sonst aber genau wie eine selbst eingetippte Konstante.

Typen

Fünf Typen stehen zur Verfügung:

Typ Default-Syntax Hinweise
int = 60, = -5 Ganzzahlen; kombinierbar mit [range: a..b]
float = 0.8, = -1.5 Dezimalzahlen; kombinierbar mit [range: a..b]
bool = true / = false Groß-/Kleinschreibung beim Einlesen egal
string = "Async" Freitext, z. B. ein Namensfragment oder ein Regex-Muster
enum = PascalCase eingeschränkt auf [enum: v1, v2, ...]; im Query als Text verglichen

Ein Default ist bei jedem Typ optional. Zahlen können mit oder ohne Anführungszeichen geschrieben werden; Strings und Enum-Werte als Zeichenkette oder als bloßer Identifier.

int / float mit Bereich

@param minCoverage: float = 0.8 [range: 0..1]

[range: a..b] ist inklusiv und gilt sowohl für den Default als auch für jeden konfigurierten Wert eines int/float-Parameters: ein Wert außerhalb der Grenzen wird abgelehnt, unabhängig davon, wo er gesetzt wurde.

bool

@param requireXmlDoc: bool = true

DocumentableDeclarations.Where(d => requireXmlDoc && !d.HasXmlDoc)

string und enum

Nutzen Sie string für Freitext (ein Namensfragment, ein Regex-Muster) und enum, wenn der Wert einer festen Menge angehören muss:

@param requiredAccess: enum = Public [enum: Public, Internal]

Types.Where(t => t.Kind == "Interface" && t.AccessModifier != requiredAccess)

Ein Wert, der nicht in der deklarierten [enum: ...]-Liste steht, wird beim Laden der Regel abgelehnt, ebenso, wenn ein Repository ihn in config.yml setzen will.

Aliase

[aliases: a, b] erlaubt es dem Query-Body (und der Repository-Konfiguration), denselben Parameter unter alternativen Namen anzusprechen:

@param maxLines: int = 60 [range: 1..500] [aliases: maxLength, limit]

maxLines, maxLength und limit lösen im Query alle zum selben Wert auf. In config.yml setzt params: { my-rule.limit: "40" } denselben Parameter wie params: { my-rule.maxLines: "40" }.

Parameter ohne Default

Lassen Sie = <default> weg, wird der Parameter Pflicht: Ein Repository muss dann einen Wert über config.yml liefern, sonst wird die Regel für dieses Repository gar nicht ausgewertet: Sie erzeugt weder Findings noch einen Fehler, aber der Lauf meldet, welcher Parameter fehlt und welchen Konfigurationsschlüssel Sie setzen müssen, zum Beispiel:

required parameter 'maxLines' is not configured. Set 'method-too-long.maxLines'
under params: in .codecharter/config.yml to enable it.

Verwenden Sie das für einen Schwellenwert, für den es keinen sinnvollen universellen Default gibt, ansonsten deklarieren Sie immer einen Default, damit die Regel sofort einsatzbereit ist.

Parameter aus einem Repository überschreiben

Ein Repository, das Ihre Regel nutzt, setzt Parameterwerte unter params: in .codecharter/config.yml, adressiert über <rule-slug>.<paramName> (der Rule-Slug ist der Dateiname der .ccr-Datei ohne Erweiterung):

params:
  method-too-long.maxLines: "40"

Werte werden als Zeichenketten geschrieben und gegen den deklarierten Typ, Bereich und die Enum-Liste geprüft, dieselben Prüfungen, die auch für den Default in der Regeldatei gelten. Ein unbekannter Rule-Slug, ein unbekannter Parametername oder ein ungültiger Wert wird von codecharter config validate gemeldet.

Ein scopes-Eintrag kann für einen Teil des Repositorys einen anderen Wert setzen; für eine gegebene Datei gewinnt der letzte passende Scope. Die vollständige Referenz zu params und scopes finden Sie unter Konfigurationsdatei.

Um einen Wert über die Kommandozeile zu setzen, statt die Datei von Hand zu bearbeiten:

codecharter config set params.method-too-long.maxLines 40
codecharter config set params.method-too-long.maxLines 25 --scope "src/Legacy/**"
  • DSL-Grammatik: die formale @param-Grammatik und alle Direktiven.
  • Konfigurationsdatei: die vollständige params-Referenz, Scopes und Validierungs-Befehle.
  • codecharter config: die Befehle config get / config set zum Bearbeiten von params über die Kommandozeile.
  • Regelbeispiele: weitere vollständige Regeln zum Übernehmen.