Skip to content

Instantly share code, notes, and snippets.

@jaycdave88
Created August 11, 2025 14:35
Show Gist options
  • Save jaycdave88/d46328d1dc78749d111c80e4fbdeaf30 to your computer and use it in GitHub Desktop.
Save jaycdave88/d46328d1dc78749d111c80e4fbdeaf30 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# SA Mac bootstrap — idempotent, with logging
set -u # don't exit on errors; we want to log them and continue
LOG_FILE="$HOME/Desktop/Setup MacBook for SA.txt"
mkdir -p "$HOME/Desktop" 2>/dev/null || true
log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" | tee -a "$LOG_FILE"; }
section() { echo | tee -a "$LOG_FILE"; log "==== $* ===="; }
section "Starting SA Mac bootstrap"
log "Logging to: $LOG_FILE"
# --- Homebrew ---
section "Homebrew"
if ! command -v brew >/dev/null 2>&1; then
log "Homebrew not found — installing"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" >>"$LOG_FILE" 2>&1 || log "ERROR: Homebrew install failed"
else
log "Homebrew already installed"
fi
BREW_PREFIX="$(/usr/bin/arch | grep -qi arm && echo /opt/homebrew || echo /usr/local)"
if [ -x "$BREW_PREFIX/bin/brew" ]; then
eval "$("$BREW_PREFIX/bin/brew" shellenv)"
else
eval "$(brew shellenv)"
fi
brew update >>"$LOG_FILE" 2>&1 || log "WARN: brew update failed"
install_formula() {
local pkg="$1"
if brew list --formula "$pkg" >/dev/null 2>&1; then
log "SKIP: brew formula $pkg already installed"
else
if brew install "$pkg" >>"$LOG_FILE" 2>&1; then
log "OK: installed brew formula $pkg"
else
log "ERROR: installing brew formula $pkg"
fi
fi
}
install_cask() {
local cask="$1"
if brew list --cask "$cask" >/dev/null 2>&1; then
log "SKIP: brew cask $cask already installed"
else
if brew install --cask "$cask" >>"$LOG_FILE" 2>&1; then
log "OK: installed brew cask $cask"
else
log "ERROR: installing brew cask $cask"
fi
fi
}
# --- Core installs ---
for f in git gh jq wget curl zsh-completions fzf zoxide direnv; do install_formula "$f"; done
install_formula pyenv
install_formula fnm
for c in iterm2 visual-studio-code sublime-text docker jetbrains-toolbox google-chrome slack zoom notion; do
install_cask "$c"
done
# --- Shell bootstrap ---
section "Shell bootstrap (.zshrc)"
ZSHRC="$HOME/.zshrc"
if ! grep -q "# augment-bootstrap" "$ZSHRC" 2>/dev/null; then
cat >> "$ZSHRC" <<'EOF'
# augment-bootstrap
export PATH="$HOME/.local/bin:$PATH"
if [ -d /opt/homebrew ]; then eval "$(/opt/homebrew/bin/brew shellenv)"; fi
if command -v pyenv >/dev/null 2>&1; then export PYENV_ROOT="$HOME/.pyenv"; eval "$(pyenv init -)"; fi
if command -v fnm >/dev/null 2>&1; then eval "$(fnm env --use-on-cd)"; fi
if command -v direnv >/dev/null 2>&1; then eval "$(direnv hook zsh)"; fi
if command -v zoxide >/dev/null 2>&1; then eval "$(zoxide init zsh)"; fi
if [ -f "$(brew --prefix 2>/dev/null)/opt/fzf/shell/key-bindings.zsh" ]; then
source "$(brew --prefix)/opt/fzf/shell/key-bindings.zsh"
fi
# end augment-bootstrap
EOF
log "OK: appended augment bootstrap to $ZSHRC"
else
log "SKIP: augment bootstrap already present in $ZSHRC"
fi
if [ -d /opt/homebrew ]; then eval "$(/opt/homebrew/bin/brew shellenv)"; fi
# --- Python latest stable ---
section "Python via pyenv"
if command -v pyenv >/dev/null 2>&1; then
PY_LATEST=$(pyenv install -l | grep -E '^\s*3\.[0-9]+\.[0-9]+$' | tr -d ' ' | tail -1)
[ -z "$PY_LATEST" ] && PY_LATEST="3.12.5"
log "Target Python: $PY_LATEST"
if pyenv versions --bare | grep -qx "$PY_LATEST"; then
log "SKIP: Python $PY_LATEST already installed"
else
pyenv install "$PY_LATEST" >>"$LOG_FILE" 2>&1 && log "OK: installed Python $PY_LATEST" || log "ERROR: Python install failed"
fi
pyenv global "$PY_LATEST"
python3 -m ensurepip --upgrade >>"$LOG_FILE" 2>&1 || true
python3 -m pip install --upgrade pip pipx >>"$LOG_FILE" 2>&1 || log "WARN: pip/pipx upgrade issue"
else
log "ERROR: pyenv not available"
fi
# --- Node latest LTS ---
section "Node via fnm"
if command -v fnm >/dev/null 2>&1; then
fnm install --lts >>"$LOG_FILE" 2>&1 || log "ERROR: Node LTS install failed"
CURRENT_LTS=$(fnm ls | awk '/LTS/ {print $1}' | tail -1)
if [ -n "$CURRENT_LTS" ]; then
fnm default "$CURRENT_LTS" && log "OK: set Node default to $CURRENT_LTS"
else
log "WARN: could not detect LTS label"
fi
else
log "ERROR: fnm not available"
fi
# --- Editor commands ---
section "Editor CLI commands"
if ! command -v code >/dev/null 2>&1 && [ -x "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code" ]; then
sudo ln -sf "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code" /usr/local/bin/code && log "OK: linked 'code'"
else
log "SKIP: 'code' already in PATH"
fi
if ! command -v subl >/dev/null 2>&1 && [ -x "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" ]; then
sudo ln -sf "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl && log "OK: linked 'subl'"
else
log "SKIP: 'subl' already in PATH"
fi
# --- Docker first run ---
section "Docker first run"
if command -v docker >/dev/null 2>&1; then
open -ga Docker >>"$LOG_FILE" 2>&1 || true
log "INFO: Accept Docker prompts if shown."
else
log "WARN: docker CLI not available"
fi
# --- Sanity checks ---
section "Sanity checks"
{
which brew && brew --version
which git && git --version
which gh && gh --version
which python3 && python3 --version
which pyenv && pyenv versions
which node && node -v
which fnm && fnm ls
which code && code --version
which subl || true
docker --version || true
} >>"$LOG_FILE" 2>&1
section "Complete"
log "Close/reopen iTerm to load changes."
log "Review $LOG_FILE for errors or warnings."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment