Linter Service¶
Overview¶
The linter service provides a shared framework to run pre- and post-linters with central ignore handling.
Abstract linter API: name, stage, and a
run(ctx)generator that yieldsLinterIssueobjects. For pre-lint, the parsed project model is available asctx.project.Class-level registration: linters call
LinterService.register(MyLinter)at import time to self-register.Central ignore rules: the service owns
IgnoreConfigand enforces user intent viashould_ignorebefore applying app-specific policy hooks.
API¶
Abstract linter¶
- class craft_application.lint.base.AbstractLinter¶
Bases:
ABCBase class for all linters.
- Linters should set:
name: stable identifier (used in ignore config)
stage: Stage.PRE or Stage.POST
- abstract run(ctx: LintContext) Iterable[LinterIssue]¶
Execute the linter and yield issues.
Types¶
- class craft_application.lint.LintContext¶
Stage-agnostic environment for linters.
project_dir: the source tree on disk
project: the parsed project model (available for pre-lint)
artifact_dirs: list of directories with built artifacts (may be empty in pre-stage)
- class craft_application.lint.LinterIssue¶
Single issue reported by a linter.
- class craft_application.lint.IgnoreSpec¶
Suppression rules for one linter.
ids: “*” to ignore every issue, or a set of issue ids
by_filename: map of issue id -> set of filename globs
IgnoreConfig is a dict[str, IgnoreSpec] mapping linter names to their ignore rules.
- craft_application.lint.should_ignore(linter_name: str, issue: LinterIssue, cfg: dict[str, IgnoreSpec]) bool¶
Return True when issue is covered by the user’s ignore rules.
Uses issue id and optional shell-style filename globs per the approved design.
Service¶
- class craft_application.services.linter.LinterService¶
Bases:
AppServiceOrchestrates linter registration, ignore config and execution.
- __init__(app: AppMetadata, services: ServiceFactory) None¶
- classmethod build_ignore_config(project_dir: Path, cli_ignores: IgnoreConfig | None = None) IgnoreConfig¶
Merge ignore config from app-specific project rules and CLI overrides.
- property issues: list[LinterIssue]¶
Return a copy of issues collected during the last run.
- property issues_by_linter: dict[str, list[LinterIssue]]¶
Return collected issues grouped by linter name.
- load_ignore_config(project_dir: Path, cli_ignores: IgnoreConfig | None = None) IgnoreConfig¶
Load ignore configuration using the class-level builder.
- post_filter_issues(linter: AbstractLinter, issues: Iterable[LinterIssue], ctx: LintContext) Iterator[LinterIssue]¶
App-specific filtering hook.
- pre_filter_linters(stage: Stage, ctx: LintContext, candidates: list[type[AbstractLinter]] | None = None) list[type[AbstractLinter]]¶
App-specific selection hook.
- classmethod register(linter_cls: type[AbstractLinter]) None¶
Register a linter class for use by the service.
- run(stage: Stage, ctx: LintContext) Iterator[LinterIssue]¶
Run linters for a stage, streaming non-suppressed issues.
For a step-by-step guide on adding linters, see Create a linter.
Ignore configuration¶
Users can suppress issues through app-specific rules stored in the project file
(if supported) and/or CLI rules (if exposed by the application). The examples
below show the IgnoreConfig shape that applications should map to:
snapcraft.desktop:
ids: ["MISSING_ICON"]
# or glob-based suppression per issue id
snapcraft.desktop:
by_filename:
MISSING_ICON: ["*/examples/*"]
Apps can override build_ignore_config (e.g., Snapcraft can parse
snapcraft.yaml: lint.ignore rules and fold them into the generic
IgnoreConfig format).