80 lines
2.5 KiB
Bash
Executable File
80 lines
2.5 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
|
|
for pkg in "${PACKAGES[@]}"; do
|
|
echo "--- stow --simulate: $pkg ---"
|
|
if stow --simulate --verbose=1 --dir="$REPO_ROOT" --target="$REPO_ROOT" "$pkg" >/dev/null 2>probe_err.txt; then
|
|
echo "ok: stow --simulate '$pkg' resolved without conflicts"
|
|
else
|
|
echo "FAIL: stow --simulate '$pkg'"
|
|
sed 's/^/ /' probe_err.txt
|
|
FAIL=$((FAIL+1))
|
|
fi
|
|
rm -f probe_err.txt
|
|
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 ]]
|