Coverage for src / python_commitlint / core / protocols.py: 100%
13 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-28 02:54 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-28 02:54 +0000
1"""Structural Protocols decoupling the linter from concrete adapters.
3These Protocols define the contracts the linter expects from its parser,
4rule, and configuration-loading collaborators so alternative implementations
5can be plugged in without inheritance.
6"""
8from pathlib import Path
9from typing import Protocol
11from python_commitlint.core.models import (
12 CommitMessage,
13 Configuration,
14 LintResult,
15 RuleConfig,
16 ValidationError,
17)
20class CommitParserProtocol(Protocol):
21 """Parses a raw commit message into a :class:`CommitMessage`."""
23 def parse(self, message: str) -> CommitMessage:
24 """Parse ``message`` and return a structured commit.
26 Args:
27 message: The raw commit message text, including newlines.
29 Returns:
30 A :class:`CommitMessage` populated with whichever fields could
31 be extracted; non-parseable messages return an empty-typed result.
32 """
33 ...
36class RuleProtocol(Protocol):
37 """A single commitlint rule that validates a parsed commit."""
39 @property
40 def name(self) -> str:
41 """The rule's stable identifier (e.g. ``type-case``)."""
42 ...
44 def validate(
45 self, commit: CommitMessage, config: RuleConfig
46 ) -> ValidationError | None:
47 """Apply the rule to ``commit`` under the given ``config``.
49 Args:
50 commit: The parsed commit to validate.
51 config: The rule's severity, condition, and optional value.
53 Returns:
54 A :class:`ValidationError` when the rule is violated, otherwise
55 ``None``.
56 """
57 ...
60class ConfigurationLoaderProtocol(Protocol):
61 """Loads a :class:`Configuration` from a path or built-in default."""
63 def load(self, config_path: Path | None = None) -> Configuration:
64 """Load the configuration and return a fully-resolved value.
66 Args:
67 config_path: Optional explicit path; when ``None`` the loader
68 searches the working directory for a default config file.
70 Returns:
71 The loaded :class:`Configuration`.
72 """
73 ...
76class CommitLinterProtocol(Protocol):
77 """Validates a commit message against the configured rule set."""
79 def lint(self, message: str) -> LintResult:
80 """Validate ``message`` and return the lint outcome.
82 Args:
83 message: The raw commit message text.
85 Returns:
86 A :class:`LintResult` containing errors, warnings, and the
87 overall ``valid`` flag.
88 """
89 ...