From 971a6eb57713411416562a9940b1072f7826ea3b Mon Sep 17 00:00:00 2001 From: nevaforget Date: Tue, 21 Apr 2026 09:04:23 +0200 Subject: [PATCH] refactor(install): restore fresh-install flow, drop transform.sh and personas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Long-standing gaps in post-install.sh plus cleanup: - post-install.sh:18 was `sudo pacman -S paru` on the wrong assumption paru had landed in [extra]. Verified: paru/paru-bin are AUR-only. Restored the original git-clone + makepkg bootstrap, added the rust buildep that archinstall does not pull in. - post-install.sh never installed AUR extras — walker, elephant, waypaper, stasis, themes all silently skipped. Now pulls packages/aur.txt after moonarch-git. - packages/official.txt: drop glab, go, npm (unused) and rustup (only needed for the paru build, handled imperatively now). - packages/aur.txt: add walker-bin (was missing entirely). - transform.sh + legacy update.sh shim removed — transform was never used in practice. - Apollo persona block out of CLAUDE.md, prior DECISIONS entries rewritten from Apollo/Ragnar to ClaudeCode. - README Transform section and scripts/ listing trimmed. - lib.sh ABOUTME updated — only post-install.sh sources it now. --- CLAUDE.md | 4 - DECISIONS.md | 36 +++- README.md | 32 +-- packages/aur.txt | 1 + packages/official.txt | 4 - scripts/lib.sh | 2 +- scripts/post-install.sh | 21 +- scripts/transform.sh | 420 ---------------------------------------- scripts/update.sh | 14 -- 9 files changed, 50 insertions(+), 484 deletions(-) delete mode 100755 scripts/transform.sh delete mode 100755 scripts/update.sh diff --git a/CLAUDE.md b/CLAUDE.md index fc26ab2..b3f5b6c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,7 +55,3 @@ Diagnose-Script das den Systemzustand gegen moonarch-Defaults prüft: - Paketlisten sind einfache Textdateien, ein Paket pro Zeile, Kommentare mit `#` - Shell-Scripts müssen POSIX-kompatibel oder explizit bash/zsh sein - Alle Pfade im archinstall-Config relativ zum Installationsziel - -## Ich bin Apollo - -Benannt nach dem Programm, das Menschen zum Mond gebracht hat — passend für ein Projekt namens Moonarch. diff --git a/DECISIONS.md b/DECISIONS.md index 11938b2..7474fb0 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -1,5 +1,23 @@ # Decisions +## 2026-04-21 – post-install.sh pulls aur.txt, rust for paru build, rustup out of official +- **Who**: Dominik, ClaudeCode +- **Why**: Three related gaps uncovered while fixing the paru bootstrap: (1) `moonarch-git` cannot depend on AUR packages, so every AUR package in `aur.txt` (walker-bin, elephant-*-bin, awww's theme, waypaper, stasis, …) was silently never installed by post-install.sh — a fresh install would have a working pacman but no launcher, no idle manager, no theming. (2) `makepkg -si` for `paru` (AUR source build) needs `rust` as makedep; neither archinstall nor post-install.sh installed it, so the restored paru bootstrap would have crashed on rust-less systems. (3) `rustup` sat in `official.txt` "for something we don't remember" — turned out to be a leftover; `rust` suffices for the paru build, and rustup is only needed for dev toolchain management which is a per-user concern, not a Moonarch default. +- **Tradeoffs**: Installing `rust` (~350MB) just to bootstrap paru feels heavy. Alternative `paru-bin` avoids the compile step entirely; rejected because Dominik's documented workflow uses `paru` (source) and consistency with that matters more than ~30s of build time. rustup can be re-added to official.txt if the dev workflow grows that demand. +- **How**: (1) post-install.sh now runs `read_packages "$AUR_PACKAGES" | paru -S --needed` after `paru -S moonarch-git`. (2) `sudo pacman -S base-devel rust` before the paru git-clone. (3) `rustup` removed from `official.txt` (remains in PKGBUILD `optdepends` for discoverability). + +## 2026-04-21 – Restore AUR bootstrap for paru in post-install.sh +- **Who**: Dominik, ClaudeCode +- **Why**: Commit 0726451 (2026-03-29) replaced the working `git clone https://aur.archlinux.org/paru.git && makepkg -si` bootstrap with `sudo pacman -S paru`, on the (wrong) assumption that paru had landed in `[extra]`. Verified against archlinux.org API: paru and paru-bin are AUR-only, not in any official repo. Fresh installs have been silently broken since — the command fails, the installer aborts before the moonarch registry is configured. +- **Tradeoffs**: Bootstrap builds paru from source, which needs `base-devel` (already pulled by archinstall). Alternative `paru-bin` would skip the compile step; chose `paru` to match the upstream recommendation the user follows. Alternative "bundle paru in the Moonarch registry" would be internally consistent but adds a dependency on a running Gitea during install. +- **How**: Replaced the `pacman -S paru` line in `post-install.sh` with the original bootstrap — `mktemp -d`, `git clone`, `makepkg -si --noconfirm`, `rm -rf`. Wrapped in an EXIT trap so the tempdir gets cleaned up even on failure. + +## 2026-04-21 – Drop transform.sh and legacy update.sh shim +- **Who**: Dominik, ClaudeCode +- **Why**: transform.sh was added 2026-03-29 to onboard users from existing Arch+Wayland systems, but was never actually used — Moonarch is installed fresh via archinstall. Maintaining it meant duplicated paru/repo/key setup, a second entry point with its own backup/pre-flight logic, and a second reason for the `/opt/moonarch` clone. scripts/update.sh was a deprecation shim from before moonarch-update moved into the moonarch-git package; obsolete now that the package ships moonup/moondoc. +- **Tradeoffs**: Existing Arch+Wayland users now have to install paru, add the `[moonarch]` repo + key manually, then `paru -S moonarch-git`. That's three commands instead of one script — acceptable since nobody actually uses that path. If the need returns, transform can be resurrected from git history. +- **How**: Deleted `scripts/transform.sh` and `scripts/update.sh`. `lib.sh` stays (still sourced by post-install.sh). README "Transform" section removed, project-structure listing trimmed. Fresh-install flow via archinstall + post-install.sh is unchanged. + ## 2026-04-20 – Registry-only install: drop paru --pkgbuilds from setup scripts - **Who**: Dominik, ClaudeCode - **Why**: Two parallel paths for finding moonarch packages (Arch registry via `[moonarch]` in pacman.conf, and paru's PKGBUILD-repo via `[moonarch-pkgbuilds]` in paru.conf) caused ambiguity during debugging: `paru -S moonarch-git` was resolving against the registry's stale DB (zombie r99 entry) while the PKGBUILD source would have had r105. Also: the PKGBUILD-repo path triggered a local build on every client, while the registry ships prebuilt binaries. With the registry DB now stable (see `moonarch-pkgbuilds/DECISIONS.md`, same date), the second mechanism is redundant. @@ -43,56 +61,56 @@ - **How**: Added paru repo config (Mode=arp + [moonarch-pkgbuilds] section) to moonarch.install post_install/post_upgrade hook. Kept post-install.sh setup for bootstrap. Removed redundant setup from transform.sh. ## 2026-04-02 – Rename paru PKGBUILD repo, move config to /etc/paru.conf -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: paru PKGBUILD repo and pacman package registry both used `[moonarch]` as section name. When pkgver-bot pushed version bumps, paru tried to resolve PKGBUILD targets (moongreet-git, moonlock-git) against the pacman repo — which only contains moonarch-git — causing "nicht alle benötigten Pakete gefunden" errors. - **Tradeoffs**: Renaming the PKGBUILD repo section means existing installations need a one-time manual fix. Using `/etc/paru.conf` instead of `~/.config/paru/paru.conf` is consistent with moonarch's system-wide config philosophy. - **How**: Renamed PKGBUILD repo section from `[moonarch]` to `[moonarch-pkgbuilds]`. Moved paru config (Mode + repo) from user-level `~/.config/paru/paru.conf` to system-wide `/etc/paru.conf`. Updated post-install.sh accordingly. ## 2026-04-01 – Replace dunst with swaync as notification daemon -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: Dunst lacks wp_fractional_scale_v1 support, causing aliased/jagged font rendering on external monitors in mixed-DPI setups (laptop eDP-1 at 2.5x, externals at 1x). Confirmed by testing: removing fractional scaling fixed the issue. swaync uses GTK4 which handles fractional scaling natively. - **Tradeoffs**: swaync is heavier than dunst (GTK4 + libadwaita dependency). Loses dunstctl CLI (replaced by swaync-client). Gains notification center panel with DnD toggle, grouping, MPRIS widget support. Waybar already had swaync-client integration with exec-if guard. - **How**: Replaced dunst with swaync in packages/official.txt and archinstall config. Niri spawn-at-startup updated. Waybar dunstctl widget removed (swaync-client widget already present). New swaync config.json and style.css based on catppuccin/swaync upstream theme with Lavender accent instead of Blue. ## 2026-03-31 – Audit: shell script quoting fixes, PKGBUILD permissions -- **Who**: Ragnar, Dom +- **Who**: ClaudeCode, Dom - **Why**: Security audit found command injection risk in moonarch-cpugov (unquoted array expansion with pkexec), word-splitting in moonarch-btnote (upower output from Bluetooth devices), and nmcli argument injection in moonarch-vpn. PKGBUILD for moongreet had world-readable cache dir. - **Tradeoffs**: `eval` in cpugov is safe because COMMANDS values are hardcoded string literals, not user input. Alternative (function dispatch) would be cleaner but over-engineered for 3 fixed entries. moonarch-btnote switched from for-loop to while+read with process substitution to avoid subshell. - **How**: (1) `eval "${COMMANDS[$choice]}"` in cpugov. (2) `while IFS= read -r` + process substitution + quoted `$DEVICE_DATA` in btnote. (3) `--` guard before `$connection` in vpn nmcli calls. (4) `install -dm700` for moongreet cache dirs in PKGBUILD. (5) `else err` logging in post-install.sh when USER_DEFAULTS missing. ## 2026-03-29 – /opt/moonarch stays root-owned, no chown to user -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: Multi-user system — chown to UID 1000 locks out other users from moonarch-update - **Tradeoffs**: sudo required for git operations in update.sh vs. simpler user-owned repo - **How**: Repo stays at /opt/moonarch owned by root:root. update.sh uses `sudo git` for fetch/pull. All scripts already use sudo for system-level operations, so this is consistent. ## 2026-03-29 – Add transform.sh for existing Arch+Wayland systems -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: Users with existing Arch+Wayland setups should be able to adopt Moonarch without reinstalling - **Tradeoffs**: Hard overwrite of all configs (user + system) vs. selective/merge approach — chose hard overwrite for simplicity and consistency - **How**: New transform.sh with pre-flight summary, backup, DM conflict resolution, and --dry-run flag. Shared helpers extracted to lib.sh. ## 2026-03-29 – Package moonarch as moonarch-git PKGBUILD -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: System artifacts (XDG configs, helper scripts, zsh config, wallpaper) should be managed by pacman for clean deployment, versioning, rollback, and deinstallation - **Tradeoffs**: /etc/xdg/ configs NOT in backup= (moonarch philosophy: system defaults flow through, users override in ~/.config/). /etc/greetd/ and /etc/moongreet/ NOT owned by package (owned by greetd/moongreet-git, overwritten via .install hook). Helper scripts move from /usr/local/bin/ to /usr/bin/ (FHS for package-managed files) - **How**: moonarch-git PKGBUILD in moonarch-pkgbuilds repo. sweet-cursors-git as separate package. moonarch-update simplified (no git-sync, pacman handles file deployment). Installer scripts (post-install.sh, transform.sh) remain for orchestration, will be refactored in a follow-up to delegate file deployment to `paru -S moonarch-git` ## 2026-03-30 – Replace Rofi with Walker as application launcher -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: Walker is Wayland-native (GTK4 + gtk4-layer-shell), has built-in providers for clipboard, bluetooth, audio (wireplumber), and Niri integration. Reduces custom shell scripts from 8 to 3. Rofi required a Wayland fork (rofi-lbonn-wayland-git) and every applet was a custom bash script. - **Tradeoffs**: Walker is newer/less battle-tested than Rofi. Requires separate Elephant daemon with per-provider packages. Dmenu mode lacks Rofi's `-a`/`-u` (active/urgent) and `-mesg` flags. Settings menu (moonarch-setmen) dropped entirely — apps are findable via Walker's app search. - **How**: Walker + Elephant as systemd user services. Native providers replace 5 rofi scripts (launcher, clipboard, bluetooth, volume, sink-switcher). 3 scripts ported to walker dmenu (vpn, cpugov, sink-switcher). Walker theme inherits GTK4 system theme colors (gtk-inherit). Old rofi configs preserved in `legacy/rofi/`. ## 2026-03-30 – Use nm-applet as VPN secret agent, add WireGuard support -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: VPN auth previously spawned a foot terminal for `nmcli --ask`, which was fragile and ugly. WireGuard connections were invisible to the VPN script and Waybar indicator because both only checked for OpenVPN (`tun0` / `vpn` type). - **Tradeoffs**: nm-applet adds a tray indicator (mitigated with `--indicator` mode which is minimal). Requires nm-applet running at session start. Alternative was gnome-keyring or a custom secret agent — nm-applet is simpler and handles all NM secret types. - **How**: nm-applet started via niri spawn-at-startup. moonarch-vpn rewritten to support both vpn and wireguard types, uses nm-applet for auth instead of foot terminal, sends notify-send for connect/disconnect results. Waybar VPN module uses `nmcli` active connection check instead of `/proc/sys/net/ipv4/conf/tun0`, plus RTMIN+9 signal for instant updates after toggle. ## 2026-03-30 – Standardize GTK theme to Colloid-Grey-Dark-Catppuccin -- **Who**: Dominik, Ragnar +- **Who**: Dominik, ClaudeCode - **Why**: gsettings had `Colloid-Dark-Catppuccin` while config files had `Colloid-Catppuccin` — inconsistent. Grey accent matches the icon theme (Colloid-Grey-Catppuccin-Dark). Explicit `-Dark` variant is more reliable than depending on `prefer-dark` color-scheme setting. - **Tradeoffs**: Explicit dark locks out light mode toggle — acceptable since Moonarch is dark-only by design. - **How**: Updated transform.sh, post-install.sh, gtk-3.0/settings.ini, and gsettings to `Colloid-Grey-Dark-Catppuccin`. GTK4 symlinks updated accordingly. diff --git a/README.md b/README.md index fa604f2..e1120f2 100644 --- a/README.md +++ b/README.md @@ -54,35 +54,6 @@ The archinstall config clones this repo to `/opt/moonarch` via custom-commands. post-install.sh handles the remaining ~95 packages, all configs, themes, services, and user setup. -### Transform (Existing Arch+Wayland System) - -Already running Arch with a Wayland compositor (Sway, Hyprland, GNOME Wayland, etc.)? -Transform converts your system to Moonarch without reinstalling. - -**Prerequisites:** Active Wayland session, git installed. - -```bash -# Clone the repo -sudo git clone https://gitea.moonarch.de/nevaforget/moonarch.git /opt/moonarch - -# Preview what will happen (no changes made) -/opt/moonarch/scripts/transform.sh --dry-run - -# Run the transform -/opt/moonarch/scripts/transform.sh - -# Reboot (do NOT log out — your previous DM is already disabled) -sudo reboot -``` - -The script will: -1. Show a pre-flight summary (package diff, config changes, detected conflicts) -2. Back up your `~/.config/`, `~/.zshrc`, and `/etc/xdg/` to timestamped tar archives -3. Disable conflicting display managers (SDDM, GDM, LightDM, etc.) -4. Remove conflicting packages (e.g. PulseAudio → PipeWire) -5. Install all Moonarch packages and configs (**hard overwrite** of most user configs; kanshi display profiles are preserved) -6. Enable greetd, firewall, and system services - ### Update ```bash @@ -114,9 +85,8 @@ packages/ aur.txt AUR packages (~20), one per line scripts/ - lib.sh Shared helpers sourced by all scripts + lib.sh Shared helpers sourced by post-install.sh post-install.sh Main automation (packages, configs, themes, services) - transform.sh Convert existing Arch+Wayland system to Moonarch moonarch-update Interactive updater (deployed to /usr/bin/ as moonup) moonarch-doctor System health checker (deployed to /usr/bin/ as moondoc) diff --git a/packages/aur.txt b/packages/aur.txt index 30902a5..8df0c33 100644 --- a/packages/aur.txt +++ b/packages/aur.txt @@ -11,6 +11,7 @@ colloid-catppuccin-theme-git otf-openmoji # Niri / Wayland Extras +walker-bin elephant-desktopapplications-bin elephant-clipboard-bin elephant-bluetooth-bin diff --git a/packages/official.txt b/packages/official.txt index 1dda4d9..324042d 100644 --- a/packages/official.txt +++ b/packages/official.txt @@ -91,11 +91,7 @@ viewnior # Development git -glab -go neovim -npm -rustup # System fwupd diff --git a/scripts/lib.sh b/scripts/lib.sh index 96577f7..490ad22 100755 --- a/scripts/lib.sh +++ b/scripts/lib.sh @@ -1,6 +1,6 @@ #!/bin/bash # ABOUTME: Shared helper functions and constants for Moonarch scripts. -# ABOUTME: Sourced by post-install.sh, update.sh and transform.sh. +# ABOUTME: Sourced by post-install.sh. # Path constants — BASH_SOURCE[1] resolves to the calling script, not lib.sh itself. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[1]}")" && pwd)" diff --git a/scripts/post-install.sh b/scripts/post-install.sh index ad315dd..9f69e3e 100755 --- a/scripts/post-install.sh +++ b/scripts/post-install.sh @@ -14,8 +14,16 @@ check_pacman # --- Install paru (AUR Helper) --- if ! command -v paru &>/dev/null; then + log "Installing paru build dependencies..." + sudo pacman -S --needed --noconfirm base-devel rust + log "Installing paru..." - sudo pacman -S --needed --noconfirm paru + PARU_TMPDIR=$(mktemp -d) + trap 'rm -rf "$PARU_TMPDIR"' EXIT + git clone https://aur.archlinux.org/paru.git "$PARU_TMPDIR/paru" + (cd "$PARU_TMPDIR/paru" && makepkg -si --noconfirm) + rm -rf "$PARU_TMPDIR" + trap - EXIT else log "paru already installed." fi @@ -66,6 +74,17 @@ log "Installing moonarch-git package..." sudo pacman -Sy --noconfirm paru -S --needed --noconfirm moonarch-git +# --- Install AUR extras (cannot be hard depends of moonarch-git) --- + +if [[ -f "$AUR_PACKAGES" ]]; then + log "Installing AUR packages from $AUR_PACKAGES..." + # shellcheck disable=SC2046 + paru -S --needed --noconfirm $(read_packages "$AUR_PACKAGES") +else + err "AUR package list not found: $AUR_PACKAGES" + exit 1 +fi + # --- User-level GTK4 symlinks for libadwaita apps --- THEME_NAME="Colloid-Grey-Dark-Catppuccin" diff --git a/scripts/transform.sh b/scripts/transform.sh deleted file mode 100755 index ed564b5..0000000 --- a/scripts/transform.sh +++ /dev/null @@ -1,420 +0,0 @@ -#!/bin/bash -# ABOUTME: Transforms an existing Arch+Wayland system into a Moonarch system. -# ABOUTME: Backs up configs, installs moonarch-git package, deploys user configs with hard overwrite. - -set -euo pipefail - -source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib.sh" - -# --- Parse arguments --- - -DRY_RUN=false -if [[ "${1:-}" == "--dry-run" ]]; then - DRY_RUN=true -fi - -# ============================================================ -# Phase 1: Prerequisites & Detection -# ============================================================ - -check_not_root -check_pacman - -# Require active Wayland session -if [[ "${XDG_SESSION_TYPE:-}" != "wayland" ]] && [[ -z "${WAYLAND_DISPLAY:-}" ]]; then - err "No active Wayland session detected. Transform requires Wayland." - exit 1 -fi - -# Detect conflicting display managers -CONFLICTING_DMS=() -for dm in sddm gdm lightdm ly lemurs; do - if systemctl is-enabled "${dm}.service" &>/dev/null; then - CONFLICTING_DMS+=("$dm") - fi -done - -# Detect conflicting packages -CONFLICTING_PKGS=() -if pacman -Qq pulseaudio &>/dev/null && ! pacman -Qq pipewire-pulse &>/dev/null; then - CONFLICTING_PKGS+=("pulseaudio") -fi - -# ============================================================ -# Phase 2: Pre-flight Summary -# ============================================================ - -echo "" -if $DRY_RUN; then - log "============================================" - log " Moonarch Transform — Dry Run" - log "============================================" -else - log "============================================" - log " Moonarch Transform — Pre-flight Summary" - log "============================================" -fi -echo "" - -log "Wayland session: detected" - -if [[ ${#CONFLICTING_DMS[@]} -gt 0 ]]; then - log "Display managers: ${CONFLICTING_DMS[*]} (will be disabled)" -else - log "Display managers: none conflicting" -fi - -if [[ ${#CONFLICTING_PKGS[@]} -gt 0 ]]; then - log "Package conflicts: ${CONFLICTING_PKGS[*]} (will be removed)" -else - log "Package conflicts: none" -fi - -echo "" -log "Actions:" -log " 1. (Optional) Backup ~/.config/, ~/.zshrc, /etc/xdg/" -log " 2. Install moonarch-git package (pulls in all dependencies)" -log " 3. Disable conflicting DMs, enable greetd" -log " 4. Overwrite ALL user configs (~/.config/)" -log " 5. Configure GTK themes, firewall, services" -echo "" - -# Show package diff -MISSING_OFFICIAL=$(comm -23 <(read_packages "$OFFICIAL_PACKAGES" | sort) <(pacman -Qqe | sort) 2>/dev/null || true) -MISSING_AUR="" -if [[ -f "$AUR_PACKAGES" ]]; then - MISSING_AUR=$(comm -23 <(read_packages "$AUR_PACKAGES" | sort) <(pacman -Qqe | sort) 2>/dev/null || true) -fi - -if [[ -n "$MISSING_OFFICIAL" ]] || [[ -n "$MISSING_AUR" ]]; then - log "Packages to install:" - if [[ -n "$MISSING_OFFICIAL" ]]; then - OFFICIAL_COUNT=$(echo "$MISSING_OFFICIAL" | wc -l) - log " Official ($OFFICIAL_COUNT):" - echo "$MISSING_OFFICIAL" | sed 's/^/ /' - fi - if [[ -n "$MISSING_AUR" ]]; then - AUR_COUNT=$(echo "$MISSING_AUR" | wc -l) - log " AUR ($AUR_COUNT):" - echo "$MISSING_AUR" | sed 's/^/ /' - fi -else - log "Packages: all already installed" -fi - -# Show config diff summary -CHANGED_XDG=0 -CHANGED_BIN=0 -for src_dir in "$DEFAULTS_DIR/xdg/"*/; do - app_name="$(basename "$src_dir")" - dest_dir="$HOME/.config/$app_name" - if [[ -d "$dest_dir" ]]; then - if ! diff -rq "$src_dir" "$dest_dir" &>/dev/null 2>&1; then - ((CHANGED_XDG++)) || true - fi - else - ((CHANGED_XDG++)) || true - fi -done -for bin in "$DEFAULTS_DIR/bin/moonarch-"*; do - name=$(basename "$bin") - if ! cmp -s "$bin" "/usr/bin/$name" 2>/dev/null; then - ((CHANGED_BIN++)) || true - fi -done -log "Config changes: $CHANGED_XDG XDG app(s), $CHANGED_BIN helper script(s)" - -echo "" -err "This will REPLACE your current desktop configuration." -echo "" - -if $DRY_RUN; then - log "Dry run complete — no changes were made." - exit 0 -fi - -if ! confirm "Proceed?"; then - log "Transform cancelled." - exit 0 -fi - -# ============================================================ -# Phase 3: Backup (optional) -# ============================================================ - -BACKUP_FILE="" -SYSTEM_BACKUP="" - -if confirm "Create backup of current configs before overwriting?"; then - BACKUP_FILE="$HOME/moonarch-backup-$(date +%Y%m%d-%H%M%S).tar.gz" - log "Creating backup: $BACKUP_FILE" - - # Build list of paths that actually exist - BACKUP_PATHS=() - [[ -d "$HOME/.config" ]] && BACKUP_PATHS+=(".config") - [[ -f "$HOME/.zshrc" ]] && BACKUP_PATHS+=(".zshrc") - [[ -d "$HOME/.zshrc.d" ]] && BACKUP_PATHS+=(".zshrc.d") - - if [[ ${#BACKUP_PATHS[@]} -gt 0 ]]; then - tar czf "$BACKUP_FILE" -C "$HOME" "${BACKUP_PATHS[@]}" - log " + User configs backed up." - fi - - # Backup system XDG separately (needs sudo) - if [[ -d /etc/xdg ]]; then - SYSTEM_BACKUP="$HOME/moonarch-backup-system-$(date +%Y%m%d-%H%M%S).tar.gz" - sudo tar czf "$SYSTEM_BACKUP" -C / etc/xdg - sudo chown "$USER:$USER" "$SYSTEM_BACKUP" - log " + System configs backed up: $SYSTEM_BACKUP" - fi - - log "Backup complete: $(du -h "$BACKUP_FILE" | cut -f1)" -else - log "Skipping backup." -fi - -# ============================================================ -# Phase 4: Disable Conflicting Display Managers -# ============================================================ - -if [[ ${#CONFLICTING_DMS[@]} -gt 0 ]]; then - log "Disabling conflicting display managers..." - for dm in "${CONFLICTING_DMS[@]}"; do - sudo systemctl disable "$dm" - log " - $dm disabled" - done -fi - -# ============================================================ -# Phase 5: Remove Conflicting Packages -# ============================================================ - -if pacman -Qq pulseaudio &>/dev/null; then - log "Removing PulseAudio (replaced by PipeWire)..." - sudo pacman -Rdd --noconfirm pulseaudio pulseaudio-alsa pulseaudio-bluetooth 2>/dev/null || true -fi - -# ============================================================ -# Phase 6: Install moonarch-git Package -# ============================================================ - -# Install paru if not present -if ! command -v paru &>/dev/null; then - log "Installing paru..." - sudo pacman -S --needed --noconfirm paru -else - log "paru already installed." -fi - -# Moonarch package registry -log "Setting up Moonarch package registry..." -if ! grep -q '\[moonarch\]' /etc/pacman.conf 2>/dev/null; then - sudo tee -a /etc/pacman.conf > /dev/null <<'EOCONF' - -[moonarch] -SigLevel = Required DatabaseOptional -Server = https://gitea.moonarch.de/api/packages/nevaforget/arch/$repo/$arch -EOCONF - log " + Moonarch repo added to pacman.conf." -else - log " ~ Moonarch repo already in pacman.conf." -fi - -log "Importing Moonarch registry signing key..." -EXPECTED_FINGERPRINT="9B02C596A4652C40CA768E75B90C8B82EA30A131" -KEY_FILE=$(mktemp) -trap 'rm -f "$KEY_FILE"' EXIT -curl -sf https://gitea.moonarch.de/api/packages/nevaforget/arch/repository.key -o "$KEY_FILE" -if [[ ! -s "$KEY_FILE" ]]; then - err "Failed to download registry key (empty response)." - exit 1 -fi -KEY_FPR=$(gpg --show-keys --with-colons "$KEY_FILE" 2>/dev/null | awk -F: '/^fpr/{print $10; exit}') -if [[ "$KEY_FPR" != "$EXPECTED_FINGERPRINT" ]]; then - err "Registry key fingerprint mismatch! Expected $EXPECTED_FINGERPRINT, got ${KEY_FPR:-}" - exit 1 -fi -KEY_ID=$(gpg --show-keys --with-colons "$KEY_FILE" 2>/dev/null | awk -F: '/^pub/{print $5}') -if [[ -n "$KEY_ID" ]] && ! sudo pacman-key --list-keys "$KEY_ID" &>/dev/null; then - sudo pacman-key --add "$KEY_FILE" - sudo pacman-key --lsign-key "$KEY_ID" - log " + Registry key $KEY_ID imported and locally signed." -else - log " ~ Registry key already imported." -fi -rm -f "$KEY_FILE" -trap - EXIT - -log "Installing moonarch-git package..." -sudo pacman -Sy --noconfirm -paru -S --needed --noconfirm moonarch-git - -# Install packages from package lists -if [[ -n "$MISSING_OFFICIAL" ]]; then - log "Installing official packages..." - echo "$MISSING_OFFICIAL" | paru -S --needed --noconfirm - -fi - -if [[ -n "$MISSING_AUR" ]]; then - log "Installing AUR packages..." - echo "$MISSING_AUR" | paru -S --needed --noconfirm - -fi - -# ============================================================ -# Phase 7: User-Level Configuration -# ============================================================ - -# User-level GTK4 symlinks for libadwaita apps -THEME_NAME="Colloid-Grey-Dark-Catppuccin" -THEME_GTK4="/usr/share/themes/$THEME_NAME/gtk-4.0" - -if [[ -d "$THEME_GTK4" ]]; then - log "Creating user-level GTK4 symlinks for $THEME_NAME..." - USER_GTK4="$HOME/.config/gtk-4.0" - mkdir -p "$USER_GTK4" - ln -sf "$THEME_GTK4/gtk-dark.css" "$USER_GTK4/gtk.css" - ln -sf "$THEME_GTK4/gtk-dark.css" "$USER_GTK4/gtk-dark.css" - rm -f "$USER_GTK4/assets" - ln -s "$THEME_GTK4/assets" "$USER_GTK4/assets" -else - err "GTK4 theme not found: $THEME_GTK4 — libadwaita apps will use fallback theme." -fi - -# gsettings -log "Setting gsettings for GTK theme..." -gsettings set org.gnome.desktop.interface gtk-theme "$THEME_NAME" -gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' -gsettings set org.gnome.desktop.interface icon-theme 'Colloid-Grey-Catppuccin-Dark' -gsettings set org.gnome.desktop.interface font-name 'UbuntuSans Nerd Font 11' - -# ============================================================ -# Phase 8: Deploy User Configs (Hard Overwrite) -# ============================================================ - -# Replace user-level XDG configs from /etc/xdg/ (deployed by moonarch-git) -log "Deploying XDG configs to ~/.config/ (overwrite)..." -for src_dir in /etc/xdg/*/; do - app_name="$(basename "$src_dir")" - # Only overwrite apps that moonarch manages - [[ -d "$DEFAULTS_DIR/xdg/$app_name" ]] || continue - # gtk-4.0 is handled separately with Colloid-Grey-Dark-Catppuccin theme symlinks - [[ "$app_name" == "gtk-4.0" ]] && continue - # kanshi profiles are user-specific (display setup) — only seed, never overwrite - [[ "$app_name" == "kanshi" ]] && [[ -d "$HOME/.config/kanshi" ]] && continue - # niri user config includes system config — never overwrite (handled below) - [[ "$app_name" == "niri" ]] && continue - dest_dir="$HOME/.config/$app_name" - rm -rf "$dest_dir" 2>/dev/null || sudo rm -rf "$dest_dir" - cp -r --no-preserve=ownership "$src_dir" "$dest_dir" - log " + $app_name/" -done - -# Niri: seed user config with include of system config (preserves user overrides) -niri_user_config="$HOME/.config/niri/config.kdl" -if [[ ! -f "$niri_user_config" ]]; then - mkdir -p "$HOME/.config/niri" - cat > "$niri_user_config" << 'NIRI_EOF' -// ABOUTME: Moonarch user niri config — includes system defaults. -// ABOUTME: Add personal overrides below the include statement. - -include "/etc/xdg/niri/config.kdl" -NIRI_EOF - log " + niri/ (seeded with include)" -else - log " ~ niri/ (user config exists, skipped)" -fi - -# Overwrite configs owned by other packages with moonarch versions -log "Deploying moonarch config overrides..." -cp /usr/share/moonarch/walker-config.toml "$HOME/.config/walker/config.toml" -log " + walker/config.toml" - -# Zsh: always create a fresh .zshrc that sources Moonarch defaults -log "Creating ~/.zshrc with Moonarch defaults..." -mkdir -p "$HOME/.zshrc.d" -echo "# Load Moonarch defaults, add custom overrides in ~/.zshrc.d/ or below" > "$HOME/.zshrc" -echo "source /etc/zsh/zshrc.moonarch" >> "$HOME/.zshrc" - -# ============================================================ -# Phase 9: Services & Finalization -# ============================================================ - -# Enable systemd user services -log "Enabling systemd user services..." -USER_SERVICES=( - "kanshi" - "wlsunset" - "stasis" - "cliphist-text" - "cliphist-image" -) - -for service in "${USER_SERVICES[@]}"; do - if systemctl --user cat "${service}.service" &>/dev/null; then - systemctl --user enable "$service" - log " + $service (user)" - else - log " ~ $service (user) not found, skipped." - fi -done - -log "Enabling services..." -SERVICES=( - "NetworkManager" - "bluetooth" - "greetd" - "systemd-timesyncd" - "ufw" - "auto-cpufreq" -) - -for service in "${SERVICES[@]}"; do - if systemctl list-unit-files "${service}.service" &>/dev/null; then - sudo systemctl enable "$service" - log " + $service" - else - log " ~ $service not found, skipped." - fi -done - -# Set shell to zsh -if [[ "$SHELL" != */zsh ]]; then - log "Setting default shell to zsh..." - chsh -s "$(which zsh)" -fi - -# Firewall -log "Configuring UFW..." -sudo ufw default deny incoming -sudo ufw default allow outgoing -sudo ufw --force enable - -# Directories -mkdir -p "$HOME/Pictures/Screenshots" -mkdir -p "$HOME/Pictures/Wallpaper" - -# ============================================================ -# Phase 10: Done -# ============================================================ - -echo "" -log "============================================" -log " Moonarch transform complete!" -log "============================================" -echo "" -if [[ -n "$BACKUP_FILE" ]]; then - log "Your previous config is backed up at:" - log " $BACKUP_FILE" - if [[ -n "$SYSTEM_BACKUP" ]]; then - log " $SYSTEM_BACKUP" - fi -fi -echo "" -log "Next steps:" -log " 1. Reboot (greetd replaces your previous display manager)" -log " 2. Place wallpapers in ~/Pictures/Wallpaper/" -log " 3. rustup default stable" -log " 4. User overrides in ~/.config/ or ~/.zshrc.d/" -echo "" -err "Do NOT log out — your previous DM is disabled. Reboot instead." -echo "" diff --git a/scripts/update.sh b/scripts/update.sh deleted file mode 100755 index fe2bd6a..0000000 --- a/scripts/update.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# ABOUTME: Legacy updater — replaced by moonarch-update from the moonarch-git package. -# ABOUTME: Prints deprecation notice and forwards if package version is available. - -echo "" -echo -e "\e[1;33m[Moonarch]\e[0m moonarch-update is now provided by the moonarch-git package." -echo -e "\e[1;33m[Moonarch]\e[0m Install with: paru -S moonarch-git" -echo -e "\e[1;33m[Moonarch]\e[0m Then run: moonarch-update" -echo "" - -if command -v moonarch-update &>/dev/null && [[ "$(which moonarch-update)" == "/usr/bin/moonarch-update" ]]; then - echo -e "\e[1;34m[Moonarch]\e[0m Package version detected. Forwarding..." - exec moonarch-update -fi