Files
python-cli-template/{{cookiecutter.project_slug}}/tasks.py
T
2026-04-23 10:48:10 +02:00

88 lines
2.2 KiB
Python

# type: ignore
import re
from pathlib import Path
from invoke import task
PYPROJECT = Path(__file__).parent / "pyproject.toml"
@task
def venv(c):
"""Sync dependencies."""
c.run("uv sync --group dev")
@task
def format(c):
"""Format code."""
c.run("uv run ruff format src tests")
@task
def lint(c):
"""Run linters."""
c.run("uv run ruff check src tests")
c.run("uv run ruff format --check src tests")
c.run("uv run mypy src")
@task
def test(c):
"""Run tests with coverage."""
c.run("uv run pytest --cov=src --cov-report=term-missing")
@task
def ci(c):
"""Run lint and tests in a clean Docker container."""
image = "{{ cookiecutter.project_slug }}-ci"
c.run(f"docker build --network=host -t {image} .")
cmd = (
"uv run ruff check src tests && "
"uv run ruff format --check src tests && "
"uv run mypy src && "
"uv run pytest --cov=src --cov-report=term-missing"
)
c.run(f"docker run --rm {image} sh -c '{cmd}'")
@task
def bump(c, part):
"""Bump version (patch/minor/major), commit, and tag."""
if part not in ("patch", "minor", "major"):
raise SystemExit("Usage: inv bump <patch|minor|major>")
result = c.run("git status --porcelain", hide=True)
if result.stdout.strip():
raise SystemExit("Working tree is dirty. Commit or stash changes first.")
text = PYPROJECT.read_text()
m = re.search(r'version = "(\d+)\.(\d+)\.(\d+)"', text)
if not m:
raise SystemExit("Could not find version in pyproject.toml")
major, minor, patch = int(m[1]), int(m[2]), int(m[3])
if part == "major":
major, minor, patch = major + 1, 0, 0
elif part == "minor":
minor, patch = minor + 1, 0
else:
patch += 1
new_version = f"{major}.{minor}.{patch}"
new_text = re.sub(r'(version = ")\d+\.\d+\.\d+(")', rf"\g<1>{new_version}\2", text)
PYPROJECT.write_text(new_text)
c.run(f'git add pyproject.toml && git commit -m "bump version to {new_version}"')
c.run(f"git tag v{new_version}")
print(f"Bumped to {new_version}")
@task
def clean(c):
"""Preview files to delete (safe mode)."""
c.run("git clean -nfdx")
if input("Delete? [y/N] ").lower() == "y":
c.run("git clean -fdx")