diff --git a/bin/setup b/bin/setup index 28c2075..e6d77b1 100755 --- a/bin/setup +++ b/bin/setup @@ -8,11 +8,11 @@ # # What this script does: # 1. Re-execs itself with bash (curl|sh consumes stdin, so bash -c re-fetch is required) -# 2. Detects OS (Debian/Ubuntu, macOS, other Linux) -# 3. Installs git if missing — apt-get on Debian/Ubuntu, xcode-select on macOS +# 2. Detects OS, installs git if missing — apt-get on Debian/Ubuntu, xcode-select on macOS +# 3. Installs zsh if missing, sets it as the default shell # 4. Clones this dotfiles repo into ~ via HTTPS (or pulls if already present) # 5. Runs arty deps — oh-my-zsh, p10k, nvm, rbenv, pyenv, zsh plugins -# 6. Installs arty zsh completion to ~/.zsh/completions/_arty +# 6. Installs arty zsh completion via: arty completion zsh --install # 7. Prints next steps # ─── Step 0: Re-exec with bash ──────────────────────────────────────────────── @@ -116,7 +116,7 @@ check_prerequisites() { # ─── Step 2: Ensure git ─────────────────────────────────────────────────────── ensure_git() { - step_header "Step 2 of 6 — Git" + step_header "Step 2 of 7 — Git" if command -v git >/dev/null 2>&1; then log_success "git $(git --version | awk '{print $3}')" @@ -155,9 +155,66 @@ ensure_git() { esac } -# ─── Step 3: Clone or update dotfiles ───────────────────────────────────────── +# ─── Step 3: Ensure zsh ─────────────────────────────────────────────────────── +ensure_zsh() { + step_header "Step 3 of 7 — Zsh" + + if command -v zsh >/dev/null 2>&1; then + log_success "zsh $(zsh --version | awk '{print $2}')" + else + log_warn "zsh not found — installing for OS: $OS" + case "$OS" in + debian) + if ! command -v sudo >/dev/null 2>&1; then + log_error "sudo is required to install zsh on Debian/Ubuntu." + log_error "Run as root: apt-get install -y zsh — then re-run this script." + exit 1 + fi + sudo apt-get update -qq + sudo apt-get install -y zsh + log_success "zsh installed: $(zsh --version | awk '{print $2}')" + ;; + macos) + if command -v brew >/dev/null 2>&1; then + brew install zsh + log_success "zsh installed: $(zsh --version | awk '{print $2}')" + else + log_warn "zsh not found and Homebrew is not available." + log_warn "Install zsh manually: https://www.zsh.org" + fi + ;; + *) + log_warn "Cannot install zsh automatically on OS: $OS" + log_warn "Please install zsh manually, then re-run this script." + ;; + esac + fi + + # Set zsh as the default shell if it isn't already. + local zsh_path + zsh_path="$(command -v zsh 2>/dev/null || true)" + if [[ -n "$zsh_path" && "$SHELL" != "$zsh_path" ]]; then + log_info "Setting zsh as default shell..." + if command -v chsh >/dev/null 2>&1; then + # Add zsh to /etc/shells if missing (required by chsh). + if ! grep -qx "$zsh_path" /etc/shells 2>/dev/null; then + echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null + fi + if sudo chsh -s "$zsh_path" "$USER" 2>/dev/null || chsh -s "$zsh_path" 2>/dev/null; then + log_success "Default shell set to zsh (takes effect on next login)" + else + log_warn "Could not set default shell automatically." + log_warn "Run manually: chsh -s $zsh_path" + fi + else + log_warn "chsh not available — set your default shell manually: chsh -s $zsh_path" + fi + fi +} + +# ─── Step 4: Clone or update dotfiles ───────────────────────────────────────── setup_dotfiles() { - step_header "Step 3 of 6 — Dotfiles" + step_header "Step 4 of 7 — Dotfiles" local is_git_repo=0 local is_this_repo=0 @@ -215,9 +272,9 @@ setup_dotfiles() { log_success "Dotfiles cloned into $HOME" } -# ─── Step 4: Install dependencies via arty ──────────────────────────────────── +# ─── Step 5: Install dependencies via arty ──────────────────────────────────── install_deps() { - step_header "Step 4 of 6 — Dependencies (arty deps)" + step_header "Step 5 of 7 — Dependencies (arty deps)" local arty_bin="$HOME/bin/arty" @@ -241,38 +298,26 @@ install_deps() { log_success "All dependencies installed" } -# ─── Step 5: Install arty zsh completion ────────────────────────────────────── +# ─── Step 6: Install arty zsh completion ────────────────────────────────────── install_completion() { - step_header "Step 5 of 6 — Zsh completion" + step_header "Step 6 of 7 — Zsh completion" local arty_bin="$HOME/bin/arty" - local completion_content - if ! completion_content="$(cd "$HOME" && "$arty_bin" completion zsh 2>/dev/null)"; then - log_warn "arty completion zsh failed — skipping." - return 0 + # Ensure tools that arty deps may have installed (yq, etc.) are on PATH. + # arty deps runs in a subshell — its PATH exports don't survive back here. + export PATH="$HOME/.local/bin:$HOME/go/bin:$PATH" + + # arty completion zsh --install writes to the first writable fpath dir, + # defaulting to ~/.zsh/completions/_arty (which .zshenv/oh-my-zsh picks up). + if ! (cd "$HOME" && "$arty_bin" completion zsh --install); then + log_warn "arty completion zsh --install failed — skipping." fi - - # Sanity-check: a valid zsh completion file starts with #compdef. - if ! echo "$completion_content" | head -1 | grep -q "#compdef"; then - log_warn "arty completion output is not a valid zsh completion — skipping." - return 0 - fi - - # Target: ~/.zsh/completions/_arty - # .zshenv sets ZSH_CUSTOM="$HOME/.zsh"; oh-my-zsh adds $ZSH_CUSTOM/completions - # to fpath automatically — this is the correct path for this configuration. - local comp_dir="$HOME/.zsh/completions" - local comp_dest="$comp_dir/_arty" - - mkdir -p "$comp_dir" - printf '%s\n' "$completion_content" > "$comp_dest" - log_success "Completion installed: $comp_dest" } -# ─── Step 6: Post-install summary ───────────────────────────────────────────── +# ─── Step 7: Post-install summary ───────────────────────────────────────────── post_install() { - step_header "Step 6 of 6 — Done" + step_header "Step 7 of 7 — Done" echo echo -e "${GREEN}${BOLD}Setup complete.${NC} Next steps:" @@ -300,10 +345,11 @@ main() { check_prerequisites # Step 1 ensure_git # Step 2 - setup_dotfiles # Step 3 - install_deps # Step 4 - install_completion # Step 5 - post_install # Step 6 + ensure_zsh # Step 3 + setup_dotfiles # Step 4 + install_deps # Step 5 + install_completion # Step 6 + post_install # Step 7 } main "$@"