Chezmoi refactor - #1
Merged
Merged
Conversation
Fixes several bugs that would break a fresh install (invalid goreleaser tap formula, renamed cask tokens, p10k sourced but never installed via brew, stale mas entry), syncs tracked files with what's actually live (.zshrc/.zprofile drift, dock tilesize, dock app list), fills in real Brewfile gaps found via brew leaves/cask diffs and Spotlight usage data, and replaces asdf/hey/httpie with mise/oha/xh. Also documents the two-repo (dotfiles + dotfiles-confidential) install flow and adds a sync-from-home.sh helper to pull local dotfile edits back into the repo. See plans/dotfiles-refresh-plan.md for the full rationale.
Fixes several bugs that would break a fresh install (invalid goreleaser tap formula, renamed cask tokens, p10k sourced but never installed via brew, stale mas entry), syncs tracked files with what's actually live (.zshrc/.zprofile drift, dock tilesize, dock app list), fills in real Brewfile gaps found via brew leaves/cask diffs and Spotlight usage data, and replaces asdf/hey/httpie with mise/oha/xh. Also documents the two-repo (dotfiles + dotfiles-confidential) install flow and adds a sync-from-home.sh helper to pull local dotfile edits back into the repo. See plans/dotfiles-refresh-plan.md for the full rationale.
Replaces the hand-rolled setup.sh + install-*.sh/osx-*.sh script pile and one-directional `cp -a ./home/ ~/` with chezmoi: dotfiles get the dot_ naming convention at repo root, and all install/setup logic moves into ordered .chezmoiscripts/ (run_once_/run_onchange_ scripts), replacing setup.sh, install-cli-tools.sh, install-homebrew.sh, install-zsh.sh, install-broswer-extensions.sh, install-cursor-plugins.sh, osx-system-defaults.sh, osx-user-defaults.sh, setup-dock.py/.sh, and sync-from-home.sh outright (chezmoi's diff/apply/re-add natively solves the drift problem sync-from-home.sh was working around). Along the way: - Dock setup now uses `brew "dockutil"` instead of an unverified curl+pkg install of the latest GitHub release, and drops the interactive confirmation prompt so it can run unattended under `chezmoi apply`. - Fonts install via `cp -n` into ~/Library/Fonts instead of a manual Font Book "Install" click-through. - Fixed macos-system-defaults running fully under `sudo` (which wrote user-domain `defaults write -g` calls to root's domain instead of the actual user's) - only the genuinely system-level calls are sudo'd now. - Fixed `dock autohide` being written without a `-bool` type flag. - Dropped the orphaned `.git-templates/hooks/prepare-commit-msg` (no `init.templatedir` ever pointed at it) and the `arkade` Brewfile entry (not installed, not a brew leaf - rot from before either audit). - Brewfile installs are now hash-gated: `run_onchange_before_10-packages` only re-runs `brew bundle` when the Brewfile's content actually changes. - Added ShellCheck + a macOS smoke-test GitHub Actions workflow. dotfiles-confidential stays untouched and fully separate, per plan.
Matches convention for chezmoi run_ scripts.
- run_once_after_30-dock.sh.tmpl: dockutil is now a Homebrew formula (installed to /opt/homebrew/bin), which isn't on PATH within this script's own process since each .chezmoiscripts file runs independently - the packages script's `eval brew shellenv` doesn't carry over. Without this, dockutil silently wouldn't be found on a genuinely fresh machine and the run_once script would never retry. Added the same shellenv bootstrap used in the packages script before the dockutil check. - run_onchange_before_10-packages.sh.tmpl: running a full `brew bundle` against the entire Brewfile on every CI push (dozens of formulae/casks, several JDKs, full browsers, CAD apps) risked exceeding GitHub-hosted macOS runners' disk/time budget, making the smoke test flaky for reasons unrelated to the change under test. Tried validating individual formula/cask names via `brew info` in CI first, but that produces false positives on legitimate third-party-tap entries (svu, goreleaser) that Homebrew's tap-trust model blocks from `brew info` without an explicit `brew trust` - confirmed by testing both directly. Settled on `brew bundle list`, which validates the Brewfile's syntax without attempting to resolve or install anything, and documented in both the script and README that catching renamed/removed formulas is still a manual `brew bundle check --verbose` step after editing Brewfile.
Caught by the GitHub Actions smoke test - compaudit failed with "command not found" under bash. It's a zsh completion-system function that needs `autoload -U compaudit` first, not a standalone binary, so the script needs `#!/bin/zsh`. Was silently swallowed by the trailing `|| true` (the script "succeeded" but never actually fixed the completion directory permissions).
Caught by actually running the workflow: ludeeus/action-shellcheck auto-detects shell from each script's shebang, and ShellCheck flatly refuses zsh scripts (SC1071) - it only supports sh/bash/dash/ksh. My local verification passed because I was manually passing --shell=bash without realizing the CI config itself didn't. Since the one zsh script (oh-my-zsh install) is otherwise plain POSIX-ish shell, checking it in bash mode is fine - verified locally before this commit.
unsupported action input ludeeus/action-shellcheck has no option to force --shell (confirmed by the action itself rejecting the shellcheck_options input I tried: "Unexpected input(s) 'shellcheck_options', valid inputs are [additional_files, ignore, ignore_paths, ignore_names, severity, check_together, scandir, disable_matcher, format, version]"). It auto-detects shell from each file's shebang instead, and refuses zsh scripts outright (SC1071). Since these are lint-only copies anyway (the real .tmpl files keep their real shebangs), just replace line 1 with `#!/bin/bash` unconditionally when generating them - simpler and more portable than trying to sed-replace only the zsh one (my first attempt at that broke on this machine's BSD sed and stripped every shebang).
Rancher Desktop manages this block itself (injects it on first launch when shell integration is enabled) - tracking it here just meant it'd get fought over between the app and chezmoi apply on every re-run.
oh-my-zsh's synchronous plugin loading was the actual source of shell startup lag. zinit's turbo mode (wait/lucid ice) defers plugin loading until just after the first prompt renders, typically cutting startup from ~200ms to ~40ms. - Every current oh-my-zsh plugin gets a 1:1 OMZP:: snippet equivalent - no functionality dropped, just deferred loading. - zsh-syntax-highlighting -> zdharma-continuum/fast-syntax-highlighting: the original doesn't tolerate turbo-mode's async loading (autosuggestions can wrap ZLE before it does, silently breaking highlighting with no error) - this is the documented, actively-maintained fork built for exactly this ordering problem. Loaded before autosuggestions with atload"!_zsh_autosuggest_start" to force synchronous init order. - zsh-autosuggestions and zsh-completions move from brew-installed to zinit-managed too, since that's what makes controlling load order possible in the first place - removed from Brewfile. - No theme added - Warp's own prompt already provides the visual look, matching current behavior (no ZSH_THEME was set before this either). - run_once_after_20-oh-my-zsh.sh.tmpl -> run_once_after_20-zinit.sh.tmpl, same run_once + directory-existence-guard pattern, just cloning zinit instead of oh-my-zsh. - Added a zsh startup verification step to the smoke test: oh-my-zsh silently warns on an unknown plugin name, but zinit's OMZP:: snippet fetch hard-errors (404) on one, so this is what actually catches a bad plugin-name mapping in CI before it reaches a real machine.
The previous check (zsh -ic 'exit') returned before most of the ~39 zinit snippets had a chance to load - the captured log only showed the first 4 (the trio + OMZP::aliases) before the step finished, meaning it wasn't actually validating the other 35 plugin names. Added a real wait and an explicit check that the last plugin in the list (OMZP::yarn) actually loaded, so a silent early-exit doesn't look like a clean pass.
20s wasn't close to enough - the previous CI run showed the 2nd zinit snippet hadn't even started downloading after 25s. Fetching ~39 individual files from GitHub with zero parallelism on a cold cache is genuinely slow; this is a one-time cost on first shell start, not representative of the actual startup-time improvement this migration is for.
…tion Direct curl validation of every OMZP:: plugin URL (bypassing zinit/turbo mode entirely) found the real bug the interactive-shell approach never reached: redis-cli isn't a real oh-my-zsh *plugin* (no .plugin.zsh file exists) - it only ships a completion file (_redis-cli). Fixed in dot_zshrc: moved it out of the plain snippet list into its own as"completion" load pointing at OMZP::redis-cli/_redis-cli, same pattern oh-my-zsh's own docs use for docker's _docker completion. Also replaced the interactive-shell-based CI check entirely. Across two separate runs (20s then 120s sleep), zsh -ic 'sleep N; exit' consistently stalled right after the very first deferred plugin regardless of how long it waited - turbo mode's queue advancement appears to depend on genuine interactive idle-time scheduling that a -c command context doesn't produce, so no amount of sleeping was going to fix it. Replaced with two steps: a short (5s) check that zsh starts without hard errors, and a direct curl check of every OMZP:: plugin URL - which is both more reliable and actually found the real bug on the first local run.
The already-tracked Library/Preferences/dev.warp.Warp-Stable.plist doesn't hold the meaningful stuff - Warp's actual theme, font, tab behavior, and keybinding settings live in ~/.warp/settings.toml instead (a plain, non-sensitive TOML file), which wasn't tracked anywhere. This is what actually restores the look on a fresh install.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.