80 lines
3.2 KiB
Bash
80 lines
3.2 KiB
Bash
#!/bin/sh
|
|||
|
|
# Print a table of tool versions: pinned (.tools/bin -- what make targets use,
|
||
|
|
# because the Makefile prepends it to recipe PATH) vs PATH-first (what your own
|
||
|
|
# shell resolves outside make).
|
||
|
|
#
|
||
|
|
# scripts/tool_versions.sh informational; always exits 0
|
||
|
|
# scripts/tool_versions.sh --strict exit 1 if a pinned tool is missing or
|
||
|
|
# has the wrong version (used by `make
|
||
|
|
# preflight`, which runs before
|
||
|
|
# all/serve/serve-lan)
|
||
|
|
set -u
|
||
|
|
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||
|
|
BIN="$ROOT/.tools/bin"
|
||
|
|
MODE=${1:-}
|
||
|
|
|
||
|
|
HUGO_PIN="v0.167.0+extended"
|
||
|
|
NODE_PIN="v22.11.0"
|
||
|
|
LYCHEE_PIN="0.24.2"
|
||
|
|
|
||
|
|
# PATH with .tools/bin stripped, so "PATH-first" shows what the user's shell
|
||
|
|
# would resolve, even though make exported .tools/bin into our PATH.
|
||
|
|
SYSPATH=$(printf '%s' "$PATH" | tr ':' '\n' | grep -vx "$BIN" | tr '\n' ':' | sed 's/:$//')
|
||
|
|
|
||
|
|
pinned_ver() {
|
||
|
|
case "$1" in
|
||
|
|
# hugo release builds report "v<ver>-<40-hex-commit>+extended"; strip the commit
|
||
|
|
hugo) [ -x "$BIN/hugo" ] && "$BIN/hugo" version 2>/dev/null | awk '{print $2}' | sed 's/-[0-9a-f]\{40,\}//' ;;
|
||
|
|
node) [ -x "$BIN/node" ] && "$BIN/node" --version 2>/dev/null ;;
|
||
|
|
npx) [ -x "$BIN/npx" ] && "$BIN/npx" --version 2>/dev/null ;;
|
||
|
|
lychee) [ -x "$BIN/lychee" ] && "$BIN/lychee" --version 2>/dev/null | awk '{print $2}' ;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
first_path() { PATH="$SYSPATH" command -v "$1" 2>/dev/null; }
|
||
|
|
|
||
|
|
first_ver() { # first_ver <tool> <path>
|
||
|
|
[ -n "${2:-}" ] || return 0
|
||
|
|
case "$1" in
|
||
|
|
hugo) "$2" version 2>/dev/null | awk '{print $2}' | sed 's/-[0-9a-f]\{40,\}//' ;;
|
||
|
|
node) "$2" --version 2>/dev/null ;;
|
||
|
|
npx) "$2" --version 2>/dev/null ;;
|
||
|
|
lychee) "$2" --version 2>/dev/null | awk '{print $2}' ;;
|
||
|
|
python3) "$2" --version 2>/dev/null | awk '{print $2}' ;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
if [ "$MODE" = "--strict" ]; then
|
||
|
|
fail=0
|
||
|
|
[ "$(pinned_ver hugo)" = "$HUGO_PIN" ] || { echo "preflight: pinned hugo $HUGO_PIN missing/wrong in $BIN" >&2; fail=1; }
|
||
|
|
[ "$(pinned_ver node)" = "$NODE_PIN" ] || { echo "preflight: pinned node $NODE_PIN missing/wrong in $BIN" >&2; fail=1; }
|
||
|
|
[ -n "$(pinned_ver npx)" ] || { echo "preflight: pinned npx missing in $BIN" >&2; fail=1; }
|
||
|
|
[ "$(pinned_ver lychee)" = "$LYCHEE_PIN" ] || { echo "preflight: pinned lychee $LYCHEE_PIN missing/wrong in $BIN" >&2; fail=1; }
|
||
|
|
command -v python3 >/dev/null 2>&1 || { echo "preflight: python3 not found on PATH (needed by serve-lan)" >&2; fail=1; }
|
||
|
|
if [ "$fail" = 1 ]; then
|
||
|
|
echo "preflight: fix with: make bootstrap" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo "preflight: OK (pinned toolchain present in $BIN)"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
row() { # row <tool> <pinned disp> <first disp> <first path>
|
||
|
|
printf '%-8s %-27s %-27s %s\n' "$1" "$2" "$3" "${4:--}"
|
||
|
|
}
|
||
|
|
|
||
|
|
echo "tool pinned (.tools/bin) PATH-first (your shell)"
|
||
|
|
for t in hugo node npx lychee; do
|
||
|
|
pv=$(pinned_ver "$t")
|
||
|
|
fp=$(first_path "$t")
|
||
|
|
fv=$(first_ver "$t" "$fp")
|
||
|
|
[ -n "$pv" ] || pv="(missing)"
|
||
|
|
[ -n "$fv" ] || fv="(not installed)"
|
||
|
|
row "$t" "$pv" "$fv" "$fp"
|
||
|
|
done
|
||
|
|
fp=$(first_path python3); fv=$(first_ver python3 "$fp")
|
||
|
|
[ -n "$fv" ] || fv="(not installed)"
|
||
|
|
row "python3" "(not pinned)" "$fv" "$fp"
|
||
|
|
echo
|
||
|
|
echo "make targets always use the pinned column. 'make bootstrap' installs it."
|