#!/usr/bin/env bash # ============================================================================= # setup-zsh.sh — Bootstrap zsh environment across devices # Supports: apt (Debian/Ubuntu), dnf (Fedora) # ============================================================================= set -euo pipefail # ── Colours ────────────────────────────────────────────────────────────────── RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' info() { echo -e "${CYAN}${BOLD}[INFO]${RESET} $*"; } success() { echo -e "${GREEN}${BOLD}[OK]${RESET} $*"; } warn() { echo -e "${YELLOW}${BOLD}[WARN]${RESET} $*"; } error() { echo -e "${RED}${BOLD}[ERROR]${RESET} $*" >&2; exit 1; } # ── Detect package manager ──────────────────────────────────────────────────── detect_pm() { if command -v apt &>/dev/null; then PM="apt" PM_INSTALL="sudo apt install -y" PM_UPDATE="sudo apt update -y" elif command -v dnf &>/dev/null; then PM="dnf" PM_INSTALL="sudo dnf install -y" PM_UPDATE="sudo dnf check-update -y || true" else error "No supported package manager found (apt or dnf required)." fi info "Detected package manager: ${BOLD}$PM${RESET}" } # ── Helpers ─────────────────────────────────────────────────────────────────── is_installed() { command -v "$1" &>/dev/null; } install_pkg() { local pkg="$1" cmd="${2:-$1}" if is_installed "$cmd"; then success "$cmd already installed — skipping." else info "Installing $pkg …" $PM_INSTALL "$pkg" success "$pkg installed." fi } # ── Install Starship ───────────────────────────────────────────────────────── install_starship() { if is_installed starship; then success "Starship already installed — skipping." else info "Installing Starship …" curl -sS https://starship.rs/install.sh | sh -s -- --yes success "Starship installed." fi } # ── Install eza ─────────────────────────────────────────────────────────────── install_eza() { if is_installed eza; then success "eza already installed — skipping." return fi info "Installing eza …" if [[ "$PM" == "apt" ]]; then sudo mkdir -p /etc/apt/keyrings wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc \ | sudo gpg --dearmor -o /etc/apt/keyrings/gierens.gpg echo "deb [signed-by=/etc/apt/keyrings/gierens.gpg] http://deb.gierens.de stable main" \ | sudo tee /etc/apt/sources.list.d/gierens.list sudo chmod 644 /etc/apt/keyrings/gierens.gpg /etc/apt/sources.list.d/gierens.list sudo apt update -y sudo apt install -y eza elif [[ "$PM" == "dnf" ]]; then # eza is in the EPEL/Fedora repos from F38+ sudo dnf install -y eza fi success "eza installed." } # ── Install fzf ─────────────────────────────────────────────────────────────── install_fzf() { if is_installed fzf; then success "fzf already installed — skipping." return fi info "Installing fzf …" if [[ "$PM" == "apt" ]]; then sudo apt install -y fzf elif [[ "$PM" == "dnf" ]]; then sudo dnf install -y fzf fi success "fzf installed." } # ── Install bat ─────────────────────────────────────────────────────────────── install_bat() { if is_installed bat; then success "bat already installed — skipping." return fi info "Installing bat …" if [[ "$PM" == "apt" ]]; then sudo apt install -y bat # On Ubuntu/Debian the binary may be 'batcat' if ! is_installed bat && is_installed batcat; then mkdir -p ~/.local/bin ln -sf "$(command -v batcat)" ~/.local/bin/bat warn "Symlinked batcat → ~/.local/bin/bat (add ~/.local/bin to PATH if needed)." fi elif [[ "$PM" == "dnf" ]]; then sudo dnf install -y bat fi success "bat installed." } # ── Install zinit ───────────────────────────────────────────────────────────── install_zinit() { local zinit_home="${HOME}/.config/zinit/zinit.git" if [[ -d "$zinit_home" ]]; then success "zinit already installed — skipping." else info "Cloning zinit …" mkdir -p "$(dirname "$zinit_home")" git clone https://github.com/zdharma-continuum/zinit.git "$zinit_home" success "zinit cloned." fi } # ── Deploy .zshrc ───────────────────────────────────────────────────────────── ZSHRC_URL="https://gitea.example.com///raw/branch/main/_zshrc" # ← update to your Gitea raw URL deploy_zshrc() { local dest="${HOME}/.zshrc" local tmp tmp="$(mktemp)" info "Downloading .zshrc from ${ZSHRC_URL} …" if ! curl -fsSL "$ZSHRC_URL" -o "$tmp"; then rm -f "$tmp" error "Failed to download .zshrc from ${ZSHRC_URL}" fi if [[ -f "$dest" ]]; then local backup="${dest}.bak.$(date +%Y%m%d_%H%M%S)" info "Backing up existing .zshrc → $backup" cp "$dest" "$backup" success "Backup created: $backup" fi mv "$tmp" "$dest" success ".zshrc deployed to $dest" } # ── Make zsh default shell ──────────────────────────────────────────────────── set_default_shell() { if [[ "$SHELL" == *"zsh"* ]]; then success "zsh is already the default shell." return fi local zsh_path zsh_path="$(command -v zsh 2>/dev/null || true)" if [[ -z "$zsh_path" ]]; then warn "zsh not found in PATH — skipping default shell change." return fi info "Setting zsh as the default shell …" chsh -s "$zsh_path" success "Default shell set to $zsh_path (takes effect on next login)." } # ── Main ────────────────────────────────────────────────────────────────────── main() { echo -e "\n${BOLD}${CYAN}╔══════════════════════════════════════╗" echo -e "║ zsh environment setup script ║" echo -e "╚══════════════════════════════════════╝${RESET}\n" detect_pm info "Updating package index …" $PM_UPDATE # Core dependencies install_pkg zsh install_pkg git install_pkg curl install_pkg wget # zsh tools install_starship install_eza install_fzf install_bat install_zinit # anifetch removed # Deploy config deploy_zshrc # Optionally switch default shell set_default_shell echo -e "\n${GREEN}${BOLD}✔ Setup complete!${RESET}" echo -e " • Start a new zsh session or run: ${BOLD}exec zsh${RESET}" echo -e " • Zinit plugins will install automatically on first zsh launch\n" } main "$@"