scripts/dev/lp-cli-argv-test builds stubs from the real invocation line in
init.sh and the real LP_CLI_ARGS line in start.sh, then pushes thirteen app
names through them — so editing either file is what makes it fail. Verified
against both regressions: dropping "$@" from the wrapper, and reading "$@"
instead of "${@:10}" in start.sh.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
87 lines
3.9 KiB
Bash
Executable File
87 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# Does an open-ended list of app names survive the trip from the command line
|
|
# into a CLI handler? Runs in $TMPDIR against stubs built from the REAL lines in
|
|
# init.sh and start.sh, so editing either is what makes this fail.
|
|
#
|
|
# scripts/dev/lp-cli-argv-test
|
|
#
|
|
# The path has two independent chokepoints, and fixing one hid the other:
|
|
#
|
|
# 1. the root wrapper (baked from init.sh) invokes start.sh with exactly nine
|
|
# hardcoded positional slots, unset ones filled with the literal "empty"
|
|
# 2. the CLI dispatcher calls its handlers with NO arguments, so "$@" and
|
|
# `shift` inside a handler operate on an empty list
|
|
#
|
|
# LP_CLI_ARGS was added for (2) but built from start.sh's "$@" — which (1) had
|
|
# already capped at nine. `restore first-run bulk` reads "${LP_CLI_ARGS[@]:5}",
|
|
# so a 13-app restore arrived as four, restored four, and reported success.
|
|
#
|
|
# Thirteen is the fixture size for a reason: it is what a real host had.
|
|
|
|
REPO="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
BASE="$(mktemp -d "${TMPDIR:-/tmp}/lp-cli-argv-test-XXXXXX")"
|
|
trap 'rm -rf "$BASE"' EXIT
|
|
|
|
fail=0
|
|
chk(){ if [[ "$2" == "$3" ]]; then echo " ok $1"; else echo " FAIL $1: got '$2' want '$3'"; fail=1; fi; }
|
|
|
|
# --- the two real lines under test -------------------------------------------
|
|
invoke=$(grep -E '^\s*\./start\.sh "\$command1"' "$REPO/init.sh" | head -1)
|
|
capture=$(grep -E '^declare -a LP_CLI_ARGS=' "$REPO/start.sh" | head -1)
|
|
[[ -n "$invoke" ]] || { echo " FAIL could not find the start.sh invocation in init.sh"; exit 1; }
|
|
[[ -n "$capture" ]] || { echo " FAIL could not find LP_CLI_ARGS in start.sh"; exit 1; }
|
|
|
|
# --- stub start.sh: the real capture line, then report what a handler sees ----
|
|
{
|
|
echo '#!/bin/bash'
|
|
echo "$capture"
|
|
# Offsets as the real handlers use them: :5 for `restore first-run bulk`
|
|
# (restore first-run bulk <idx> <host> app…), :4 for `restore preflight`.
|
|
echo 'bulk=(); for a in "${LP_CLI_ARGS[@]:5}"; do [[ -z "$a" || "$a" == "empty" ]] && continue; bulk+=("$a"); done'
|
|
echo 'pref=(); for a in "${LP_CLI_ARGS[@]:4}"; do [[ -z "$a" || "$a" == "empty" ]] && continue; pref+=("$a"); done'
|
|
echo 'echo "BULK=${#bulk[@]}:${bulk[*]}"'
|
|
echo 'echo "PREF=${#pref[@]}"'
|
|
echo 'echo "SLOT1=$1 SLOT5=$5 SLOT9=$9"'
|
|
} > "$BASE/start.sh"
|
|
chmod +x "$BASE/start.sh"
|
|
|
|
# --- stub wrapper: the nine slots exactly as the real one builds them ---------
|
|
{
|
|
echo '#!/bin/bash'
|
|
for i in $(seq 1 9); do echo "command$i=\"\${$i:-empty}\""; done
|
|
echo 'script_dir="$(dirname "$0")"'
|
|
echo 'cd "$script_dir"'
|
|
echo "$invoke"
|
|
} > "$BASE/wrapper"
|
|
chmod +x "$BASE/wrapper"
|
|
|
|
APPS=(bookstack grafana matrix mattermost navidrome nextcloud prometheus
|
|
rocketchat speedtest stalwart stoat trivy vikunja)
|
|
|
|
echo "--- 13 app names through 'restore first-run bulk' ---"
|
|
out=$("$BASE/wrapper" restore first-run bulk 2 QuantumOtter "${APPS[@]}")
|
|
bulk=$(sed -n 's/^BULK=\([0-9]*\):.*/\1/p' <<< "$out")
|
|
names=$(sed -n 's/^BULK=[0-9]*://p' <<< "$out")
|
|
chk "count" "$bulk" "13"
|
|
chk "first app" "${names%% *}" "bookstack"
|
|
chk "last app" "${names##* }" "vikunja"
|
|
|
|
echo "--- the nine legacy slots still behave as before ---"
|
|
# argv here is: restore(1) first-run(2) bulk(3) 2(4) QuantumOtter(5)
|
|
# bookstack(6) grafana(7) matrix(8) mattermost(9) — so slot 9 is the fourth app,
|
|
# which is exactly the cap that made a 13-app restore into a 4-app one.
|
|
slots=$(sed -n 's/^SLOT1=//p' <<< "$out")
|
|
chk "slots" "$slots" "restore SLOT5=QuantumOtter SLOT9=mattermost"
|
|
|
|
echo "--- unset slots still arrive as the literal \"empty\", and are dropped ---"
|
|
out=$("$BASE/wrapper" restore preflight 2 QuantumOtter)
|
|
chk "no phantom apps" "$(sed -n 's/^PREF=//p' <<< "$out")" "0"
|
|
|
|
echo "--- an explicit six, which used to be capped at five ---"
|
|
out=$("$BASE/wrapper" restore preflight 2 QuantumOtter "${APPS[@]:0:6}")
|
|
chk "count" "$(sed -n 's/^PREF=//p' <<< "$out")" "6"
|
|
|
|
echo ""
|
|
if (( fail )); then echo "FAILED"; exit 1; fi
|
|
echo "All argv checks passed."
|