Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/rules/copier/template-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Tasks use `/bin/sh` (POSIX shell), not bash. Use POSIX-compatible syntax.
- `copier update` uses these tags to select the appropriate template version.
- Introduce `_migrations` in `copier.yml` when a new version renames or removes template
files, to guide users through the update.
- See `scripts/bump_version.py` and `.github/workflows/release.yml` for the release
- See `src/{{ package_name }}/common/bump_version.py` and `.github/workflows/release.yml` for the release
automation workflow.

## Dual-hierarchy maintenance
Expand Down
17 changes: 6 additions & 11 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ _skip_if_exists:
- mkdocs.yml
- pyproject.toml
- README.md
- scripts/bump_version.py
- SECURITY.md
- src/{{ package_name }}/__init__.py
- src/{{ package_name }}/common/bump_version.py


# -------------------------------------------------------------------------
# Questions / Prompts
Expand Down Expand Up @@ -140,15 +141,10 @@ include_cli:
help: Generate a Typer-based CLI entry point and console script?
default: false

include_logging_setup:
type: bool
help: Add a logging_config module with configure_logging() (stdlib logging + structlog)?
default: false

include_git_cliff:
type: bool
help: Add git-cliff, cliff.toml, and a just changelog recipe for release notes?
default: false
default: true

# -------------------------------------------------------------------------
# Computed values
Expand Down Expand Up @@ -182,7 +178,7 @@ github_actions_python_versions:
# when the host Python lacks `ensurepip`/`pip` (common on minimal distro Pythons).
# - To avoid template generation failing on machines without `uv`, we bootstrap `uv` first.
# We try `pip` if available; otherwise we fall back to Astral's installer script.
# - Keep tasks idempotent. It's okay if `uv self update` fails (offline / restricted envs).
# - Keep tasks idempotent.
#
# Copy vs update: these tasks run after both `copier copy` and `copier update` (not gated
# with _copier_operation) so the lockfile and local env stay aligned with the template after
Expand Down Expand Up @@ -226,7 +222,6 @@ _tasks:

command -v uv >/dev/null 2>&1
'
- command: uv self update || true
- command: uv lock
- command: >-
uv sync --frozen --extra dev --extra test
Expand All @@ -238,14 +233,14 @@ _tasks:
- command: uv run basedpyright
- command: rm -f cliff.toml
when: "{{ not include_git_cliff }}"
- command: rm -f src/{{ package_name }}/logging_config.py
when: "{{ not include_logging_setup }}"
- command: rm -f src/{{ package_name }}/cli.py
when: "{{ not include_cli }}"
- command: rm -f mkdocs.yml
when: "{{ not include_docs }}"
- command: sh -c 'rm -f docs/index.md docs/ci.md 2>/dev/null; rmdir docs 2>/dev/null || true'
when: "{{ not include_docs }}"
- command: >-
sh -c 'find . -type f -empty ! -path "./.git/*" ! -path "./.venv/*" -delete'
- command: echo "✅ Project {{ project_name }} created successfully!"
- command: echo "📁 Location $(pwd)"
- command: echo "🚀 Run 'just ci' to verify everything works"
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ skip_covered = false
pythonVersion = "3.11"
typeCheckingMode = "standard"
reportMissingImports = true
include = ["tests", "scripts"]
reportImplicitOverride = false
reportMissingTypeStubs = false
reportUnknownMemberType = false
Expand Down
6 changes: 4 additions & 2 deletions scripts/sync_skip_if_exists.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
"template/.github/CODE_OF_CONDUCT.md.jinja": ".github/CODE_OF_CONDUCT.md",
"template/.github/ISSUE_TEMPLATE/bug_report.md.jinja": ".github/ISSUE_TEMPLATE/bug_report.md",
"template/.github/ISSUE_TEMPLATE/feature_request.md.jinja": ".github/ISSUE_TEMPLATE/feature_request.md",
"template/scripts/bump_version.py.jinja": "scripts/bump_version.py",
"template/src/{{ package_name }}/common/bump_version.py.jinja": (
"src/{{ package_name }}/common/bump_version.py"
),
}

# Always include these (user customization hotspots even if not in the map above).
Expand All @@ -44,7 +46,7 @@
".github/CODE_OF_CONDUCT.md",
".github/ISSUE_TEMPLATE/bug_report.md",
".github/ISSUE_TEMPLATE/feature_request.md",
"scripts/bump_version.py",
"src/{{ package_name }}/common/bump_version.py",
]

# Paths touched at least this often in recent history are added to the skip list.
Expand Down
4 changes: 2 additions & 2 deletions template/.github/workflows/release.yml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ jobs:
fi

if [ -n "{% raw %}${{ inputs.version }}{% endraw %}" ]; then
NEW_VERSION="$(uv run python scripts/bump_version.py --new-version "{% raw %}${{ inputs.version }}{% endraw %}")"
NEW_VERSION="$(uv run python src/{{ package_name }}/common/bump_version.py --new-version "{% raw %}${{ inputs.version }}{% endraw %}")"
else
NEW_VERSION="$(uv run python scripts/bump_version.py --bump "{% raw %}${{ inputs.bump }}{% endraw %}")"
NEW_VERSION="$(uv run python src/{{ package_name }}/common/bump_version.py --bump "{% raw %}${{ inputs.bump }}{% endraw %}")"
fi
echo "version=${NEW_VERSION}" >> "${GITHUB_OUTPUT}"

Expand Down
36 changes: 32 additions & 4 deletions template/justfile.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,43 @@ type:

# -------------------------------------------------------------------------
# Testing
#
# Default: Minimal logging (quiet mode, dots only, warnings/errors only)
# For verbose output with test names, use: just test-verbose
# For full debug output, use: just test-debug
# For failed tests only, use: just test-lf
# -------------------------------------------------------------------------

test: _set_env
# Run tests with minimal output (default, fast, token-efficient)
test:
@uv run --active pytest tests/

# Run only slow tests
slow:
@uv run --active pytest tests/ -m slow

# Run tests in parallel with minimal output
test-parallel:
@uv run --active pytest tests/ -n auto

# Run tests with verbose output (shows test names, INFO logs)
test-verbose:
@uv run --active pytest tests/ -v

test-parallel: _set_env
@uv run --active pytest tests/ -v -n auto
# Run tests with full debug output (shows all DEBUG logs)
test-debug:
@uv run --active pytest tests/ -vv --show-debug

# Re-run only the tests that failed in the last run
test-lf:
@uv run --active pytest tests/ --lf

# Stop on first test failure (fast feedback)
test-first-fail:
@uv run --active pytest tests/ -x

coverage: _set_env
# Run tests with coverage report (full HTML/XML/term output)
coverage:
@uv run --active pytest tests/ \
--cov={{ package_name }} \
--cov-report=term-missing \
Expand Down
10 changes: 9 additions & 1 deletion template/pyproject.toml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,20 @@ addopts = [
"--cov={{ package_name }}",
"--cov-report=term-missing",
"--cov-report=xml",
"--tb=short",
"--log-level=WARNING",
"-m", "not slow",
"-p", "no:cacheprovider",
"-ra",
]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"integration: marks tests as integration tests",
]
filterwarnings = [
"ignore::DeprecationWarning",
"ignore::PendingDeprecationWarning",
]

# ==========================================================================
# Coverage Configuration
Expand All @@ -177,7 +186,6 @@ omit = [
"**/__init__.py",
"*/tests/*",
"*/__pycache__/*",
"*/common/*",
]

[tool.coverage.report]
Expand Down
Loading
Loading