Zum Inhalt springen

Configurable rule parameters with @param and config.yml

How to declare configurable @param values in a rule, use them in the query body, and let repositories override them from config.yml.

Relationship to other pages: DSL grammar has the formal @param grammar. This page is the task-oriented walkthrough: why to parameterize a rule, how to declare each type, and how a repository tunes the value without touching the rule file.

A hard-coded threshold like m.LinesOfCode > 60 forces every team that adopts your rule to accept your number. Declaring the threshold as a @param instead keeps the rule's logic fixed while letting each repository set its own value from .codecharter/config.yml — no fork, no edited rule file.

Declaring a parameter

@param sits in the rule's header, alongside @name and @severity:

@param <name>: <type> [= <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)

Inside the query body, maxLines is a normal identifier that resolves to its configured value (or the default when nothing overrides it). A parameter name is shadowed by a let-bound or loop variable of the same name, but otherwise behaves exactly like a constant you typed in yourself.

Types

Five types are available:

Type Default syntax Notes
int = 60, = -5 whole numbers; combine with [range: a..b]
float = 0.8, = -1.5 decimal numbers; combine with [range: a..b]
bool = true / = false case-insensitive on the way in
string = "Async" free text, e.g. a name fragment or regex pattern
enum = PascalCase restricted to [enum: v1, v2, ...]; compared as text in the query

A default is optional for every type. Numbers may be written with or without quotes; strings and enum values may be quoted or bare identifiers.

int / float with a range

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

[range: a..b] is inclusive and applies to the default as well as to any override — a value outside the bounds is rejected, whichever side declared it.

bool

@param requireXmlDoc: bool = true

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

string and enum

Use string for free text (a name fragment, a regex pattern) and enum when the value must be one of a fixed set:

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

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

A value that is not in the declared [enum: ...] list is rejected when the rule loads, or when a repository tries to set it in config.yml.

Aliases

[aliases: a, b] lets the query body — and repository config — refer to the same parameter under alternative names:

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

maxLines, maxLength, and limit all resolve to the same value inside the query. In config.yml, params: { my-rule.limit: "40" } sets the same parameter as params: { my-rule.maxLines: "40" }.

Parameters without a default

Omitting = <default> makes the parameter required: a repository must supply a value through config.yml, or the rule is not evaluated for that repository at all — it produces no findings and no error, but the run reports which parameter is missing and which config key to set, for example:

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

Use this for a threshold that has no reasonable one-size-fits-all default — otherwise, always declare a default so the rule works out of the box.

Overriding parameters from a repository

A repository consuming your rule sets parameter values under params: in .codecharter/config.yml, keyed by <rule-slug>.<paramName> (the rule slug is the .ccr file name without its extension):

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

Values are written as strings and validated against the declared type, range, and enum list — the same checks that apply to the default in the rule file. An unknown rule slug, an unknown parameter name, or a value that fails validation is reported by codecharter config validate.

A scopes entry can set a different value for part of the repository; the last matching scope wins for a given file. See Configuration file for the full params and scopes reference.

To set a value from the command line instead of editing the file by hand:

codecharter config set params.method-too-long.maxLines 40
codecharter config set params.method-too-long.maxLines 25 --scope "src/Legacy/**"

Where to go next