# Target for code coverage. Coverage task will fail if below this. coverage_goal := env("COVERAGE_GOAL", "90") # --------------------------------------------------------------------------- # Help # --------------------------------------------------------------------------- # Check for environment issues. [group('help')] doctor: @command -v uv >/dev/null || { echo "uv is not installed"; exit 1; } @uv run ruff --version @uv run mypy --version @uv run pytest --version @echo "Python environment looks good." # --------------------------------------------------------------------------- # Python # --------------------------------------------------------------------------- # Build Python package. [group('python')] build: uv build --clear # Publish Python package. [group('python')] publish: uv publish # --------------------------------------------------------------------------- # Dependencies # --------------------------------------------------------------------------- # Install dependencies. [arg('mode', help='Either DEV or PROD')] [group('python')] sync mode='DEV': if [[ "{{ mode }}" == "DEV" ]]; then \ uv sync --locked --all-extras --dev; \ else \ uv sync --frozen; \ fi # Update dependencies. [group('python')] update: uv lock --upgrade uv sync # Update specific dependency. [group('python')] update-package package: uv lock --upgrade-package {{ package }} uv sync # --------------------------------------------------------------------------- # Formatting / linting # --------------------------------------------------------------------------- # Run Python formatter. [group('python')] format: uv run ruff format # Check that Python code is formatted correctly. [group('python')] format-check: uv run ruff format --check # Run Python linter. [arg('mode', help='Set to CI to output in GitHub format.')] [group('python')] lint mode='DEV': @if [[ "{{ mode }}" == "CI" ]]; then \ uv run ruff check --output-format=github; \ else \ uv run ruff check; \ fi # Run Python type checker. [group('python')] typecheck: uv run mypy --check-untyped-defs src # --------------------------------------------------------------------------- # Python Tests # --------------------------------------------------------------------------- # Run all tests. [group('python')] test args="tests": uv run pytest {{ args }} # Run tests and produce code coverage. [group('python')] coverage: uv run pytest \ tests \ --cov=src \ --cov-report=term-missing \ --cov-report=xml \ --cov-fail-under={{ coverage_goal }} # --------------------------------------------------------------------------- # Security # --------------------------------------------------------------------------- # Audit dependencies for vulnerabilities. [group('security')] audit: uv audit --no-dev # --------------------------------------------------------------------------- # Common workflows # --------------------------------------------------------------------------- # Run pre-commit checks. [group('workflow')] check: format-check lint typecheck test # Remove build and/or run files. [group('workflow')] clean: rm -rf \ dist \ .mypy_cache \ .pytest_cache \ .ruff_cache \ .coverage \ coverage.xml find . \ -type d \ -name __pycache__ \ -prune \ -exec rm -rf {} +