diff --git a/.chezmoi.yaml.tmpl b/.chezmoi.yaml.tmpl index 0cab74f..0253b13 100644 --- a/.chezmoi.yaml.tmpl +++ b/.chezmoi.yaml.tmpl @@ -3,10 +3,19 @@ {{- if hasKey .chezmoi.osRelease "idLike" -}} {{- $idLike = .chezmoi.osRelease.idLike -}} {{- end -}} -{{- if or (eq .chezmoi.osRelease.id "arch") (contains "arch" $idLike) -}} +{{- $osId := .chezmoi.osRelease.id -}} +{{- /* Gentoo's /etc/os-release uses single-quoted values (e.g. ID='gentoo'), + and the parser doesn't strip them, so strip here. Other distros use + double-quoted or unquoted values which the parser handles. */ -}} +{{- if hasPrefix "'" $osId -}} + {{- $osId = trimAll "'" $osId -}} +{{- end -}} +{{- if or (eq $osId "arch") (contains "arch" $idLike) -}} {{- $osFamily = "arch" -}} -{{- else if or (eq .chezmoi.osRelease.id "debian") (contains "debian" $idLike) -}} +{{- else if or (eq $osId "debian") (contains "debian" $idLike) -}} {{- $osFamily = "debian" -}} +{{- else if eq $osId "gentoo" -}} + {{- $osFamily = "gentoo" -}} {{- end -}} encryption: "age" # chezmoi's builtin age implementation requires a TTY for passphrase-style @@ -71,7 +80,7 @@ age: data: os_family: {{ $osFamily | quote }} - os_id: {{ .chezmoi.osRelease.id | quote }} + os_id: {{ $osId | quote }} # Sway/Wayland desktop stack — opt-in at bootstrap time. When you # run `chezmoi init` for the first time, you'll be asked: diff --git a/README.md b/README.md index b05c170..06adf8a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Remote: `https://git.melonbread.xyz/rain/gnu-plus-dotfiles.git` (HTTPS for boots ## What's in here ``` -.chezmoi.yaml.tmpl os_family detection (debian | arch) +.chezmoi.yaml.tmpl os_family detection (debian | arch | gentoo) dot_zshrc.tmpl zsh config with os_family-conditional aliases dot_tmux.conf tmux + tpm + gruvbox plugin stack dot_gitconfig.tmpl git + delta @@ -29,14 +29,27 @@ dot_config/ waybar/ waybar status bar mako/ (arch-only) mako notification daemon -run_once_00-install-bootstrap-tools.sh.tmpl +run_once_00-install-bootstrap-tools.sh.tmpl age, curl, git, base-devel (pacman/apt/emerge) run_once_05-install-hosts.sh.tmpl merge LAN host entries into /etc/hosts -run_once_10-add-chaotic-aur.sh.tmpl (arch-only) -run_once_20-install-user-packages.sh.tmpl -run_onchange_30-ensure-cargo.sh.tmpl -run_once_40-install-sway.sh.tmpl (desktops only) sway + wofi + foot +run_once_10-add-chaotic-aur.sh.tmpl (arch-only) chaotic-aur + paru +run_once_10-add-gentoo-overlays.sh.tmpl (gentoo-only) enable GURU overlay +run_once_20-install-user-packages.sh.tmpl (arch+debian) user package set +run_once_20-install-user-packages-gentoo.sh.tmpl (gentoo-only) user package set via emerge +run_onchange_30-ensure-cargo.sh.tmpl rustup + bat/topgrade/cargo-update (all 3 OSes) +run_once_40-install-sway.sh.tmpl (arch+debian) sway + wofi + foot +run_once_40-install-sway-gentoo.sh.tmpl (gentoo-only) sway stack via emerge ``` +## Gentoo notes + +Gentoo support was added 2026-06-23 with the GURU overlay requirement. Key differences from arch/debian: + +- **No binary packages by default** — `emerge` compiles from source. The bootstrap scripts set `--ask=n --nospinner --quiet-build --keep-going` so installs don't prompt and don't abort on a single failure. +- **USE flags matter** — `run_once_20-install-user-packages-gentoo.sh` writes to `/etc/portage/package.use/zz-gentoo-bootstrap` BEFORE emerging, so the right features are enabled for `eza`, `foot`, `waybar`, etc. +- **GURU overlay is required** — `run_once_10-add-gentoo-overlays.sh` runs `eselect repository enable guru` + `emaint sync -r guru`. Many user packages (eza, lazygit, topgrade) live in GURU; the main tree alone won't suffice. +- **Per-machine os-release parsing** — Gentoo's `/etc/os-release` uses single-quoted values (e.g. `ID='gentoo'`), and the parser doesn't strip them, so the `os_family` template strips them with `trimAll "'"`. Without that fix, `.chezmoi.osRelease.id` returns `'gentoo'` (with literal quotes), and the `eq "gentoo"` test fails. +- **bun is not in any gentoo overlay** — the official curl installer (`curl -fsSL https://bun.sh/install | bash`) is the fallback path, just like debian. + ## Onboarding a new box **One command.** Copy/paste this on a fresh debian-stable or arch-base install: diff --git a/run_once_00-install-bootstrap-tools.sh.tmpl b/run_once_00-install-bootstrap-tools.sh.tmpl index 587333c..114b3fb 100755 --- a/run_once_00-install-bootstrap-tools.sh.tmpl +++ b/run_once_00-install-bootstrap-tools.sh.tmpl @@ -54,8 +54,42 @@ else log "all base tools already installed; skipping apt" fi +{{ else if eq .os_family "gentoo" -}} +# Gentoo: bootstrap tools come from the main tree. `age` is in the +# main tree (app-crypt/age), curl/ca-certificates/git are @system. +# Skip the install only if everything is already present (no +# `emerge` no-op — emerge is slow and a fresh sync can take minutes). +MISSING_PKGS=() +for p in age curl ca-certificates git wget gnupg; do + if ! command -v "$p" >/dev/null 2>&1; then + MISSING_PKGS+=("$p") + fi +done + +if (( ${#MISSING_PKGS[@]} > 0 )); then + log "emerge bootstrap tools (missing: ${MISSING_PKGS[*]})" + # On Gentoo, `emerge --sync` is required first to populate the + # portage tree. If the box hasn't synced in a while, do it now. + # Skip the sync if /var/db/repos/gentoo is recent (< 1 day). + sync_needed=1 + if [[ -d /var/db/repos/gentoo ]]; then + # Check age of the metadata timestamp + sync_needed=$(find /var/db/repos/gentoo -name 'metadata.timestamp' -mtime -1 2>/dev/null | head -1 | wc -l) + fi + if (( sync_needed == 0 )); then + log "portage tree is fresh (< 1 day old); skipping emerge --sync" + else + log "emerge --sync (portage tree is stale or missing)" + sudo emerge --sync + fi + log "emerge bootstrap tools" + sudo emerge --ask=n --nospinner --quiet-build "${MISSING_PKGS[@]}" +else + log "all base tools already installed; skipping emerge" +fi + {{ else -}} -die "unsupported os_family: {{ .os_family }} (this script supports arch or debian)" +die "unsupported os_family: {{ .os_family }} (this script supports arch, debian, or gentoo)" {{ end -}} log "bootstrap tools installed" diff --git a/run_once_10-add-gentoo-overlays.sh.tmpl b/run_once_10-add-gentoo-overlays.sh.tmpl new file mode 100644 index 0000000..4596609 --- /dev/null +++ b/run_once_10-add-gentoo-overlays.sh.tmpl @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# ============================================================================= +# run_once_05-add-gentoo-overlays.sh.tmpl (gentoo-only) +# Add the GURU overlay to the portage repository list. GURU is the +# community overlay (like AUR for arch) where packages like bun, eza, +# sway, etc. live when they're not in the main tree. +# +# Idempotent: skips if GURU is already enabled. +# Run-order: 00 (bootstrap) → 05-overlays (here) → 10-add-{chaotic,debian} +# → 20-install-packages → 40-install-sway +# ============================================================================= +set -euo pipefail + +log() { printf '\033[1;34m[overlays]\033[0m %s\n' "$*"; } +die() { printf '\033[1;31m[overlays ERROR]\033[0m %s\n' "$*" >&2; exit 1; } + +# This script is gentoo-only. Guarded by the chezmoi template engine; +# on arch/debian it never renders (only this single file path). + +if [[ ! -d /var/db/repos/gentoo ]]; then + die "/var/db/repos/gentoo missing — this doesn't look like a gentoo system" +fi + +# --- 1. GURU overlay --- +# User explicitly requires GURU. Per the bootstrap-runbook skill: gentoo +# boxes without GURU can't install most of the user packages (eza, fzf, +# fd-find on stable, lazygit, topgrade, etc.) because they only ship in +# the main tree as ~amd64 or only live in GURU. +if [[ -d /var/db/repos/guru ]]; then + log "GURU overlay already enabled at /var/db/repos/guru — skipping" +else + log "enabling GURU overlay via eselect repository" + # `eselect repository` needs the overlays.xml index; sync first if missing + if ! sudo eselect repository list 2>&1 | grep -qi guru; then + log "fetching overlays.xml index" + sudo emaint sync --auto + fi + sudo eselect repository enable guru + # Sync just the new repo so we don't re-pull the entire gentoo tree + log "syncing GURU overlay" + sudo emaint sync -r guru + log "GURU overlay enabled and synced" +fi + +# --- 2. Verify --- +log "enabled overlays:" +eselect repository list 2>&1 | sed 's/^/ /' + +# Verify the GURU repo is readable +if [[ ! -f /var/db/repos/guru/profiles/repo_name ]]; then + die "/var/db/repos/guru/profiles/repo_name missing — overlay didn't sync cleanly" +fi +GURU_NAME=$(cat /var/db/repos/guru/profiles/repo_name) +log "GURU repo verified: $GURU_NAME" + +log "overlays ready" \ No newline at end of file diff --git a/run_once_20-install-user-packages-gentoo.sh.tmpl b/run_once_20-install-user-packages-gentoo.sh.tmpl new file mode 100644 index 0000000..c8e4d5e --- /dev/null +++ b/run_once_20-install-user-packages-gentoo.sh.tmpl @@ -0,0 +1,211 @@ +#!/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 (eza, lazygit) need explicit USE flags or keyword unmask. +# Set them in package.use/package.accept_keywords so emerge sees them. +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: needs explicit accept_keywords (was masked), USE=git enables git status column +# Skip if already set +if ! grep -q "^app-misc/eza" "$USE_DIR/zz-gentoo-bootstrap" 2>/dev/null; then + log "writing USE flags: app-misc/eza git" + echo "app-misc/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 +GENTOO_PKGS=( + app-shells/zsh + app-shells/zsh-completions + app-shells/zsh-syntax-highlighting + app-admin/tmux + app-editors/neovim + dev-vcs/git + sys-devel/base-devel + app-text/bat + sys-process/btop + sys-process/htop + app-text/fastfetch + app-misc/eza + app-shells/fzf + app-misc/fd + sys-apps/ripgrep + app-shells/zoxide + app-shells/starship + # lazygit is in GURU (app-vim/lazygit? actually app-misc/lazygit in guru) + # topgrade is in GURU + # 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 (lazygit, topgrade) +GURU_PKGS=( + app-misc/lazygit + app-misc/topgrade +) + +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 \ No newline at end of file diff --git a/run_once_40-install-sway-gentoo.sh.tmpl b/run_once_40-install-sway-gentoo.sh.tmpl new file mode 100644 index 0000000..769414e --- /dev/null +++ b/run_once_40-install-sway-gentoo.sh.tmpl @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# ============================================================================= +# run_once_40-install-sway-gentoo.sh.tmpl (gentoo-only) +# Install the sway + wofi + foot + supporting tooling desktop stack on +# gentoo. Equivalent to run_once_40-install-sway.sh.tmpl's arch/debian +# branches. +# +# Gated on .sway_setup. When false (Pis, headless boxes), this script +# exits 0 without doing anything. +# ============================================================================= +set -euo pipefail + +log() { printf '\033[1;34m[sway]\033[0m %s\n' "$*"; } + +# --- 0. Gate on .sway_setup --- +{{ if not .sway_setup -}} +log "sway_setup not enabled for this host (.sway_setup=false). Skipping." +log "To enable: touch ~/.config/chezmoi/features/sway && chezmoi apply" +exit 0 +{{ end -}} + +# Gentoo package set for sway + companions. All live in the main tree +# except some compositor deps that may need ~amd64. +SWAY_PKGS=( + gui-wm/sway + gui-apps/wofi + gui-apps/foot + gui-apps/swaybg + gui-apps/swaylock + gui-apps/swayidle + media-gfx/grim + media-gfx/slurp + gui-apps/waybar + gui-apps/wl-clipboard + x11-terms/foot-terminfo # for $TERM=foot support +) + +log "checking sway stack: ${SWAY_PKGS[*]}" + +# On gentoo, USE flags matter. Set the ones we need BEFORE emerging. +USE_DIR="/etc/portage/package.use/sway-bootstrap" +sudo mkdir -p "$(dirname "$USE_DIR")" +# sway itself doesn't need flags, but foot needs `+X +wayland`, waybar +# needs `+X +wayland +network +tray +upower +wireplumber`. Lay them out. +# Note: most gentoo ebuilds for these packages have sensible defaults, +# but be explicit for reproducibility. +sudo tee "$USE_DIR" >/dev/null <<'USE_FLAGS' +gui-wm/sway X wayland +gui-apps/foot X wayland +gui-apps/wofi X wayland +gui-apps/waybar X wayland tray upower wireplumber +USE_FLAGS + +# Map package names to actual binaries (some packages ship under a +# different name, e.g. wl-clipboard provides wl-copy/wl-paste). +# On gentoo the package name is `gui-apps/wl-clipboard` but the +# binary is `wl-copy`. Strip the category prefix and look up the map. +declare -A PKG_BIN=( + [gui-apps/wl-clipboard]="wl-copy" + [x11-terms/foot-terminfo]="foot" +) +MISSING_PKGS=() +for p in "${SWAY_PKGS[@]}"; do + bin="${PKG_BIN[$p]:-$(basename "$p")}" + if ! command -v "$bin" >/dev/null 2>&1; then + MISSING_PKGS+=("$p") + fi +done + +if (( ${#MISSING_PKGS[@]} > 0 )); then + log "missing: ${MISSING_PKGS[*]}" + log "emerge sway stack (gentoo compiles from source; this may take a while)" + sudo emerge --ask=n --nospinner --quiet-build --keep-going \ + --with-bdeps=y --autounmask-license=y \ + "${MISSING_PKGS[@]}" +else + log "all sway packages already installed; skipping emerge" +fi + +log "sway stack installed" +sway --version 2>&1 | head -1 +foot --version 2>&1 | head -1 +wofi --version 2>&1 | head -1 + +# Mark the box so subsequent chezmoi applies know sway is enabled +mkdir -p ~/.config/chezmoi/features +touch ~/.config/chezmoi/features/sway +log "marked box: ~/.config/chezmoi/features/sway" + +log "sway stack install complete" \ No newline at end of file diff --git a/run_onchange_30-ensure-cargo.sh.tmpl b/run_onchange_30-ensure-cargo.sh.tmpl index a89c3f1..363f829 100755 --- a/run_onchange_30-ensure-cargo.sh.tmpl +++ b/run_onchange_30-ensure-cargo.sh.tmpl @@ -37,7 +37,7 @@ log "cargo installed: $(cargo --version)" # --- 2. Install bat (upstream binary, not renamed batcat) --- # On debian, apt installs bat as "batcat" (Debian has its own unrelated bat). -# The clean fix is cargo install on debian, pacman on arch. +# The clean fix is cargo install on debian, pacman on arch, portage on gentoo. {{ if eq .os_family "debian" -}} if ! command -v bat >/dev/null 2>&1; then log "installing bat via cargo (debian renames upstream bat to batcat)" @@ -46,6 +46,13 @@ if ! command -v bat >/dev/null 2>&1; then else log "bat already installed: $(bat --version)" fi +{{ else if eq .os_family "gentoo" -}} +# Gentoo: app-text/bat is in main, ships upstream binary +if ! command -v bat >/dev/null 2>&1; then + log "WARNING: bat not installed — should have been installed by run_once_20" +else + log "bat already installed (gentoo: app-text/bat): $(bat --version)" +fi {{ else -}} # Arch already installs upstream bat via pacman [extra]. log "skipping cargo bat install (os_family={{ .os_family }}, pacman handles it)" @@ -58,6 +65,7 @@ log "skipping cargo bat install (os_family={{ .os_family }}, pacman handles it)" # - arch: topgrade is in [chaotic-aur] (we have chaotic-aur configured). # Use pacman to get system-tracked installs. # - debian: topgrade isn't in apt. Install via cargo (no PM alternative). +# - gentoo: topgrade is in GURU overlay. Use emerge. if ! command -v topgrade >/dev/null 2>&1; then {{ if eq .os_family "arch" -}} log "installing topgrade via pacman (chaotic-aur)" @@ -65,6 +73,9 @@ if ! command -v topgrade >/dev/null 2>&1; then {{ else if eq .os_family "debian" -}} log "installing topgrade via cargo (debian has no topgrade package)" cargo install topgrade --locked +{{ else if eq .os_family "gentoo" -}} + log "installing topgrade via emerge (gentoo: app-misc/topgrade in GURU)" + sudo emerge --ask=n --nospinner --quiet-build app-misc/topgrade {{ else -}} log "WARNING: topgrade install not configured for os_family={{ .os_family }}" {{ end -}} @@ -75,7 +86,7 @@ fi # --- 4. Install cargo-update (so we can `cargo install-update -a`) --- # Used to bump cargo-installed packages. Arch has it in [extra]; debian -# doesn't ship it. +# doesn't ship it; gentoo has it in main (dev-util/cargo-update). if ! command -v cargo-install-update >/dev/null 2>&1; then {{ if eq .os_family "arch" -}} log "installing cargo-update via pacman" @@ -83,6 +94,9 @@ if ! command -v cargo-install-update >/dev/null 2>&1; then {{ else if eq .os_family "debian" -}} log "installing cargo-update via cargo (debian has no cargo-update package)" cargo install cargo-update --locked +{{ else if eq .os_family "gentoo" -}} + log "installing cargo-update via emerge (gentoo: dev-util/cargo-update)" + sudo emerge --ask=n --nospinner --quiet-build dev-util/cargo-update {{ else -}} log "WARNING: cargo-update install not configured for os_family={{ .os_family }}" {{ end -}}