Two corrections to the GURU package list: 1. lazygit: was 'app-misc/lazygit' but GURU has it at 'dev-vcs/lazygit'. emerge failed with 'no ebuilds to satisfy' on app-misc/lazygit. 2. topgrade: not in any gentoo overlay. It's installed via cargo (handled by run_onchange_30-ensure-cargo.sh which has 'cargo install topgrade --locked' as the debian branch — same applies on gentoo). Removing it from the GURU emerge list avoids the same 'no ebuilds' error.
218 lines
No EOL
8.3 KiB
Bash
218 lines
No EOL
8.3 KiB
Bash
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# run_once_20-install-user-packages-gentoo.sh.tmpl (gentoo-only)
|
|
# Install the user package set on gentoo via emerge.
|
|
#
|
|
# Equivalent to run_once_20-install-user-packages.sh.tmpl's arch/debian
|
|
# branches, but using portage. Key differences:
|
|
# - USE flags matter (e.g. eza has git feature flag, fzf has shell-completion)
|
|
# - Some packages are only in GURU overlay (eza, lazygit, topgrade, etc.)
|
|
# - emerge is slow (compiles from source); distcc handles remote builds
|
|
# - Bun isn't in any gentoo overlay; use the official curl install
|
|
#
|
|
# Runs after 00-install-bootstrap-tools.sh and 10-add-gentoo-overlays.sh.
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
# Make user-local bins (bun, omp, cargo) visible to the script even when
|
|
# invoked from a non-interactive context (e.g. `chezmoi apply` over SSH).
|
|
export PATH="/usr/bin:/bin:$HOME/.local/bin:$HOME/.bun/bin:$HOME/.cargo/bin:$PATH"
|
|
|
|
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}"
|
|
|
|
# ----------------------------- GENTOO ---------------------------------------
|
|
# On gentoo, `emerge` is the only PM (plus the GURU overlay for some
|
|
# packages). Many of the user packages live in GURU, so we run emerge with
|
|
# GURU enabled. Distcc is recommended for this box (2-core Ivy Bridge +
|
|
# MAKEOPTS=-j50 means it's relying on remote build hosts via DISTCC_HOSTS).
|
|
#
|
|
# Package selection mirrors the arch/debian script. Where a package is
|
|
# only available with USE flags, we set them in /etc/portage/package.use/
|
|
# before emerging. Where a package is ~amd64-only, we accept_keywords.
|
|
|
|
log "checking user packages (gentoo)"
|
|
|
|
# Step 1: USE flags + accept_keywords for packages that need them
|
|
# Some packages need explicit USE flags or keyword unmask. Set them in
|
|
# package.use/package.accept_keywords so emerge sees them.
|
|
# eza is at sys-apps/eza (not app-misc/eza — that's a common typo).
|
|
USE_DIR="/etc/portage/package.use"
|
|
ACCEPT_DIR="/etc/portage/package.accept_keywords"
|
|
mkdir -p "$USE_DIR" "$ACCEPT_DIR" 2>/dev/null || true
|
|
sudo mkdir -p "$USE_DIR" "$ACCEPT_DIR"
|
|
|
|
# eza: USE=git enables git status column
|
|
# Skip if already set
|
|
if ! grep -q "^sys-apps/eza" "$USE_DIR/zz-gentoo-bootstrap" 2>/dev/null; then
|
|
log "writing USE flags: sys-apps/eza git"
|
|
echo "sys-apps/eza git" | sudo tee "$USE_DIR/zz-gentoo-bootstrap" >/dev/null
|
|
fi
|
|
|
|
# fzf-tab, zsh-autosuggestions: gentoo has them in app-shells/ but newer
|
|
# versions may need unmask. Use the ones in the tree first; if too old,
|
|
# we'll install via oh-my-zsh custom plugins (gentoo's ebuilds can lag).
|
|
|
|
# Step 2: Define the package set
|
|
# Note: on Gentoo there's no `base-devel` meta-package. The toolchain
|
|
# (gcc, binutils, glibc, make, patch, etc.) is part of the @system set
|
|
# which is always installed. We only need to list user-space packages.
|
|
GENTOO_PKGS=(
|
|
app-shells/zsh
|
|
app-shells/zsh-completions
|
|
app-shells/zsh-syntax-highlighting
|
|
app-admin/tmux
|
|
app-editors/neovim
|
|
dev-vcs/git
|
|
app-text/bat
|
|
sys-process/btop
|
|
sys-process/htop
|
|
app-text/fastfetch
|
|
sys-apps/eza # in main, sys-apps category (not app-misc!)
|
|
app-shells/fzf
|
|
sys-apps/fd # in main, sys-apps category (not app-misc!)
|
|
sys-apps/ripgrep
|
|
app-shells/zoxide
|
|
app-shells/starship
|
|
# lazygit is in GURU (app-misc/lazygit)
|
|
# topgrade is in GURU (app-misc/topgrade)
|
|
# media-video/yt-dlp is in main
|
|
app-text/jq
|
|
app-arch/unzip
|
|
app-arch/p7zip
|
|
net-misc/openssh
|
|
# bun: NOT in gentoo (main or GURU). Install via official curl.
|
|
)
|
|
|
|
# Step 3: Determine what's missing
|
|
# gentoo's emerge has a "is it installed?" check via `qlist` or `equery`.
|
|
# Simpler: check if the binary is on PATH.
|
|
MISSING_PKGS=()
|
|
for p in "${GENTOO_PKGS[@]}"; do
|
|
# Use the package basename as a proxy for "is the binary installed"
|
|
bin_name=$(basename "$p")
|
|
# Strip the category for the binary lookup (e.g. app-shells/zsh -> zsh)
|
|
if ! command -v "$bin_name" >/dev/null 2>&1; then
|
|
MISSING_PKGS+=("$p")
|
|
fi
|
|
done
|
|
|
|
# Step 4: Install
|
|
if (( ${#MISSING_PKGS[@]} > 0 )); then
|
|
log "emerge --newuse user packages (missing: ${MISSING_PKGS[*]})"
|
|
log "this may take a while (gentoo compiles from source; distcc helps)"
|
|
# --ask=n: no prompts
|
|
# --nospinner: cleaner output
|
|
# --quiet-build: only show errors during compile
|
|
# --keep-going: don't abort if one package fails
|
|
# --with-bdeps=y: include build deps so we don't accidentally skip them
|
|
sudo emerge --ask=n --nospinner --quiet-build --keep-going \
|
|
--with-bdeps=y --autounmask-license=y \
|
|
"${MISSING_PKGS[@]}"
|
|
else
|
|
log "all user packages already installed; skipping emerge"
|
|
fi
|
|
|
|
# Step 5: GURU-only packages
|
|
# Note: topgrade is NOT in any gentoo overlay (not main, not GURU).
|
|
# It's installed via `cargo install topgrade --locked` (handled by
|
|
# run_onchange_30-ensure-cargo.sh). The cargo binary is at
|
|
# ~/.cargo/bin which we put on PATH at the top of this script.
|
|
# lazygit IS in GURU but at dev-vcs/lazygit (not app-misc/lazygit).
|
|
GURU_PKGS=(
|
|
dev-vcs/lazygit
|
|
)
|
|
|
|
GURU_MISSING=()
|
|
for p in "${GURU_PKGS[@]}"; do
|
|
bin_name=$(basename "$p")
|
|
if ! command -v "$bin_name" >/dev/null 2>&1; then
|
|
GURU_MISSING+=("$p")
|
|
fi
|
|
done
|
|
|
|
if (( ${#GURU_MISSING[@]} > 0 )); then
|
|
log "emerge GURU packages (missing: ${GURU_MISSING[*]})"
|
|
sudo emerge --ask=n --nospinner --quiet-build --keep-going \
|
|
--with-bdeps=y --autounmask-license=y \
|
|
"${GURU_MISSING[@]}"
|
|
fi
|
|
|
|
# Step 6: bun (no gentoo package) — install via official curl, fallback path
|
|
if ! command -v bun >/dev/null 2>&1; then
|
|
log "installing bun via official curl installer (no gentoo package)"
|
|
curl -fsSL https://bun.sh/install | BUN_INSTALL="$HOME/.local" bash
|
|
fi
|
|
|
|
# Post-install verification: bun must be on PATH
|
|
if ! command -v bun >/dev/null 2>&1; then
|
|
log "ERROR: bun install succeeded but bun is not on PATH"
|
|
log " check \$BUN_INSTALL/bin/bun exists and is in PATH"
|
|
exit 1
|
|
fi
|
|
BUN_VER=$(bun --version 2>/dev/null)
|
|
log "bun: $BUN_VER (from official bun.sh installer; gentoo has no package)"
|
|
|
|
# Step 7: oh-my-zsh + plugins
|
|
if [[ ! -d "$USER_HOME/.oh-my-zsh" ]]; then
|
|
log "installing oh-my-zsh"
|
|
RUNZSH=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
|
|
|
|
# Plugins: zsh-autosuggestions, zsh-syntax-highlighting, zsh-history-substring-search, fzf-tab
|
|
declare -A PLUGINS=(
|
|
[zsh-autosuggestions]="https://github.com/zsh-users/zsh-autosuggestions"
|
|
[zsh-syntax-highlighting]="https://github.com/zsh-users/zsh-syntax-highlighting"
|
|
[zsh-history-substring-search]="https://github.com/zsh-users/zsh-history-substring-search"
|
|
[fzf-tab]="https://github.com/Aloxaf/fzf-tab"
|
|
)
|
|
for plugin in "${!PLUGINS[@]}"; do
|
|
if [[ -d "$ZSH_CUSTOM/plugins/$plugin" ]]; then
|
|
log "plugin already present: $ZSH_CUSTOM/plugins/$plugin"
|
|
else
|
|
log "cloning plugin: $plugin"
|
|
git clone --depth=1 "${PLUGINS[$plugin]}" "$ZSH_CUSTOM/plugins/$plugin"
|
|
fi
|
|
done
|
|
|
|
# Step 8: tpm (tmux plugin manager)
|
|
if [[ ! -d "$USER_HOME/.tmux/plugins/tpm" ]]; then
|
|
log "installing tpm"
|
|
git clone https://github.com/tmux-plugins/tpm "$USER_HOME/.tmux/plugins/tpm"
|
|
else
|
|
log "tpm already installed"
|
|
fi
|
|
|
|
# Step 9: Maple Mono NF font
|
|
if ! fc-list | grep -qi "Maple Mono NF"; then
|
|
log "installing Maple Mono NF font"
|
|
# Download the latest release zip
|
|
TMPFONT=$(mktemp -d)
|
|
curl -fsSL "https://github.com/subframe7536/Maple-font/releases/latest/download/MapleMono-NF.zip" \
|
|
-o "$TMPFONT/MapleMono-NF.zip"
|
|
mkdir -p "$USER_HOME/.local/share/fonts"
|
|
unzip -q "$TMPFONT/MapleMono-NF.zip" -d "$USER_HOME/.local/share/fonts"
|
|
fc-cache -fv >/dev/null 2>&1
|
|
rm -rf "$TMPFONT"
|
|
else
|
|
log "Maple Mono NF already installed"
|
|
fi
|
|
|
|
# Step 10: zsh as login shell
|
|
if [[ "$(getent passwd rain | cut -d: -f7)" != "/usr/bin/zsh" ]]; then
|
|
log "changing default shell to /usr/bin/zsh"
|
|
sudo chsh -s /usr/bin/zsh rain
|
|
else
|
|
log "zsh already the login shell"
|
|
fi
|
|
|
|
log "all user packages installed"
|
|
zsh --version
|
|
nvim --version | head -1
|
|
tmux -V |