feat: bootstrap.sh wraps the first command; the URL stays an argument

This commit is contained in:
bcherb2
2026-08-22 21:52:28 -04:00
parent 4043787a58
commit ea10ba9d4a
3 changed files with 52 additions and 0 deletions
+13
View File
@@ -1095,6 +1095,19 @@ else
printf ' \033[33mskip\033[0m needs python3 to open a pty\n' printf ' \033[33mskip\033[0m needs python3 to open a pty\n'
fi fi
printf '\n\033[1mbootstrap.sh — the first command, wrapped\033[0m\n'
B=$ROOT/bootstrap.sh
if sh -n "$B" 2>/dev/null; then ok "bootstrap.sh parses"; else no "bootstrap.sh has a syntax error"; fi
# The same property the phase 3 negative test asserts for the tier as a whole:
# this file ships in the public repo, so it names no real host, ever.
if grep -qEi 'djdadi|15\.204|xeta' "$B"; then no "bootstrap.sh names a real host"; else ok "bootstrap.sh names no real host"; fi
# No URL from argv, env, or a tty -> usage and exit 2, before curl runs.
rc=0; out=$(DOTFILES_URL= sh "$B" </dev/null 2>&1) || rc=$?
is "no URL anywhere is refused, not guessed" 2 "$rc"
has "…and says how to call it" "usage:" "$out"
rc=0; out=$(sh "$B" "" </dev/null 2>&1) || rc=$?
is "an empty argument is an error too, not a prompt hang" 2 "$rc"
printf '\n\033[1minteractive loop (needs a pty)\033[0m\n' printf '\n\033[1minteractive loop (needs a pty)\033[0m\n'
if command -v fzf >/dev/null && command -v curl >/dev/null && command -v script >/dev/null; then if command -v fzf >/dev/null && command -v curl >/dev/null && command -v script >/dev/null; then
out=$(sh ./listen-test.sh 2>/dev/null | tr -d '\r' || true) out=$(sh ./listen-test.sh 2>/dev/null | tr -d '\r' || true)
+7
View File
@@ -22,6 +22,13 @@ sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply <this repo url>
~/.local/bin/dotup ~/.local/bin/dotup
``` ```
The first line is also wrapped as `bootstrap.sh` in this repo, for anyone who
can fetch it raw but cannot remember chezmoi's incantation:
```sh
curl -fsSL <this repo raw url>/bootstrap.sh | sh -s -- <this repo url>
```
Two commands. The first lays down the files and clones the six externals; the Two commands. The first lays down the files and clones the six externals; the
second picks and installs the software. There is no third step, and nothing second picks and installs the software. There is no third step, and nothing
here prompts for anything. here prompts for anything.
Executable
+32
View File
@@ -0,0 +1,32 @@
#!/bin/sh
# bootstrap.sh -- the whole "first command" of a fresh machine, so nobody has
# to remember chezmoi's incantation. Everything after this is dotup's job.
#
# sh bootstrap.sh <public-repo-url> # or run it bare and answer the prompt
#
# The repo URL is an argument rather than a constant for the same reason the
# tests prompt for it: this tier is public and names no real host. Your own
# paste-ready line lives in the private repo's runbook.
set -u
URL=${1:-${DOTFILES_URL:-}}
# Prompt only when someone is there to answer: `curl | sh` and the test
# harness both arrive with stdin not a terminal, and must fail fast instead
# of hanging on a prompt nobody sees.
if [ -z "$URL" ] && [ -t 0 ]; then
printf 'Public repo clone URL: ' >&2
IFS= read -r URL || :
fi
[ -n "$URL" ] || { echo "usage: bootstrap.sh <public-repo-url>" >&2; exit 2; }
command -v curl >/dev/null 2>&1 \
|| { echo "bootstrap.sh: curl is required and not installed" >&2; exit 1; }
# Not fatal -- the public tier applies fine as root -- but brew-only packages
# (lazygit, omp, herdr) will refuse later, so say it now rather than then.
[ "$(id -u)" -ne 0 ] || echo "bootstrap.sh: running as root — Homebrew will refuse later; a normal user with sudo is the happy path" >&2
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply "$URL" || exit 1
echo
echo "next: ~/.local/bin/dotup (full path — this shell's PATH predates the install)"