Skip to content

Linter: Support per-rule custom configuration options - #2194

Open
markokajzer wants to merge 6 commits into
marcoroth:mainfrom
markokajzer:marko/linter-rule-options
Open

Linter: Support per-rule custom configuration options#2194
markokajzer wants to merge 6 commits into
marcoroth:mainfrom
markokajzer:marko/linter-rule-options

Conversation

@markokajzer

@markokajzer markokajzer commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

part of #1204

Adds support for per-rule configuration

Approach

  • Shared rule configuration such as enabled, severity, and file filters continue to be validated by the config schema.
  • Custom options and their schemas are defined by the rules that own them.
  • The linter validates custom options after all built-in and project-local rules are available.
  • Unknown options and invalid values produce a configuration error before linting begins, including for disabled rules.

Error Handling

Validation stops at the first error. Unknown option names are grouped into a single error, while invalid values are reported one at a time.

For comparison, Rubocop 1.84 behaves as follows:

  • Two unsupported option names: prints both warnings and continues.
  • Two invalid values/types: stops at the first fatal error; the second appears after fixing the first.

Adjusted rules

html-allowed-script-type

Follow up on #1201 to add the configuration options missing from the initial implementation

  • allowedTypes allows changing the list of permitted script types
  • allowBlank controls whether the type attribute may be omitted

erb-no-unused-expressions

  • allowedMethods allows adding receiverless methods that may be intentionally ignored

Configuration Example

linter:
  rules:
    html-allowed-script-type:
      enabled: true
      allowedTypes:
        - application/json
      allowBlank: false

    erb-no-unused-expressions:
      enabled: false
      allowedMethods:
        - breadcrumb

Alternatives considered

  • Config-owned schemas: validate every built-in rule directly in @herb-tools/config. This enables one-pass validation, but couples config to the linter and cannot naturally support project-local rules.
  • Central rule registry: store every rule class and schema in a dedicated RuleLibrary/registry. This makes discovery and validation explicit, but introduces another abstraction and potentially global state.
    • Note: Rubocop uses a Cop::Registry module. allAvailableRules serves a smaller version of that role, without introducing a registry abstraction just yet
  • Static schemas on rule classes: avoids instantiating rules during validation, but makes defaults and TypeScript generics more awkward.

@github-actions github-actions Bot added documentation Improvements or additions to documentation linter @herb-tools/linter for HTML+ERB templates typescript TypeScript source across the javascript/ packages linter-rule Individual linter rules and their documentation config Herb configuration file handling and config options labels Aug 12, 2026
@markokajzer
markokajzer force-pushed the marko/linter-rule-options branch from 06b4a1d to 31b1ba6 Compare August 12, 2026 01:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Herb configuration file handling and config options documentation Improvements or additions to documentation linter @herb-tools/linter for HTML+ERB templates linter-rule Individual linter rules and their documentation typescript TypeScript source across the javascript/ packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant