#!/bin/bash # ╔══════════════════════════════════════════════════════════════════════════════╗ # ║ setup/modules/lib/logging.sh — Shared logging helpers ║ # ║ ║ # ║ PURPOSE: ║ # ║ Provides colored console output functions used by every module script. ║ # ║ Source this file at the top of any module with: ║ # ║ source "$(dirname "${BASH_SOURCE[0]}")/lib/logging.sh" ║ # ║ ║ # ║ WHY A SHARED LIB: ║ # ║ Centralizes formatting so all modules have consistent output. One change ║ # ║ here affects every module's output style. ║ # ║ ║ # ║ ALSO PROVIDES: ║ # ║ - ensure_flatpak: bootstrap Flatpak + Flathub for any app module ║ # ║ - apply_flatpak_theme: apply the cyberqueer GTK theme to a Flatpak app ║ # ╚══════════════════════════════════════════════════════════════════════════════╝ # Shared logging helpers — source this in every module # ── ANSI color codes ────────────────────────────────────────────────────────── # These are escape sequences that terminal emulators interpret as colors. # Format: \e[m where code 31=red, 32=green, 33=yellow, 0=reset. GREEN="\e[32m" YELLOW="\e[33m" RED="\e[31m" RESET="\e[0m" # ── Logging functions ────────────────────────────────────────────────────────── # Each function takes a message string and formats it with a colored prefix. # WHY: Consistent, colored output makes it easy to scan install logs at a glance # and immediately identify success, skips, warnings, or errors. # log: normal progress message — green [+] prefix # Used for: "doing X now", successful completions log() { printf "${GREEN}[+] %s${RESET}\n" "$*"; } # skip: indicates something was already done — yellow [~] prefix # Used for: idempotency checks ("X already installed") skip() { printf "${YELLOW}[~] %s${RESET}\n" "$*"; } # warn: non-fatal warning — yellow [!] prefix to stderr # Used for: recoverable issues that don't abort the module warn() { printf "${YELLOW}[!] %s${RESET}\n" "$*" >&2; } # err: fatal error — red [✖] prefix to stderr # Used for: unrecoverable failures (caller decides whether to exit) err() { printf "${RED}[✖] %s${RESET}\n" "$*" >&2; } # ── Chroot-/session-aware operation helpers ──────────────────────────────────── # Modules are frequently run inside the archiso installer's chroot, where the # new system's systemd is NOT the running init and there is no user session bus. # In that environment: # * `systemctl enable` works (it only writes symlinks), and # * `systemctl start` / `--now` / `systemctl --user` / `gsettings` FAIL, # which would abort a module running under `set -e`. These helpers make those # operations safe so an install completes; the runtime bits take effect on first # boot / first login instead. # in_chroot: true when running inside a chroot (no booted system manager here). in_chroot() { systemd-detect-virt --chroot 2>/dev/null; } # have_user_bus: true when a user session D-Bus is reachable (needed by # `systemctl --user`, gsettings/dconf, flatpak --user overrides, etc.). have_user_bus() { [[ -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]] && return 0 [[ -S "${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/bus" ]] } # enable_service: enable units to start at boot. Best-effort — a failure is # warned, never fatal, so one unenroll-able unit can't abort the whole module. enable_service() { sudo systemctl enable "$@" 2>/dev/null \ || warn "Could not enable: $* — enable it after first boot." } # start_service: start units only when a system manager is actually running. # Inside the installer chroot there is none, so we skip — the unit starts on # first boot via its enable symlink. start_service() { if in_chroot; then skip "Not starting '$*' now (install chroot) — it starts on first boot." return 0 fi sudo systemctl start "$@" 2>/dev/null || warn "Could not start: $*" } # ── ensure_flatpak ───────────────────────────────────────────────────────────── # WHY: Many optional app modules install via Flatpak. Rather than duplicating # the bootstrap code in every app script, this function handles it once. # WHAT: Installs flatpak if missing, adds Flathub remote if not already present. ensure_flatpak() { # Check if flatpak binary is available; install it via pacman if not if ! command -v flatpak &>/dev/null; then log "Installing flatpak..." sudo pacman -S --noconfirm --needed flatpak fi # Add the Flathub remote at --system scope (global install for all users). # A non-root user requesting a system action triggers the # org.freedesktop.Flatpak SystemHelper over D-Bus + polkit, which is not # activatable in a chroot/bare-TTY install — the "The name is not activatable" # failure. Running via sudo (as root) performs the system operation directly, # so no helper/polkit is involved and global installs work during setup. if ! flatpak remotes --system 2>/dev/null | grep -q flathub; then log "Adding Flathub remote (system)..." sudo flatpak remote-add --system --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo fi } # ── apply_flatpak_theme ──────────────────────────────────────────────────────── # WHY: Flatpak apps run in sandboxes and can't access the host ~/.themes directory # by default. We must explicitly grant filesystem access AND set GTK_THEME. # WHAT: Copies the cyberqueer GTK theme into ~/.themes, grants the Flatpak app # read-only access to that directory, and overrides the GTK_THEME env var. # # Usage: apply_flatpak_theme # e.g. apply_flatpak_theme org.gnome.gedit apply_flatpak_theme() { local app_id="$1" local theme_name="cyberqueer" # The theme lives in the dotfiles repo under gtk-themes/cyberqueer/ local theme_src="$HOME/Dotfiles/gtk-themes/$theme_name" local themes_dir="$HOME/.themes" # Guard: if the theme source doesn't exist, skip gracefully with a warning if [[ ! -d "$theme_src" ]]; then warn "Cyberqueer theme not found at $theme_src — skipping Flatpak theme override." return 0 fi # Copy the theme into the user's ~/.themes/ so it's accessible mkdir -p "$themes_dir" cp -r "$theme_src" "$themes_dir/$theme_name" # Grant the Flatpak app read-only access to ~/.themes using a per-user override. # This avoids needing a global system-wide Flatpak override. flatpak override --user --filesystem="$themes_dir":ro "$app_id" # Set GTK_THEME env var for this app so GTK picks up the correct theme name flatpak override --user --env=GTK_THEME="$theme_name" "$app_id" log "Cyberqueer theme applied to $app_id." }