You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
motief/docs/plans/2026-04-24-006-activate-pre...

146 lines
4.2 KiB

---
title: "feat: Activate pre-commit hooks (black, ruff, isort)"
type: feat
status: active
date: 2026-04-24
---
# Activate Pre-commit Hooks
## Overview
`.pre-commit-config.yaml` exists but is explicitly disabled ("intentionally minimal and does not enable hooks by installing them"). Activating black, ruff, and isort would enforce CODE_STYLE.md conventions automatically and eliminate style-only review comments.
## Problem Frame
- Code style is documented in CODE_STYLE.md but not enforced automatically
- Contributors may submit PRs with inconsistent formatting
- Review time is spent on style nits instead of logic
- No CI check for formatting violations
## Requirements Trace
- R1. Pre-commit hooks run black, ruff, and isort
- R2. Hooks are enforced in CI (fail build on violations)
- R3. Hooks use the same versions as pyproject.toml dev dependencies
- R4. Initial run reformats existing code without breaking tests
## Scope Boundaries
**Included:**
- Update `.pre-commit-config.yaml`
- Add CI workflow step for pre-commit
- Run initial format across codebase
**Excluded:**
- Adding new linters or rules
- Changing CODE_STYLE.md conventions
- Fixing logic bugs found by ruff (separate PR)
## Key Technical Decisions
- **Use pre-commit.ci or GitHub Action** — pre-commit.ci is zero-config but may not work on Gitea. Use a GitHub Actions step as fallback.
- **Single large format commit** — Run once, commit formatting changes separately from config changes so reviewers can see the diff.
- **Skip tests during format** — Formatting should not change behavior, but run tests after to verify.
## Implementation Units
- [ ] U1. **Update .pre-commit-config.yaml**
**Goal:** Enable black, ruff, and isort with versions matching pyproject.toml.
**Requirements:** R1, R3
**Dependencies:** None
**Files:**
- Modify: `.pre-commit-config.yaml`
**Approach:**
- Remove the "does not enable hooks" comment
- Add repos for black, ruff, isort with pinned versions
- Set ruff to match CODE_STYLE.md rules
- Configure isort profile (black-compatible)
**Test scenarios:**
- Happy path: `pre-commit run --all-files` completes successfully
- Error path: A file with style violations fails the hook
- Integration: Versions match pyproject.toml dev deps
**Verification:**
- `pre-commit run --all-files` runs without config errors
---
- [ ] U2. **Add pre-commit CI step**
**Goal:** Block PRs that violate formatting rules.
**Requirements:** R2
**Dependencies:** U1
**Files:**
- Modify: `.github/workflows/pytest.yml` (or create separate lint.yml)
**Approach:**
- Add a job that runs `pre-commit run --all-files`
- Use the same uv setup as the pytest workflow
- Install pre-commit via uv
**Test scenarios:**
- Happy path: Clean code passes pre-commit CI
- Error path: Violations fail the CI job
**Verification:**
- Pushing a formatting violation fails the check
- Pushing clean code passes
---
- [ ] U3. **Run initial format across codebase**
**Goal:** Bring all existing code into compliance so future PRs only touch their own changes.
**Requirements:** R4
**Dependencies:** U1
**Files:**
- Modify: All Python files (mechanical reformatting)
**Approach:**
- Run `pre-commit run --all-files`
- Commit formatting changes separately
- Run full test suite: `uv run pytest tests/ -q`
**Execution note:** This is a mechanical change. Characterization tests should pass unchanged. If tests fail, the formatter broke something — investigate before committing.
**Test scenarios:**
- Integration: All existing tests pass after formatting
- Edge case: No logic changes introduced by formatting
**Verification:**
- `uv run pytest tests/ -q` passes
- `git diff` shows only whitespace/import changes
---
## Risks & Dependencies
| Risk | Mitigation |
|------|------------|
| Massive format commit obscures git blame | Use `.git-blame-ignore-revs` to ignore the format commit |
| Ruff finds existing logic issues | Fix or suppress in separate PR; don't mix with activation |
| Contributors without pre-commit installed | CI catches it; add setup note to README |
## Documentation / Operational Notes
- Add pre-commit setup to README quickstart
- Document `.git-blame-ignore-revs` usage
## Sources & References
- Config: `.pre-commit-config.yaml`
- Style guide: `CODE_STYLE.md`
- Dependencies: `pyproject.toml`