add bootstrap.sh
This commit is contained in:
188
bootstrap.sh
Normal file
188
bootstrap.sh
Normal file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ====== CONFIG ======
|
||||
DOTFILES_DIR="${DOTFILES_DIR:-$HOME/repos/dotfiles}"
|
||||
DOTFILES_GIT_URL="${DOTFILES_GIT_URL:-}" # ex: git@github.com:TON_USER/dotfiles.git
|
||||
STOW_PACKAGES_DEFAULT=("zsh" "tmux" "nvim" "hypr" "hypridle" "waybar" "alacritty")
|
||||
|
||||
INSTALL_FONTS="${INSTALL_FONTS:-1}" # 1 = install nerd font, 0 = skip
|
||||
SET_DEFAULT_SHELL="${SET_DEFAULT_SHELL:-1}" # 1 = chsh to zsh, 0 = skip
|
||||
|
||||
# ====== HELPERS ======
|
||||
log() { printf "\n\033[1m==>\033[0m %s\n" "$*"; }
|
||||
warn() { printf "\033[33mWARN:\033[0m %s\n" "$*" >&2; }
|
||||
die() { printf "\033[31mERR:\033[0m %s\n" "$*" >&2; exit 1; }
|
||||
|
||||
have() { command -v "$1" >/dev/null 2>&1; }
|
||||
|
||||
require_sudo() {
|
||||
if [ "${EUID:-$(id -u)}" -ne 0 ]; then
|
||||
if ! have sudo; then die "sudo is required"; fi
|
||||
fi
|
||||
}
|
||||
|
||||
sudo_run() {
|
||||
if [ "${EUID:-$(id -u)}" -eq 0 ]; then
|
||||
"$@"
|
||||
else
|
||||
sudo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# ====== OS CHECK ======
|
||||
if [ ! -f /etc/os-release ]; then
|
||||
die "Unsupported OS (no /etc/os-release). This script targets Debian/Ubuntu."
|
||||
fi
|
||||
|
||||
. /etc/os-release
|
||||
case "${ID:-}" in
|
||||
debian|ubuntu|linuxmint|pop)
|
||||
;;
|
||||
*)
|
||||
warn "OS ID=${ID:-unknown}. Script is written for Debian/Ubuntu; proceeding anyway."
|
||||
;;
|
||||
esac
|
||||
|
||||
# ====== APT PACKAGES ======
|
||||
log "Installing base packages (git, stow, zsh, tmux, neovim, etc.)"
|
||||
require_sudo
|
||||
sudo_run apt update
|
||||
sudo_run apt install -y \
|
||||
git curl ca-certificates stow \
|
||||
zsh tmux neovim \
|
||||
ripgrep fd-find \
|
||||
unzip zip tar \
|
||||
fontconfig
|
||||
|
||||
# Optional: tools often needed by nvim plugins (treesitter, etc.)
|
||||
sudo_run apt install -y build-essential || true
|
||||
|
||||
# Hypr ecosystem (availability depends on distro/repo)
|
||||
# We try, but do not fail if packages aren't found.
|
||||
log "Trying to install Hyprland ecosystem packages (best effort)"
|
||||
sudo_run apt install -y hyprland hypridle waybar alacritty 2>/dev/null || true
|
||||
|
||||
# ====== DOTFILES CLONE (OPTIONAL) ======
|
||||
if [ ! -d "$DOTFILES_DIR/.git" ]; then
|
||||
if [ -n "$DOTFILES_GIT_URL" ]; then
|
||||
log "Cloning dotfiles repo into: $DOTFILES_DIR"
|
||||
mkdir -p "$(dirname "$DOTFILES_DIR")"
|
||||
git clone "$DOTFILES_GIT_URL" "$DOTFILES_DIR"
|
||||
else
|
||||
warn "DOTFILES_DIR has no .git and DOTFILES_GIT_URL is empty."
|
||||
warn "Skipping clone. (Set DOTFILES_GIT_URL env var to auto-clone.)"
|
||||
fi
|
||||
else
|
||||
log "Dotfiles repo already present: $DOTFILES_DIR"
|
||||
fi
|
||||
|
||||
# ====== OH-MY-ZSH ======
|
||||
if [ ! -d "$HOME/.oh-my-zsh" ]; then
|
||||
log "Installing Oh My Zsh"
|
||||
# Unattended install: does not launch zsh at end
|
||||
RUNZSH=no CHSH=no KEEP_ZSHRC=yes \
|
||||
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||
else
|
||||
log "Oh My Zsh already installed"
|
||||
fi
|
||||
|
||||
# ====== POWERLEVEL10K + PLUGINS ======
|
||||
ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
|
||||
|
||||
log "Installing Powerlevel10k theme + useful plugins"
|
||||
mkdir -p "$ZSH_CUSTOM/themes" "$ZSH_CUSTOM/plugins"
|
||||
|
||||
if [ ! -d "$ZSH_CUSTOM/themes/powerlevel10k" ]; then
|
||||
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
|
||||
"$ZSH_CUSTOM/themes/powerlevel10k"
|
||||
else
|
||||
log "powerlevel10k already present"
|
||||
fi
|
||||
|
||||
if [ ! -d "$ZSH_CUSTOM/plugins/zsh-autosuggestions" ]; then
|
||||
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions \
|
||||
"$ZSH_CUSTOM/plugins/zsh-autosuggestions"
|
||||
else
|
||||
log "zsh-autosuggestions already present"
|
||||
fi
|
||||
|
||||
if [ ! -d "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" ]; then
|
||||
git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting \
|
||||
"$ZSH_CUSTOM/plugins/zsh-syntax-highlighting"
|
||||
else
|
||||
log "zsh-syntax-highlighting already present"
|
||||
fi
|
||||
|
||||
# ====== NERD FONT (FOR P10K) ======
|
||||
if [ "$INSTALL_FONTS" = "1" ]; then
|
||||
log "Installing Meslo Nerd Font (for Powerlevel10k) (best effort)"
|
||||
FONT_DIR="$HOME/.local/share/fonts"
|
||||
mkdir -p "$FONT_DIR"
|
||||
|
||||
# Meslo Nerd Font (p10k recommended) - download 4 variants
|
||||
# If this fails (no internet), it won't abort the script.
|
||||
curl -fsSL -o "$FONT_DIR/MesloLGS NF Regular.ttf" \
|
||||
"https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Meslo/L/Regular/MesloLGSNerdFont-Regular.ttf" || true
|
||||
curl -fsSL -o "$FONT_DIR/MesloLGS NF Bold.ttf" \
|
||||
"https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Meslo/L/Bold/MesloLGSNerdFont-Bold.ttf" || true
|
||||
curl -fsSL -o "$FONT_DIR/MesloLGS NF Italic.ttf" \
|
||||
"https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Meslo/L/Italic/MesloLGSNerdFont-Italic.ttf" || true
|
||||
curl -fsSL -o "$FONT_DIR/MesloLGS NF Bold Italic.ttf" \
|
||||
"https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Meslo/L/Bold-Italic/MesloLGSNerdFont-BoldItalic.ttf" || true
|
||||
|
||||
if have fc-cache; then
|
||||
fc-cache -f >/dev/null 2>&1 || true
|
||||
fi
|
||||
else
|
||||
log "Skipping font installation (INSTALL_FONTS=0)"
|
||||
fi
|
||||
|
||||
# ====== STOW APPLY ======
|
||||
if [ -d "$DOTFILES_DIR" ]; then
|
||||
log "Applying stow packages into \$HOME (target=~)"
|
||||
cd "$DOTFILES_DIR"
|
||||
|
||||
# Only stow packages that exist as directories
|
||||
stow_args=()
|
||||
for pkg in "${STOW_PACKAGES_DEFAULT[@]}"; do
|
||||
if [ -d "$pkg" ]; then
|
||||
stow_args+=("$pkg")
|
||||
else
|
||||
warn "Package dir missing, skipping: $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${#stow_args[@]}" -eq 0 ]; then
|
||||
warn "No stow package dirs found in $DOTFILES_DIR. Nothing to apply."
|
||||
else
|
||||
# Use verbose so you see what happened
|
||||
stow -v -t "$HOME" "${stow_args[@]}"
|
||||
fi
|
||||
else
|
||||
warn "DOTFILES_DIR not found: $DOTFILES_DIR (skipping stow apply)"
|
||||
fi
|
||||
|
||||
# ====== DEFAULT SHELL ======
|
||||
if [ "$SET_DEFAULT_SHELL" = "1" ]; then
|
||||
if have zsh; then
|
||||
log "Setting default shell to zsh (may prompt for password)"
|
||||
# Ensure zsh is in /etc/shells
|
||||
if ! grep -q "$(command -v zsh)" /etc/shells 2>/dev/null; then
|
||||
warn "zsh not listed in /etc/shells; attempting to add (requires sudo)"
|
||||
require_sudo
|
||||
echo "$(command -v zsh)" | sudo_run tee -a /etc/shells >/dev/null
|
||||
fi
|
||||
chsh -s "$(command -v zsh)" "$USER" || true
|
||||
else
|
||||
warn "zsh not found; cannot set default shell"
|
||||
fi
|
||||
else
|
||||
log "Skipping default shell change (SET_DEFAULT_SHELL=0)"
|
||||
fi
|
||||
|
||||
log "Bootstrap complete."
|
||||
log "Next steps:"
|
||||
echo " - Open a new terminal (or log out/in) to use zsh."
|
||||
echo " - If p10k prompts, run: p10k configure"
|
||||
echo " - If Hypr/Waybar are missing, you may need distro-specific repos (not always in apt)."
|
||||
Reference in New Issue
Block a user