#!/bin/bash # chezmoi is how dotup ARRIVES, so "it must already be here" is the natural # assumption -- and it is wrong often enough to have broken a real install. # # get.chezmoi.io installs to ./bin RELATIVE TO THE CWD when -b is not given, # which is exactly what the README's one-liner does. Run it from $HOME and the # binary lands in ~/bin; run it from /workspace, as anyone in a container does, # and it lands in /workspace/bin. Neither is on PATH, and the private tier then # failed with `chezmoi: not found` AFTER writing the bws token -- half # configured, at the very last step, having already spent the password. # # So this scenario puts the machine in exactly that state -- chezmoi nowhere # find_tool looks -- and asks two questions: # # does dotup install one, before asking for anything? # and if it CANNOT, does it say so before the password rather than after? # # It cannot be a unit test on a developer box: find_tool probes # /home/linuxbrew/.linuxbrew/bin by absolute path, and any box with linuxbrew # satisfies the lookup no matter what PATH says. A container has no such # directory, so absence here is real. set -u fail() { echo "FAIL: $*"; exit 1; } ok() { echo " ok $*"; } # ---- public tier first, unaided, exactly as the README says ------------------ sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply "$PUB_URL" >/tmp/init.log 2>&1 \ || { tail -20 /tmp/init.log; fail "public tier init"; } D=$HOME/.local/bin/dotup [ -x "$D" ] || fail "no dotup after the public apply" ok "public tier applied" # ---- now take chezmoi away, everywhere find_tool looks ---------------------- for c in "$HOME/.local/bin/chezmoi" "$HOME/bin/chezmoi" "$HOME/.npm-global/bin/chezmoi" \ /usr/local/bin/chezmoi /usr/local/go/bin/chezmoi \ /home/linuxbrew/.linuxbrew/bin/chezmoi /opt/homebrew/bin/chezmoi; do [ -e "$c" ] && { sudo rm -f "$c" || rm -f "$c"; } done command -v chezmoi >/dev/null 2>&1 && fail "chezmoi is still on PATH; the state under test never happened" for c in "$HOME/.local/bin/chezmoi" "$HOME/bin/chezmoi" "$HOME/.npm-global/bin/chezmoi" \ /usr/local/bin/chezmoi /usr/local/go/bin/chezmoi \ /home/linuxbrew/.linuxbrew/bin/chezmoi /opt/homebrew/bin/chezmoi; do [ -e "$c" ] && fail "chezmoi is still at $c -- find_tool would find it" done ok "chezmoi is absent from every place find_tool looks" # ---- tick the row that needs it, and answer q at the first prompt ------------ # `q` is enough: ensure_chezmoi runs BEFORE the prompt on purpose, so whatever # it did has already happened by the time the first question is asked. S=${XDG_CONFIG_HOME:-$HOME/.config}/dotfiles mkdir -p "$S"; printf 'private/private-repo\n' > "$S/selected" printf 'q\n' | timeout 180 script -q -c "$D private" /dev/null >/tmp/priv.log 2>&1 rc=$? out=$(tr -d '\r' /dev/null 2>&1 || fail "the installed chezmoi does not run" ok "the installed chezmoi is a working binary" # The ordering that makes the failure survivable: chezmoi is resolved BEFORE # anything is asked for. If it can only be discovered missing afterwards, the # password has been spent and the token is already on disk. a=$(printf '%s\n' "$out" | grep -n 'installing it' | head -1 | cut -d: -f1) b=$(printf '%s\n' "$out" | grep -n 'Bootstrap URL' | head -1 | cut -d: -f1) [ -n "$a" ] && [ -n "$b" ] && [ "$a" -lt "$b" ] \ || fail "chezmoi was not resolved before the first prompt (installing=$a prompt=$b)" ok "chezmoi was resolved before the first question was asked" case $out in *"public-only machine"*) ok "q at the prompt left a public-only machine" ;; *) fail "q was not accepted at the URL prompt" ;; esac echo "CHEZMOI-ABSENT PASS"