#!/bin/bash # ABOUTME: Moonarch system updater — updates system, repo and defaults. # ABOUTME: Should be run regularly to keep the system in sync. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" OFFICIAL_PACKAGES="$PROJECT_DIR/packages/official.txt" AUR_PACKAGES="$PROJECT_DIR/packages/aur.txt" DEFAULTS_DIR="$PROJECT_DIR/defaults" # --- Helper functions --- log() { echo -e "\e[1;34m[Moonarch]\e[0m $*" } err() { echo -e "\e[1;31m[Moonarch ERROR]\e[0m $*" >&2 } read_packages() { grep -v '^\s*#' "$1" | grep -v '^\s*$' } confirm() { read -r -p "$1 [y/N] " response [[ "$response" =~ ^[yY]$ ]] } # --- Prerequisites --- if [[ $EUID -eq 0 ]]; then err "Do NOT run as root." exit 1 fi # --- 1. Update Moonarch repo --- log "=== Update Moonarch repo ===" cd "$PROJECT_DIR" if git rev-parse --is-inside-work-tree &>/dev/null; then LOCAL=$(git rev-parse HEAD) git fetch origin REMOTE=$(git rev-parse @{u} 2>/dev/null || echo "$LOCAL") if [[ "$LOCAL" != "$REMOTE" ]]; then log "Updates available." git --no-pager log --oneline "$LOCAL".."$REMOTE" echo "" if confirm "Update repo?"; then git pull --ff-only log "Repo updated." else log "Repo update skipped." fi else log "Repo is up to date." fi else log "Not a git repo — repo update skipped." fi # --- 2. Update system packages --- log "=== Update system packages ===" if confirm "Run pacman -Syu?"; then sudo pacman -Syu else log "System update skipped." fi if command -v paru &>/dev/null; then if confirm "Update AUR packages (paru -Sua)?"; then paru -Sua else log "AUR update skipped." fi fi # --- 3. Install missing packages --- log "=== Reconcile package lists ===" if [[ -f "$OFFICIAL_PACKAGES" ]]; then MISSING_OFFICIAL=$(comm -23 <(read_packages "$OFFICIAL_PACKAGES" | sort) <(pacman -Qqe | sort) || true) if [[ -n "$MISSING_OFFICIAL" ]]; then log "Missing official packages:" echo "$MISSING_OFFICIAL" if confirm "Install?"; then # shellcheck disable=SC2086 sudo pacman -S --needed --noconfirm $MISSING_OFFICIAL fi else log "All official packages installed." fi fi if [[ -f "$AUR_PACKAGES" ]] && command -v paru &>/dev/null; then MISSING_AUR=$(comm -23 <(read_packages "$AUR_PACKAGES" | sort) <(pacman -Qqe | sort) || true) if [[ -n "$MISSING_AUR" ]]; then log "Missing AUR packages:" echo "$MISSING_AUR" if confirm "Install?"; then # shellcheck disable=SC2086 paru -S --needed --noconfirm $MISSING_AUR fi else log "All AUR packages installed." fi fi # --- 4. Update defaults --- log "=== Update defaults ===" # XDG Defaults CHANGED_XDG=false if ! diff -rq "$DEFAULTS_DIR/xdg/" /etc/xdg/ --exclude='*.pyc' &>/dev/null 2>&1; then CHANGED_XDG=true fi if $CHANGED_XDG; then log "XDG defaults have changed." diff -rq "$DEFAULTS_DIR/xdg/" /etc/xdg/ --exclude='*.pyc' 2>/dev/null | head -20 || true echo "" if confirm "Deploy XDG defaults to /etc/xdg/?"; then sudo cp -r "$DEFAULTS_DIR/xdg/"* /etc/xdg/ log "XDG defaults updated." fi else log "XDG defaults are up to date." fi # Binaries CHANGED_BIN=false for bin in "$DEFAULTS_DIR/bin/moonarch-"*; do name=$(basename "$bin") if ! cmp -s "$bin" "/usr/local/bin/$name" 2>/dev/null; then CHANGED_BIN=true break fi done if $CHANGED_BIN; then log "Moonarch binaries have changed." for bin in "$DEFAULTS_DIR/bin/moonarch-"*; do name=$(basename "$bin") if ! cmp -s "$bin" "/usr/local/bin/$name" 2>/dev/null; then log " ~ $name" fi done if confirm "Deploy binaries to /usr/local/bin/?"; then sudo install -m 755 "$DEFAULTS_DIR/bin/moonarch-"* /usr/local/bin/ log "Binaries updated." fi else log "Binaries are up to date." fi # Zsh if ! cmp -s "$DEFAULTS_DIR/shell/zshrc" /etc/zsh/zshrc.moonarch 2>/dev/null; then log "Zsh defaults have changed." if confirm "Update Zsh defaults?"; then sudo cp "$DEFAULTS_DIR/shell/zshrc" /etc/zsh/zshrc.moonarch log "Zsh defaults updated." fi else log "Zsh defaults are up to date." fi # --- 5. Orphaned packages --- log "=== Orphaned packages ===" ORPHANS=$(pacman -Qdtq 2>/dev/null || true) if [[ -n "$ORPHANS" ]]; then log "Orphaned packages found:" echo "$ORPHANS" if confirm "Remove?"; then # shellcheck disable=SC2086 sudo pacman -Rsn --noconfirm $ORPHANS fi else log "No orphaned packages." fi # --- Done --- log "" log "============================================" log " Moonarch update complete!" log "============================================"