set -euo pipefail
THRESHOLD="${THRESHOLD:-70}"
MODE="human"
while [[ $# -gt 0 ]]; do
case "$1" in
--ci) MODE="ci"; shift ;;
--json) MODE="json"; shift ;;
--threshold) THRESHOLD="$2"; shift 2 ;;
*) echo "Unknown arg: $1"; exit 1 ;;
esac
done
if ! command -v cargo-llvm-cov &>/dev/null; then
echo "cargo-llvm-cov not found. Attempting install..."
if ! cargo install cargo-llvm-cov --locked 2>&1; then
echo ""
echo "ERROR: Failed to install cargo-llvm-cov."
echo ""
echo "Install manually with one of:"
echo " cargo install cargo-llvm-cov --locked"
echo " cargo binstall cargo-llvm-cov"
echo " brew install cargo-llvm-cov (macOS)"
echo ""
echo "Or in CI, use: taiki-e/install-action@cargo-llvm-cov"
exit 2
fi
fi
EXPORT_DIR="$(mktemp -d)"
trap 'rm -rf "$EXPORT_DIR"' EXIT
echo "Running tests with coverage instrumentation..."
echo ""
cargo llvm-cov nextest \
--all-features \
--json \
--output-path "$EXPORT_DIR/coverage.json" \
2>&1 | tail -1
if [[ "$MODE" == "json" ]]; then
cat "$EXPORT_DIR/coverage.json"
exit 0
fi
cargo llvm-cov report \
--all-features \
--text \
2>/dev/null > "$EXPORT_DIR/text-report.txt" || true
echo ""
echo "================================================================"
echo " COVERAGE FEEDBACK"
echo "================================================================"
echo ""
LINES_TOTAL=$(grep -o '"lines":{[^}]*}' "$EXPORT_DIR/coverage.json" | tail -1 | grep -o '"count":[0-9]*' | head -1 | cut -d: -f2)
LINES_COVERED=$(grep -o '"lines":{[^}]*}' "$EXPORT_DIR/coverage.json" | tail -1 | grep -o '"covered":[0-9]*' | head -1 | cut -d: -f2)
FUNCS_TOTAL=$(grep -o '"functions":{[^}]*}' "$EXPORT_DIR/coverage.json" | tail -1 | grep -o '"count":[0-9]*' | head -1 | cut -d: -f2)
FUNCS_COVERED=$(grep -o '"functions":{[^}]*}' "$EXPORT_DIR/coverage.json" | tail -1 | grep -o '"covered":[0-9]*' | head -1 | cut -d: -f2)
if [[ -z "$LINES_TOTAL" || "$LINES_TOTAL" == "0" ]]; then
echo "WARNING: Could not parse coverage JSON. Raw text report:"
echo ""
cat "$EXPORT_DIR/text-report.txt"
exit 0
fi
LINE_PCT=$((LINES_COVERED * 100 / LINES_TOTAL))
FUNC_PCT=$((FUNCS_COVERED * 100 / FUNCS_TOTAL))
echo " Lines: $LINES_COVERED / $LINES_TOTAL ($LINE_PCT%)"
echo " Functions: $FUNCS_COVERED / $FUNCS_TOTAL ($FUNC_PCT%)"
echo ""
echo "----------------------------------------------------------------"
echo " UNCOVERED (the ping-back)"
echo "----------------------------------------------------------------"
echo ""
if [[ -f "$EXPORT_DIR/text-report.txt" ]]; then
awk '
/^-/ { next }
/^Filename/ { next }
/^TOTAL/ { next }
/^$/ { next }
{
# Fields vary but file is $1, look for miss counts
if (NF >= 7) {
file = $1
region_miss = $3
line_miss = $6
if (region_miss + 0 > 0 || line_miss + 0 > 0) {
printf " %-50s regions_miss=%-4s lines_miss=%-4s\n", file, region_miss, line_miss
}
}
}
' "$EXPORT_DIR/text-report.txt"
fi
echo ""
echo "----------------------------------------------------------------"
echo " UNCOVERED FUNCTIONS"
echo "----------------------------------------------------------------"
echo ""
python3 -c "
import json, sys
with open('$EXPORT_DIR/coverage.json') as f:
data = json.load(f)
uncovered = []
for file_data in data.get('data', [{}])[0].get('functions', []):
name = file_data.get('name', '')
count = file_data.get('count', 0)
filenames = file_data.get('filenames', [])
regions = file_data.get('regions', [])
if count == 0 and 'test' not in name.lower():
loc = filenames[0] if filenames else '?'
# Clean up the function name (demangle)
short = name.split('::')[-1] if '::' in name else name
mod_path = '::'.join(name.split('::')[:-1])
uncovered.append((loc, mod_path, short))
uncovered.sort()
if not uncovered:
print(' All functions covered!')
else:
current_file = ''
for loc, mod_path, fn_name in uncovered:
if loc != current_file:
current_file = loc
print(f' {loc}:')
print(f' -> {mod_path}::{fn_name}()')
print()
print(f' Total uncovered functions: {len(uncovered)}')
" 2>/dev/null || echo " (install python3 for function-level detail, or use --json)"
echo ""
echo "================================================================"
if [[ "$MODE" == "ci" ]]; then
if [[ "$LINE_PCT" -lt "$THRESHOLD" ]]; then
echo ""
echo "FAIL: Line coverage $LINE_PCT% < threshold $THRESHOLD%"
echo "Fix the uncovered functions listed above."
exit 1
else
echo ""
echo "PASS: Line coverage $LINE_PCT% >= threshold $THRESHOLD%"
fi
fi