#!/usr/bin/env bash # Summarize Rust compiler errors into a clean, readable log. # Prefers cargo JSON + jq; falls back to sed/awk parser if jq is unavailable. # Output file: /tmp/cargo_errors_only.log (override with OUT env var) set -euo pipefail OUT=${OUT:-/tmp/cargo_errors_only.log} PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "") if [[ -n "$PROJECT_ROOT" ]]; then cd "$PROJECT_ROOT" fi # Ensure colorless output from cargo to avoid ANSI in fallback export CARGO_TERM_COLOR=never # Function: JSON mode (best) run_json_mode() { # Capture cargo's exit code from the first command in the pipeline set +e set +o pipefail cargo check --message-format=json -q "$@" 2>/dev/null \ | jq -r 'select(.reason=="compiler-message" and .message.level=="error") | .message.rendered' \ | tee "$OUT" local cargo_status=${PIPESTATUS[0]} set -o pipefail set -e return "$cargo_status" } # Function: Fallback parser (no jq required) run_fallback_mode() { # We intentionally capture stderr (diagnostics) and stdout set +e set +o pipefail cargo check -q "$@" 2>&1 \ | sed -r 's/\x1B\[[0-9;]*[mK]//g' \ | awk ' BEGIN{inerr=0} /^warning:/{inerr=0; next} /^error(\[|:)/{inerr=1} # Drop cargo/rustc warning summaries while still inside an error block inerr && /[0-9]+ warnings? emitted/ {next} inerr{print} ' \ | tee "$OUT" local cargo_status=${PIPESTATUS[0]} set -o pipefail set -e return "$cargo_status" } status=0 if command -v jq >/dev/null 2>&1; then if ! run_json_mode "$@"; then status=$? fi else echo "INFO: jq not found; using fallback parser (install jq for best results)." >&2 if ! run_fallback_mode "$@"; then status=$? fi fi exit "$status"