testsAndMisc/meta/scripts/report_live_state.sh
Krzysztof kuhy Rudnicki b50b146dad report_live_state: also scan installed scripts under /usr/local
Found while surveying system-maintenance: /usr/local/bin holds copies
that hardcode repo paths, and no section of the inventory looked there.
The installed copy is what actually runs, so grepping the repo for its
own paths never finds them.

Three were invisible until now:

  periodic-system-maintenance.sh  3 paths into digital_wellbeing + hosts
  hosts-file-monitor.sh           1 path into hosts
  wsg-grabber                     PYTHONPATH into the repo root

The first runs hourly, which means the two subsystem extractions coming
next have to reinstall it -- editing the repo copy alone would leave the
live one pointing at a directory that no longer exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 17:44:10 +02:00

139 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# ============================================================================
# Report every place on this machine that points into this repo.
#
# The restructure moves whole subtrees out of testsAndMisc. Anything that
# names a path inside the repo - a systemd unit, an /etc config, a symlink on
# PATH - keeps pointing at the old location and breaks silently once the
# target moves. This script is the checklist: run it before a move to record
# what must be repointed, and after a move to prove nothing was missed.
#
# report_live_state.sh # human-readable report
# report_live_state.sh --check # exit 1 if anything still points here
#
# --check is the post-move gate. A clean run means no live reference remains.
# ============================================================================
set -euo pipefail
SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_NAME
readonly REPO="${REPO:-$HOME/testsAndMisc}"
CHECK_ONLY=0
usage() {
echo "Usage: $SCRIPT_NAME [--check]"
echo "Options:"
echo " --check Exit 1 if any live reference into the repo remains"
echo " -h, --help Show this help"
exit 0
}
# Units whose ExecStart/WorkingDirectory/Environment names a repo path.
# Root units need no privilege to read; user units live under $HOME.
report_systemd() {
echo "## systemd units"
local found=0 unit
while IFS= read -r unit; do
[[ -n "$unit" ]] || continue
found=1
printf ' %s\n' "$unit"
grep -n "$REPO\|%h/testsAndMisc" "$unit" | sed 's/^/ /'
done < <(grep -rl "$REPO\|%h/testsAndMisc" \
/etc/systemd/system "$HOME/.config/systemd/user" 2>/dev/null | sort)
((found)) || echo " (none)"
return "$found"
}
# Non-unit config under /etc that hardcodes a repo path (guard-lib targets,
# sudoers drop-ins, pacman hooks).
report_etc() {
echo "## /etc references"
local found=0 path
while IFS= read -r path; do
[[ -n "$path" ]] || continue
case "$path" in */systemd/*) continue ;; esac
found=1
printf ' %s\n' "$path"
grep -n "$REPO" "$path" 2>/dev/null | sed 's/^/ /'
done < <(grep -rl "$REPO" /etc 2>/dev/null | sort)
((found)) || echo " (none)"
return "$found"
}
# Scripts INSTALLED outside the repo that name a path inside it. These are the
# easiest references to miss: the copy under /usr/local/bin is what actually
# runs, so grepping the repo for its own paths never finds them, and a stale
# one fails at whatever hour its timer next fires.
report_installed() {
echo "## installed scripts referencing the repo"
local found=0 path
while IFS= read -r path; do
[[ -n "$path" ]] || continue
found=1
printf ' %s\n' "$path"
grep -n "$REPO" "$path" 2>/dev/null | sed 's/^/ /'
done < <(grep -rl "$REPO" /usr/local/bin /usr/local/lib 2>/dev/null | sort)
((found)) || echo " (none)"
return "$found"
}
# Symlinks anywhere in $HOME resolving into the repo: i3blocks, ~/.local/bin,
# oh-my-zsh custom. Depth 4 covers every known location without walking the
# whole home directory.
report_symlinks() {
echo "## symlinks into the repo"
local found=0 link target
while IFS= read -r link; do
[[ -n "$link" ]] || continue
found=1
target="$(readlink "$link")"
printf ' %s -> %s\n' "$link" "$target"
done < <(find "$HOME" -maxdepth 4 -type l -lname "*testsAndMisc*" \
-not -path "$REPO/*" 2>/dev/null | sort)
((found)) || echo " (none)"
return "$found"
}
main() {
local any=0
report_systemd || any=1
echo
report_etc || any=1
echo
report_installed || any=1
echo
report_symlinks || any=1
if ((CHECK_ONLY)); then
if ((any)); then
echo
echo "$SCRIPT_NAME: live references into $REPO remain (see above)" >&2
return 1
fi
echo
echo "$SCRIPT_NAME: no live reference points into $REPO"
fi
return 0
}
while [[ $# -gt 0 ]]; do
case "$1" in
--check)
CHECK_ONLY=1
shift
;;
-h | --help)
usage
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
main