Skip to content

Hotfix: empty if/then/fi syntax error + /lb chezmoi bootstrap URL#23

Merged
vaintrub merged 2 commits into
masterfrom
chore/secrets-architecture
May 17, 2026
Merged

Hotfix: empty if/then/fi syntax error + /lb chezmoi bootstrap URL#23
vaintrub merged 2 commits into
masterfrom
chore/secrets-architecture

Conversation

@vaintrub
Copy link
Copy Markdown
Owner

Summary

Two follow-ups to PR #22 that landed AFTER the squash merge:

Critical: empty if/then/fi syntax error

On a first apply (e.g. jetson via SSH after chezmoi update post-merge), gh is not on PATH yet — mise installs it during this same apply. The wrapper's {{ if lookPath "gh" }} guard evaluates false at template render time, so the inner gh-auth block is omitted entirely, producing a syntactically invalid empty if/then/fi:

if [ -z "${GITHUB_TOKEN:-}" ]; then
fi

Shell errors: Syntax error: "fi" unexpected. Apply aborts before mise even runs.

Fix: switch the gh check from template-time lookPath to runtime command -v gh. Rendered output is always syntactically valid; gh path picks up on subsequent applies once mise has installed gh — same intent as the original template guard, just deferred render→exec.

chezmoi bootstrap URL → get.chezmoi.io/lb

Default get.chezmoi.io URL installs chezmoi to ./bin/<binary> (CWD-relative). For a user running the one-liner from $HOME, that lands at ~/bin/chezmoi. Ubuntu's ~/.profile adds ~/bin to PATH only IF the directory exists at login time, so a fresh install creates the directory mid-session and the running shell never picks it up — chezmoi: command not found after the bootstrap. Bit me on jetson.

Switch all four bootstrap one-liners to chezmoi's /lb URL variant (documented at chezmoi.io/install — lb = local bin). Installs directly to ~/.local/bin/chezmoi, which is XDG-standard, included in PATH by both ~/.profile and ~/.zprofile on Ubuntu/Debian, and almost always pre-existing.

Why a separate PR

PR #22 was squash-merged before I caught either issue. Branch had two additional commits beyond the merge point.

Test plan

  • CI green on chore/secrets-architecture (run 25994759888)
  • chezmoi execute-template on the wrapper renders valid syntax in both gh on PATH and gh not on PATH cases
  • Jetson re-chezmoi update after merge → apply completes; pre-existing ~/bin/chezmoi migration documented for already-bitten machines (see commit msg)

Recovery for machines with ~/bin/chezmoi from the old URL

mv ~/bin/chezmoi ~/.local/bin/chezmoi
rmdir ~/bin 2>/dev/null

vaintrub added 2 commits May 17, 2026 16:19
Default `get.chezmoi.io` URL installs chezmoi to `./bin/<binary>` relative
to CWD — for a user running the one-liner from $HOME, that lands at
`~/bin/chezmoi`. Ubuntu's default ~/.profile has a conditional that adds
~/bin to PATH only IF the directory exists at login time, so a fresh
install creates the directory mid-session and the running shell never
picks it up. Result: `chezmoi: command not found` after the bootstrap.

Switch all four bootstrap one-liners to chezmoi's `/lb` URL variant
(documented at chezmoi.io/install — "lb" = local bin). That installs
directly to `~/.local/bin/chezmoi`, which:

  - is the XDG standard location for user-installed binaries
  - is added to PATH by both `~/.profile` and `~/.zprofile` on Ubuntu
    /Debian by default (modern stanzas check ~/.local/bin too)
  - already exists on most systems (cargo/pip --user/gem --user-install
    populate it), so the PATH conditional has fired at prior logins
  - matches where mise itself installs in our Linux bootstrap path
    (ensure-prereqs.sh curl-pipe → ~/.local/bin/mise)

No behavioural change in chezmoi itself; the binary works identically
once on PATH. Four references updated: README §Install (Mac + Linux),
§First-time bootstrap checklist, and AGENTS.md §"What this repo is".

Recovery for machines already bitten by the old one-liner:

    mv ~/bin/chezmoi ~/.local/bin/chezmoi
    rmdir ~/bin 2>/dev/null
On a first apply, `gh` isn't on PATH yet — mise installs it during this
same run. The template's `{{ if lookPath "gh" }}` guard evaluates false
at render time, so the inner gh-auth block is omitted entirely, producing
a syntactically invalid empty if/then/fi:

    if [ -z "${GITHUB_TOKEN:-}" ]; then
    fi

Shell errors out: `Syntax error: "fi" unexpected`. Hit by jetson on first
chezmoi update post-merge.

Fix: switch the gh check from template-time `lookPath` to runtime
`command -v gh`. Rendered output is always valid syntax; gh path picks up
on subsequent applies once mise has installed gh, exactly like the
original lookPath intent (just deferred from render to exec).

No CI change — apply-dev runs `chezmoi init --apply --promptDefaults`
which installs gh in the same step, but apply-dev was passing because
GITHUB_TOKEN was already set via env (cascade block returned early at the
outer `[ -z ]` check), masking the syntax error.
@vaintrub vaintrub merged commit 7085a87 into master May 17, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant