# dataloader-util developer tasks
# Run `just` (no args) to list available tasks.

set dotenv-load := true
set shell := ["bash", "-uc"]

# Default task: list available recipes.
default:
    @just --list

# Sync dev environment (creates .venv if missing, installs deps).
dev:
    uv sync

# Run unit tests (skips integration tests by default).
test:
    uv run pytest -m "not integration"

# Run integration tests (requires docker compose up for some tests).
test-integration:
    uv run pytest -m integration

# Run all tests.
test-all:
    uv run pytest

# Run unit tests with coverage.
test-cov:
    uv run pytest -m "not integration" --cov=dataloader_util --cov-report=term-missing

# Lint with ruff.
lint:
    uv run ruff check

# Format with ruff (check only).
fmt:
    uv run ruff format --check

# Format with ruff (write).
fmt-write:
    uv run ruff format

# Type-check with ty.
types:
    uv run ty check

# Run all checks: lint + types + unit tests.
check: lint types test
    @echo "all checks passed"

# Run the same local security gates as CI: Bandit SAST, pip-audit SCA, and Trivy image scan.
security-scan: sast sca docker-build-security docker-scan
    @echo "security scans passed"

# Run the same Bandit SAST scan as CI and save reports/bandit.json.
sast:
    mkdir -p reports
    uvx bandit -r src -f json -o reports/bandit.json --exit-zero
    uvx bandit -r src --severity-level high --confidence-level medium

# Run the same pip-audit SCA scan as CI and save reports/pip-audit.json.
sca:
    mkdir -p reports
    uv export --frozen --no-dev --no-emit-project --no-hashes --format requirements.txt --output-file reports/requirements.txt > /dev/null
    uvx pip-audit -r reports/requirements.txt --format json --output reports/pip-audit.json

# Auto-fix lint issues and format.
fix:
    uv run ruff check --fix
    uv run ruff format

# Bump the project version, commit the change, and create a matching release tag.
# Usage: just bump-version [major|minor|bugfix]
bump-version bump="bugfix":
    @set -euo pipefail; \
    case "{{bump}}" in \
      major|minor) uv_bump="{{bump}}" ;; \
      bugfix|patch) uv_bump="patch" ;; \
      *) echo "Usage: just bump-version [major|minor|bugfix]" >&2; exit 2 ;; \
    esac; \
    if ! git diff --quiet || ! git diff --cached --quiet; then \
      echo "Working tree has uncommitted changes; commit or stash them first." >&2; \
      exit 1; \
    fi; \
    version="$(uv version --bump "$uv_bump" --dry-run --short)"; \
    tag="v${version}"; \
    if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then \
      echo "Tag ${tag} already exists." >&2; \
      exit 1; \
    fi; \
    uv version --bump "$uv_bump" --no-sync; \
    git add pyproject.toml uv.lock; \
    git commit -m "Bump version to ${version}"; \
    git tag "$tag"; \
    echo "Bumped version to ${version} and created tag ${tag}."

# Build the Docker image locally (tag: dataloader-util:dev).
docker-build:
    docker build -t dataloader-util:dev .

# Build the Docker image without cache for vulnerability scanning (tag: dataloader-util:dev).
docker-build-security:
    docker build --pull --no-cache -t dataloader-util:dev .

# Build and run the Docker image against a local config file.
# Usage: just docker-run examples/simple.yaml
docker-run config:
    docker run --rm -t \
        -v "$(pwd):/workspace:ro" \
        -v "$(pwd)/{{config}}:/config/config.yaml:ro" \
        dataloader-util:dev \
        run --config /config/config.yaml

# Scan the locally-built Docker image with Trivy (same gate as CI).
docker-scan:
    .forgejo/scripts/scan-image.sh
