This document describes the .pre-commit-config.yaml file structure, which defines automated quality checks that run at various stages of the Git workflow. The configuration enforces code hygiene, validates file formats, runs Python linting/formatting via ruff, and validates commit messages via commitizen.
For information about the complete development workflow and quality gates, see Pre-commit Hooks and Code Quality. For ruff-specific configuration, see CLI Architecture and Entry Points. For commitizen configuration, see Commitizen Configuration (cz.toml).
The .pre-commit-config.yaml file is located at afterpython/.pre-commit-config.yaml in the project root. It is automatically created during project initialization by the init_pre_commit() function, which copies the template from src/afterpython/templates/pre-commit-config-template.yaml1-49
The initialization process also runs pre-commit install --install-hooks to install the hooks into .git/hooks/, enabling automatic execution during Git operations.
Sources: src/afterpython/tools/pre_commit.py27-37 afterpython/.pre-commit-config.yaml1-51
The pre-commit configuration consists of three main sections:
| Section | Purpose | Configuration Key |
|---|---|---|
| Hook Types | Defines which Git hook stages to install | default_install_hook_types |
| Exclusions | Specifies file/directory patterns to skip | exclude |
| Repositories | Lists hook repositories and their configurations | repos |
This setting ensures that all three hook types are installed automatically without requiring explicit --hook-type flags during pre-commit install. Without this configuration, only pre-commit hooks would be installed by default.
Sources: afterpython/.pre-commit-config.yaml1-6
The _website/ directory is excluded from all pre-commit checks because it contains generated website code from the project-website-template repository, which is managed separately and should not be linted by project-specific rules.
Sources: afterpython/.pre-commit-config.yaml7
The following diagram shows the three Git hook stages and when they execute:
Sources: afterpython/.pre-commit-config.yaml3-50
The configuration integrates three hook repositories, each serving a specific purpose:
Sources: afterpython/.pre-commit-config.yaml8-50
The pre-commit-hooks repository provides basic file hygiene checks:
| Hook ID | Stage | Purpose |
|---|---|---|
trailing-whitespace | pre-commit | Removes trailing whitespace from all files |
end-of-file-fixer | pre-commit | Ensures files end with a single newline character |
check-yaml | pre-commit | Validates YAML syntax in .yaml and .yml files |
check-toml | pre-commit | Validates TOML syntax in .toml files |
check-added-large-files | pre-commit | Prevents accidentally committing large files (default 500KB) |
All these hooks run at the pre-commit stage, before the commit is created. They automatically fix issues when possible (trailing whitespace, EOF) or block the commit if validation fails (YAML/TOML syntax, large files).
Sources: afterpython/.pre-commit-config.yaml9-26
The ruff hooks provide Python-specific code quality enforcement:
| Hook ID | Stage | Purpose | Arguments |
|---|---|---|---|
ruff-check | pre-commit | Runs ruff linter to detect code quality issues | --config ./afterpython/ruff.toml |
ruff-format | pre-commit | Formats Python code according to ruff rules | --config ./afterpython/ruff.toml |
Both hooks reference ./afterpython/ruff.toml for configuration, which defines linting rules, line length, and formatting preferences. The ruff-check hook runs first to identify issues, followed by ruff-format to apply automatic formatting fixes.
Sources: afterpython/.pre-commit-config.yaml27-41
The commitizen hooks enforce conventional commit standards and branch naming conventions:
| Hook ID | Stage | Purpose |
|---|---|---|
commitizen | commit-msg | Validates commit message format against conventional commits specification |
commitizen-branch | pre-push | Validates branch names before pushing to remote |
The commitizen hook runs at the commit-msg stage, after the commit message is entered but before the commit is created. It ensures messages follow the format: type(scope): description. The commitizen-branch hook runs at the pre-push stage to validate branch naming conventions.
Commitizen configuration is stored in afterpython/cz.toml (see Commitizen Configuration (cz.toml)).
Sources: afterpython/.pre-commit-config.yaml42-50
The init_pre_commit() function handles initial setup:
The function copies src/afterpython/templates/pre-commit-config-template.yaml1-49 to afterpython/.pre-commit-config.yaml, then runs ap pre-commit install --install-hooks via subprocess to install hooks into the Git repository.
Sources: src/afterpython/tools/pre_commit.py27-37
The update_pre_commit() function allows programmatic updates to the configuration:
This function uses the deep_merge() utility to merge update dictionaries into the existing configuration, preserving unmodified sections. After writing the updated configuration, it reinstalls hooks to ensure the changes take effect.
Sources: src/afterpython/tools/pre_commit.py13-24
The pre-commit configuration integrates into the three-tier quality gate system:
| Tier | Trigger | Enforcement |
|---|---|---|
| Local Development | Manual via ap lint or automatic via Git commands | Immediate feedback before commit/push |
| CI Pipeline | Automatic on push to remote | Comprehensive validation in clean environment |
| Deployment | Automatic on successful CI | Production deployment gates |
The pre-commit hooks provide the first tier of quality enforcement, catching issues immediately during local development. This prevents broken code from reaching CI and reduces iteration time.
For the complete quality gate architecture, see Developer Workflow and Quality Gates. For CI-level validation, see CI Workflow (ci.yml).
Sources: afterpython/.pre-commit-config.yaml1-51 src/afterpython/tools/pre_commit.py1-38
Refresh this wiki