#!/usr/bin/env bash # scope-check.sh — Validate that git diff only touches declared files. # Usage: ./scripts/scope-check.sh "file1.cs" "file2.cs" ... # Exit 0 if all changed files are in scope, 1 if any are outside. # # Checks staged, unstaged, and untracked changes against the allowed list. # Supports glob patterns in the allowed list (e.g. "ytLive.Tests/*"). set -euo pipefail if [ $# -eq 0 ]; then echo "Usage: $0 \"file1.cs\" \"file2.cs\" ..." echo " Pass the declared file list as arguments." exit 1 fi # Collect allowed patterns into an array allowed=("$@") # Gather all changed files: working tree vs HEAD (tracked) + staged + untracked changed=$({ git diff --name-only HEAD 2>/dev/null || true git diff --name-only --cached 2>/dev/null || true git ls-files --others --exclude-standard 2>/dev/null || true } | sort -u) if [ -z "$changed" ]; then echo "✓ No changes detected." exit 0 fi violations=() while IFS= read -r file; do matched=false for pattern in "${allowed[@]}"; do if [[ "$file" == $pattern ]]; then matched=true break fi done if [ "$matched" = false ]; then violations+=("$file") fi done <<< "$changed" if [ ${#violations[@]} -eq 0 ]; then echo "✓ Scope check passed — all changed files are in scope." exit 0 fi echo "✗ SCOPE VIOLATION — the following files are outside the declared scope:" for f in "${violations[@]}"; do echo " - $f" done echo "" echo "Either justify the edit or revert the change." exit 1