run_once_20 runs BEFORE run_onchange_30 in the bootstrap chain, so 'command -v cargo' inside run_once_20 was always false on a fresh box — cargo install bat was skipped, leaving bat missing on debian. Move the bat install to run_onchange_30 (which runs last, after rustup is installed). Restructure the script to: 1. Ensure cargo is installed (existing logic) 2. Install bat via cargo on debian only (new logic, gated by os_family) This way the bootstrap chain becomes: run_once_00 -> run_once_10 -> run_once_20 (apt packages, neovim, oh-my-zsh, font) -> run_onchange_30 (rustup, then bat from crates.io) Crouton currently has rustup installed but no bat (cargo install in progress in background). Re-running chezmoi init will skip run_once_20 (state recorded) and re-run run_onchange_30 (content changed), which will see bat missing and trigger cargo install automatically.
204 lines
No EOL
7.1 KiB
Bash
Executable file
204 lines
No EOL
7.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# run_once_20-install-user-packages.sh.tmpl
|
|
# Install zsh, tmux, neovim, fastfetch, plus the modern CLI replacements
|
|
# the .zshrc aliases depend on (bat, btop, eza, fzf, fd, ripgrep, zoxide,
|
|
# starship, lazygit, yt-dlp, etc.)
|
|
#
|
|
# Also: install oh-my-zsh, zsh-autosuggestions, zsh-syntax-highlighting,
|
|
# zsh-history-substring-search.
|
|
#
|
|
# Runs as the unprivileged user, but uses sudo for system packages.
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
log() { printf '\033[1;34m[packages]\033[0m %s\n' "$*"; }
|
|
die() { printf '\033[1;31m[packages ERROR]\033[0m %s\n' "$*" >&2; exit 1; }
|
|
|
|
USER_HOME="${HOME:-$(eval echo "~$(whoami)")}"
|
|
ZSH_CUSTOM="${ZSH_CUSTOM:-$USER_HOME/.oh-my-zsh/custom}"
|
|
|
|
{{ if eq .os_family "arch" -}}
|
|
# ----------------------------- ARCH ---------------------------------------
|
|
log "pacman -Syu"
|
|
sudo pacman -Syu --noconfirm
|
|
|
|
PACMAN_PKGS=(
|
|
zsh tmux neovim git base-devel
|
|
bat btop htop fastfetch
|
|
eza fzf fd ripgrep zoxide starship
|
|
lazygit yt-dlp jq
|
|
unzip p7zip
|
|
openssh
|
|
)
|
|
|
|
log "installing pacman packages"
|
|
sudo pacman -S --needed --noconfirm "${PACMAN_PKGS[@]}"
|
|
|
|
{{ else if eq .os_family "debian" -}}
|
|
# ----------------------------- DEBIAN --------------------------------------
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
sudo apt-get update -y
|
|
sudo apt-get upgrade -y
|
|
|
|
APT_PKGS=(
|
|
zsh tmux git build-essential
|
|
btop htop fastfetch
|
|
eza fzf fd-find ripgrep zoxide starship
|
|
lazygit yt-dlp jq
|
|
unzip p7zip
|
|
openssh-client
|
|
ca-certificates curl wget
|
|
fontconfig
|
|
)
|
|
|
|
log "installing apt packages"
|
|
sudo apt-get install -y --no-install-recommends "${APT_PKGS[@]}"
|
|
|
|
# fd on Debian ships as 'fdfind' to avoid clashing with fd (the dedupe tool).
|
|
# Symlink so .zshrc can find 'fd' on PATH.
|
|
if command -v fdfind >/dev/null 2>&1 && ! command -v fd >/dev/null 2>&1; then
|
|
log "symlinking fdfind -> fd in ~/.local/bin"
|
|
mkdir -p "$USER_HOME/.local/bin"
|
|
ln -sf "$(command -v fdfind)" "$USER_HOME/.local/bin/fd"
|
|
fi
|
|
|
|
# Debian ships 'bat' as 'batcat' due to a name clash with an unrelated
|
|
# package. The install happens in run_onchange_30 (after rustup is ready,
|
|
# via `cargo install bat`).
|
|
|
|
# Neovim — install official binary tarball, pinned to a known-good version.
|
|
# Bump NVIM_TARGET_VERSION to upgrade. ~/.local/bin/update-neovim.sh does
|
|
# the same check + download so topgrade can invoke it for upgrades.
|
|
NVIM_TARGET_VERSION="v0.11.4"
|
|
ARCH="$(uname -m)"
|
|
case "$ARCH" in
|
|
x86_64)
|
|
NVIM_TARBALL="nvim-linux64.tar.gz"
|
|
NVIM_EXTRACT_DIR="nvim-linux64"
|
|
;;
|
|
aarch64|arm64)
|
|
NVIM_TARBALL="nvim-linux-arm64.tar.gz"
|
|
NVIM_EXTRACT_DIR="nvim-linux-arm64"
|
|
;;
|
|
*)
|
|
die "unsupported arch for neovim tarball: $ARCH"
|
|
;;
|
|
esac
|
|
|
|
if command -v nvim >/dev/null 2>&1; then
|
|
INSTALLED_VER="$(nvim --version 2>/dev/null | head -1 | awk '{print $2}')"
|
|
if [[ "$INSTALLED_VER" == "$NVIM_TARGET_VERSION" ]]; then
|
|
log "neovim $INSTALLED_VER matches target — skipping"
|
|
NVIM_TARBALL=""
|
|
else
|
|
log "neovim $INSTALLED_VER != target $NVIM_TARGET_VERSION — upgrading"
|
|
fi
|
|
fi
|
|
|
|
if [[ -n "$NVIM_TARBALL" ]]; then
|
|
log "downloading neovim $NVIM_TARGET_VERSION ($NVIM_TARBALL)"
|
|
cd /tmp
|
|
if ! curl -fL --retry 3 \
|
|
"https://github.com/neovim/neovim/releases/download/${NVIM_TARGET_VERSION}/${NVIM_TARBALL}" \
|
|
-o nvim.tar.gz; then
|
|
die "failed to download neovim tarball"
|
|
fi
|
|
sudo rm -rf /opt/nvim-linux* /usr/local/bin/nvim
|
|
sudo tar -xzf nvim.tar.gz -C /opt/
|
|
sudo ln -sf "/opt/${NVIM_EXTRACT_DIR}/bin/nvim" /usr/local/bin/nvim
|
|
rm -f nvim.tar.gz
|
|
fi
|
|
|
|
# Verify neovim is reachable (PATH may need /usr/local/bin explicitly for this run)
|
|
if ! command -v nvim >/dev/null 2>&1 && [[ -x /usr/local/bin/nvim ]]; then
|
|
export PATH="/usr/local/bin:$PATH"
|
|
fi
|
|
|
|
{{ else -}}
|
|
die "unsupported os_family: {{ .os_family }}"
|
|
{{ end -}}
|
|
|
|
# --------------------------- OH-MY-ZSH -------------------------------------
|
|
if [[ ! -d "$USER_HOME/.oh-my-zsh" ]]; then
|
|
log "installing oh-my-zsh (unattended)"
|
|
RUNZSH=no CHSH=no sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
|
else
|
|
log "oh-my-zsh already installed"
|
|
fi
|
|
|
|
# zsh plugins (loaded by .zshrc)
|
|
install_zsh_plugin() {
|
|
local repo="$1" target="$2"
|
|
if [[ -d "$target" ]]; then
|
|
log "plugin already present: $target"
|
|
else
|
|
log "cloning plugin: $repo"
|
|
git clone --depth 1 "https://github.com/$repo.git" "$target"
|
|
fi
|
|
}
|
|
|
|
install_zsh_plugin zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions"
|
|
install_zsh_plugin zsh-users/zsh-syntax-highlighting "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting"
|
|
install_zsh_plugin zsh-users/zsh-history-substring-search "$ZSH_CUSTOM/plugins/zsh-history-substring-search"
|
|
|
|
# --------------------------- TPM (tmux plugin manager) ---------------------
|
|
if [[ ! -d "$USER_HOME/.tmux/plugins/tpm" ]]; then
|
|
log "cloning tmux plugin manager"
|
|
mkdir -p "$USER_HOME/.tmux/plugins"
|
|
git clone --depth 1 https://github.com/tmux-plugins/tpm "$USER_HOME/.tmux/plugins/tpm"
|
|
else
|
|
log "tpm already installed"
|
|
fi
|
|
|
|
# --------------------------- Maple Mono NF font ----------------------------
|
|
# nvim init.lua references "Maple Mono NF". Install it so the default font works.
|
|
# Pin Maple-font version. Bump manually if a release breaks things.
|
|
MAPLE_FONT_VERSION="v7.9"
|
|
|
|
if fc-list 2>/dev/null | grep -qi "Maple Mono NF"; then
|
|
log "Maple Mono NF already installed"
|
|
else
|
|
{{ if eq .os_family "arch" -}}
|
|
log "installing maplemono-nf-cn from AUR (via paru)"
|
|
paru -S --needed --noconfirm maplemono-nf-cn
|
|
{{ else if eq .os_family "debian" -}}
|
|
log "downloading MapleMono-NF.zip from subframe7536/Maple-font $MAPLE_FONT_VERSION"
|
|
FONT_DIR="$USER_HOME/.local/share/fonts/maple-mono-nf"
|
|
mkdir -p "$FONT_DIR"
|
|
TMP_ZIP="$(mktemp /tmp/maple-font.XXXXXX.zip)"
|
|
if curl -fL --retry 3 \
|
|
"https://github.com/subframe7536/Maple-font/releases/download/${MAPLE_FONT_VERSION}/MapleMono-NF.zip" \
|
|
-o "$TMP_ZIP"; then
|
|
log "extracting font files"
|
|
unzip -q -o "$TMP_ZIP" -d "$FONT_DIR"
|
|
rm -f "$TMP_ZIP"
|
|
log "refreshing font cache (fc-cache)"
|
|
if command -v fc-cache >/dev/null 2>&1; then
|
|
fc-cache -fv >/dev/null
|
|
else
|
|
log "WARNING: fc-cache not found — install fontconfig package"
|
|
fi
|
|
else
|
|
log "WARNING: failed to download Maple Mono NF — nvim will warn about missing font"
|
|
log "manual install: https://github.com/subframe7536/Maple-font"
|
|
rm -f "$TMP_ZIP"
|
|
fi
|
|
{{ else -}}
|
|
log "WARNING: font install not configured for os_family={{ .os_family }}"
|
|
{{ end -}}
|
|
fi
|
|
|
|
# --------------------------- set zsh as default shell ---------------------
|
|
USER_SHELL="$(getent passwd "$(whoami)" | cut -d: -f7)"
|
|
if [[ "$USER_SHELL" != "$(command -v zsh)" ]]; then
|
|
log "changing login shell to zsh"
|
|
sudo chsh -s "$(command -v zsh)" "$(whoami)"
|
|
else
|
|
log "zsh already the login shell"
|
|
fi
|
|
|
|
log "all user packages installed"
|
|
zsh --version
|
|
nvim --version | head -1
|
|
tmux -V |