From f67a5ccf2d8df0c3fe3a94240216b79b76f70504 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 17 Apr 2026 03:24:52 +0200 Subject: [PATCH] docs: align README and CLAUDE docs with tooling and layout - Root CLAUDE: script_imports, check vs test-ci-matrix, audit, rules tree - README: dedupe review, clarify check/test-ci-matrix/audit - tests/CLAUDE: paths, package layout under tests/unit - template CLAUDE: workflow filenames; jinja rules tree - rules README: copier/template-conventions in structure tree Made-with: Cursor --- .claude/rules/README.md | 3 ++- CLAUDE.md | 26 +++++++++++++++----------- README.md | 5 ++--- template/.claude/rules/README.md | 3 ++- template/CLAUDE.md | 7 +++++-- template/CLAUDE.md.jinja | 9 ++++++--- tests/CLAUDE.md | 25 +++++++++---------------- 7 files changed, 41 insertions(+), 37 deletions(-) diff --git a/.claude/rules/README.md b/.claude/rules/README.md index 26594f3..00fc256 100644 --- a/.claude/rules/README.md +++ b/.claude/rules/README.md @@ -35,7 +35,8 @@ delete or shrink the rule — do not duplicate. ├── bash/ # Shell script-specific ├── yaml/ # YAML authoring conventions ├── markdown/ # Markdown authoring conventions -└── copier/ # Copier template-repo conventions +└── copier/ # Copier update workflow and answers-file rules + └── template-conventions.md ``` Detailed how-to content that previously lived here has moved to skills: diff --git a/CLAUDE.md b/CLAUDE.md index 57d3f8a..7dd4256 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,7 +21,7 @@ destination folder. │ ├── .github/workflows/ # Generated CI/CD workflows │ └── … # pyproject.toml.jinja, justfile.jinja, CLAUDE.md.jinja, … ├── tests/ # pytest suite for this meta-repo (see tests/CLAUDE.md) -│ ├── constants.py # REPO_ROOT / TEMPLATE_ROOT / COPIER_YAML for nested test modules +│ ├── script_imports.py # REPO_ROOT + load_script_module() for unit tests importing scripts/ │ ├── conftest.py # top-level shared fixtures │ ├── unit/ # fast isolated script tests │ ├── integration/ # Copier copy/update integration suite @@ -117,11 +117,14 @@ just ci This runs: `fix` → `check`. `check` bundles: `uv sync --frozen`, `fmt-check`, `ruff check`, `basedpyright`, -`sync-check`, `docs-check` (D-only; redundant with `ruff check` for enforcement), `test-ci-matrix` -(same pytest commands as `tests.yml` for 3.11/3.12/3.13), `pre-commit run --all-files`, `audit` (pip-audit). +`sync-check`, `docs-check` (D-only; redundant with `ruff check` for enforcement), `test-ci` +(pytest with coverage on the default Python 3.11 venv — same command as the 3.11 leg of `tests.yml`), +`pre-commit run --all-files`. Dependency audit (`pip-audit`) is **not** part of `check`; run +`just audit` locally or rely on `security.yml` on GitHub (CodeQL is GHA-only). Use `just test-ci-matrix` +to exercise the full 3.11 / 3.12 / 3.13 matrix locally. -Together, `lint.yml` + `tests.yml` + `security.yml` mirror these checks on GitHub (CodeQL is -GHA-only). All steps must pass before a PR is mergeable. +Together, `lint.yml` + `tests.yml` + `security.yml` cover the merge gate on GitHub. All steps must +pass before a PR is mergeable. ## Generating a test project from the template @@ -240,17 +243,18 @@ and are readable by any AI assistant (Claude Code, Cursor, or any LLM): ``` .claude/rules/ ├── README.md ← how to read and write rules; dual-hierarchy explained -├── common/ ← language-agnostic: coding-style, git-workflow, testing, security, -│ development-workflow, code-review -├── python/ ← Python: coding-style, testing, patterns, security, hooks -├── jinja/ ← Jinja2: coding-style, testing (meta-repo only) +├── common/ ← language-agnostic: coding-style, git-workflow, testing, security, hooks +├── python/ ← Python: coding-style, testing, hooks ├── bash/ ← Bash: coding-style, security ├── markdown/ ← placement rules, authoring conventions -├── yaml/ ← YAML formatting for copier.yml and workflows (meta-repo only) +├── yaml/ ← YAML formatting for copier.yml and workflows (meta-repo only) └── copier/ ← Copier template conventions (meta-repo only) └── template-conventions.md ``` +Jinja2 and broader Copier how-tos live under `.claude/skills/` (for example `jinja-guide/`), not +as a separate `rules/jinja/` tree. + The `template/.claude/rules/` tree mirrors this structure for generated projects (common, python, bash, markdown — no Jinja, yaml, or Copier-specific rules). @@ -407,5 +411,5 @@ just clean # removes build/, dist/, .pytest_cache, .ruff_cache, __pycache__, * - Added `CLAUDE.md` in `template/` — explains Jinja2 source layout, Copier variables, dual `.claude/` hierarchy - Added `CLAUDE.md` in `tests/` — explains test patterns, helpers, categories, and how to add new tests - Added `CLAUDE.md` in `scripts/` — documents each script, CLI flags, outputs, and CI integration -- Added `CLAUDE.md` in `.claude/` — orientation hub for hooks, commands, rules, and the dual-hierarchy +- Documented hooks and rules in `.claude/hooks/README.md` and `.claude/rules/README.md` (dual hierarchy with `template/.claude/`) - Added `CLAUDE.md` in `.github/` — documents all meta-repo workflows and design principles diff --git a/README.md b/README.md index dcbab7f..d81dbf7 100644 --- a/README.md +++ b/README.md @@ -144,15 +144,14 @@ Other useful commands: - 🔍 **`just lint`**: lint check - 🧠 **`just type`**: type check (basedpyright **standard** mode) - 📜 **`just docs-check`**: Google-style docstrings (ruff `D` only) -- ✅ **`just review`**: `fix` → `lint` → `type` → `docs-check` +- ✅ **`just review`**: `fix` → `lint` → `type` → `docs-check` (no tests; pre-merge static checks) - 🧪 **`just test`**: run template integration tests (renders the template and asserts output) - 📊 **`just coverage`**: run tests with coverage report - ⚡ **`just test-parallel`**: run tests in parallel (faster) - 🔁 **`just precommit`**: run pre-commit on all files - 🩺 **`just doctor`**: print toolchain and project versions - 🔗 **`just sync-check`**: validate root/template sync policy (`scripts/check_root_template_sync.py`) -- ✋ **`just check`**: read-only full gate (matches GitHub Actions lint + tests + security steps) -- 🔄 **`just review`**: `fix` + `lint` + `type` + `docs-check` (no tests, pre-merge validation) +- ✋ **`just check`**: read-only gate (`fmt-check`, lint, types, sync-check, docstrings, `test-ci`, pre-commit). For the full Python 3.11–3.13 matrix locally, use **`just test-ci-matrix`**. Dependency audit: **`just audit`** (also runs in `security.yml` on GitHub). ### Testing this template diff --git a/template/.claude/rules/README.md b/template/.claude/rules/README.md index 26594f3..00fc256 100644 --- a/template/.claude/rules/README.md +++ b/template/.claude/rules/README.md @@ -35,7 +35,8 @@ delete or shrink the rule — do not duplicate. ├── bash/ # Shell script-specific ├── yaml/ # YAML authoring conventions ├── markdown/ # Markdown authoring conventions -└── copier/ # Copier template-repo conventions +└── copier/ # Copier update workflow and answers-file rules + └── template-conventions.md ``` Detailed how-to content that previously lived here has moved to skills: diff --git a/template/CLAUDE.md b/template/CLAUDE.md index 8e8c69a..daaa629 100644 --- a/template/CLAUDE.md +++ b/template/CLAUDE.md @@ -59,11 +59,14 @@ template/ │ ├── workflows/ │ │ ├── ci.yml.jinja # Main test matrix (Python 3.11–3.13) │ │ ├── lint.yml.jinja # Ruff + basedpyright on PRs -│ │ ├── dependency-review.yml.jinja # Dependency diff review on PRs (optional) │ │ ├── docs.yml.jinja # MkDocs deploy to gh-pages (conditional) │ │ ├── pre-commit-update.yml.jinja # Weekly pre-commit autoupdate │ │ ├── release.yml.jinja # Version bump + GitHub Release (conditional) -│ │ └── security.yml.jinja # CodeQL + pip-audit (conditional) +│ │ ├── security.yml.jinja # CodeQL + pip-audit (conditional) +│ │ ├── dependency-review.yml # PR dependency review (static) +│ │ ├── labeler.yml # Path-based PR labels (static) +│ │ ├── pr-policy.yml # PR title/body/commits (static) +│ │ └── stale.yml # Stale issue/PR bot (static) │ ├── ISSUE_TEMPLATE/ # Bug report + feature request templates │ ├── CODE_OF_CONDUCT.md.jinja │ ├── CODEOWNERS.jinja diff --git a/template/CLAUDE.md.jinja b/template/CLAUDE.md.jinja index b62fd22..4e727cb 100644 --- a/template/CLAUDE.md.jinja +++ b/template/CLAUDE.md.jinja @@ -82,10 +82,13 @@ and are readable by any AI assistant (Claude Code, Cursor, or any LLM): ``` .claude/rules/ ├── README.md ← how to read and write rules -├── common/ ← language-agnostic: coding-style, git-workflow, testing, security, … -├── python/ ← Python: coding-style, testing, patterns, security, hooks +├── common/ ← language-agnostic: coding-style, git-workflow, testing, security, hooks +├── python/ ← Python: coding-style, testing, hooks ├── bash/ ← Bash: coding-style, security -└── markdown/ ← placement rules, authoring conventions +├── yaml/ ← YAML authoring (workflows, config) +├── markdown/ ← placement rules, authoring conventions +└── copier/ ← Copier update workflow (see `paths` in `template-conventions.md`) + └── template-conventions.md ``` ## Standards enforcement diff --git a/tests/CLAUDE.md b/tests/CLAUDE.md index 8f4cbd7..719e398 100644 --- a/tests/CLAUDE.md +++ b/tests/CLAUDE.md @@ -10,7 +10,7 @@ optional features are gated properly. |---|---| | `conftest.py` | Top-level pytest fixtures shared across all test tiers | | `unit/` | Fast isolated tests for automation scripts in `scripts/` | -| `script_imports.py` | `load_script_module()` helper for importing `scripts/*.py` in unit tests | +| `script_imports.py` | `REPO_ROOT` and `load_script_module()` for unit tests that import `scripts/*.py` | | `unit/conftest.py` | Fixtures shared within the unit tier | | `integration/` | Tests exercising Copier copy/update across the full template | | `integration/conftest.py` | Fixtures shared within the integration tier | @@ -80,8 +80,8 @@ optional features are gated properly. ### Package structure - `src//__init__.py`, `core.py`, `common/` modules all exist. -- `tests//test_core.py`, `test_support.py` exist. -- `conftest.py` exists. +- `tests/unit/test_core.py`, `tests/unit/common/test_support.py` (and other `tests/unit/common/*`) exist. +- `tests/conftest.py` exists. ### Logging layout - `logging_manager.py` is present under `common/`. @@ -103,20 +103,13 @@ just coverage # run with coverage report RUN_TEMPLATE_INTEGRATION=1 just test # include slow integration tests ``` -## Path constants — no shared file +## Path constants -Do **not** create a shared constants file (e.g. `constants.py`) for path values. -Define path constants at the top of each test file that needs them: - -```python -from pathlib import Path - -REPO_ROOT = Path(__file__).resolve().parent.parent.parent # adjust depth as needed -TEMPLATE_ROOT = REPO_ROOT / "template" -COPIER_YAML = REPO_ROOT / "copier.yml" -``` - -Constants are trivial one-liners; a shared module adds indirection with no benefit. +- **Unit tests** that load `scripts/*.py` should import **`REPO_ROOT`** from **`tests.script_imports`** + (see `tests/unit/test_*.py`). +- **Integration tests** (for example `integration/test_template.py`) define **`REPO_ROOT`**, + **`TEMPLATE_ROOT`**, and **`COPIER_YAML`** at the top of the file — do not add a separate + `constants.py` module for these; keep paths next to the tests that use them. ## Adding a new test