fix: resolve chezmoi instead of assuming it is on PATH
The private tier died with `chezmoi: not found` on a real install, AFTER the
bws token had been written -- half-configured, at the last step, password
already spent.
dotup arrives VIA chezmoi, so "it must be here already" is the natural
assumption. It is wrong: 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 is ~/bin/chezmoi; run it from /workspace, as anyone
in a container does, and it is /workspace/bin/chezmoi. Neither is on PATH, and
~/.local/bin is not either in bash -- the same gap that makes bare `dotup` fail
on a fresh box.
find_tool exists for precisely this and the call site bypassed it.
- find_tool now also searches $HOME/bin
- ensure_chezmoi resolves it, and installs to ~/.local/bin only if it truly
is absent, mirroring ensure_bws
- the init uses "$CHEZMOI", never the bare name
- resolution happens BEFORE the credential prompt, so this fails while it is
still free rather than after the password is spent
Verified by reproducing the exact scenario: installer run from /workspace, so
chezmoi lands in /workspace/bin and nothing on PATH can see it. Old code:
`chezmoi: not found`. New: detected, installed, prompt reached. Also confirmed
~/bin/chezmoi is found WITHOUT re-downloading, so the common case costs nothing.
113 -> 117.
This commit is contained in:
@@ -195,6 +195,23 @@ is "PRIV_CFG is not the default config path" "0" \
|
|||||||
is "the private source is locked down after clone" "1" \
|
is "the private source is locked down after clone" "1" \
|
||||||
"$(grep -c 'chmod -R go-rwx "\$PRIV_SRC"' $D)"
|
"$(grep -c 'chmod -R go-rwx "\$PRIV_SRC"' $D)"
|
||||||
|
|
||||||
|
printf '\n\033[1mchezmoi is not assumed to be on PATH\033[0m\n'
|
||||||
|
# dotup ARRIVES via chezmoi, so "it must be here already" is the natural
|
||||||
|
# assumption and it is wrong: get.chezmoi.io installs to ./bin relative to the
|
||||||
|
# CWD when -b is not given, which is what the README one-liner does. From
|
||||||
|
# /workspace that is /workspace/bin, on no PATH anywhere. The private tier died
|
||||||
|
# with `chezmoi: not found` AFTER writing the bws token.
|
||||||
|
is "nothing calls chezmoi by bare name" "0" \
|
||||||
|
"$(grep -cE '^[[:space:]]*chezmoi (init|apply|update)' $D)"
|
||||||
|
is "the init uses the resolved path" "1" \
|
||||||
|
"$(grep -cF '"$CHEZMOI" init --apply' $D)"
|
||||||
|
is "find_tool looks in ~/bin too" "1" \
|
||||||
|
"$(grep -cF '"$HOME/bin/$1"' $D)"
|
||||||
|
# Resolution happens before the prompt: discovering it afterwards means the
|
||||||
|
# password is spent and the token is already on disk.
|
||||||
|
is "chezmoi is resolved before the password is asked for" "yes" \
|
||||||
|
"$(awk '/ensure_chezmoi \|\|/{e=NR} /head_ "private tier"/{h=NR} END{print (e && h && e<h) ? "yes" : "no"}' $D)"
|
||||||
|
|
||||||
printf '\n\033[1ma wrong password is not a reinstall\033[0m\n'
|
printf '\n\033[1ma wrong password is not a reinstall\033[0m\n'
|
||||||
# The endpoint credentials are asked for at the very END of a run, after every
|
# The endpoint credentials are asked for at the very END of a run, after every
|
||||||
# package is installed. Any non-200 used to be fatal, so one mistyped character
|
# package is installed. Any non-200 used to be fatal, so one mistyped character
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ have() { find_tool "$1" >/dev/null 2>&1; }
|
|||||||
# moment dotup exits.
|
# moment dotup exits.
|
||||||
find_tool() {
|
find_tool() {
|
||||||
command -v "$1" 2>/dev/null && return 0
|
command -v "$1" 2>/dev/null && return 0
|
||||||
for ft_c in "$HOME/.local/bin/$1" "$HOME/.npm-global/bin/$1" \
|
for ft_c in "$HOME/.local/bin/$1" "$HOME/bin/$1" "$HOME/.npm-global/bin/$1" \
|
||||||
"/usr/local/bin/$1" "/usr/local/go/bin/$1" \
|
"/usr/local/bin/$1" "/usr/local/go/bin/$1" \
|
||||||
"/home/linuxbrew/.linuxbrew/bin/$1" "/opt/homebrew/bin/$1"; do
|
"/home/linuxbrew/.linuxbrew/bin/$1" "/opt/homebrew/bin/$1"; do
|
||||||
[ -x "$ft_c" ] && { printf '%s\n' "$ft_c"; return 0; }
|
[ -x "$ft_c" ] && { printf '%s\n' "$ft_c"; return 0; }
|
||||||
@@ -392,6 +392,29 @@ BWS_PIN=2.1.0
|
|||||||
#
|
#
|
||||||
# So it lives here, called from cmd_private beside the token it exists to read.
|
# So it lives here, called from cmd_private beside the token it exists to read.
|
||||||
# Nothing installs bws unless something is about to hand it a token.
|
# Nothing installs bws unless something is about to hand it a token.
|
||||||
|
# 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 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 resolve it the way every other tool here is resolved, and install it if it
|
||||||
|
# genuinely is not present. CHEZMOI holds the resolved path; nothing calls the
|
||||||
|
# bare name.
|
||||||
|
CHEZMOI=chezmoi
|
||||||
|
ensure_chezmoi() {
|
||||||
|
if CHEZMOI=$(find_tool chezmoi); then return 0; fi
|
||||||
|
say " chezmoi is not on PATH or in the usual places — installing it"
|
||||||
|
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$HOME/.local/bin" >/dev/null 2>&1 \
|
||||||
|
|| { err "the chezmoi installer failed"; return 1; }
|
||||||
|
CHEZMOI=$(find_tool chezmoi) || { err "chezmoi still not found after installing it"; return 1; }
|
||||||
|
say " chezmoi installed to ~/.local/bin"
|
||||||
|
}
|
||||||
|
|
||||||
ensure_bws() {
|
ensure_bws() {
|
||||||
have bws && { say " bws $(bws --version 2>/dev/null | awk '{print $2}') already present"; return 0; }
|
have bws && { say " bws $(bws --version 2>/dev/null | awk '{print $2}') already present"; return 0; }
|
||||||
command -v unzip >/dev/null 2>&1 || { err "bws needs unzip; install it and re-run"; return 1; }
|
command -v unzip >/dev/null 2>&1 || { err "bws needs unzip; install it and re-run"; return 1; }
|
||||||
@@ -778,6 +801,14 @@ cmd_private() {
|
|||||||
[ ! -r "$BWS_TOKEN" ] || { say " bws token already present"; want_bws=0; }
|
[ ! -r "$BWS_TOKEN" ] || { say " bws token already present"; want_bws=0; }
|
||||||
[ "$want_repo" -eq 1 ] || [ "$want_bws" -eq 1 ] || return 0
|
[ "$want_repo" -eq 1 ] || [ "$want_bws" -eq 1 ] || return 0
|
||||||
|
|
||||||
|
# Resolve chezmoi BEFORE asking for anything. It is needed only for the repo
|
||||||
|
# row, but finding out it is missing afterwards means the password has already
|
||||||
|
# been typed and spent, the bws token is already on disk, and the machine is
|
||||||
|
# left half-configured at the last step. Fail before the prompt or not at all.
|
||||||
|
if [ "$want_repo" -eq 1 ]; then
|
||||||
|
ensure_chezmoi || { err "the private repo cannot be cloned without chezmoi"; return 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
head_ "private tier"
|
head_ "private tier"
|
||||||
say " The address is in no repository. Leave it blank to stay public-only."
|
say " The address is in no repository. Leave it blank to stay public-only."
|
||||||
# Read into variables: nothing reaches argv, so nothing reaches `ps`.
|
# Read into variables: nothing reaches argv, so nothing reaches `ps`.
|
||||||
@@ -914,7 +945,7 @@ cmd_private() {
|
|||||||
else
|
else
|
||||||
printf '%s + chezmoi init --apply --source %s -c %s %s%s\n' \
|
printf '%s + chezmoi init --apply --source %s -c %s %s%s\n' \
|
||||||
"$DIM" "$PRIV_SRC" "$PRIV_CFG" "$(redact_url "$p_clean")" "$R" >&2
|
"$DIM" "$PRIV_SRC" "$PRIV_CFG" "$(redact_url "$p_clean")" "$R" >&2
|
||||||
chezmoi init --apply --source "$PRIV_SRC" -c "$PRIV_CFG" "$p_clean" \
|
"$CHEZMOI" init --apply --source "$PRIV_SRC" -c "$PRIV_CFG" "$p_clean" \
|
||||||
|| err "private repo init failed"
|
|| err "private repo init failed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user