#!/usr/bin/env bash set -uo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" BUILD_DIR="$REPO_ROOT/build/release" WARNINGS_LOG="/tmp/warnings.log" failures=0 fail() { printf 'ERROR: %s\n' "$1" >&2 failures=$((failures + 1)) } info() { printf '%s\n' "$1" } check_stale_files() { info 'Checking for stale backup files...' local stale_files stale_files="$({ find "$REPO_ROOT" \ \( -path "$REPO_ROOT/.git" -o -path "$REPO_ROOT/build" \) -prune -o \ -type f \ \( -name '*.bak' -o -name '*.orig' -o -name '*.tmp' -o -name '*.swp' -o -name '*~' \) \ -print } | sed "s#^$REPO_ROOT/##" | sort)" if [[ -n "$stale_files" ]]; then printf 'Stale backup files found:\n%s\n' "$stale_files" >&2 fail 'Remove stale backup files before committing.' return fi info 'No stale backup files found.' } check_build_warnings() { info 'Checking for compiler warnings with strict warnings enabled...' local project_warning_lines if ! command -v meson >/dev/null 2>&1; then fail 'meson is not installed.' return fi if ! command -v ninja >/dev/null 2>&1; then fail 'ninja is not installed.' return fi if [[ ! -f "$BUILD_DIR/build.ninja" ]]; then fail "Meson build directory not configured: $BUILD_DIR" return fi if ! meson configure "$BUILD_DIR" -Dstrict_warnings=enabled; then fail 'Failed to enable strict warnings in the Meson build directory.' return fi rm -f "$WARNINGS_LOG" if ! ninja -C "$BUILD_DIR" clean; then fail 'Failed to clean the release build directory.' return fi if ! ninja -C "$BUILD_DIR" 2>&1 | tee "$WARNINGS_LOG"; then fail 'Build failed while checking strict compiler warnings.' return fi project_warning_lines="$(grep -E '(^|[^[:alpha:]])warning:' "$WARNINGS_LOG" | grep -E '^(\.\./\.\./)?(src|include|tests)/' || true)" if [[ -n "$project_warning_lines" ]]; then printf 'Compiler warnings were found in %s\n%s\n' "$WARNINGS_LOG" "$project_warning_lines" >&2 fail 'Strict warning build produced compiler warnings in project sources.' return fi info 'Strict warning build completed with zero warnings.' } check_clang_tidy() { info 'Running clang-tidy on src/*.cpp files...' if ! command -v clang-tidy >/dev/null 2>&1; then fail 'clang-tidy is not installed.' return fi if [[ ! -f "$BUILD_DIR/compile_commands.json" ]]; then fail "compile_commands.json not found in $BUILD_DIR" return fi local file local tidy_failures=0 while IFS= read -r file; do [[ -n "$file" ]] || continue if ! clang-tidy -p "$BUILD_DIR" "$file"; then tidy_failures=$((tidy_failures + 1)) fi done < <(find "$REPO_ROOT/src" -type f -name '*.cpp' | sort) if [[ "$tidy_failures" -gt 0 ]]; then fail "clang-tidy reported issues in $tidy_failures file(s)." return fi info 'clang-tidy passed.' } cd "$REPO_ROOT" || exit 2 check_stale_files check_build_warnings check_clang_tidy if [[ "$failures" -gt 0 ]]; then printf 'Hygiene checks failed (%d issue(s)).\n' "$failures" >&2 exit 1 fi printf 'Hygiene checks passed.\n'