#!/bin/bash # ============================================================================ # Run only the tests related to files changed vs HEAD (staged, unstaged and # untracked). Quiet: failures plus a one-line summary. Falls back to the full # suite when a change cannot be mapped to tests. Generated by repo_contract. # ============================================================================ set -euo pipefail cd "$(git rev-parse --show-toplevel)" CHANGED=() while IFS= read -r f; do [[ -n "$f" && -e "$f" ]] && CHANGED+=("$f") done < <({ git diff --name-only HEAD 2>/dev/null || true; git ls-files --others --exclude-standard; } | sort -u) pytest_run() { if [[ -f uv.lock ]]; then uv run pytest "$@" elif [[ -f poetry.lock ]]; then poetry run pytest "$@" else python3 -m pytest "$@"; fi } if grep -qs testmon pyproject.toml requirements*.txt; then pytest_run --testmon -q --tb=short; exit $? fi full=0 dart=0 dfull=0 tests=() dtests=() for f in "${CHANGED[@]}"; do case "$f" in */conftest.py | conftest.py | pyproject.toml | requirements*.txt | pytest.ini | setup.cfg) full=1 ;; phone_app/lib/*.dart) rel="${f#phone_app/lib/}" [[ -f "phone_app/test/${rel%.dart}_test.dart" ]] && dtests+=("test/${rel%.dart}_test.dart") dart=1 ;; phone_app/test/*_test.dart) dtests+=("${f#phone_app/}"); dart=1 ;; phone_app/pubspec.yaml | phone_app/pubspec.lock) dart=1; dfull=1 ;; *.py) base="$(basename "$f" .py)" if [[ "$base" == test_* || "$base" == *_test ]]; then tests+=("$f") else while IFS= read -r t; do tests+=("$t"); done \ < <(git ls-files "*test_${base}.py" "*${base}_test.py") fi ;; esac done dart_run() { if [[ $dfull -eq 1 || ${#dtests[@]} -eq 0 ]]; then (cd phone_app && flutter test --reporter=compact) else (cd phone_app && flutter test --reporter=compact "${dtests[@]}"); fi } if [[ $full -eq 0 && ${#CHANGED[@]} -eq 0 ]]; then echo "no changes vs HEAD: nothing to test"; exit 0; fi if [[ $full -eq 0 && ( ${#tests[@]} -gt 0 || $dart -eq 1 ) ]]; then rc=0 [[ ${#tests[@]} -gt 0 ]] && { pytest_run -q --tb=short --no-cov "${tests[@]}" || rc=$?; } [[ $dart -eq 1 ]] && { dart_run || rc=$?; } exit $rc fi if [[ $full -eq 0 ]] && ! printf '%s\n' "${CHANGED[@]}" | grep -q '\.py$'; then echo "no python changes: nothing to test"; exit 0 fi echo "no mapped tests: running full suite" pytest_run -q --tb=short --no-cov