#!/usr/bin/env bash # Requires bash ≥ 4 for `mapfile`; on macOS install via `brew install bash` # and invoke as `bash scripts/quality/license-headers.sh`. The portable # fallback below works on bash 3.2 too. # scripts/quality/license-headers.sh # # Verify that every source file under code/ carries an SPDX-License- # Identifier header. The project policy (doc/release-policy.md) is: # # * Every conformallab++ source file (.h, .hpp, .cpp under code/include # or code/src, but NOT code/deps/) must have: # SPDX-License-Identifier: MIT # * The copyright line is encouraged but not enforced (the year is # allowed to lag). # # Files under code/deps/ are vendored third-party code (Eigen, JSON, # GLFW, libigl, …) and are skipped — they carry their own licenses. # # Exit codes: # 0 every checked file has the SPDX header # 1 at least one file is missing it # 2 prerequisite missing # # Run from any directory; the script resolves the repo root from its own path. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "$ROOT" SPDX="SPDX-License-Identifier: MIT" # Files to check: code/include + code/src + code/tests. Skip code/deps. FILES_LIST="$(find code/include code/src code/tests \ \( -name "*.h" -o -name "*.hpp" -o -name "*.cpp" \) \ -type f 2>/dev/null \ | grep -v "^code/deps/" \ | grep -v " 2\." \ | sort)" n_total=0 n_missing=0 missing_list="" while IFS= read -r f; do [ -z "$f" ] && continue n_total=$((n_total + 1)) # Check only the first 30 lines — SPDX must be near the top. if ! head -30 "$f" | grep -q "$SPDX"; then n_missing=$((n_missing + 1)) missing_list="$missing_list $f " fi done <&2 exit 2 fi echo "Checked $n_total source files for SPDX header." if [ "$n_missing" -gt 0 ]; then echo echo "FAIL: $n_missing file(s) missing '$SPDX' in their first 30 lines:" printf '%s' "$missing_list" echo echo "Recovery: add this two-line header at the top of each file:" echo " // Copyright (c) 2024-$(date +%Y) Tarik Moussa." echo " // $SPDX" exit 1 fi echo "OK: every checked file carries '$SPDX'." exit 0