diff --git a/scripts/ui-drift-audit.sh b/scripts/ui-drift-audit.sh index 04cc518..da9cb06 100644 --- a/scripts/ui-drift-audit.sh +++ b/scripts/ui-drift-audit.sh @@ -9,12 +9,61 @@ fi ROOT="$(git rev-parse --show-toplevel)" cd "$ROOT" +# Detect whether ripgrep is available. Fall back to grep so the audit cannot +# silently pass on hosts without rg (which was hiding regressions until now). +if command -v rg >/dev/null 2>&1; then + SEARCH_BACKEND="rg" +else + SEARCH_BACKEND="grep" + echo "[ui-drift-audit] note: ripgrep not found, falling back to grep" >&2 +fi + +# Build a search command that maps rg --glob exclusions to grep --exclude. +search() { + local pattern="$1" + shift + if [[ "$SEARCH_BACKEND" == "rg" ]]; then + rg -n "$pattern" "$@" --glob '!**/*.test.*' || true + else + # grep equivalent: -rnE with --exclude for test files. Translate + # rg-style --glob '!path' arguments into grep --exclude entries so the + # caller's exclusions (e.g. the @bytelyst/ui adapter file) still apply. + local targets=() + local extra_excludes=() + while [[ $# -gt 0 ]]; do + case "$1" in + --glob) + local glob_arg="${2:-}" + if [[ "$glob_arg" == "!"* ]]; then + local glob_path="${glob_arg#!}" + # grep --exclude matches against the basename, so reduce the + # exclusion to a filename pattern. If callers exclude paths + # like 'web/src/components/ui/Primitives.tsx', the basename + # 'Primitives.tsx' is the exclusion key. + extra_excludes+=("--exclude=$(basename "$glob_path")") + fi + shift 2 + ;; + *) + targets+=("$1") + shift + ;; + esac + done + grep -rnE "$pattern" "${targets[@]}" \ + --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" \ + --exclude="*.test.*" --exclude="*.spec.*" \ + --exclude-dir=node_modules --exclude-dir=.next \ + ${extra_excludes[@]+"${extra_excludes[@]}"} 2>/dev/null || true + fi +} + report() { local title="$1" local pattern="$2" shift 2 local matches - matches="$(rg -n "$pattern" "$@" --glob '!**/*.test.*' || true)" + matches="$(search "$pattern" "$@")" echo "=== $title ===" if [[ -z "$matches" ]]; then