Files
omarchycn/test/shell.d/mise-wrapper-quiet-migration-test.sh
535d8f3485 Regenerate mise wrappers that still print mise's output to stdout (#8041)
omarchy-mise-install gained --quiet on its `mise use -g` line so a wrapper
no longer prints mise's "tools: pkg@version" ahead of the tool's own
output. That only changes wrappers written from then on, and the migration
that installed the current ones is already marked complete, so every
wrapper already on disk keeps polluting stdout: `claude --version` still
answers with two lines, and a wrapper for a protocol-speaking command
answers with a line its caller cannot parse.

Rewrite them through omarchy-mise-install so the template stays in one
place. Wrappers were written by four different generated forms over time
and only the ones a later migration happened to regenerate moved forward,
so all four are recognized. The whole file has to match one of them
exactly, which leaves a wrapper someone has added a line to alone and
makes a second run a no-op.


Claude-Session: https://claude.ai/code/session_01Mv1FyKG2VGZRdtknQ7YjU8

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 14:36:09 +02:00

161 lines
6.1 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"
migration="$ROOT/migrations/1787573629.sh"
test_dir=$(mktemp -d)
trap 'rm -rf "$test_dir"' EXIT
home="$test_dir/home"
bin_dir="$home/.local/bin"
mkdir -p "$bin_dir"
# The migration calls omarchy-mise-install to rewrite a wrapper, so the real
# one has to be reachable: this proves the template it writes today, not a
# copy of it that could drift.
run_migration() {
HOME="$home" PATH="$ROOT/bin:$PATH" bash -euo pipefail "$migration" >/dev/null
}
write_stale_wrapper() {
local command=$1 package=$2 bin=$3
cat >"$bin_dir/$command" <<EOF
#!/bin/bash
export MISE_MINIMUM_RELEASE_AGE=0
mise use -g "$package" || exit 1
exec mise x "$package" -- "$bin" "\$@"
EOF
chmod +x "$bin_dir/$command"
}
# The template before MISE_MINIMUM_RELEASE_AGE was added. A wrapper installed
# by hand for a custom tool can still be on this form.
write_pre_export_wrapper() {
local command=$1 package=$2 bin=$3
cat >"$bin_dir/$command" <<EOF
#!/bin/bash
mise use -g "$package" || exit 1
exec mise x "$package" -- "$bin" "\$@"
EOF
chmod +x "$bin_dir/$command"
}
write_stale_wrapper claude claude claude
write_stale_wrapper omp github:can1357/oh-my-pi omp
write_stale_wrapper ghui npm:@kitlangton/ghui ghui
write_pre_export_wrapper custom-tool "github:someone/custom-tool" custom-tool
# The form omarchy-mise-install wrote when the earlier PATH-recursion migration
# ran, and the one before that. Neither carries `|| exit 1`.
cat >"$bin_dir/mise-exec-era" <<'EOF'
#!/bin/bash
mise use -g "npm:some/tool"
exec mise exec "npm:some/tool" -- "tool-bin" "$@"
EOF
cat >"$bin_dir/bare-exec-era" <<'EOF'
#!/bin/bash
mise use -g "aqua:some/other"
exec "other-bin" "$@"
EOF
chmod +x "$bin_dir/mise-exec-era" "$bin_dir/bare-exec-era"
run_migration
grep -qF 'mise use -g --quiet "claude" || exit 1' "$bin_dir/claude" ||
fail "migration adds --quiet to a stale wrapper"
pass "migration adds --quiet to a stale wrapper"
grep -qF 'mise use -g --quiet "github:can1357/oh-my-pi" || exit 1' "$bin_dir/omp" ||
fail "migration keeps a wrapper's package when the command name differs"
grep -qF 'exec mise x "github:can1357/oh-my-pi" -- "omp" "$@"' "$bin_dir/omp" ||
fail "migration keeps a wrapper's bin name when the command name differs"
pass "migration preserves package and bin names"
grep -qF 'exec mise x "npm:@kitlangton/ghui" -- "ghui" "$@"' "$bin_dir/ghui" ||
fail "migration preserves a scoped npm package name"
pass "migration preserves a scoped npm package name"
grep -qF 'mise use -g --quiet "github:someone/custom-tool" || exit 1' "$bin_dir/custom-tool" ||
fail "migration rewrites a wrapper on the pre-export template"
grep -qF 'export MISE_MINIMUM_RELEASE_AGE=0' "$bin_dir/custom-tool" ||
fail "migration brings a pre-export wrapper up to the current template"
pass "migration rewrites wrappers on the pre-export template"
grep -qF 'mise use -g --quiet "npm:some/tool" || exit 1' "$bin_dir/mise-exec-era" ||
fail "migration rewrites a wrapper on the mise-exec template"
grep -qF 'exec mise x "npm:some/tool" -- "tool-bin" "$@"' "$bin_dir/mise-exec-era" ||
fail "migration keeps the bin name from a mise-exec wrapper"
grep -qF 'mise use -g --quiet "aqua:some/other" || exit 1' "$bin_dir/bare-exec-era" ||
fail "migration rewrites a wrapper on the bare-exec template"
grep -qF 'exec mise x "aqua:some/other" -- "other-bin" "$@"' "$bin_dir/bare-exec-era" ||
fail "migration keeps the bin name from a bare-exec wrapper"
pass "migration rewrites every generated form that predates --quiet"
[[ -x $bin_dir/claude ]] || fail "migration leaves the rewritten wrapper executable"
pass "migration leaves the rewritten wrapper executable"
# Running twice must not touch an already-quiet wrapper.
before=$(cat "$bin_dir/claude")
run_migration
[[ $(cat "$bin_dir/claude") == "$before" ]] || fail "migration is idempotent"
pass "migration is idempotent"
# Anything the generator did not write is the user's own file.
cat >"$bin_dir/hand-written" <<'EOF'
#!/bin/bash
export MISE_MINIMUM_RELEASE_AGE=0
mise use -g "something" || exit 1
echo "and then something else entirely"
EOF
cat >"$bin_dir/mismatched" <<'EOF'
#!/bin/bash
export MISE_MINIMUM_RELEASE_AGE=0
mise use -g "one-package" || exit 1
exec mise x "another-package" -- "bin" "$@"
EOF
# A generated wrapper someone added a line to. Regenerating would drop that
# line, so the exact-match check has to leave the whole file alone.
cat >"$bin_dir/customized" <<'EOF'
#!/bin/bash
export MISE_MINIMUM_RELEASE_AGE=0
export SOME_TOKEN=abc123
mise use -g "customized" || exit 1
exec mise x "customized" -- "customized" "$@"
EOF
printf '#!/bin/bash\necho hi\n' >"$bin_dir/unrelated"
# uv and uvx land in ~/.local/bin from the Python dev env. A wrapper is a few
# short lines, so a real binary must be skipped on size, never read in whole.
head -c 5000000 /dev/urandom >"$bin_dir/uv"
chmod +x "$bin_dir/uv"
ln -s "$bin_dir/claude" "$bin_dir/linked"
hand_written_before=$(cat "$bin_dir/hand-written")
mismatched_before=$(cat "$bin_dir/mismatched")
unrelated_before=$(cat "$bin_dir/unrelated")
customized_before=$(cat "$bin_dir/customized")
run_migration
[[ $(cat "$bin_dir/hand-written") == "$hand_written_before" ]] ||
fail "migration leaves a hand-written script that calls mise alone"
[[ $(cat "$bin_dir/mismatched") == "$mismatched_before" ]] ||
fail "migration leaves a wrapper whose two lines disagree alone"
[[ $(cat "$bin_dir/unrelated") == "$unrelated_before" ]] ||
fail "migration leaves an unrelated script alone"
[[ $(cat "$bin_dir/customized") == "$customized_before" ]] ||
fail "migration leaves a generated wrapper a user has added a line to alone"
[[ -L $bin_dir/linked ]] || fail "migration leaves a symlink alone"
[[ $(stat -c%s "$bin_dir/uv") -eq 5000000 ]] || fail "migration leaves a native binary alone"
pass "migration only rewrites wrappers it recognizes"
# A machine with no ~/.local/bin at all must not fail the run.
empty_home="$test_dir/empty-home"
mkdir -p "$empty_home"
HOME="$empty_home" PATH="$ROOT/bin:$PATH" bash -euo pipefail "$migration" >/dev/null ||
fail "migration succeeds when ~/.local/bin is missing"
pass "migration succeeds when ~/.local/bin is missing"