Configuration reference

The linter is configured under two tables in mago.toml: [linter] for tool-wide settings and [linter.rules] for per-rule settings.

[linter]
integrations = ["symfony", "phpunit"]
excludes = ["src/Generated/"]
baseline = "linter-baseline.toml"

[linter.rules]
# Disable a rule completely
ambiguous-function-call = { enabled = false }

# Change a rule's severity level
no-else-clause = { level = "warning" }

# Configure a rule's specific options
cyclomatic-complexity = { threshold = 20 }

# Exclude specific paths from one rule
prefer-static-closure = { exclude = ["tests/"] }

[linter]

OptionTypeDefaultDescription
excludesstring list[]Paths or globs the linter skips. Additive to the global source.excludes.
integrationsstring list[]Framework integrations to enable. The full list is on the integrations page.
baselinestringnonePath to a baseline file. When set, the linter uses it as the default baseline so you do not have to pass --baseline every run. CLI --baseline overrides this.
baseline-variantstring"loose"Variant for newly-generated baselines. Either "loose" (count-based, resilient) or "strict" (line-exact). See baseline variants.
minimum-fail-levelstring"error"Lowest severity that triggers a non-zero exit. Values: "note", "help", "warning", "error". The CLI --minimum-fail-level overrides this.

excludes here adds to the global list. Files matched globally are always excluded; this option lets you exclude additional files from the linter only.

[source]
excludes = ["cache/**"]              # excluded from every tool

[linter]
excludes = ["database/migrations/**"]  # additionally excluded from the linter only

[linter.rules]

Each key under this table is a rule code, written in kebab-case. Every rule accepts the common options below; some rules also accept their own.

Common options

OptionTypeDefaultDescription
enabledbooleanvariesEnable or disable the rule.
levelstringvariesSeverity. Values: "error", "warning", "help", "note".
excludestring list[]Paths or globs the rule skips. Other rules still apply to those files.

Per-rule excludes

exclude is useful when a rule is generally valuable but not appropriate for one slice of the codebase, like generated code or test fixtures.

[linter.rules]
prefer-static-closure = { enabled = true, exclude = ["tests/"] }
no-goto              = { exclude = ["src/Legacy/"] }
no-eval              = { exclude = ["src/Templating/Compiler.php"] }
no-global            = { exclude = ["**/*Test.php"] }

Each entry can be a plain path or a glob:

  • Plain paths ("tests", "tests/", "src/Foo.php") match as prefixes against the relative file path from the project root.
  • Glob patterns (any entry containing *, ?, [, or {) match the full relative path using the same glob engine the global source.excludes uses, with the [source.glob] settings applied.

Glob patterns in per-rule exclude require Mago 1.20 or later. Earlier releases only accept plain prefix paths.

Per-rule exclude is not the same as [linter].excludes:

  • [linter].excludes removes files from every rule.
  • A rule's own exclude removes files from that one rule. Other rules still apply.

Rule-specific options

Some rules accept additional options. cyclomatic-complexity is a typical example:

[linter.rules]
cyclomatic-complexity = { level = "error", threshold = 15 }

To discover the options for any specific rule, ask Mago:

mago lint --explain cyclomatic-complexity

The full per-rule reference is on the rules page.

Extension rules

Rules registered by extensions accept the common options under their vendor-qualified code. Quote the code, because it contains a /:

[linter.rules]
"acme/no-eval" = { level = "warning", exclude = ["tests/"] }

[linter.rules."acme/prefer-array-any"]
enabled = false

When enabled or level is omitted, the rule keeps the default its extension registered. A code without a / is always treated as a built-in rule, so only vendor-qualified extension codes can be configured here. mago lint and the mago extension commands warn about configured codes that no enabled extension registers.

Extension rule settings require Mago 1.58 or later.

↳ Edit this page →