Files
dotfiles/test/probe_stow.sh
T

84 lines
2.6 KiB
Bash
Executable File

#!/bin/bash
# test/probe_stow.sh
#
# Verifies that each package the Makefile stows actually resolves and that
# stow can create all symlinks into the target without conflicts.
#
# This is a DRY RUN: it uses `stow --simulate` and creates no real symlinks.
# It catches bugs like `stow nvim` for a non-existent `nvim/` package.
#
# Usage:
# bash test/probe_stow.sh # probe every stow-able package
# bash test/probe_stow.sh <pkg>... # probe specific packages
set -uo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT" || exit 1
# A stow-able package is any tracked top-level directory that contains a
# dot-prefixed config subtree (or a dot-prefixed top-level file/dir).
tracked_basenames() {
git ls-files | awk -F/ 'NF>1 {print $1}' | sort -u
}
is_stowable() {
local pkg="$1"
[[ -d "$REPO_ROOT/$pkg" ]] || return 1
# stow needs at least one dot-prefixed entry at the package root
git ls-files "$pkg/" | grep -qE "^$pkg/\." || return 1
}
# Determine which packages to probe.
PACKAGES=()
if [[ $# -eq 0 ]]; then
while IFS= read -r b; do
[[ -z "$b" ]] && continue
is_stowable "$b" && PACKAGES+=("$b")
done < <(tracked_basenames)
else
PACKAGES=("$@")
fi
if [[ ${#PACKAGES[@]} -eq 0 ]]; then
echo "probe_stow.sh: no stow-able packages found" >&2
exit 1
fi
echo "== Probing stow packages: ${PACKAGES[*]} =="
FAIL=0
ERR_LOG="$(mktemp -t probe_stow.XXXXXX)"
cleanup() { rm -f "$ERR_LOG"; }
trap cleanup EXIT
for pkg in "${PACKAGES[@]}"; do
echo "--- stow --simulate: $pkg ---"
if stow --simulate --verbose=1 --dir="$REPO_ROOT" --target="$REPO_ROOT" "$pkg" >/dev/null 2>"$ERR_LOG"; then
echo "ok: stow --simulate '$pkg' resolved without conflicts"
else
echo "FAIL: stow --simulate '$pkg'"
sed 's/^/ /' "$ERR_LOG"
FAIL=$((FAIL+1))
fi
done
# Cross-check: does the Makefile stow anything that is NOT in our package set?
echo "== Checking Makefile stow targets against stow-able packages =="
make_pkgs="$(grep -P '^\t' Makefile | grep -oE 'stow [A-Za-z0-9_-]+' | awk '{print $2}' | sort -u)"
for mp in $make_pkgs; do
if is_stowable "$mp"; then
echo "ok: Makefile 'stow $mp' matches a stow-able package"
else
echo "FAIL: Makefile 'stow $mp' does not match a stow-able package"
FAIL=$((FAIL+1))
fi
done
echo
echo "=============================================="
echo "probe_stow.sh: $(( ${#PACKAGES[@]} + $(printf '%s\n' $make_pkgs | grep -c . || true) )) checks, $FAIL failed"
echo "=============================================="
[[ $FAIL -eq 0 ]]