whiskers.git / tools / check-private.sh
1#!/usr/bin/env bash

Fail if any tracked file contains a term from .private-terms. See tools/README.md.

tools/check-private.sh [terms-file]      (default: .private-terms at the repository root)

One term per line, matched case-insensitively as a fixed string; blank lines and lines starting with # are ignored. The terms file is gitignored and never committed. Prints file:line for each hit (not the matching text, so the output does not itself spread the term), exit 1 on any.

9set -euo pipefail
10cd "$(dirname "$0")/.."
11terms="${1:-.private-terms}"
12if [ ! -f "$terms" ]; then
13  if [ "${WHISKERS_REQUIRE_PRIVATE_TERMS:-0}" = 1 ]; then
14    echo "check-private: $terms is missing and WHISKERS_REQUIRE_PRIVATE_TERMS=1" >&2
15    exit 2
16  fi
17  echo "check-private: no $terms; nothing to check against (see tools/README.md)" >&2
18  exit 0
19fi
20patterns="$(mktemp)"
21trap 'rm -f "$patterns"' EXIT
22grep -v -e '^[[:space:]]*$' -e '^[[:space:]]*#' "$terms" | sed 's/\r$//' > "$patterns" || true
23if [ ! -s "$patterns" ]; then
24  echo "check-private: $terms has no terms" >&2
25  exit 0
26fi

-I skips binary files, -n gives line numbers; -o is not used so the term is not echoed.

28hits="$(git grep -I -n -i -F -f "$patterns" -- . ':!.private-terms' | cut -d: -f1,2 || true)"

Binary files (screenshots) are checked by name only.

30names="$(git ls-files | grep -i -F -f "$patterns" | sed 's/$/:0 (file name)/' || true)"
31all="$(printf '%s\n%s\n' "$hits" "$names" | sed '/^$/d')"
32if [ -n "$all" ]; then
33  echo "check-private: a private term appears in tracked files:" >&2
34  echo "$all" >&2
35  exit 1
36fi
37echo "check-private: clean ($(wc -l < "$patterns") term(s) checked)"