Add Gentoo support with GURU overlay requirement
Tadbit (tadbit-gentoo, x86_64, gcc 15.2.1, TKG kernel) joins the
homelab as the 7th machine — the first gentoo box. Adds Gentoo
support to the bootstrap alongside arch and debian.
New scripts:
- run_once_10-add-gentoo-overlays.sh.tmpl: enables GURU overlay
via 'eselect repository enable guru' + 'emaint sync -r guru'.
Idempotent — skips if GURU is already at /var/db/repos/guru.
GURU is required because eza, lazygit, topgrade, and most modern
CLI tools only live in GURU (not main).
- run_once_20-install-user-packages-gentoo.sh.tmpl: emerge-based
user package set. Writes USE flags to package.use/ BEFORE
emerging so foot/wofi/waybar get the right features. Detects
missing packages via 'command -v <basename>'. Falls back to
the official curl installer for bun (no gentoo package).
- run_once_40-install-sway-gentoo.sh.tmpl: sway stack via emerge
with USE flags for X+wayland+tray+upower+wireplumber.
Updated scripts:
- .chezmoi.yaml.tmpl: os_family detection now also matches 'gentoo'.
Critical fix: Gentoo's /etc/os-release uses single-quoted values
('gentoo' not 'gentoo' or "gentoo"), and chezmoi's parser doesn't
strip them. Without trimAll "'", .chezmoi.osRelease.id returns
the literal string 'gentoo' with quotes, and the eq test fails.
Symptom: os_family silently becomes 'unknown'.
- run_once_00-install-bootstrap-tools.sh.tmpl: added gentoo branch
that uses emerge --sync + emerge (skipping if tree is < 1 day old).
- run_onchange_30-ensure-cargo.sh.tmpl: added gentoo branch for
bat (already installed by emerge, just verify), topgrade (GURU),
cargo-update (dev-util/cargo-update in main).
README: documented Gentoo-specific quirks (USE flags, GURU,
single-quote parsing, no binary packages).
This commit is contained in:
parent
1b596bd894
commit
36e9d3e0ce
7 changed files with 439 additions and 12 deletions
|
|
@ -3,10 +3,19 @@
|
||||||
{{- if hasKey .chezmoi.osRelease "idLike" -}}
|
{{- if hasKey .chezmoi.osRelease "idLike" -}}
|
||||||
{{- $idLike = .chezmoi.osRelease.idLike -}}
|
{{- $idLike = .chezmoi.osRelease.idLike -}}
|
||||||
{{- end -}}
|
{{- 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" -}}
|
{{- $osFamily = "arch" -}}
|
||||||
{{- else if or (eq .chezmoi.osRelease.id "debian") (contains "debian" $idLike) -}}
|
{{- else if or (eq $osId "debian") (contains "debian" $idLike) -}}
|
||||||
{{- $osFamily = "debian" -}}
|
{{- $osFamily = "debian" -}}
|
||||||
|
{{- else if eq $osId "gentoo" -}}
|
||||||
|
{{- $osFamily = "gentoo" -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
encryption: "age"
|
encryption: "age"
|
||||||
# chezmoi's builtin age implementation requires a TTY for passphrase-style
|
# chezmoi's builtin age implementation requires a TTY for passphrase-style
|
||||||
|
|
@ -71,7 +80,7 @@ age:
|
||||||
|
|
||||||
data:
|
data:
|
||||||
os_family: {{ $osFamily | quote }}
|
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
|
# Sway/Wayland desktop stack — opt-in at bootstrap time. When you
|
||||||
# run `chezmoi init` for the first time, you'll be asked:
|
# run `chezmoi init` for the first time, you'll be asked:
|
||||||
|
|
|
||||||
25
README.md
25
README.md
|
|
@ -12,7 +12,7 @@ Remote: `https://git.melonbread.xyz/rain/gnu-plus-dotfiles.git` (HTTPS for boots
|
||||||
## What's in here
|
## 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_zshrc.tmpl zsh config with os_family-conditional aliases
|
||||||
dot_tmux.conf tmux + tpm + gruvbox plugin stack
|
dot_tmux.conf tmux + tpm + gruvbox plugin stack
|
||||||
dot_gitconfig.tmpl git + delta
|
dot_gitconfig.tmpl git + delta
|
||||||
|
|
@ -29,14 +29,27 @@ dot_config/
|
||||||
waybar/ waybar status bar
|
waybar/ waybar status bar
|
||||||
mako/ (arch-only) mako notification daemon
|
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_05-install-hosts.sh.tmpl merge LAN host entries into /etc/hosts
|
||||||
run_once_10-add-chaotic-aur.sh.tmpl (arch-only)
|
run_once_10-add-chaotic-aur.sh.tmpl (arch-only) chaotic-aur + paru
|
||||||
run_once_20-install-user-packages.sh.tmpl
|
run_once_10-add-gentoo-overlays.sh.tmpl (gentoo-only) enable GURU overlay
|
||||||
run_onchange_30-ensure-cargo.sh.tmpl
|
run_once_20-install-user-packages.sh.tmpl (arch+debian) user package set
|
||||||
run_once_40-install-sway.sh.tmpl (desktops only) sway + wofi + foot
|
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
|
## Onboarding a new box
|
||||||
|
|
||||||
**One command.** Copy/paste this on a fresh debian-stable or arch-base install:
|
**One command.** Copy/paste this on a fresh debian-stable or arch-base install:
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,42 @@ else
|
||||||
log "all base tools already installed; skipping apt"
|
log "all base tools already installed; skipping apt"
|
||||||
fi
|
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 -}}
|
{{ 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 -}}
|
{{ end -}}
|
||||||
|
|
||||||
log "bootstrap tools installed"
|
log "bootstrap tools installed"
|
||||||
|
|
|
||||||
56
run_once_10-add-gentoo-overlays.sh.tmpl
Normal file
56
run_once_10-add-gentoo-overlays.sh.tmpl
Normal file
|
|
@ -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"
|
||||||
211
run_once_20-install-user-packages-gentoo.sh.tmpl
Normal file
211
run_once_20-install-user-packages-gentoo.sh.tmpl
Normal file
|
|
@ -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
|
||||||
90
run_once_40-install-sway-gentoo.sh.tmpl
Normal file
90
run_once_40-install-sway-gentoo.sh.tmpl
Normal file
|
|
@ -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"
|
||||||
|
|
@ -37,7 +37,7 @@ log "cargo installed: $(cargo --version)"
|
||||||
|
|
||||||
# --- 2. Install bat (upstream binary, not renamed batcat) ---
|
# --- 2. Install bat (upstream binary, not renamed batcat) ---
|
||||||
# On debian, apt installs bat as "batcat" (Debian has its own unrelated bat).
|
# 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 eq .os_family "debian" -}}
|
||||||
if ! command -v bat >/dev/null 2>&1; then
|
if ! command -v bat >/dev/null 2>&1; then
|
||||||
log "installing bat via cargo (debian renames upstream bat to batcat)"
|
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
|
else
|
||||||
log "bat already installed: $(bat --version)"
|
log "bat already installed: $(bat --version)"
|
||||||
fi
|
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 -}}
|
{{ else -}}
|
||||||
# Arch already installs upstream bat via pacman [extra].
|
# Arch already installs upstream bat via pacman [extra].
|
||||||
log "skipping cargo bat install (os_family={{ .os_family }}, pacman handles it)"
|
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).
|
# - arch: topgrade is in [chaotic-aur] (we have chaotic-aur configured).
|
||||||
# Use pacman to get system-tracked installs.
|
# Use pacman to get system-tracked installs.
|
||||||
# - debian: topgrade isn't in apt. Install via cargo (no PM alternative).
|
# - 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 ! command -v topgrade >/dev/null 2>&1; then
|
||||||
{{ if eq .os_family "arch" -}}
|
{{ if eq .os_family "arch" -}}
|
||||||
log "installing topgrade via pacman (chaotic-aur)"
|
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" -}}
|
{{ else if eq .os_family "debian" -}}
|
||||||
log "installing topgrade via cargo (debian has no topgrade package)"
|
log "installing topgrade via cargo (debian has no topgrade package)"
|
||||||
cargo install topgrade --locked
|
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 -}}
|
{{ else -}}
|
||||||
log "WARNING: topgrade install not configured for os_family={{ .os_family }}"
|
log "WARNING: topgrade install not configured for os_family={{ .os_family }}"
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
@ -75,7 +86,7 @@ fi
|
||||||
|
|
||||||
# --- 4. Install cargo-update (so we can `cargo install-update -a`) ---
|
# --- 4. Install cargo-update (so we can `cargo install-update -a`) ---
|
||||||
# Used to bump cargo-installed packages. Arch has it in [extra]; debian
|
# 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 ! command -v cargo-install-update >/dev/null 2>&1; then
|
||||||
{{ if eq .os_family "arch" -}}
|
{{ if eq .os_family "arch" -}}
|
||||||
log "installing cargo-update via pacman"
|
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" -}}
|
{{ else if eq .os_family "debian" -}}
|
||||||
log "installing cargo-update via cargo (debian has no cargo-update package)"
|
log "installing cargo-update via cargo (debian has no cargo-update package)"
|
||||||
cargo install cargo-update --locked
|
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 -}}
|
{{ else -}}
|
||||||
log "WARNING: cargo-update install not configured for os_family={{ .os_family }}"
|
log "WARNING: cargo-update install not configured for os_family={{ .os_family }}"
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue