#!/usr/bin/env bash # check-coverage-thresholds.sh — Enforce minimum test coverage for critical packages. # # Runs `go test -cover` on specified packages and fails if any package # drops below its defined minimum coverage threshold. # # Usage: scripts/check-coverage-thresholds.sh set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$REPO_ROOT" log() { printf '[coverage] %s\n' "$*" } err() { printf '[coverage] FAIL: %s\n' "$*" >&2 } # Package thresholds: "package_path:minimum_percent" # Set ~2% below current values to catch regressions without blocking on noise. THRESHOLDS=( "internal/sync:70" "internal/storage:60" "internal/service:50" "internal/service/conversion:80" "internal/cli:30" "internal/model:40" ) failures=0 passes=0 for entry in "${THRESHOLDS[@]}"; do pkg="${entry%%:*}" threshold="${entry##*:}" # Run go test with coverage and extract percentage output=$(go test -cover "./$pkg" 2>&1) || { err "$pkg — tests failed" failures=$((failures + 1)) continue } # Extract coverage percentage (e.g., "coverage: 72.1% of statements") coverage=$(echo "$output" | grep -oE 'coverage: [0-9]+\.[0-9]+%' | grep -oE '[0-9]+\.[0-9]+' || echo "0.0") if [[ -z "$coverage" || "$coverage" == "0.0" ]]; then # Package might have no test files or no statements if echo "$output" | grep -q '\[no test files\]'; then err "$pkg — no test files (threshold: ${threshold}%)" failures=$((failures + 1)) else err "$pkg — could not determine coverage (threshold: ${threshold}%)" failures=$((failures + 1)) fi continue fi # Compare using awk for floating-point comparison passed=$(awk "BEGIN { print ($coverage >= $threshold) ? 1 : 0 }") if [[ "$passed" -eq 1 ]]; then log "$pkg: ${coverage}% >= ${threshold}% threshold" passes=$((passes + 1)) else err "$pkg: ${coverage}% < ${threshold}% threshold" failures=$((failures + 1)) fi done echo "" log "Results: ${passes} passed, ${failures} failed (${#THRESHOLDS[@]} packages checked)" if [[ "$failures" -gt 0 ]]; then err "Coverage threshold check failed." exit 1 fi log "All coverage thresholds met." exit 0