From 100754d827ea7604bc4c797b54fff257896961ea Mon Sep 17 00:00:00 2001 From: Jose Jimenez Date: Thu, 19 Feb 2026 20:12:21 +0100 Subject: [PATCH] curl installer fixed, update command added --- install.sh | 256 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 165 insertions(+), 91 deletions(-) diff --git a/install.sh b/install.sh index febacfe..a7bdbdb 100755 --- a/install.sh +++ b/install.sh @@ -1,54 +1,60 @@ #!/usr/bin/env bash set -e -# ==================== -# Logging (early definitions for clone step) -# ==================== -log_info() { echo "[INFO] $*"; } -log_warn() { echo "[WARN] $*"; } -log_error() { echo "[ERROR] $*" >&2; } - -# ==================== -# Detect installation method and setup DOTFILES_DIR -# ==================== -if [ -f "$(dirname "$0")/zsh/zshrc" ]; then - # Running from cloned repo - DOTFILES_DIR="$(cd "$(dirname "$0")" && pwd)" - CLEANUP_DOTFILES=false - log_info "Running from cloned repository at $DOTFILES_DIR" -else - # Running from curl, need to clone - DOTFILES_DIR="$HOME/.dotfiles-tmp" - CLEANUP_DOTFILES=true - - log_info "Running from curl, cloning dotfiles repository..." - - rm -rf "$DOTFILES_DIR" - git clone https://github.com/jjsalinas/dotfiles.git "$DOTFILES_DIR" - - log_info "Repository cloned to temporary location: $DOTFILES_DIR" -fi - # ==================== # Defaults # ==================== THEME="clean" ADD_NVM=false DRY_RUN=false +UPDATE_PLUGINS=false +CHECK=false ZSH_DIR="$HOME/.zsh" ZSHRC="$HOME/.zshrc" ZSHRC_LOCAL="$HOME/.zshrc.local" ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" +# Detect if we're being piped from curl (no local repo available) +PIPED_INSTALL=false +if [ -z "$BASH_SOURCE" ] || [ "$BASH_SOURCE" = "bash" ] || [ "$0" = "bash" ]; then + PIPED_INSTALL=true +fi + +# If piped, we need to clone the repo first and re-exec from there +if $PIPED_INSTALL; then + REPO_URL="https://github.com/jjsalinas/dotfiles.git" + CLONE_DIR="$HOME/.dotfiles" + + echo "[INFO] Piped install detected — cloning repo to $CLONE_DIR" + if [ -d "$CLONE_DIR" ]; then + echo "[INFO] Repo already exists, pulling latest" + git -C "$CLONE_DIR" pull --ff-only + else + git clone "$REPO_URL" "$CLONE_DIR" + fi + + echo "[INFO] Re-executing installer from cloned repo" + exec bash "$CLONE_DIR/install.sh" "$@" +fi + +# Running from a local clone — resolve DOTFILES_DIR normally +DOTFILES_DIR="$(cd "$(dirname "$0")" && pwd)" + # ==================== -# Helper functions +# Logging # ==================== +log_info() { echo "[INFO] $*"; } +log_warn() { echo "[WARN] $*"; } +log_ok() { echo "[OK] $*"; } +log_fail() { echo "[FAIL] $*"; } +log_error() { echo "[ERROR] $*" >&2; } + run() { if $DRY_RUN; then log_info "[dry-run] $*" else - eval "$@" + "$@" fi } @@ -65,6 +71,8 @@ Usage: Options: --theme Oh My Zsh theme to use (default: clean) --add-nvm Enable Node Version Manager config + --update Update installed plugins (git pull) + --check Verify installation without making changes --dry-run Show actions without making changes --help Show this help and exit @@ -81,6 +89,12 @@ Examples: ./install.sh --theme robbyrussell ./install.sh --add-nvm ./install.sh --theme agnoster --add-nvm --dry-run + ./install.sh --update + ./install.sh --check + +One-line install: + curl -fsSL https://raw.githubusercontent.com/jjsalinas/dotfiles/main/install.sh | bash + curl -fsSL https://raw.githubusercontent.com/jjsalinas/dotfiles/main/install.sh | bash -s -- --theme clean --add-nvm EOF } @@ -96,6 +110,12 @@ while [[ $# -gt 0 ]]; do --add-nvm) ADD_NVM=true ;; + --update) + UPDATE_PLUGINS=true + ;; + --check) + CHECK=true + ;; --dry-run) DRY_RUN=true ;; @@ -111,11 +131,71 @@ while [[ $# -gt 0 ]]; do shift done +# ==================== +# --check mode +# ==================== +if $CHECK; then + log_info "Running installation check..." + FAILURES=0 + + check_ok() { log_ok "$1"; } + check_fail() { log_fail "$1"; FAILURES=$((FAILURES + 1)); } + + # Commands + command -v zsh >/dev/null 2>&1 && check_ok "zsh is installed" || check_fail "zsh not found" + command -v git >/dev/null 2>&1 && check_ok "git is installed" || check_fail "git not found" + command -v fzf >/dev/null 2>&1 && check_ok "fzf is installed" || check_fail "fzf not found" + [ -d "$HOME/.oh-my-zsh" ] && check_ok "Oh My Zsh is installed" || check_fail "Oh My Zsh not found at ~/.oh-my-zsh" + + # Plugins + [ -d "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" ] \ + && check_ok "zsh-syntax-highlighting plugin exists" \ + || check_fail "zsh-syntax-highlighting plugin missing" + + [ -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ] \ + && check_ok "zsh-autosuggestions plugin exists" \ + || check_fail "zsh-autosuggestions plugin missing" + + # Symlinks + check_symlink() { + local link="$1" target="$2" + if [ -L "$link" ] && [ "$(readlink "$link")" = "$target" ]; then + check_ok "symlink OK: $link -> $target" + elif [ -L "$link" ]; then + check_fail "symlink wrong target: $link -> $(readlink "$link") (expected $target)" + elif [ -e "$link" ]; then + check_fail "exists but not a symlink: $link" + else + check_fail "symlink missing: $link" + fi + } + + check_symlink "$ZSHRC" "$DOTFILES_DIR/zsh/zshrc" + check_symlink "$ZSH_DIR/keybindings.zsh" "$DOTFILES_DIR/zsh/keybindings.zsh" + check_symlink "$ZSH_DIR/history.zsh" "$DOTFILES_DIR/zsh/history.zsh" + check_symlink "$ZSH_DIR/fzf.zsh" "$DOTFILES_DIR/zsh/fzf.zsh" + check_symlink "$ZSH_DIR/plugins.zsh" "$DOTFILES_DIR/zsh/plugins.zsh" + + # .zshrc.local + [ -f "$ZSHRC_LOCAL" ] \ + && check_ok ".zshrc.local exists" \ + || check_fail ".zshrc.local missing (theme not configured)" + + echo "" + if [ "$FAILURES" -eq 0 ]; then + log_info "All checks passed." + exit 0 + else + log_error "$FAILURES check(s) failed." + exit 1 + fi +fi + # ==================== # Preconditions # ==================== if [ ! -d "$HOME/.oh-my-zsh" ]; then - log_error "Oh My Zsh is not installed. Install it first." + log_error "Oh My Zsh is not installed. Install it first: https://ohmyz.sh" exit 1 fi @@ -127,6 +207,8 @@ if command -v apt >/dev/null 2>&1; then PKG_INSTALL="sudo apt install -y" elif command -v dnf >/dev/null 2>&1; then PKG_INSTALL="sudo dnf install -y" +elif command -v brew >/dev/null 2>&1; then + PKG_INSTALL="brew install" else PKG_INSTALL="" fi @@ -136,73 +218,66 @@ fi # ==================== log_info "Installing dependencies" if [ -n "$PKG_INSTALL" ]; then - command -v git >/dev/null 2>&1 || run "$PKG_INSTALL git" - command -v fzf >/dev/null 2>&1 || run "$PKG_INSTALL fzf" + command -v git >/dev/null 2>&1 || run $PKG_INSTALL git + command -v fzf >/dev/null 2>&1 || run $PKG_INSTALL fzf fi +# ==================== +# Plugin install/update helper +# ==================== +install_or_update_plugin() { + local name="$1" + local url="$2" + local dest="$ZSH_CUSTOM/plugins/$name" + + if [ -d "$dest" ]; then + if $UPDATE_PLUGINS; then + log_info "Updating $name" + run git -C "$dest" pull --ff-only + else + log_warn "$name already installed (use --update to pull latest)" + fi + else + log_info "Installing $name" + run git clone "$url" "$dest" + fi +} + # ==================== # Plugins # ==================== -log_info "Installing zsh-syntax-highlighting" -if [ ! -d "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" ]; then - run "git clone https://github.com/zsh-users/zsh-syntax-highlighting \ - '$ZSH_CUSTOM/plugins/zsh-syntax-highlighting'" -else - log_warn "zsh-syntax-highlighting already installed" -fi +install_or_update_plugin "zsh-syntax-highlighting" \ + "https://github.com/zsh-users/zsh-syntax-highlighting" -log_info "Installing zsh-autosuggestions (disabled by default)" -if [ ! -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ]; then - run "git clone https://github.com/zsh-users/zsh-autosuggestions \ - '$ZSH_CUSTOM/plugins/zsh-autosuggestions'" -else - log_warn "zsh-autosuggestions already installed" -fi +install_or_update_plugin "zsh-autosuggestions" \ + "https://github.com/zsh-users/zsh-autosuggestions" # ==================== # Backup existing files # ==================== if [ -f "$ZSHRC" ] && [ ! -L "$ZSHRC" ]; then log_info "Backing up existing .zshrc" - run "cp '$ZSHRC' '$ZSHRC.backup.$(date +%s)'" + run cp "$ZSHRC" "$ZSHRC.backup.$(date +%s)" fi # ==================== -# Copy or Symlink files +# Symlinks # ==================== log_info "Creating zsh config directory" -run "mkdir -p '$ZSH_DIR'" +run mkdir -p "$ZSH_DIR" -if $CLEANUP_DOTFILES; then - # Running from curl - copy files instead of symlinking - log_info "Copying zsh config files" - run "cp '$DOTFILES_DIR/zsh/zshrc' '$ZSHRC'" - run "cp '$DOTFILES_DIR/zsh/keybindings.zsh' '$ZSH_DIR/keybindings.zsh'" - run "cp '$DOTFILES_DIR/zsh/history.zsh' '$ZSH_DIR/history.zsh'" - run "cp '$DOTFILES_DIR/zsh/fzf.zsh' '$ZSH_DIR/fzf.zsh'" - run "cp '$DOTFILES_DIR/zsh/plugins.zsh' '$ZSH_DIR/plugins.zsh'" +log_info "Linking zsh config files" +run ln -sf "$DOTFILES_DIR/zsh/zshrc" "$ZSHRC" +run ln -sf "$DOTFILES_DIR/zsh/keybindings.zsh" "$ZSH_DIR/keybindings.zsh" +run ln -sf "$DOTFILES_DIR/zsh/history.zsh" "$ZSH_DIR/history.zsh" +run ln -sf "$DOTFILES_DIR/zsh/fzf.zsh" "$ZSH_DIR/fzf.zsh" +run ln -sf "$DOTFILES_DIR/zsh/plugins.zsh" "$ZSH_DIR/plugins.zsh" - if $ADD_NVM; then - log_info "Copying NVM config" - run "cp '$DOTFILES_DIR/zsh/nvm.zsh' '$ZSH_DIR/nvm.zsh'" - else - run "rm -f '$ZSH_DIR/nvm.zsh' || true" - fi +if $ADD_NVM; then + log_info "Linking NVM config" + run ln -sf "$DOTFILES_DIR/zsh/nvm.zsh" "$ZSH_DIR/nvm.zsh" else - # Running from cloned repo - use symlinks for easier updates - log_info "Linking zsh config files" - run "ln -sf '$DOTFILES_DIR/zsh/zshrc' '$ZSHRC'" - run "ln -sf '$DOTFILES_DIR/zsh/keybindings.zsh' '$ZSH_DIR/keybindings.zsh'" - run "ln -sf '$DOTFILES_DIR/zsh/history.zsh' '$ZSH_DIR/history.zsh'" - run "ln -sf '$DOTFILES_DIR/zsh/fzf.zsh' '$ZSH_DIR/fzf.zsh'" - run "ln -sf '$DOTFILES_DIR/zsh/plugins.zsh' '$ZSH_DIR/plugins.zsh'" - - if $ADD_NVM; then - log_info "Linking NVM config" - run "ln -sf '$DOTFILES_DIR/zsh/nvm.zsh' '$ZSH_DIR/nvm.zsh'" - else - run "rm -f '$ZSH_DIR/nvm.zsh' || true" - fi + run rm -f "$ZSH_DIR/nvm.zsh" fi # ==================== @@ -210,25 +285,24 @@ fi # ==================== log_info "Setting theme: $THEME" if ! $DRY_RUN; then - cat << EOF > "$ZSHRC_LOCAL" + # Only write .zshrc.local if theme has changed (or file doesn't exist) + current_theme="" + if [ -f "$ZSHRC_LOCAL" ]; then + current_theme=$(grep -oP '(?<=ZSH_THEME=")[^"]+' "$ZSHRC_LOCAL" 2>/dev/null || true) + fi + + if [ "$current_theme" != "$THEME" ]; then + cat << EOF > "$ZSHRC_LOCAL" export ZSH_THEME="$THEME" EOF + log_info "Theme set to: $THEME" + else + log_warn ".zshrc.local already has theme '$THEME', skipping" + fi else log_info "[dry-run] would write ~/.zshrc.local with theme $THEME" fi -# ==================== -# Cleanup -# ==================== -if $CLEANUP_DOTFILES; then - log_info "Cleaning up temporary files" - if ! $DRY_RUN; then - rm -rf "$DOTFILES_DIR" - else - log_info "[dry-run] would remove $DOTFILES_DIR" - fi -fi - # ==================== # Done # ====================