#!/usr/bin/env bash # ============================================================================= # run_once_00-install-bootstrap-tools.sh.tmpl # Install age, curl, ca-certificates, git — needed before anything else. # Idempotent: skips if already installed. # ============================================================================= set -euo pipefail log() { printf '\033[1;34m[bootstrap]\033[0m %s\n' "$*"; } die() { printf '\033[1;31m[bootstrap ERROR]\033[0m %s\n' "$*" >&2; exit 1; } # This script runs as the invoking user via `chezmoi apply`/`init`. It uses # sudo for system package installs. If sudo isn't passwordless, the user # will be prompted once per sudo invocation. {{ if eq .os_family "arch" -}} # Only sync the package DB if anything is missing. Avoids a no-op sudo # (which would still prompt for a password even when there's nothing to # install) on boxes where all the bootstrap tools are already present. MISSING_PKGS=() for p in age curl ca-certificates git base-devel wget; do if ! command -v "$p" >/dev/null 2>&1 && ! pacman -Qi "$p" >/dev/null 2>&1; then MISSING_PKGS+=("$p") fi done if (( ${#MISSING_PKGS[@]} > 0 )); then log "pacman-sync (missing: ${MISSING_PKGS[*]})" sudo pacman -Sy --noconfirm log "install base tools (arch)" sudo pacman -S --needed --noconfirm "${MISSING_PKGS[@]}" else log "all base tools already installed; skipping pacman" fi {{ else if eq .os_family "debian" -}} export DEBIAN_FRONTEND=noninteractive # Only run apt if anything is missing, so a no-op sudo isn't required. MISSING_PKGS=() for p in age curl ca-certificates git wget gnupg libssl-dev pkg-config; do if ! command -v "$p" >/dev/null 2>&1; then MISSING_PKGS+=("$p") fi done if (( ${#MISSING_PKGS[@]} > 0 )); then log "apt-update (missing: ${MISSING_PKGS[*]})" sudo apt-get update -y log "apt-upgrade" sudo apt-get upgrade -y log "install base tools (debian)" sudo apt-get install -y --no-install-recommends "${MISSING_PKGS[@]}" 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, debian, or gentoo)" {{ end -}} log "bootstrap tools installed" command -v age && age --version command -v git && git --version