Copier template that generates opinionated Python projects with uv, ruff, mypy, pytest, pre-commit, and GitHub Actions.
copier.yaml— template variables, feature toggles, and_taskspost-copy stepstemplate/— all source files;_subdirectory: templatemakes this the output root- Files with
.jinjaextension are rendered by Copier; all others are copied verbatim - Copier variable syntax:
{{ variable_name }}in.jinjafiles - Conditional blocks:
{% if use_docker != 'none' %}…{% endif %} _tasksin copier.yaml run sequentially after copy: rename package dir → remove unused features → git init → uv sync → pre-commit install
just validate-standard # render default variant and run ruff + mypy + pytest
just validate-all # run all 8 variants (mirrors CI matrix)
just validate-full # kitchen-sink: all features on
just release [patch|minor|major] # tag and push a release
uv run pytest # test template rendering helpers only
uv run ruff check . # lint template helpers (src/, tests/)To test locally: uvx copier copy --defaults . /tmp/test-output
- Feature toggles are vars in copier.yaml — default to opt-in (false / none / minimal)
- Adding a feature toggle requires updating: copier.yaml, affected
.jinjafiles, the_tasksremoval step, the justfile validate recipe, and the CI matrix in.github/workflows/validate-template.yml - Escape Jinja syntax that must survive into generated projects:
{% raw %}{{ raw_jinja }}{% endraw %} - Never add
.jinjato files that have no template variables (.gitignore, static YAML, etc.) _subdirectory: templateand_excludein copier.yaml control what Copier sees — do not move template root files outsidetemplate/
validate-standard, validate-minimal, validate-cli, validate-api, validate-db, validate-iot, validate-gpu-ml, validate-full