diff --git a/AGENTS.md b/AGENTS.md index b383587cfd0..4b64ae7844a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -84,6 +84,7 @@ Use these instead of raw shell commands: - `omarchy-pkg-drop` - remove packages; use this instead of raw `pacman -R*` - `omarchy-notification-send` - send desktop notifications; do not call `notify-send` directly - `omarchy-hw-asus-rog` - detect ASUS ROG hardware (and similar `hw-*` commands) +- `omarchy-hw-arch` / `omarchy-hw-aarch64` / `omarchy-hw-apple-silicon` - architecture and Apple Silicon detection; do not call `uname -m` or grep `/proc/device-tree/compatible` in install or runtime code. `omarchy-mac-setup` may read `uname -m` because it can run from `curl | bash` before the checkout exists. Historical migrations keep their original checks. Commands installed by Omarchy's default package set are runtime invariants. Invoke them directly; do not add defensive `omarchy-cmd-present` / `omarchy-cmd-missing` checks around them. Use command-presence helpers only for genuinely optional dependencies or code that can run before the default package set is installed. diff --git a/bin/omarchy-capture-screenrecording b/bin/omarchy-capture-screenrecording index 1f8a169b3a6..6787fee9330 100755 --- a/bin/omarchy-capture-screenrecording +++ b/bin/omarchy-capture-screenrecording @@ -60,7 +60,7 @@ REC_PID="" # so use wf-recorder there. Elsewhere prefer gpu-screen-recorder, falling back to # wf-recorder only if gpu-screen-recorder isn't installed. select_recorder_backend() { - if grep -qa apple /proc/device-tree/compatible 2>/dev/null; then + if omarchy-hw-apple-silicon; then echo "wf-recorder" elif omarchy-cmd-present gpu-screen-recorder; then echo "gpu-screen-recorder" diff --git a/bin/omarchy-hibernation-setup b/bin/omarchy-hibernation-setup index dd4d6457c08..f42b18d33e3 100755 --- a/bin/omarchy-hibernation-setup +++ b/bin/omarchy-hibernation-setup @@ -15,7 +15,7 @@ done # Apple Silicon / Asahi: resume path is Limine-oriented and hibernate is # unreliable; never create swap or limine drop-ins on aarch64 (even with --force). -if [[ $(uname -m) == "aarch64" ]]; then +if omarchy-hw-aarch64; then echo "Skipping hibernation setup (not supported on aarch64 / Omarchy Mac)" exit 0 fi diff --git a/bin/omarchy-hw-aarch64 b/bin/omarchy-hw-aarch64 new file mode 100755 index 00000000000..1d379633a55 --- /dev/null +++ b/bin/omarchy-hw-aarch64 @@ -0,0 +1,10 @@ +#!/bin/bash + +# omarchy:summary=Detect whether the machine is aarch64. + +# Codebase split: pacman tree, installer, package filter, aarch64-only tools. +# Self-contained so bootstrap can invoke it by absolute path before PATH is set. +case ${OMARCHY_UNAME_M:-$(uname -m)} in +aarch64 | arm64) exit 0 ;; +esac +exit 1 diff --git a/bin/omarchy-hw-apple-silicon b/bin/omarchy-hw-apple-silicon new file mode 100755 index 00000000000..78302bcab7d --- /dev/null +++ b/bin/omarchy-hw-apple-silicon @@ -0,0 +1,12 @@ +#!/bin/bash + +# omarchy:summary=Detect Apple Silicon (Asahi) hardware. + +# Hardware split: notch, Asahi HID, vulkan-asahi, wf-recorder, asahi-audio. +# aarch64 is not enough — a Raspberry Pi must not take the Apple path. +# OMARCHY_APPLE_COMPATIBLE stubs the device-tree file for tests. +case ${OMARCHY_UNAME_M:-$(uname -m)} in +aarch64 | arm64) ;; +*) exit 1 ;; +esac +grep -qi apple "${OMARCHY_APPLE_COMPATIBLE:-/proc/device-tree/compatible}" 2>/dev/null diff --git a/bin/omarchy-hw-arch b/bin/omarchy-hw-arch new file mode 100755 index 00000000000..861c11a99d4 --- /dev/null +++ b/bin/omarchy-hw-arch @@ -0,0 +1,12 @@ +#!/bin/bash + +# omarchy:summary=Print the canonical machine architecture (aarch64 or x86_64). + +# Maps uname's arm64 alias; unsupported or failed detection returns no name. +# OMARCHY_UNAME_M stubs uname for tests (same idea as OMARCHY_PCI_DEVICES_PATH). +arch="${OMARCHY_UNAME_M:-$(uname -m)}" || exit 1 +case $arch in +aarch64 | arm64) printf '%s\n' aarch64 ;; +x86_64) printf '%s\n' x86_64 ;; +*) exit 1 ;; +esac diff --git a/bin/omarchy-hw-laptop b/bin/omarchy-hw-laptop index d812b04cd30..6596874980d 100755 --- a/bin/omarchy-hw-laptop +++ b/bin/omarchy-hw-laptop @@ -11,9 +11,15 @@ done # button. 8=Portable 9=Laptop 10=Notebook 14=Sub Notebook 30=Tablet # 31=Convertible 32=Detachable. chassis_type="" -read -r chassis_type <"${OMARCHY_DMI_CHASSIS_TYPE_PATH:-/sys/class/dmi/id/chassis_type}" 2>/dev/null || true +dmi_chassis="${OMARCHY_DMI_CHASSIS_TYPE_PATH:-/sys/class/dmi/id/chassis_type}" +[[ -f $dmi_chassis ]] && read -r chassis_type <"$dmi_chassis" || true case "$chassis_type" in 8 | 9 | 10 | 14 | 30 | 31 | 32) exit 0 ;; esac +# Asahi MacBooks often expose neither an ACPI lid nor DMI chassis_type. +# Only fall back when DMI said nothing — an explicit desktop chassis (Mac +# Studio, Mini, or a test stub) must not be overridden by Apple Silicon. +[[ -z $chassis_type ]] && omarchy-hw-apple-silicon && exit 0 + exit 1 diff --git a/bin/omarchy-install-1password b/bin/omarchy-install-1password index 8e0edd73c79..51e4656f527 100755 --- a/bin/omarchy-install-1password +++ b/bin/omarchy-install-1password @@ -11,7 +11,7 @@ INSTALL_DIR="/opt/1Password" BIN_LINK="/usr/local/bin/1password" # Only run on aarch64 -if [ "$(uname -m)" != "aarch64" ]; then +if [[ $(omarchy-hw-arch) != "aarch64" ]]; then echo "Skipping: 1Password aarch64 installer only runs on aarch64 architecture" exit 0 fi diff --git a/bin/omarchy-install-cursor b/bin/omarchy-install-cursor index c336ac99775..1404c6c555b 100755 --- a/bin/omarchy-install-cursor +++ b/bin/omarchy-install-cursor @@ -4,7 +4,7 @@ set -euo pipefail VERSION="2.6.20" -ARCH="$(uname -m)" +ARCH="$(omarchy-hw-arch)" CURSOR_DIR="/opt/cursor" CURSOR_APPIMAGE="$CURSOR_DIR/cursor.AppImage" CURSOR_BIN="/usr/local/bin/cursor" diff --git a/bin/omarchy-install-docker-dbs b/bin/omarchy-install-docker-dbs index 55cffc1b2c4..b11038e531f 100755 --- a/bin/omarchy-install-docker-dbs +++ b/bin/omarchy-install-docker-dbs @@ -5,7 +5,7 @@ options=("MySQL" "PostgreSQL" "Redis" "MongoDB" "MariaDB") -if [[ $(uname -m) == "x86_64" ]]; then +if [[ $(omarchy-hw-arch) == "x86_64" ]]; then options+=("MSSQL") fi diff --git a/bin/omarchy-install-gaming-steam b/bin/omarchy-install-gaming-steam index 1620e893533..7dcf1c5e3f4 100755 --- a/bin/omarchy-install-gaming-steam +++ b/bin/omarchy-install-gaming-steam @@ -9,7 +9,7 @@ echo "Installing Steam..." omarchy-pkg-add steam omarchy-install-gaming-gpu-lib32 -if [[ $(uname -m) == aarch64 ]]; then +if omarchy-hw-aarch64; then omarchy-launch-steam --prepare fi diff --git a/bin/omarchy-install-preinstalls b/bin/omarchy-install-preinstalls index 7300c1bd4ff..78051cfe65f 100755 --- a/bin/omarchy-install-preinstalls +++ b/bin/omarchy-install-preinstalls @@ -27,7 +27,7 @@ if gum confirm "Are you sure you want to restore all preinstalled web apps, TUI omacalc omawrite ) - if [[ $(uname -m) == "aarch64" ]]; then + if omarchy-hw-aarch64; then preinstall_packages+=(obsidian-appimage) fi diff --git a/bin/omarchy-install-service-1password b/bin/omarchy-install-service-1password index 80fe3e03b65..daab80b0cd3 100755 --- a/bin/omarchy-install-service-1password +++ b/bin/omarchy-install-service-1password @@ -22,7 +22,7 @@ install_chromium_extension() { } echo "Installing 1Password..." -if [[ $(uname -m) == "aarch64" ]]; then +if omarchy-hw-aarch64; then # The AUR PKGBUILD is x86_64-only, so omarchy-pkg-add fails outright here. # omarchy-install-1password takes the official arm64 tarball instead. omarchy-install-1password diff --git a/bin/omarchy-launch-steam b/bin/omarchy-launch-steam index b363d418c45..425ca05a498 100755 --- a/bin/omarchy-launch-steam +++ b/bin/omarchy-launch-steam @@ -76,7 +76,7 @@ PY } prepare_asahi() { - [[ $(uname -m) == aarch64 ]] || return 0 + omarchy-hw-aarch64 || return 0 write_steam_desktop patch_steam_ui } @@ -86,7 +86,7 @@ if [[ ${1:-} == --prepare ]]; then exit 0 fi -if [[ $(uname -m) == aarch64 ]] && omarchy-cmd-present muvm && omarchy-cmd-present FEXBash; then +if omarchy-hw-aarch64 && omarchy-cmd-present muvm && omarchy-cmd-present FEXBash; then launcher="$HOME/.local/share/fex-steam/steam-launcher/bin_steam.sh" if [[ -f $launcher ]]; then diff --git a/bin/omarchy-pkg-add b/bin/omarchy-pkg-add index 694df8e4cdd..131eceac8a6 100755 --- a/bin/omarchy-pkg-add +++ b/bin/omarchy-pkg-add @@ -5,30 +5,32 @@ # omarchy:examples=omarchy pkg add jq ripgrep # omarchy:requires-sudo=true -# Mac fork: upstream migrations sometimes install packages that don't exist in -# Arch Linux ARM's repos (e.g. x86-only packages). Filter to what is actually -# installable here so those installs skip cleanly with a warning instead of -# hard-failing the whole migration. -to_install=() -for pkg in "$@"; do - if pacman -Q "$pkg" &>/dev/null || pacman -Si "$pkg" &>/dev/null; then - to_install+=("$pkg") - else - echo -e "\033[33mSkipping '$pkg': not available in the repos on this system\033[0m" >&2 - fi -done - -((${#to_install[@]})) || exit 0 +# On aarch64, upstream migrations sometimes name packages Arch Linux ARM does +# not serve. Filter to what is installable so those skip with a warning instead +# of failing the whole transaction. On x86 this is a no-op: missing packages +# fail, matching upstream. +packages=("$@") +if omarchy-hw-aarch64; then + packages=() + for pkg in "$@"; do + if pacman -Q "$pkg" &>/dev/null || pacman -Si "$pkg" &>/dev/null; then + packages+=("$pkg") + else + echo -e "\033[33mSkipping '$pkg': not available in the repos on this system\033[0m" >&2 + fi + done + ((${#packages[@]})) || exit 0 +fi -if omarchy-pkg-missing "${to_install[@]}"; then +if omarchy-pkg-missing "${packages[@]}"; then if (( EUID == 0 )); then - pacman -S --noconfirm --needed "${to_install[@]}" || exit 1 + pacman -S --noconfirm --needed "${packages[@]}" || exit 1 else - sudo pacman -S --noconfirm --needed "${to_install[@]}" || exit 1 + sudo pacman -S --noconfirm --needed "${packages[@]}" || exit 1 fi fi -for pkg in "${to_install[@]}"; do +for pkg in "${packages[@]}"; do # Secondary check to handle states where pacman doesn't actually register an error if ! pacman -Q "$pkg" &>/dev/null; then echo -e "\033[31mError: Package '$pkg' did not install\033[0m" >&2 diff --git a/bin/omarchy-pkg-publish-aarch64 b/bin/omarchy-pkg-publish-aarch64 index a86f3ce53a6..f173acdaaed 100755 --- a/bin/omarchy-pkg-publish-aarch64 +++ b/bin/omarchy-pkg-publish-aarch64 @@ -10,9 +10,9 @@ # self-hosted git server is up. It went down mid-install once and took the # whole desktop with it, because there is no Quattro shell without quickshell. # -# The fix is the repo that already exists. default/pacman/pacman-stable.conf -# points pacman at a GitHub release serving a real pacman database, and this -# publishes into it: build on this machine, add to the database, upload. +# The fix is the repo that already exists under default/pacman/aarch64/. +# Its stable config points pacman at a GitHub release serving a real pacman +# database, and this publishes into it: build on this machine, add to the database, upload. # Installs then fetch a binary instead of building one. # # Run it on Apple Silicon as your regular user, with gh logged in to the @@ -31,10 +31,10 @@ readonly checkout="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" find_pacman_conf() { local candidate for candidate in \ - "$checkout/default/pacman/pacman-stable.conf" \ - "${OMARCHY_PATH:-}/default/pacman/pacman-stable.conf" \ - "$HOME/.local/share/omarchy/default/pacman/pacman-stable.conf" \ - /usr/share/omarchy/default/pacman/pacman-stable.conf \ + "$checkout/default/pacman/aarch64/pacman-stable.conf" \ + "${OMARCHY_PATH:-}/default/pacman/aarch64/pacman-stable.conf" \ + "$HOME/.local/share/omarchy/default/pacman/aarch64/pacman-stable.conf" \ + /usr/share/omarchy/default/pacman/aarch64/pacman-stable.conf \ /etc/pacman.conf; do [[ -n $candidate && -f $candidate ]] || continue grep -q '^\[omarchy-aarch64\]' "$candidate" || continue @@ -151,8 +151,8 @@ main() { (( ${#built[@]} )) || fail "no packages in $from_dir" else (( ${#packages[@]} )) || packages=(quickshell-git) - [[ $(uname -m) == "aarch64" ]] || - fail "building runs on Apple Silicon; use --from to publish packages built elsewhere" + omarchy-hw-aarch64 || + fail "building runs on aarch64; use --from to publish packages built elsewhere" command -v makepkg >/dev/null || fail "makepkg is required (install base-devel)" local build_dir="$work_root/build" diff --git a/bin/omarchy-refresh-pacman b/bin/omarchy-refresh-pacman index 5bf9c80de26..5b0c320ac01 100755 --- a/bin/omarchy-refresh-pacman +++ b/bin/omarchy-refresh-pacman @@ -5,9 +5,6 @@ sudo cp -f /etc/pacman.conf /etc/pacman.conf.bak sudo cp -f /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak -if [[ -f /etc/pacman.d/mirrorlist.asahi-alarm ]]; then - sudo cp -f /etc/pacman.d/mirrorlist.asahi-alarm /etc/pacman.d/mirrorlist.asahi-alarm.bak -fi channel="${1:-stable}" @@ -19,16 +16,29 @@ fi echo "Setting channel to $channel" echo -sudo cp -f "$OMARCHY_PATH/default/pacman/pacman-$channel.conf" /etc/pacman.conf -sudo cp -f "$OMARCHY_PATH/default/pacman/mirrorlist" /etc/pacman.d/mirrorlist -sudo cp -f "$OMARCHY_PATH/default/pacman/mirrorlist.asahi-alarm" /etc/pacman.d/mirrorlist.asahi-alarm +if omarchy-hw-aarch64; then + pacman_dir="$OMARCHY_PATH/default/pacman/aarch64" + mirrorlist_src="$pacman_dir/mirrorlist" + if [[ -f /etc/pacman.d/mirrorlist.asahi-alarm ]]; then + sudo cp -f /etc/pacman.d/mirrorlist.asahi-alarm /etc/pacman.d/mirrorlist.asahi-alarm.bak + fi +else + pacman_dir="$OMARCHY_PATH/default/pacman" + mirrorlist_src="$pacman_dir/mirrorlist-$channel" +fi + +sudo cp -f "$pacman_dir/pacman-$channel.conf" /etc/pacman.conf +sudo cp -f "$mirrorlist_src" /etc/pacman.d/mirrorlist +if omarchy-hw-aarch64; then + sudo cp -f "$pacman_dir/mirrorlist.asahi-alarm" /etc/pacman.d/mirrorlist.asahi-alarm +fi # Allow user customization of /etc/pacman.conf before the upgrade runs omarchy-hook pre-refresh-pacman # Reset all package DBs and then update targets=() -if [[ $(uname -m) == "aarch64" ]]; then +if omarchy-hw-aarch64; then source "$OMARCHY_PATH/install/helpers/arm-package-sources.sh" # Keep the original configuration saved before the channel replacement. omarchy_arm_prepare_package_sources /etc/pacman.conf preserve-backup || exit 1 diff --git a/bin/omarchy-refresh-pacman-mirrorlist b/bin/omarchy-refresh-pacman-mirrorlist index 95d0528bc1d..a2bf6fba426 100755 --- a/bin/omarchy-refresh-pacman-mirrorlist +++ b/bin/omarchy-refresh-pacman-mirrorlist @@ -13,8 +13,21 @@ # missing from the system file. This avoids removing Arch Linux ARM or user-added # mirrors while still making Omarchy's recommended servers available. -SRC="$OMARCHY_PATH/default/pacman/mirrorlist" -ASAHI_SRC="$OMARCHY_PATH/default/pacman/mirrorlist.asahi-alarm" +if omarchy-hw-aarch64; then + SRC="$OMARCHY_PATH/default/pacman/aarch64/mirrorlist" + ASAHI_SRC="$OMARCHY_PATH/default/pacman/aarch64/mirrorlist.asahi-alarm" +else + pacman_conf="${OMARCHY_PACMAN_CONF_PATH:-/etc/pacman.conf}" + channel=stable + for candidate in stable rc edge; do + if grep -qF "https://pkgs.omarchy.org/$candidate/" "$pacman_conf" 2>/dev/null; then + channel="$candidate" + break + fi + done + SRC="$OMARCHY_PATH/default/pacman/mirrorlist-$channel" + ASAHI_SRC="" +fi DEST="/etc/pacman.d/mirrorlist" ASAHI_DEST="/etc/pacman.d/mirrorlist.asahi-alarm" diff --git a/bin/omarchy-remove-preinstalls b/bin/omarchy-remove-preinstalls index 8475ecc39a8..90985aa4882 100755 --- a/bin/omarchy-remove-preinstalls +++ b/bin/omarchy-remove-preinstalls @@ -32,7 +32,7 @@ if gum confirm "Are you sure you want to remove all preinstalled web apps, TUI w omacalc omawrite ) - if [[ $(uname -m) == "aarch64" ]]; then + if omarchy-hw-aarch64; then preinstall_packages+=(obsidian-appimage) fi omarchy-pkg-drop "${preinstall_packages[@]}" diff --git a/bin/omarchy-system-boot-to-esp b/bin/omarchy-system-boot-to-esp index f90de78d388..8250039812d 100644 --- a/bin/omarchy-system-boot-to-esp +++ b/bin/omarchy-system-boot-to-esp @@ -95,7 +95,7 @@ main() { done (( EUID == 0 )) || fail "run as root" - [[ $(uname -m) == "aarch64" ]] || fail "this tool is for Apple Silicon (aarch64) installs" + omarchy-hw-apple-silicon || fail "this tool is for Apple Silicon installs" if findmnt -no SOURCE /boot >/dev/null 2>&1; then log "/boot is already its own mount -- nothing to do." diff --git a/bin/omarchy-system-btrfs-migrate b/bin/omarchy-system-btrfs-migrate index d21e760e619..1b99938c52c 100755 --- a/bin/omarchy-system-btrfs-migrate +++ b/bin/omarchy-system-btrfs-migrate @@ -758,7 +758,7 @@ run_stage() { local encrypt="$1" (( EUID == 0 )) || fail "run as root" - [[ $(uname -m) == aarch64 ]] || fail "this tool is for Apple Silicon (aarch64) installs" + omarchy-hw-apple-silicon || fail "this tool is for Apple Silicon installs" [[ -f ${BASH_SOURCE[0]} ]] || fail "run this from a file, not via a pipe (curl -O it first)" [[ -d /boot/grub ]] || fail "no GRUB found at /boot/grub; unsupported boot layout" diff --git a/bin/omarchy-update-keyring b/bin/omarchy-update-keyring index 09f3442044e..2d76bae6520 100755 --- a/bin/omarchy-update-keyring +++ b/bin/omarchy-update-keyring @@ -5,7 +5,7 @@ set -e -if [[ $(uname -m) == "aarch64" ]]; then +if omarchy-hw-aarch64; then source "$OMARCHY_PATH/install/helpers/arm-package-sources.sh" omarchy_arm_prepare_package_sources # Refresh the distribution keyring before the immediately following full diff --git a/bin/omarchy-update-restart b/bin/omarchy-update-restart index 6c0a5587e4c..1ee17019c17 100755 --- a/bin/omarchy-update-restart +++ b/bin/omarchy-update-restart @@ -2,21 +2,43 @@ # omarchy:summary=Restart after an update when the kernel changed # Compare kernel version before and after updates. -# Mac fork: this fork ships the Apple-Silicon kernel, so kernel-update detection -# compares the linux-asahi *package version* (not upstream's `uname -r` vs -# module-dir-name match, which is fragile across kernel naming). Keep this form. -kernel_before=$(cat /tmp/omarchy-kernel-before 2>/dev/null) -kernel_after=$(pacman -Q linux-asahi 2>/dev/null | awk '{print $2}') -rm -f /tmp/omarchy-kernel-before - -if [[ -n $kernel_before && $kernel_before != "$kernel_after" ]]; then - gum confirm "Linux kernel has been updated. Reboot?" && omarchy-state clear re*-required && sudo reboot now -fi +if omarchy-hw-apple-silicon; then + # Apple Silicon ships linux-asahi; compare that package version rather than + # upstream's uname -r vs module-dir-name match, which is fragile across Asahi + # kernel naming. + kernel_before=$(cat /tmp/omarchy-kernel-before 2>/dev/null) + kernel_after=$(pacman -Q linux-asahi 2>/dev/null | awk '{print $2}') + rm -f /tmp/omarchy-kernel-before + + if [[ -n $kernel_before && $kernel_before != "$kernel_after" ]]; then + gum confirm "Linux kernel has been updated. Reboot?" && omarchy-state clear re*-required && sudo reboot now + fi + + if find /usr/lib/modules -maxdepth 2 -name vmlinuz -newermt "$(uptime -s)" 2>/dev/null | grep -q .; then + gum confirm "Linux kernel has been updated. Reboot?" && omarchy-system-reboot + elif [[ -f $HOME/.local/state/omarchy/reboot-required ]]; then + gum confirm "Updates require reboot. Ready?" && omarchy-system-reboot + fi +else + running_kernel=$(uname -r) + kernel_updated=true + + for kernel in /usr/lib/modules/*/vmlinuz; do + if [[ -f $kernel ]] && pacman -Qo "$kernel" &>/dev/null; then + installed_kernel=$(basename "$(dirname "$kernel")") -if find /usr/lib/modules -maxdepth 2 -name vmlinuz -newermt "$(uptime -s)" 2>/dev/null | grep -q .; then - gum confirm "Linux kernel has been updated. Reboot?" && omarchy-system-reboot -elif [[ -f $HOME/.local/state/omarchy/reboot-required ]]; then - gum confirm "Updates require reboot. Ready?" && omarchy-system-reboot + if [[ $installed_kernel == $running_kernel ]]; then + kernel_updated=false + break + fi + fi + done + + if [[ $kernel_updated == "true" ]]; then + gum confirm "Linux kernel has been updated. Reboot?" && omarchy-system-reboot + elif [[ -f $HOME/.local/state/omarchy/reboot-required ]]; then + gum confirm "Updates require reboot. Ready?" && omarchy-system-reboot + fi fi running_hyprland=$(readlink /proc/$(pgrep -x Hyprland)/exe 2>/dev/null) diff --git a/bin/omarchy-update-system-pkgs b/bin/omarchy-update-system-pkgs index c22fa59b8e8..8293ae10d0d 100755 --- a/bin/omarchy-update-system-pkgs +++ b/bin/omarchy-update-system-pkgs @@ -6,7 +6,7 @@ set -e targets=() -if [[ $(uname -m) == "aarch64" ]]; then +if omarchy-hw-aarch64; then source "$OMARCHY_PATH/install/helpers/arm-package-sources.sh" omarchy_arm_prepare_package_sources mapfile -t targets < <(omarchy_arm_package_targets) diff --git a/bin/omarchy-upgrade-to-quattro b/bin/omarchy-upgrade-to-quattro index f3939e0b592..9101b5452af 100755 --- a/bin/omarchy-upgrade-to-quattro +++ b/bin/omarchy-upgrade-to-quattro @@ -118,7 +118,7 @@ esac # This is the upstream x86 upgrade: it repoints pacman at Omarchy's x86_64 # mirrors and packages, which do not serve aarch64. On Apple Silicon the Mac # upgrade (omarchy-upgrade-to-quattro-mac) wires the source checkout instead. -[[ $(uname -m) != "aarch64" ]] || fail "This is the upstream x86 upgrade. On Apple Silicon run omarchy-upgrade-to-quattro-mac." +[[ $(omarchy-hw-arch) == "x86_64" ]] || fail "This is the upstream x86 upgrade. On Apple Silicon run omarchy-upgrade-to-quattro-mac." # Land on the Quattro equivalent of wherever the machine already is, unless the # caller said otherwise. Stable machines get the production packages off the diff --git a/bin/omarchy-upgrade-to-quattro-mac b/bin/omarchy-upgrade-to-quattro-mac index 88996d78690..c58e108fd7f 100755 --- a/bin/omarchy-upgrade-to-quattro-mac +++ b/bin/omarchy-upgrade-to-quattro-mac @@ -87,8 +87,8 @@ done command -v sudo >/dev/null 2>&1 || fail "sudo is required." command -v pacman >/dev/null 2>&1 || fail "This upgrade is only supported on Arch-based systems with pacman." command -v yay >/dev/null 2>&1 || fail "yay is required to build AUR packages. Install it first." -[[ $(uname -m) == "aarch64" ]] || fail "This is the Apple Silicon upgrade. On x86 machines use omarchy-upgrade-to-quattro." -grep -qi apple /proc/device-tree/compatible 2>/dev/null || warn "This does not look like Apple hardware; continuing anyway." +omarchy-hw-aarch64 || fail "This is the Apple Silicon upgrade. On x86 machines use omarchy-upgrade-to-quattro." +omarchy-hw-apple-silicon || warn "This does not look like Apple hardware; continuing anyway." [[ -d $checkout/.git ]] || fail "No Omarchy checkout found at $checkout. Is Omarchy Mac 3.x installed?" if (( ! yes )); then @@ -173,8 +173,8 @@ ensure_arm_package_repo() { if ! grep -q '^\[omarchy-aarch64\]' /etc/pacman.conf; then local block block=$(sed -n '/^\[omarchy-aarch64\]/,/^Server[[:space:]]*=/p' \ - "$checkout/default/pacman/pacman-stable.conf") - [[ -n $block ]] || fail "default/pacman/pacman-stable.conf has no [omarchy-aarch64] section." + "$checkout/default/pacman/aarch64/pacman-stable.conf") + [[ -n $block ]] || fail "default/pacman/aarch64/pacman-stable.conf has no [omarchy-aarch64] section." log "Adding the Omarchy ARM package repo" printf '\n%s\n' "$block" | sudo tee -a /etc/pacman.conf >/dev/null diff --git a/bin/omarchy-voxtype-install b/bin/omarchy-voxtype-install index a527538fbb5..23bed98409a 100755 --- a/bin/omarchy-voxtype-install +++ b/bin/omarchy-voxtype-install @@ -11,7 +11,7 @@ if gum confirm "Install Voxtype + AI model (~150MB) to enable dictation?"; then # Mac fork: voxtype-bin ships x86_64-only prebuilt binaries; on Apple Silicon # build the source package instead (voxtype, arch includes aarch64) via the AUR # helper. wtype is in the repos on both. - if [[ "$(uname -m)" == "aarch64" ]]; then + if omarchy-hw-aarch64; then omarchy-pkg-add wtype omarchy-pkg-aur-add voxtype else diff --git a/bin/omarchy-windows-vm b/bin/omarchy-windows-vm index 6bafe7932f2..eccbe468617 100755 --- a/bin/omarchy-windows-vm +++ b/bin/omarchy-windows-vm @@ -2,8 +2,7 @@ # omarchy:summary=Set up a Windows VM (unsupported on Apple Silicon) # Check for ARM64 architecture first -ARCH=$(uname -m) -if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then +if omarchy-hw-aarch64; then cat << 'EOF' ╔═══════════════════════════════════════════════════════════════╗ @@ -22,7 +21,7 @@ if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then ╚═══════════════════════════════════════════════════════════════╝ EOF - echo "Current architecture: $ARCH" + echo "Current architecture: $(omarchy-hw-arch)" echo "This feature is only available on x86_64 systems." echo exit 1 diff --git a/build-packages.sh b/build-packages.sh index b07d84fc647..51f6620cc7d 100755 --- a/build-packages.sh +++ b/build-packages.sh @@ -196,7 +196,7 @@ build_package() { } main() { - [[ $(uname -m) == "aarch64" ]] || fail "This builds the Apple Silicon packages; run it on aarch64." + omarchy-hw-aarch64 || fail "This builds the Apple Silicon packages; run it on aarch64." command -v makepkg >/dev/null || fail "makepkg is required (install base-devel)." (( EUID != 0 )) || fail "Run this as your regular user, not as root." diff --git a/default/pacman/mirrorlist b/default/pacman/aarch64/mirrorlist similarity index 100% rename from default/pacman/mirrorlist rename to default/pacman/aarch64/mirrorlist diff --git a/default/pacman/aarch64/mirrorlist-edge b/default/pacman/aarch64/mirrorlist-edge new file mode 100644 index 00000000000..e9d9dad324d --- /dev/null +++ b/default/pacman/aarch64/mirrorlist-edge @@ -0,0 +1,57 @@ +# +# Arch Linux ARM repository mirrorlist +# Generated on 2023-02-06 +# + +## Geo-IP based mirror selection and load balancing +Server = http://mirror.archlinuxarm.org/$arch/$repo + +### Mirrors by country + +### Denmark +## Aalborg +# Server = http://dk.mirror.archlinuxarm.org/$arch/$repo + +### Germany +## Aachen +# Server = http://de3.mirror.archlinuxarm.org/$arch/$repo +## Berlin +# Server = http://de.mirror.archlinuxarm.org/$arch/$repo +## Coburg +# Server = http://de4.mirror.archlinuxarm.org/$arch/$repo +## Falkenstein +# Server = http://eu.mirror.archlinuxarm.org/$arch/$repo +# Server = http://de5.mirror.archlinuxarm.org/$arch/$repo + +### Greece +## Athens +# Server = http://gr.mirror.archlinuxarm.org/$arch/$repo + +### Hungary +## Budapest +# Server = http://hu.mirror.archlinuxarm.org/$arch/$repo + +### Japan +## Tokyo +# Server = http://jp.mirror.archlinuxarm.org/$arch/$repo + +### Singapore +# Server = http://sg.mirror.archlinuxarm.org/$arch/$repo + +### Taiwan +## Hsinchu +# Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo +## New Taipei City +# Server = http://tw.mirror.archlinuxarm.org/$arch/$repo + +### United Kingdom +## London +# Server = http://uk.mirror.archlinuxarm.org/$arch/$repo + +### United States +## California +# Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo +## Florida +# Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo +## New Jersey +# Server = http://nj.us.mirror.archlinuxarm.org/$arch/$repo diff --git a/default/pacman/aarch64/mirrorlist-rc b/default/pacman/aarch64/mirrorlist-rc new file mode 100644 index 00000000000..e9d9dad324d --- /dev/null +++ b/default/pacman/aarch64/mirrorlist-rc @@ -0,0 +1,57 @@ +# +# Arch Linux ARM repository mirrorlist +# Generated on 2023-02-06 +# + +## Geo-IP based mirror selection and load balancing +Server = http://mirror.archlinuxarm.org/$arch/$repo + +### Mirrors by country + +### Denmark +## Aalborg +# Server = http://dk.mirror.archlinuxarm.org/$arch/$repo + +### Germany +## Aachen +# Server = http://de3.mirror.archlinuxarm.org/$arch/$repo +## Berlin +# Server = http://de.mirror.archlinuxarm.org/$arch/$repo +## Coburg +# Server = http://de4.mirror.archlinuxarm.org/$arch/$repo +## Falkenstein +# Server = http://eu.mirror.archlinuxarm.org/$arch/$repo +# Server = http://de5.mirror.archlinuxarm.org/$arch/$repo + +### Greece +## Athens +# Server = http://gr.mirror.archlinuxarm.org/$arch/$repo + +### Hungary +## Budapest +# Server = http://hu.mirror.archlinuxarm.org/$arch/$repo + +### Japan +## Tokyo +# Server = http://jp.mirror.archlinuxarm.org/$arch/$repo + +### Singapore +# Server = http://sg.mirror.archlinuxarm.org/$arch/$repo + +### Taiwan +## Hsinchu +# Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo +## New Taipei City +# Server = http://tw.mirror.archlinuxarm.org/$arch/$repo + +### United Kingdom +## London +# Server = http://uk.mirror.archlinuxarm.org/$arch/$repo + +### United States +## California +# Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo +## Florida +# Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo +## New Jersey +# Server = http://nj.us.mirror.archlinuxarm.org/$arch/$repo diff --git a/default/pacman/aarch64/mirrorlist-stable b/default/pacman/aarch64/mirrorlist-stable new file mode 100644 index 00000000000..e9d9dad324d --- /dev/null +++ b/default/pacman/aarch64/mirrorlist-stable @@ -0,0 +1,57 @@ +# +# Arch Linux ARM repository mirrorlist +# Generated on 2023-02-06 +# + +## Geo-IP based mirror selection and load balancing +Server = http://mirror.archlinuxarm.org/$arch/$repo + +### Mirrors by country + +### Denmark +## Aalborg +# Server = http://dk.mirror.archlinuxarm.org/$arch/$repo + +### Germany +## Aachen +# Server = http://de3.mirror.archlinuxarm.org/$arch/$repo +## Berlin +# Server = http://de.mirror.archlinuxarm.org/$arch/$repo +## Coburg +# Server = http://de4.mirror.archlinuxarm.org/$arch/$repo +## Falkenstein +# Server = http://eu.mirror.archlinuxarm.org/$arch/$repo +# Server = http://de5.mirror.archlinuxarm.org/$arch/$repo + +### Greece +## Athens +# Server = http://gr.mirror.archlinuxarm.org/$arch/$repo + +### Hungary +## Budapest +# Server = http://hu.mirror.archlinuxarm.org/$arch/$repo + +### Japan +## Tokyo +# Server = http://jp.mirror.archlinuxarm.org/$arch/$repo + +### Singapore +# Server = http://sg.mirror.archlinuxarm.org/$arch/$repo + +### Taiwan +## Hsinchu +# Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo +## New Taipei City +# Server = http://tw.mirror.archlinuxarm.org/$arch/$repo + +### United Kingdom +## London +# Server = http://uk.mirror.archlinuxarm.org/$arch/$repo + +### United States +## California +# Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo +## Florida +# Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo +## New Jersey +# Server = http://nj.us.mirror.archlinuxarm.org/$arch/$repo diff --git a/default/pacman/mirrorlist.asahi-alarm b/default/pacman/aarch64/mirrorlist.asahi-alarm similarity index 100% rename from default/pacman/mirrorlist.asahi-alarm rename to default/pacman/aarch64/mirrorlist.asahi-alarm diff --git a/default/pacman/aarch64/pacman-edge.conf b/default/pacman/aarch64/pacman-edge.conf new file mode 100644 index 00000000000..b869880c19b --- /dev/null +++ b/default/pacman/aarch64/pacman-edge.conf @@ -0,0 +1,45 @@ +# See the pacman.conf(5) manpage for option and repository directives + +[options] +Color +ILoveCandy +VerbosePkgLists +HoldPkg = pacman glibc +Architecture = aarch64 +CheckSpace +ParallelDownloads = 5 +DownloadUser = alpm + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional + +# pacman searches repositories in the order defined here +# Mac-specific packages remain in the community ARM repository. +# Without it herdr drags in a zig0.15 build that aarch64 cannot even use, +# costing about two hours of a fresh install before it fails. +# Only explicitly selected Hyprland packages use official edge. +[omarchy] +Usage = Sync +SigLevel = Required DatabaseOptional +Server = https://pkgs.omarchy.org/edge/$arch + +[omarchy-aarch64] +SigLevel = Optional TrustAll +Server = https://github.com/omarchy-mac/omarchy-pkgs-aarch64/releases/download/edge + +[asahi-alarm] +Include = /etc/pacman.d/mirrorlist.asahi-alarm + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +[alarm] +Include = /etc/pacman.d/mirrorlist + +[aur] +Include = /etc/pacman.d/mirrorlist diff --git a/default/pacman/aarch64/pacman-rc.conf b/default/pacman/aarch64/pacman-rc.conf new file mode 100644 index 00000000000..b869880c19b --- /dev/null +++ b/default/pacman/aarch64/pacman-rc.conf @@ -0,0 +1,45 @@ +# See the pacman.conf(5) manpage for option and repository directives + +[options] +Color +ILoveCandy +VerbosePkgLists +HoldPkg = pacman glibc +Architecture = aarch64 +CheckSpace +ParallelDownloads = 5 +DownloadUser = alpm + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional + +# pacman searches repositories in the order defined here +# Mac-specific packages remain in the community ARM repository. +# Without it herdr drags in a zig0.15 build that aarch64 cannot even use, +# costing about two hours of a fresh install before it fails. +# Only explicitly selected Hyprland packages use official edge. +[omarchy] +Usage = Sync +SigLevel = Required DatabaseOptional +Server = https://pkgs.omarchy.org/edge/$arch + +[omarchy-aarch64] +SigLevel = Optional TrustAll +Server = https://github.com/omarchy-mac/omarchy-pkgs-aarch64/releases/download/edge + +[asahi-alarm] +Include = /etc/pacman.d/mirrorlist.asahi-alarm + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +[alarm] +Include = /etc/pacman.d/mirrorlist + +[aur] +Include = /etc/pacman.d/mirrorlist diff --git a/default/pacman/aarch64/pacman-stable.conf b/default/pacman/aarch64/pacman-stable.conf new file mode 100644 index 00000000000..87aa84081b4 --- /dev/null +++ b/default/pacman/aarch64/pacman-stable.conf @@ -0,0 +1,106 @@ + + +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = aarch64 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#NoProgressBar +CheckSpace +#VerbosePkgLists +ParallelDownloads = 5 +DownloadUser = alpm + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux ARM +# packagers with `pacman-key --populate archlinuxarm`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +# Mac-specific packages remain in the community ARM repository. +# Without it herdr drags in a zig0.15 build that aarch64 cannot even use, +# costing about two hours of a fresh install before it fails. +# Only explicitly selected Hyprland packages use official edge. +[omarchy] +Usage = Sync +SigLevel = Required DatabaseOptional +Server = https://pkgs.omarchy.org/edge/$arch + +[omarchy-aarch64] +SigLevel = Optional TrustAll +Server = https://github.com/omarchy-mac/omarchy-pkgs-aarch64/releases/download/edge + +[asahi-alarm] +Include = /etc/pacman.d/mirrorlist.asahi-alarm + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +[alarm] +Include = /etc/pacman.d/mirrorlist + +[aur] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/default/pacman/pacman.conf b/default/pacman/aarch64/pacman.conf similarity index 100% rename from default/pacman/pacman.conf rename to default/pacman/aarch64/pacman.conf diff --git a/default/pacman/mirrorlist-edge b/default/pacman/mirrorlist-edge index e9d9dad324d..914c1fa768b 100644 --- a/default/pacman/mirrorlist-edge +++ b/default/pacman/mirrorlist-edge @@ -1,57 +1 @@ -# -# Arch Linux ARM repository mirrorlist -# Generated on 2023-02-06 -# - -## Geo-IP based mirror selection and load balancing -Server = http://mirror.archlinuxarm.org/$arch/$repo - -### Mirrors by country - -### Denmark -## Aalborg -# Server = http://dk.mirror.archlinuxarm.org/$arch/$repo - -### Germany -## Aachen -# Server = http://de3.mirror.archlinuxarm.org/$arch/$repo -## Berlin -# Server = http://de.mirror.archlinuxarm.org/$arch/$repo -## Coburg -# Server = http://de4.mirror.archlinuxarm.org/$arch/$repo -## Falkenstein -# Server = http://eu.mirror.archlinuxarm.org/$arch/$repo -# Server = http://de5.mirror.archlinuxarm.org/$arch/$repo - -### Greece -## Athens -# Server = http://gr.mirror.archlinuxarm.org/$arch/$repo - -### Hungary -## Budapest -# Server = http://hu.mirror.archlinuxarm.org/$arch/$repo - -### Japan -## Tokyo -# Server = http://jp.mirror.archlinuxarm.org/$arch/$repo - -### Singapore -# Server = http://sg.mirror.archlinuxarm.org/$arch/$repo - -### Taiwan -## Hsinchu -# Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo -## New Taipei City -# Server = http://tw.mirror.archlinuxarm.org/$arch/$repo - -### United Kingdom -## London -# Server = http://uk.mirror.archlinuxarm.org/$arch/$repo - -### United States -## California -# Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo -## Florida -# Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo -## New Jersey -# Server = http://nj.us.mirror.archlinuxarm.org/$arch/$repo +Server = https://mirror.omarchy.org/$repo/os/$arch diff --git a/default/pacman/mirrorlist-rc b/default/pacman/mirrorlist-rc index e9d9dad324d..0692a0a1692 100644 --- a/default/pacman/mirrorlist-rc +++ b/default/pacman/mirrorlist-rc @@ -1,57 +1 @@ -# -# Arch Linux ARM repository mirrorlist -# Generated on 2023-02-06 -# - -## Geo-IP based mirror selection and load balancing -Server = http://mirror.archlinuxarm.org/$arch/$repo - -### Mirrors by country - -### Denmark -## Aalborg -# Server = http://dk.mirror.archlinuxarm.org/$arch/$repo - -### Germany -## Aachen -# Server = http://de3.mirror.archlinuxarm.org/$arch/$repo -## Berlin -# Server = http://de.mirror.archlinuxarm.org/$arch/$repo -## Coburg -# Server = http://de4.mirror.archlinuxarm.org/$arch/$repo -## Falkenstein -# Server = http://eu.mirror.archlinuxarm.org/$arch/$repo -# Server = http://de5.mirror.archlinuxarm.org/$arch/$repo - -### Greece -## Athens -# Server = http://gr.mirror.archlinuxarm.org/$arch/$repo - -### Hungary -## Budapest -# Server = http://hu.mirror.archlinuxarm.org/$arch/$repo - -### Japan -## Tokyo -# Server = http://jp.mirror.archlinuxarm.org/$arch/$repo - -### Singapore -# Server = http://sg.mirror.archlinuxarm.org/$arch/$repo - -### Taiwan -## Hsinchu -# Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo -## New Taipei City -# Server = http://tw.mirror.archlinuxarm.org/$arch/$repo - -### United Kingdom -## London -# Server = http://uk.mirror.archlinuxarm.org/$arch/$repo - -### United States -## California -# Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo -## Florida -# Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo -## New Jersey -# Server = http://nj.us.mirror.archlinuxarm.org/$arch/$repo +Server = https://rc-mirror.omarchy.org/$repo/os/$arch diff --git a/default/pacman/mirrorlist-stable b/default/pacman/mirrorlist-stable index e9d9dad324d..1c2dc11ca20 100644 --- a/default/pacman/mirrorlist-stable +++ b/default/pacman/mirrorlist-stable @@ -1,57 +1 @@ -# -# Arch Linux ARM repository mirrorlist -# Generated on 2023-02-06 -# - -## Geo-IP based mirror selection and load balancing -Server = http://mirror.archlinuxarm.org/$arch/$repo - -### Mirrors by country - -### Denmark -## Aalborg -# Server = http://dk.mirror.archlinuxarm.org/$arch/$repo - -### Germany -## Aachen -# Server = http://de3.mirror.archlinuxarm.org/$arch/$repo -## Berlin -# Server = http://de.mirror.archlinuxarm.org/$arch/$repo -## Coburg -# Server = http://de4.mirror.archlinuxarm.org/$arch/$repo -## Falkenstein -# Server = http://eu.mirror.archlinuxarm.org/$arch/$repo -# Server = http://de5.mirror.archlinuxarm.org/$arch/$repo - -### Greece -## Athens -# Server = http://gr.mirror.archlinuxarm.org/$arch/$repo - -### Hungary -## Budapest -# Server = http://hu.mirror.archlinuxarm.org/$arch/$repo - -### Japan -## Tokyo -# Server = http://jp.mirror.archlinuxarm.org/$arch/$repo - -### Singapore -# Server = http://sg.mirror.archlinuxarm.org/$arch/$repo - -### Taiwan -## Hsinchu -# Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo -## New Taipei City -# Server = http://tw.mirror.archlinuxarm.org/$arch/$repo - -### United Kingdom -## London -# Server = http://uk.mirror.archlinuxarm.org/$arch/$repo - -### United States -## California -# Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo -## Florida -# Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo -## New Jersey -# Server = http://nj.us.mirror.archlinuxarm.org/$arch/$repo +Server = https://stable-mirror.omarchy.org/$repo/os/$arch diff --git a/default/pacman/pacman-edge.conf b/default/pacman/pacman-edge.conf index b869880c19b..a968d26d468 100644 --- a/default/pacman/pacman-edge.conf +++ b/default/pacman/pacman-edge.conf @@ -5,7 +5,7 @@ Color ILoveCandy VerbosePkgLists HoldPkg = pacman glibc -Architecture = aarch64 +Architecture = auto CheckSpace ParallelDownloads = 5 DownloadUser = alpm @@ -16,30 +16,29 @@ SigLevel = Required DatabaseOptional LocalFileSigLevel = Optional # pacman searches repositories in the order defined here -# Mac-specific packages remain in the community ARM repository. -# Without it herdr drags in a zig0.15 build that aarch64 cannot even use, -# costing about two hours of a fresh install before it fails. -# Only explicitly selected Hyprland packages use official edge. -[omarchy] -Usage = Sync -SigLevel = Required DatabaseOptional -Server = https://pkgs.omarchy.org/edge/$arch - -[omarchy-aarch64] -SigLevel = Optional TrustAll -Server = https://github.com/omarchy-mac/omarchy-pkgs-aarch64/releases/download/edge - -[asahi-alarm] -Include = /etc/pacman.d/mirrorlist.asahi-alarm - [core] Include = /etc/pacman.d/mirrorlist [extra] Include = /etc/pacman.d/mirrorlist -[alarm] +[multilib] Include = /etc/pacman.d/mirrorlist -[aur] -Include = /etc/pacman.d/mirrorlist +[omarchy] +Server = https://pkgs.omarchy.org/edge/$arch + +# Repositories for debug symbol packages. +# +# These upstream debug packages will only match core/extra/multilib packages from the Omarchy edge +# channel. Also note that you may not need to enable these repositories for many debugging tools -- +# debuginfod will work fine if you're on Omarchy edge. +# +# [core-debug] +# Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch +# +# [extra-debug] +# Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch +# +# [multilib-debug] +# Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch diff --git a/default/pacman/pacman-rc.conf b/default/pacman/pacman-rc.conf index b869880c19b..66ad3fb4518 100644 --- a/default/pacman/pacman-rc.conf +++ b/default/pacman/pacman-rc.conf @@ -5,7 +5,7 @@ Color ILoveCandy VerbosePkgLists HoldPkg = pacman glibc -Architecture = aarch64 +Architecture = auto CheckSpace ParallelDownloads = 5 DownloadUser = alpm @@ -16,30 +16,14 @@ SigLevel = Required DatabaseOptional LocalFileSigLevel = Optional # pacman searches repositories in the order defined here -# Mac-specific packages remain in the community ARM repository. -# Without it herdr drags in a zig0.15 build that aarch64 cannot even use, -# costing about two hours of a fresh install before it fails. -# Only explicitly selected Hyprland packages use official edge. -[omarchy] -Usage = Sync -SigLevel = Required DatabaseOptional -Server = https://pkgs.omarchy.org/edge/$arch - -[omarchy-aarch64] -SigLevel = Optional TrustAll -Server = https://github.com/omarchy-mac/omarchy-pkgs-aarch64/releases/download/edge - -[asahi-alarm] -Include = /etc/pacman.d/mirrorlist.asahi-alarm - [core] Include = /etc/pacman.d/mirrorlist [extra] Include = /etc/pacman.d/mirrorlist -[alarm] +[multilib] Include = /etc/pacman.d/mirrorlist -[aur] -Include = /etc/pacman.d/mirrorlist +[omarchy] +Server = https://pkgs.omarchy.org/rc/$arch diff --git a/default/pacman/pacman-stable.conf b/default/pacman/pacman-stable.conf index 87aa84081b4..7e4b55381c5 100644 --- a/default/pacman/pacman-stable.conf +++ b/default/pacman/pacman-stable.conf @@ -1,106 +1,29 @@ - - -# /etc/pacman.conf -# # See the pacman.conf(5) manpage for option and repository directives -# -# GENERAL OPTIONS -# [options] -# The following paths are commented out with their default values listed. -# If you wish to use different paths, uncomment and update the paths. -#RootDir = / -#DBPath = /var/lib/pacman/ -#CacheDir = /var/cache/pacman/pkg/ -#LogFile = /var/log/pacman.log -#GPGDir = /etc/pacman.d/gnupg/ -#HookDir = /etc/pacman.d/hooks/ -HoldPkg = pacman glibc -#XferCommand = /usr/bin/curl -L -C - -f -o %o %u -#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u -#CleanMethod = KeepInstalled -Architecture = aarch64 - -# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup -#IgnorePkg = -#IgnoreGroup = - -#NoUpgrade = -#NoExtract = - -# Misc options -#UseSyslog -#Color -#NoProgressBar +Color +ILoveCandy +VerbosePkgLists +HoldPkg = pacman glibc +Architecture = auto CheckSpace -#VerbosePkgLists ParallelDownloads = 5 DownloadUser = alpm # By default, pacman accepts packages signed by keys that its local keyring # trusts (see pacman-key and its man page), as well as unsigned packages. -SigLevel = Required DatabaseOptional -LocalFileSigLevel = Optional -#RemoteFileSigLevel = Required - -# NOTE: You must run `pacman-key --init` before first using pacman; the local -# keyring can then be populated with the keys of all official Arch Linux ARM -# packagers with `pacman-key --populate archlinuxarm`. - -# -# REPOSITORIES -# - can be defined here or included from another file -# - pacman will search repositories in the order defined here -# - local/custom mirrors can be added here or in separate files -# - repositories listed first will take precedence when packages -# have identical names, regardless of version number -# - URLs will have $repo replaced by the name of the current repo -# - URLs will have $arch replaced by the name of the architecture -# -# Repository entries are of the format: -# [repo-name] -# Server = ServerName -# Include = IncludePath -# -# The header [repo-name] is crucial - it must be present and -# uncommented to enable the repo. -# - -# The testing repositories are disabled by default. To enable, uncomment the -# repo name header and Include lines. You can add preferred servers immediately -# after the header, and they will be used before the default mirrors. - -# Mac-specific packages remain in the community ARM repository. -# Without it herdr drags in a zig0.15 build that aarch64 cannot even use, -# costing about two hours of a fresh install before it fails. -# Only explicitly selected Hyprland packages use official edge. -[omarchy] -Usage = Sync SigLevel = Required DatabaseOptional -Server = https://pkgs.omarchy.org/edge/$arch - -[omarchy-aarch64] -SigLevel = Optional TrustAll -Server = https://github.com/omarchy-mac/omarchy-pkgs-aarch64/releases/download/edge - -[asahi-alarm] -Include = /etc/pacman.d/mirrorlist.asahi-alarm +LocalFileSigLevel = Optional +# pacman searches repositories in the order defined here [core] Include = /etc/pacman.d/mirrorlist [extra] Include = /etc/pacman.d/mirrorlist -[alarm] -Include = /etc/pacman.d/mirrorlist - -[aur] +[multilib] Include = /etc/pacman.d/mirrorlist -# An example of a custom package repository. See the pacman manpage for -# tips on creating your own repositories. -#[custom] -#SigLevel = Optional TrustAll -#Server = file:///home/custompkgs +[omarchy] +Server = https://pkgs.omarchy.org/stable/$arch diff --git a/docs/file-layout.md b/docs/file-layout.md index 2a9d965bf89..edf06ccd23a 100644 --- a/docs/file-layout.md +++ b/docs/file-layout.md @@ -5,6 +5,10 @@ system. ## Mental model +Architecture is detected by `omarchy-hw-arch` (prints `aarch64` or `x86_64`; returns nonzero with no stdout for unsupported or failed detection), `omarchy-hw-aarch64` (boolean), and `omarchy-hw-apple-silicon` (aarch64 plus Apple in the device tree). Those three commands are the only place install and runtime code may read `uname -m` or `/proc/device-tree/compatible`. `omarchy-mac-setup` is the exception: it can run from `curl | bash` before the repo exists. + +x86 uses the files at `default/pacman/` (upstream Omarchy). aarch64 uses `default/pacman/aarch64/`. `omarchy-refresh-pacman` selects the tree. `install.sh` runs `install/aarch64/install.sh` on aarch64 and points x86 users at the Omarchy ISO. + Two Arch packages are built from this one repo (PKGBUILDs live in the separate `omarchy-pkgs` repository, under `pkgbuilds/`): diff --git a/fix-mirrors.sh b/fix-mirrors.sh index 997f4c68faf..94fd7bdecf7 100755 --- a/fix-mirrors.sh +++ b/fix-mirrors.sh @@ -7,16 +7,16 @@ set -euo pipefail -ARCH="$(uname -m)" -if [[ $ARCH != "aarch64" ]]; then - echo "[ERROR] Asahi Alarm requires aarch64 (detected: $ARCH)" >&2 +_fix_mirrors_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +if ! "$_fix_mirrors_root/bin/omarchy-hw-aarch64"; then + echo "[ERROR] Asahi Alarm requires aarch64 (detected: $("$_fix_mirrors_root/bin/omarchy-hw-arch"))" >&2 exit 1 fi OMARCHY_PATH="${OMARCHY_PATH:-$HOME/.local/share/omarchy}" -PACMAN_CONF_SRC="$OMARCHY_PATH/default/pacman/pacman.conf" -ASAHI_MIRRORLIST_SRC="$OMARCHY_PATH/default/pacman/mirrorlist.asahi-alarm" -SRC="$OMARCHY_PATH/default/pacman/mirrorlist" +PACMAN_CONF_SRC="$OMARCHY_PATH/default/pacman/aarch64/pacman.conf" +ASAHI_MIRRORLIST_SRC="$OMARCHY_PATH/default/pacman/aarch64/mirrorlist.asahi-alarm" +SRC="$OMARCHY_PATH/default/pacman/aarch64/mirrorlist" DEST="/etc/pacman.d/mirrorlist" ASAHI_MIRRORLIST_DEST="/etc/pacman.d/mirrorlist.asahi-alarm" PACMAN_ARCH="aarch64" diff --git a/install.sh b/install.sh index 8cb6d95538b..07f4e875e10 100755 --- a/install.sh +++ b/install.sh @@ -1,314 +1,17 @@ #!/bin/bash -# Fresh Omarchy 4 install for Apple Silicon. -# -# Upstream installs Omarchy 4 from the ISO, which has no aarch64 build and -# cannot boot an Apple Silicon Mac anyway. Both Omarchy packages are arch=any, -# so this builds them from this checkout and installs them as the ISO would. +# Architecture dispatcher. aarch64 has no Omarchy ISO, so it runs the Apple +# Silicon installer. x86 installs from https://omarchy.org/. set -euo pipefail readonly checkout="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -readonly package_output="$checkout/build-output" -readonly asahi_alarm_key="12CE6799A94A3F1B5DDFFE88F576553597FB8FEB" -source "$checkout/install/helpers/arm-package-sources.sh" +export PATH="$checkout/bin:${PATH:-}" -# gum is how the rest of Omarchy talks to people, but it arrives with the -# omarchy package well into this script, so every helper falls back to plain -# output until ensure_gum has run. -log() { - if command -v gum >/dev/null 2>&1; then - gum style --bold --foreground 2 "==> $*" - else - printf '\033[32m==>\033[0m %s\n' "$*" - fi -} +if "$checkout/bin/omarchy-hw-aarch64"; then + exec bash "$checkout/install/aarch64/install.sh" "$@" +fi -warn() { - if command -v gum >/dev/null 2>&1; then - gum style --bold --foreground 3 "Warning: $*" >&2 - else - printf '\033[33mWarning:\033[0m %s\n' "$*" >&2 - fi -} - -fail() { - if command -v gum >/dev/null 2>&1; then - gum style --bold --foreground 1 "Error: $*" >&2 - else - printf '\033[31mError:\033[0m %s\n' "$*" >&2 - fi - exit 1 -} - -# Asahi Alarm ships LANG=C, and nothing else in the install path replaces it. -ensure_utf8_locale() { - source "$checkout/install/preflight/locale.sh" -} - -ensure_gum() { - command -v gum >/dev/null 2>&1 && return 0 - - # Installed up front rather than waiting for the omarchy package, so the - # whole install looks like Omarchy instead of only its last third. - sudo pacman -S --needed --noconfirm gum >/dev/null 2>&1 || - warn "Could not install gum; falling back to plain output." -} - -check_preconditions() { - (( EUID != 0 )) || fail "Run this as your regular user, not as root. It uses sudo where needed." - [[ $(uname -m) == "aarch64" ]] || fail "This is the Apple Silicon installer. On x86 machines install from the ISO." - command -v pacman >/dev/null || fail "This installer only supports Arch-based systems." - command -v sudo >/dev/null || fail "sudo is required." - grep -qi apple /proc/device-tree/compatible 2>/dev/null || - warn "This does not look like Apple hardware; continuing anyway." -} - -ensure_aur_helper() { - command -v yay >/dev/null && return 0 - - log "Installing yay (needed for the AUR packages in the default set)" - sudo pacman -S --needed --noconfirm git base-devel - local workspace - workspace="$(mktemp -d)" - git clone https://aur.archlinux.org/yay.git "$workspace/yay" - (cd "$workspace/yay" && makepkg -si --noconfirm --needed) - rm -rf "$workspace" -} - -ensure_package_sources() { - # A fresh machine has no omarchy-pkgs checkout, and build-packages.sh needs - # the PKGBUILDs. Respect an existing one so a developer can build offline. - if [[ -n ${OMARCHY_PKGS_PATH:-} && -d ${OMARCHY_PKGS_PATH:-} ]]; then - return 0 - fi - - local cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/omarchy-build" - local pkgs_checkout="$cache_dir/omarchy-pkgs" - - if [[ -d $pkgs_checkout/.git ]]; then - log "Updating the PKGBUILD checkout" - git -C "$pkgs_checkout" pull --ff-only || warn "Could not update $pkgs_checkout; using it as is." - else - log "Cloning the PKGBUILD checkout" - mkdir -p "$cache_dir" - git clone --depth 1 https://github.com/omacom/omarchy-pkgs.git "$pkgs_checkout" - fi - - export OMARCHY_PKGS_PATH="$pkgs_checkout" -} - -build_omarchy_packages() { - log "Building the Omarchy packages from this checkout" - OMARCHY_PACKAGE_OUTPUT="$package_output" "$checkout/build-packages.sh" -} - -install_omarchy_packages() { - log "Installing the Omarchy packages" - - local artifact - local -a built=() - for artifact in "$package_output"/*.pkg.tar.*; do - [[ -f $artifact && $artifact != *.sig ]] || continue - built+=("$artifact") - done - (( ${#built[@]} )) || fail "No packages were built in $package_output." - sudo pacman -U --needed --noconfirm "${built[@]}" - - # env-bootstrap is the single source of truth for OMARCHY_PATH and PATH, and - # this shell started before the package existed. - source /usr/share/omarchy/default/bash/env-bootstrap -} - -# The Asahi Alarm image normally ships this keyring already. A generic -# aarch64 base does not, and pacman refuses to create the asahi-alarm database -# until its master key is trusted. Install the keyring before the first refresh -# so later AUR and ARM-repo package operations do not fail with a misleading -# "database does not exist" error. -ensure_asahi_alarm_keyring() { - grep -q '^\[asahi-alarm\]' /etc/pacman.conf || return 0 - pacman -Q asahi-alarm-keyring >/dev/null 2>&1 && return 0 - - if ! sudo pacman-key --list-keys "$asahi_alarm_key" >/dev/null 2>&1; then - log "Importing the Asahi Alarm package signing key" - sudo pacman-key --recv-keys "$asahi_alarm_key" --keyserver hkps://keyserver.ubuntu.com - fi - sudo pacman-key --lsign-key "$asahi_alarm_key" >/dev/null - - log "Installing the Asahi Alarm package keyring" - sudo pacman -Sy --needed --noconfirm asahi-alarm-keyring -} - -# Compared in bash rather than with grep against a process substitution, which -# ugrep answers differently from GNU grep. -# The shipped pacman.conf only lands during post-install, after the package set -# is already installed, so the repo has to be added now: otherwise herdr builds -# zig0.15 from source for two hours and aarch64 rejects it anyway. -ensure_arm_package_repo() { - if ! grep -q '^\[omarchy-aarch64\]' /etc/pacman.conf; then - local block - block=$(sed -n '/^\[omarchy-aarch64\]/,/^Server[[:space:]]*=/p' \ - "$checkout/default/pacman/pacman-stable.conf") - [[ -n $block ]] || fail "default/pacman/pacman-stable.conf has no [omarchy-aarch64] section." - - log "Adding the Omarchy ARM package repo" - printf '\n%s\n' "$block" | sudo tee -a /etc/pacman.conf >/dev/null - fi - - ensure_asahi_alarm_keyring - omarchy_arm_prepare_package_sources - local -a targets - mapfile -t targets < <(omarchy_arm_package_targets) - log "Upgrading system packages and installing the compatible Hyprland stack" - sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Syu --needed --noconfirm "${targets[@]}" -} - -load_unavailable_packages() { - local unavailable="$checkout/install/omarchy-aarch64-unavailable.packages" line - - unavailable_packages=() - [[ -f $unavailable ]] || return 0 - - while read -r line; do - [[ -n $line ]] && unavailable_packages+=("$line") - done < <(grep -vE '^[[:space:]]*(#|$)' "$unavailable") -} - -confirm() { - local question="$1" - - if command -v gum >/dev/null 2>&1; then - # --default=false to match the [y/N] fallback below: gum selects Yes - # otherwise, so Enter accepts -- and what this asks about is whether to - # spend three hours building packages that were measured to fail. - gum confirm --default=false "$question" /dev/null || fail "Compatible package missing after system upgrade: $package" - continue - fi - # These compile a dependency chain for hours before failing an architecture - # check, so do not start them unless asked to. - if (( ! attempt_unavailable )) && package_is_unavailable_here "$package"; then - unbuildable+=("$package") - continue - fi - yay -S --needed --noconfirm "$package" " - fi - - # Apple GPUs cannot run gpu-screen-recorder; recording falls back to this. - yay -S --needed --noconfirm wf-recorder /dev/null - fi - sudo umount "$top" - sudo rmdir "$top" -} - -main() { - check_preconditions - ensure_utf8_locale - ensure_arm_package_repo - ensure_gum - ensure_aur_helper - ensure_package_sources - build_omarchy_packages - install_omarchy_packages - install_default_package_set - seed_user_defaults - run_system_setup - snapshot_factory_baseline - - log "Install complete. Reboot to start Omarchy." -} - -main "$@" +echo "On x86_64, install Omarchy from the ISO: https://omarchy.org/" >&2 +echo "aarch64 uses install/aarch64/install.sh." >&2 +exit 1 diff --git a/install/aarch64/install.sh b/install/aarch64/install.sh new file mode 100755 index 00000000000..a085adbabbe --- /dev/null +++ b/install/aarch64/install.sh @@ -0,0 +1,315 @@ +#!/bin/bash + +# Fresh Omarchy 4 install for Apple Silicon. +# +# Upstream installs Omarchy 4 from the ISO, which has no aarch64 build and +# cannot boot an Apple Silicon Mac anyway. Both Omarchy packages are arch=any, +# so this builds them from this checkout and installs them as the ISO would. + +set -euo pipefail + +# This file lives at install/aarch64/install.sh; checkout is the repo root. +readonly checkout="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)" +readonly package_output="$checkout/build-output" +readonly asahi_alarm_key="12CE6799A94A3F1B5DDFFE88F576553597FB8FEB" +source "$checkout/install/helpers/arm-package-sources.sh" + +# gum is how the rest of Omarchy talks to people, but it arrives with the +# omarchy package well into this script, so every helper falls back to plain +# output until ensure_gum has run. +log() { + if command -v gum >/dev/null 2>&1; then + gum style --bold --foreground 2 "==> $*" + else + printf '\033[32m==>\033[0m %s\n' "$*" + fi +} + +warn() { + if command -v gum >/dev/null 2>&1; then + gum style --bold --foreground 3 "Warning: $*" >&2 + else + printf '\033[33mWarning:\033[0m %s\n' "$*" >&2 + fi +} + +fail() { + if command -v gum >/dev/null 2>&1; then + gum style --bold --foreground 1 "Error: $*" >&2 + else + printf '\033[31mError:\033[0m %s\n' "$*" >&2 + fi + exit 1 +} + +# Asahi Alarm ships LANG=C, and nothing else in the install path replaces it. +ensure_utf8_locale() { + source "$checkout/install/preflight/locale.sh" +} + +ensure_gum() { + command -v gum >/dev/null 2>&1 && return 0 + + # Installed up front rather than waiting for the omarchy package, so the + # whole install looks like Omarchy instead of only its last third. + sudo pacman -S --needed --noconfirm gum >/dev/null 2>&1 || + warn "Could not install gum; falling back to plain output." +} + +check_preconditions() { + (( EUID != 0 )) || fail "Run this as your regular user, not as root. It uses sudo where needed." + "$checkout/bin/omarchy-hw-aarch64" || fail "This is the Apple Silicon installer. On x86 machines install from the ISO." + command -v pacman >/dev/null || fail "This installer only supports Arch-based systems." + command -v sudo >/dev/null || fail "sudo is required." + "$checkout/bin/omarchy-hw-apple-silicon" || + warn "This does not look like Apple hardware; continuing anyway." +} + +ensure_aur_helper() { + command -v yay >/dev/null && return 0 + + log "Installing yay (needed for the AUR packages in the default set)" + sudo pacman -S --needed --noconfirm git base-devel + local workspace + workspace="$(mktemp -d)" + git clone https://aur.archlinux.org/yay.git "$workspace/yay" + (cd "$workspace/yay" && makepkg -si --noconfirm --needed) + rm -rf "$workspace" +} + +ensure_package_sources() { + # A fresh machine has no omarchy-pkgs checkout, and build-packages.sh needs + # the PKGBUILDs. Respect an existing one so a developer can build offline. + if [[ -n ${OMARCHY_PKGS_PATH:-} && -d ${OMARCHY_PKGS_PATH:-} ]]; then + return 0 + fi + + local cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/omarchy-build" + local pkgs_checkout="$cache_dir/omarchy-pkgs" + + if [[ -d $pkgs_checkout/.git ]]; then + log "Updating the PKGBUILD checkout" + git -C "$pkgs_checkout" pull --ff-only || warn "Could not update $pkgs_checkout; using it as is." + else + log "Cloning the PKGBUILD checkout" + mkdir -p "$cache_dir" + git clone --depth 1 https://github.com/omacom/omarchy-pkgs.git "$pkgs_checkout" + fi + + export OMARCHY_PKGS_PATH="$pkgs_checkout" +} + +build_omarchy_packages() { + log "Building the Omarchy packages from this checkout" + OMARCHY_PACKAGE_OUTPUT="$package_output" "$checkout/build-packages.sh" +} + +install_omarchy_packages() { + log "Installing the Omarchy packages" + + local artifact + local -a built=() + for artifact in "$package_output"/*.pkg.tar.*; do + [[ -f $artifact && $artifact != *.sig ]] || continue + built+=("$artifact") + done + (( ${#built[@]} )) || fail "No packages were built in $package_output." + sudo pacman -U --needed --noconfirm "${built[@]}" + + # env-bootstrap is the single source of truth for OMARCHY_PATH and PATH, and + # this shell started before the package existed. + source /usr/share/omarchy/default/bash/env-bootstrap +} + +# The Asahi Alarm image normally ships this keyring already. A generic +# aarch64 base does not, and pacman refuses to create the asahi-alarm database +# until its master key is trusted. Install the keyring before the first refresh +# so later AUR and ARM-repo package operations do not fail with a misleading +# "database does not exist" error. +ensure_asahi_alarm_keyring() { + grep -q '^\[asahi-alarm\]' /etc/pacman.conf || return 0 + pacman -Q asahi-alarm-keyring >/dev/null 2>&1 && return 0 + + if ! sudo pacman-key --list-keys "$asahi_alarm_key" >/dev/null 2>&1; then + log "Importing the Asahi Alarm package signing key" + sudo pacman-key --recv-keys "$asahi_alarm_key" --keyserver hkps://keyserver.ubuntu.com + fi + sudo pacman-key --lsign-key "$asahi_alarm_key" >/dev/null + + log "Installing the Asahi Alarm package keyring" + sudo pacman -Sy --needed --noconfirm asahi-alarm-keyring +} + +# Compared in bash rather than with grep against a process substitution, which +# ugrep answers differently from GNU grep. +# The shipped pacman.conf only lands during post-install, after the package set +# is already installed, so the repo has to be added now: otherwise herdr builds +# zig0.15 from source for two hours and aarch64 rejects it anyway. +ensure_arm_package_repo() { + if ! grep -q '^\[omarchy-aarch64\]' /etc/pacman.conf; then + local block + block=$(sed -n '/^\[omarchy-aarch64\]/,/^Server[[:space:]]*=/p' \ + "$checkout/default/pacman/aarch64/pacman-stable.conf") + [[ -n $block ]] || fail "default/pacman/aarch64/pacman-stable.conf has no [omarchy-aarch64] section." + + log "Adding the Omarchy ARM package repo" + printf '\n%s\n' "$block" | sudo tee -a /etc/pacman.conf >/dev/null + fi + + ensure_asahi_alarm_keyring + omarchy_arm_prepare_package_sources + local -a targets + mapfile -t targets < <(omarchy_arm_package_targets) + log "Upgrading system packages and installing the compatible Hyprland stack" + sudo env OMARCHY_UPDATE_PACMAN=1 pacman -Syu --needed --noconfirm "${targets[@]}" +} + +load_unavailable_packages() { + local unavailable="$checkout/install/omarchy-aarch64-unavailable.packages" line + + unavailable_packages=() + [[ -f $unavailable ]] || return 0 + + while read -r line; do + [[ -n $line ]] && unavailable_packages+=("$line") + done < <(grep -vE '^[[:space:]]*(#|$)' "$unavailable") +} + +confirm() { + local question="$1" + + if command -v gum >/dev/null 2>&1; then + # --default=false to match the [y/N] fallback below: gum selects Yes + # otherwise, so Enter accepts -- and what this asks about is whether to + # spend three hours building packages that were measured to fail. + gum confirm --default=false "$question" /dev/null || fail "Compatible package missing after system upgrade: $package" + continue + fi + # These compile a dependency chain for hours before failing an architecture + # check, so do not start them unless asked to. + if (( ! attempt_unavailable )) && package_is_unavailable_here "$package"; then + unbuildable+=("$package") + continue + fi + yay -S --needed --noconfirm "$package" " + fi + + # Apple GPUs cannot run gpu-screen-recorder; recording falls back to this. + yay -S --needed --noconfirm wf-recorder /dev/null + fi + sudo umount "$top" + sudo rmdir "$top" +} + +main() { + check_preconditions + ensure_utf8_locale + ensure_arm_package_repo + ensure_gum + ensure_aur_helper + ensure_package_sources + build_omarchy_packages + install_omarchy_packages + install_default_package_set + seed_user_defaults + run_system_setup + snapshot_factory_baseline + + log "Install complete. Reboot to start Omarchy." +} + +main "$@" diff --git a/install/hardware/apple/audio.sh b/install/hardware/apple/audio.sh index be0d9f91bf0..90df3a01fe7 100644 --- a/install/hardware/apple/audio.sh +++ b/install/hardware/apple/audio.sh @@ -24,13 +24,12 @@ # on purpose -- these drivers can be damaged by what the hardware will happily # ask them to do. -compatible="${OMARCHY_APPLE_COMPATIBLE:-/proc/device-tree/compatible}" OMARCHY_ASAHI_AUDIO_PACKAGES_CHANGED=0 # Every device-tree machine has a compatible file, so it has to name Apple -- # otherwise a Raspberry Pi would install the Asahi stack too. -[[ $(uname -m) == "aarch64" ]] || return 0 -[[ -f $compatible ]] && grep -Faiq 'apple,' "$compatible" || return 0 +# Tests stub this via OMARCHY_UNAME_M and OMARCHY_APPLE_COMPATIBLE. +omarchy-hw-apple-silicon || return 0 # pkg-missing rather than a bare pkg-add, so the migration can tell whether this # actually installed anything and only then ask for a reboot. diff --git a/install/hardware/apple/fix-asahi-hid-race.sh b/install/hardware/apple/fix-asahi-hid-race.sh index 6e06d74a8a5..40f3103dea6 100755 --- a/install/hardware/apple/fix-asahi-hid-race.sh +++ b/install/hardware/apple/fix-asahi-hid-race.sh @@ -9,7 +9,7 @@ # session. Loading the drivers from the initramfs makes the devices bind # correctly on first registration, so the churn never happens. # See docs/apple-silicon-trackpad.md. -if [[ $(uname -m) == "aarch64" ]] && grep -qi apple /proc/device-tree/compatible 2>/dev/null; then +if omarchy-hw-apple-silicon; then echo "Detected Apple Silicon Mac: early-loading Apple HID modules" sudo mkdir -p /etc/mkinitcpio.conf.d sudo tee /etc/mkinitcpio.conf.d/apple_hid_modules.conf >/dev/null <<'EOF' diff --git a/install/hardware/apple/fix-brcmfmac-supplicant.sh b/install/hardware/apple/fix-brcmfmac-supplicant.sh index 19c572affeb..8d744ffdd96 100644 --- a/install/hardware/apple/fix-brcmfmac-supplicant.sh +++ b/install/hardware/apple/fix-brcmfmac-supplicant.sh @@ -30,7 +30,7 @@ # breakage back. sys_vendor="$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null || true)" -if [[ $(uname -m) == "x86_64" ]] && +if [[ $(omarchy-hw-arch) == "x86_64" ]] && { lspci -nn | grep "106b:180[12]" >/dev/null || { [[ $sys_vendor == Apple* ]] && lspci -nn | grep -E "14e4:(43ba|43bb|43bc|43a3|43dc|4464|4488|4425|4433)" >/dev/null; }; }; then diff --git a/install/hardware/fix-fkeys.sh b/install/hardware/fix-fkeys.sh index facf9f4fc88..b3e68e9544e 100644 --- a/install/hardware/fix-fkeys.sh +++ b/install/hardware/fix-fkeys.sh @@ -2,7 +2,20 @@ # does. The Mac media bindings depend on it: default/hypr/bindings/media.lua # binds bare XF86MonBrightness* and SHIFT+XF86MonBrightness*, so the top row has # to emit media keycodes without Fn for display and keyboard brightness to work. -if [[ ! -f /etc/modprobe.d/hid_apple.conf ]]; then - sudo mkdir -p /etc/modprobe.d - echo "options hid_apple fnmode=1" | sudo tee /etc/modprobe.d/hid_apple.conf >/dev/null +# hid_apple is the Apple keyboard driver. Writing this on a non-Apple x86 +# machine is a Mac-fork leak. Apple Silicon uses fnmode=1; x86 machines that +# actually load hid_apple keep upstream's fnmode=2. Stock Arch kernels often +# *ship* the module, so modinfo is not evidence it is in use. +hid_apple_module="${OMARCHY_HID_APPLE_MODULE_PATH:-/sys/module/hid_apple}" +hid_apple_conf="${OMARCHY_HID_APPLE_CONF_PATH:-/etc/modprobe.d/hid_apple.conf}" +fnmode="" +if omarchy-hw-apple-silicon; then + fnmode=1 +elif [[ $(omarchy-hw-arch) == "x86_64" && -d $hid_apple_module ]]; then + fnmode=2 +fi + +if [[ -n $fnmode && ! -f $hid_apple_conf ]]; then + sudo mkdir -p "$(dirname "$hid_apple_conf")" + echo "options hid_apple fnmode=$fnmode" | sudo tee "$hid_apple_conf" >/dev/null fi diff --git a/install/hardware/vulkan.sh b/install/hardware/vulkan.sh index 609b832c218..ed65f5d8ae2 100644 --- a/install/hardware/vulkan.sh +++ b/install/hardware/vulkan.sh @@ -10,7 +10,7 @@ declare -A VULKAN_DRIVERS=( PACKAGES=() -if [[ $(uname -m) == "aarch64" ]] && [[ -f /proc/device-tree/compatible ]] && grep -qi "apple" /proc/device-tree/compatible 2>/dev/null; then +if omarchy-hw-apple-silicon; then PACKAGES+=(vulkan-asahi) fi diff --git a/install/post-install/optional-apps.sh b/install/post-install/optional-apps.sh index fcf8e0e8175..7c6eae7882e 100755 --- a/install/post-install/optional-apps.sh +++ b/install/post-install/optional-apps.sh @@ -2,9 +2,9 @@ # Install optional proprietary/AUR apps (1Password, etc.) # Only run on aarch64 -if [ "$(uname -m)" != "aarch64" ]; then - echo "Skipping optional apps: not aarch64 architecture" - return 0 +if [[ $(omarchy-hw-arch) != "aarch64" ]]; then + echo "Skipping optional apps: not aarch64 architecture" + return 0 fi # This leaf runs from omarchy-apply-system, which puts the checkout's bin/ diff --git a/install/post-install/pacman.sh b/install/post-install/pacman.sh index 8becfd87008..bb73f63825f 100644 --- a/install/post-install/pacman.sh +++ b/install/post-install/pacman.sh @@ -1,22 +1,31 @@ # Configure pacman after package installation completes. Offline target package # installs use the live ISO's offline pacman.conf until this final restore. -cp -f "$OMARCHY_PATH/default/pacman/pacman-${OMARCHY_MIRROR:-stable}.conf" /etc/pacman.conf +if omarchy-hw-aarch64; then + pacman_dir="$OMARCHY_PATH/default/pacman/aarch64" +else + pacman_dir="$OMARCHY_PATH/default/pacman" +fi +mirror="${OMARCHY_MIRROR:-stable}" +cp -f "$pacman_dir/pacman-${mirror}.conf" /etc/pacman.conf + +mirrorlist_src="$pacman_dir/mirrorlist-${mirror}" +[[ -f $mirrorlist_src ]] || mirrorlist_src="$pacman_dir/mirrorlist" + # Overwriting the mirrorlist throws away the Asahi Alarm mirrors the machine # was installed with, leaving one slow generic server. Keep what is there and # append ours only where it is missing, as omarchy-refresh-pacman-mirrorlist does. -if [[ -s /etc/pacman.d/mirrorlist ]] && grep -qE '^[[:space:]]*Server[[:space:]]*=' /etc/pacman.d/mirrorlist; then - while read -r mirror; do - grep -qxF "$mirror" /etc/pacman.d/mirrorlist || printf '%s\n' "$mirror" >>/etc/pacman.d/mirrorlist - done < <(grep -E '^[[:space:]]*Server[[:space:]]*=' "$OMARCHY_PATH/default/pacman/mirrorlist-${OMARCHY_MIRROR:-stable}") +if omarchy-hw-aarch64 && [[ -s /etc/pacman.d/mirrorlist ]] && grep -qE '^[[:space:]]*Server[[:space:]]*=' /etc/pacman.d/mirrorlist; then + while read -r mirror_line; do + grep -qxF "$mirror_line" /etc/pacman.d/mirrorlist || printf '%s\n' "$mirror_line" >>/etc/pacman.d/mirrorlist + done < <(grep -E '^[[:space:]]*Server[[:space:]]*=' "$mirrorlist_src") else - cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-${OMARCHY_MIRROR:-stable}" /etc/pacman.d/mirrorlist + cp -f "$mirrorlist_src" /etc/pacman.d/mirrorlist fi -# Every pacman.conf variant here Includes the asahi-alarm mirrorlist, so ship it -# with them. Without the file pacman refuses to parse its config at all, which -# breaks every later package operation on the installed system. -if [[ -f $OMARCHY_PATH/default/pacman/mirrorlist.asahi-alarm ]]; then - cp -f "$OMARCHY_PATH/default/pacman/mirrorlist.asahi-alarm" /etc/pacman.d/mirrorlist.asahi-alarm +# aarch64 pacman.conf Includes the asahi-alarm mirrorlist, so ship it with them. +# Without the file pacman refuses to parse its config at all. +if omarchy-hw-aarch64 && [[ -f $pacman_dir/mirrorlist.asahi-alarm ]]; then + cp -f "$pacman_dir/mirrorlist.asahi-alarm" /etc/pacman.d/mirrorlist.asahi-alarm fi # Wait for CUPS to own the file, the way omarchy-settings does, so pacman does diff --git a/install/preflight/arm-mirrors.sh b/install/preflight/arm-mirrors.sh index 967ad473c00..9162ea8c5bf 100755 --- a/install/preflight/arm-mirrors.sh +++ b/install/preflight/arm-mirrors.sh @@ -3,10 +3,9 @@ # This script automatically configures ARM mirrors if on ARM architecture # Only run on ARM64 systems -ARCH="$(uname -m)" -if [[ "$ARCH" != "aarch64" ]]; then +if [[ $(omarchy-hw-arch) != "aarch64" ]]; then if [[ "${OMARCHY_DEBUG:-}" == "1" ]]; then - echo "[DEBUG] Not an ARM64 system (detected: $ARCH), skipping ARM mirror setup" + echo "[DEBUG] Not an ARM64 system (detected: $(omarchy-hw-arch)), skipping ARM mirror setup" fi exit 0 fi diff --git a/install/user/hardware/apple/obsidian.sh b/install/user/hardware/apple/obsidian.sh index a4c8131891a..a74920295fc 100644 --- a/install/user/hardware/apple/obsidian.sh +++ b/install/user/hardware/apple/obsidian.sh @@ -8,7 +8,7 @@ # carries aarch64 and extracts Obsidian's own arm64 AppImage, so ask for that # one by name. Verified on an M2 Max: obsidian-appimage-1.12.7-1-aarch64 builds # and runs. -if [[ $(uname -m) == "aarch64" ]] && omarchy-cmd-missing obsidian; then +if omarchy-hw-aarch64 && omarchy-cmd-missing obsidian; then echo "Installing Obsidian for Apple Silicon (the AppImage build)." # The Omarchy ARM repo carries a built obsidian-appimage, so try the repos diff --git a/install/user/hardware/apple/share-picker.sh b/install/user/hardware/apple/share-picker.sh index 9e3d839dcf3..90c8f1afcc4 100644 --- a/install/user/hardware/apple/share-picker.sh +++ b/install/user/hardware/apple/share-picker.sh @@ -1,7 +1,7 @@ # hyprland-preview-share-picker in omarchy-base.packages has no aarch64 build, so # xdg-desktop-portal-hyprland shows no source chooser and browser sharing silently # degrades to tab-only. The -git package builds on aarch64, and only as the user. -if [[ $(uname -m) == "aarch64" ]] && omarchy-cmd-missing hyprland-preview-share-picker; then +if omarchy-hw-aarch64 && omarchy-cmd-missing hyprland-preview-share-picker; then echo "Installing the browser screen-share picker for Apple Silicon." omarchy-pkg-aur-add hyprland-preview-share-picker-git || diff --git a/install/user/mise-work.sh b/install/user/mise-work.sh index 42faf045e61..b1bc5dab13c 100644 --- a/install/user/mise-work.sh +++ b/install/user/mise-work.sh @@ -19,7 +19,7 @@ case ${OMARCHY_SETUP_CONTEXT:-runtime} in esac # Node ships per-architecture tarballs, and Apple Silicon needs the arm64 one. -case $(uname -m) in +case $(omarchy-hw-arch) in aarch64) NODE_TARBALL_ARCH=arm64 ;; *) NODE_TARBALL_ARCH=x64 ;; esac diff --git a/shell/plugins/bar/Bar.qml b/shell/plugins/bar/Bar.qml index 8bbc3e8c1e4..ce2076e7665 100644 --- a/shell/plugins/bar/Bar.qml +++ b/shell/plugins/bar/Bar.qml @@ -335,8 +335,8 @@ Item { property bool appleSiliconHost: false Process { running: true - command: ["bash", "-c", "grep -qi apple /proc/device-tree/compatible 2>/dev/null && echo yes || echo no"] - stdout: SplitParser { onRead: function(line) { root.appleSiliconHost = String(line).trim() === "yes" } } + command: [Quickshell.env("OMARCHY_PATH") + "/bin/omarchy-hw-apple-silicon"] + onExited: function(exitCode) { root.appleSiliconHost = exitCode === 0 } } function normalizePosition(value) { diff --git a/test/run-mirrorlist-sim.sh b/test/run-mirrorlist-sim.sh index b1c735780a5..df094be21d8 100755 --- a/test/run-mirrorlist-sim.sh +++ b/test/run-mirrorlist-sim.sh @@ -12,7 +12,7 @@ SRC="$WORKDIR/src_mirrorlist" DEST="$WORKDIR/dest_mirrorlist" # Use the repository's bundled default mirrorlist as the SRC -cp "$ROOT/default/pacman/mirrorlist" "$SRC" +cp "$ROOT/default/pacman/aarch64/mirrorlist" "$SRC" # Create sample existing system mirrorlist cat >"$DEST" <<'EOF' diff --git a/test/shell.d/aarch64-compat-test.sh b/test/shell.d/aarch64-compat-test.sh index d2f3e7f764b..af6c1919b64 100644 --- a/test/shell.d/aarch64-compat-test.sh +++ b/test/shell.d/aarch64-compat-test.sh @@ -8,18 +8,39 @@ source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" # assert the repo's aarch64 surface without needing Asahi hardware. The dynamic # checks at the bottom simulate aarch64 with stubbed commands. -# Every pacman.conf the repo ships must pin Architecture = aarch64. A config -# that omits it inherits the machine's uname, which is right on a Mac today but -# silently wrong the moment upstream x86 defaults are synced back in. +# x86 configs at default/pacman/ must stay byte-compatible with upstream: +# Architecture = auto and the x86 [omarchy] repo. Pinning aarch64 here would +# break every x86 install the moment this tree is merged. for config in "$ROOT"/default/pacman/pacman*.conf; do - grep -qF 'Architecture = aarch64' "$config" || - fail "every shipped pacman config pins aarch64" "missing in: $(basename "$config")" + grep -qF 'Architecture = auto' "$config" || + fail "x86 pacman configs keep Architecture = auto" "missing in: $(basename "$config")" + grep -qF '[omarchy]' "$config" || + fail "x86 pacman configs offer the upstream [omarchy] repo" "missing in: $(basename "$config")" + grep -qF 'pkgs.omarchy.org' "$config" || + fail "x86 pacman configs point at pkgs.omarchy.org" "missing in: $(basename "$config")" + grep -qF 'Architecture = aarch64' "$config" && + fail "x86 pacman configs must not pin aarch64" "pinned in: $(basename "$config")" + grep -qF '[omarchy-aarch64]' "$config" && + fail "x86 pacman configs must not offer the ARM repo" "in: $(basename "$config")" done -pass "every shipped pacman config pins aarch64" - -# Official edge serves ARM packages, but only the selected compatibility stack -# may use it. Keep architecture, channel, and signature constraints explicit. -for config in "$ROOT"/default/pacman/pacman*.conf; do +pass "x86 pacman configs match upstream" + +grep -qF 'Server = https://pkgs.omarchy.org/stable/$arch' "$ROOT/default/pacman/pacman-stable.conf" || + fail "x86 stable pacman config points at the stable Omarchy repo" +grep -qF 'Server = https://pkgs.omarchy.org/rc/$arch' "$ROOT/default/pacman/pacman-rc.conf" || + fail "x86 rc pacman config points at the rc Omarchy repo, not edge" +grep -qF 'Server = https://pkgs.omarchy.org/edge/$arch' "$ROOT/default/pacman/pacman-edge.conf" || + fail "x86 edge pacman config points at the edge Omarchy repo" +pass "x86 pacman channel configs keep their upstream repo URLs" + +# aarch64 configs live under default/pacman/aarch64/ so they cannot leak into +# an x86 refresh. They pin aarch64, offer the community ARM repository, and +# restrict official edge to explicitly selected compatibility packages. +for config in "$ROOT"/default/pacman/aarch64/pacman*.conf; do + grep -qF 'Architecture = aarch64' "$config" || + fail "every aarch64 pacman config pins aarch64" "missing in: $(basename "$config")" + grep -qF '[omarchy-aarch64]' "$config" || + fail "every aarch64 pacman config offers the Omarchy ARM repo" "missing in: $(basename "$config")" section=$(awk '/^\[/ { selected = ($0 == "[omarchy]") } selected { print }' "$config") grep -qxF 'Usage = Sync' <<< "$section" || fail "official edge requires explicit targets in $config" grep -qxF 'SigLevel = Required DatabaseOptional' <<< "$section" || fail "official edge requires signed packages in $config" @@ -28,32 +49,29 @@ for config in "$ROOT"/default/pacman/pacman*.conf; do fail "no x86 or alternate-channel official repository in $config" fi done -pass "official edge is architecture-aware, signed, and explicit-target-only" +pass "aarch64 pacman configs pin ARM and restrict official edge" # The regular distribution mirrorlists must remain Arch Linux ARM sources; # official edge belongs only in its restricted, separate repository section. leaky=() while read -r file; do [[ -n $file ]] || continue - leaky+=("$(basename "$file")") -done < <(grep -l 'omarchy\.org' "$ROOT"/default/pacman/mirrorlist* 2>/dev/null || true) + leaky+=("${file#"$ROOT"/}") +done < <(grep -l 'omarchy\.org' "$ROOT"/default/pacman/aarch64/mirrorlist* 2>/dev/null || true) (( ${#leaky[@]} == 0 )) || - fail "no shipped mirrorlist points at an x86 Omarchy mirror" "still x86: ${leaky[*]}" -pass "no shipped mirrorlist points at an x86 Omarchy mirror" - -# Every aarch64 pacman config anywhere in the repo — not just default/pacman/ — -# has to offer [omarchy-aarch64], or herdr falls back to a multi-hour zig build -# that aarch64 rejects (install.sh:116). -missing_arm=() -for config in "$ROOT"/config/*.conf "$ROOT"/default/pacman/*.conf; do - [[ -f $config ]] || continue - grep -qF 'Architecture = aarch64' "$config" || continue - grep -qF '[omarchy-aarch64]' "$config" || missing_arm+=("${config#"$ROOT"/}") -done -(( ${#missing_arm[@]} == 0 )) || - fail "every aarch64 pacman config offers the Omarchy ARM repo" \ - "missing [omarchy-aarch64]: ${missing_arm[*]}" -pass "every aarch64 pacman config offers the Omarchy ARM repo" + fail "no aarch64 mirrorlist points at an x86 Omarchy mirror" "still x86: ${leaky[*]}" +pass "no aarch64 mirrorlist points at an x86 Omarchy mirror" + +# refresh-pacman selects the tree from omarchy-hw-aarch64 rather than shipping +# a single aarch64-only pacman.conf. +grep -qF 'omarchy-hw-aarch64' "$ROOT/bin/omarchy-refresh-pacman" || + fail "omarchy-refresh-pacman selects the pacman tree by architecture" +pass "omarchy-refresh-pacman selects the pacman tree by architecture" + +grep -qF 'pkgs.omarchy.org/$candidate/' "$ROOT/bin/omarchy-refresh-pacman-mirrorlist" && + grep -qF 'mirrorlist-$channel' "$ROOT/bin/omarchy-refresh-pacman-mirrorlist" || + fail "the x86 mirrorlist refresh follows the installed package channel" +pass "the x86 mirrorlist refresh follows the installed package channel" # Paths must derive from OMARCHY_PATH (AGENTS.md); a hardcoded HOME breaks once # the checkout is wired to /usr/share/omarchy. @@ -66,11 +84,15 @@ pass "the mirrorlist refresh derives its source from OMARCHY_PATH" # must refuse to run on Apple Silicon (the inverse of the guard in # omarchy-upgrade-to-quattro-mac). It is not safe to execute here — it writes # /etc through sudo — so assert the guard statically instead. -grep -qF 'uname -m' "$ROOT/bin/omarchy-upgrade-to-quattro" && - grep -qF 'aarch64' "$ROOT/bin/omarchy-upgrade-to-quattro" || +grep -qF '[[ $(omarchy-hw-arch) == "x86_64" ]]' "$ROOT/bin/omarchy-upgrade-to-quattro" || fail "the upstream x86 upgrade fences itself off on Apple Silicon" pass "the upstream x86 upgrade fences itself off on Apple Silicon" +negated_arch_calls=$(rg -n '! omarchy-hw-aarch64' "$ROOT/bin" "$ROOT/install" || true) +[[ -z $negated_arch_calls ]] || + fail "architecture gates never turn a missing detector into x86 success" "$negated_arch_calls" +pass "all architecture gates fail closed when detection is unavailable" + # --- Simulated aarch64 environment ------------------------------------------ # The Mac fork's safety net: omarchy-pkg-add must skip a package the Arch ARM @@ -125,6 +147,10 @@ write_stub sudo '#!/bin/bash "$@" ' +write_stub omarchy-hw-aarch64 '#!/bin/bash +exit 0 +' + ARM_ONLY_PKG="ripgrep" \ PKG_TEST_STATE="$test_tmp/installed" \ PKG_TEST_LOG="$test_tmp/install.log" \ @@ -138,3 +164,28 @@ grep -qF 'ripgrep' "$test_tmp/install.log" || ! grep -qF 'lib32-nvidia-utils' "$test_tmp/install.log" || fail "the package helper never passes an unavailable package to pacman" "$(cat "$test_tmp/install.log")" pass "the package helper skips x86-only packages instead of failing the install" + +# On x86 the filter is off: a missing package is passed to pacman and the +# helper fails, matching upstream omarchy-pkg-add. +write_stub omarchy-hw-aarch64 '#!/bin/bash +exit 1 +' +rm -f "$test_tmp/installed" "$test_tmp/install.log" "$test_tmp/skip.log" +set +e +ARM_ONLY_PKG="ripgrep" \ + PKG_TEST_STATE="$test_tmp/installed" \ + PKG_TEST_LOG="$test_tmp/install.log" \ + PATH="$stub_bin:$PATH" \ + "$ROOT/bin/omarchy-pkg-add" ripgrep lib32-nvidia-utils >/dev/null 2>"$test_tmp/skip.log" +x86_status=$? +set -e +(( x86_status != 0 )) || fail "x86 pkg-add fails when a package is missing" +! grep -qF "Skipping 'lib32-nvidia-utils'" "$test_tmp/skip.log" || + fail "x86 pkg-add does not skip missing packages" "$(cat "$test_tmp/skip.log")" +grep -qF 'lib32-nvidia-utils' "$test_tmp/install.log" || + fail "x86 pkg-add passes the missing package to pacman" "$(cat "$test_tmp/install.log")" +pass "x86 pkg-add fails on missing packages, matching upstream" + +grep -qF 'EUID == 0' "$ROOT/bin/omarchy-pkg-add" || + fail "omarchy-pkg-add keeps the upstream root path that calls pacman without sudo" +pass "omarchy-pkg-add keeps the upstream EUID pacman path" diff --git a/test/shell.d/aarch64-packages-test.sh b/test/shell.d/aarch64-packages-test.sh index f3168dc9991..93e4374f941 100755 --- a/test/shell.d/aarch64-packages-test.sh +++ b/test/shell.d/aarch64-packages-test.sh @@ -22,15 +22,15 @@ for package in "${unavailable_packages[@]}"; do done pass "every unavailable entry is in the default package set" -grep -qF 'package_is_unavailable_here' "$ROOT/install.sh" || +grep -qF 'package_is_unavailable_here' "$ROOT/install/aarch64/install.sh" || fail "the installer filters the default set through the unavailable list" pass "the installer filters the default set through the unavailable list" # The list is a default, not a verdict: AUR packages gain ARM support over time, # so a stale entry has to cost a prompt rather than be permanently wrong. -grep -qF 'OMARCHY_TRY_UNAVAILABLE' "$ROOT/install.sh" || +grep -qF 'OMARCHY_TRY_UNAVAILABLE' "$ROOT/install/aarch64/install.sh" || fail "the unavailable list can be overridden" -grep -qF '[[ -r /dev/tty ]] || return 1' "$ROOT/install.sh" || +grep -qF '[[ -r /dev/tty ]] || return 1' "$ROOT/install/aarch64/install.sh" || fail "the installer skips without a terminal instead of blocking on a prompt" pass "the unavailable list is a prompt-able default, and never blocks a headless install" @@ -46,19 +46,19 @@ pass "packages the ARM repo provides are installed, not skipped" # Without a repo carrying them, herdr pulls zig0.15 and builds it for hours # before aarch64 rejects it. -for config in "$ROOT"/default/pacman/pacman*.conf; do +for config in "$ROOT"/default/pacman/aarch64/pacman*.conf; do grep -qF '[omarchy-aarch64]' "$config" || - fail "every shipped pacman config offers the Omarchy ARM repo" "missing in: $(basename "$config")" + fail "every aarch64 pacman config offers the Omarchy ARM repo" "missing in: $(basename "$config")" # A Server line needs no mirrorlist installed alongside it, unlike an Include. grep -A3 -F '[omarchy-aarch64]' "$config" | grep -qE '^Server[[:space:]]*=' || fail "the ARM repo is reached by Server, not an Include" "in: $(basename "$config")" done -pass "every shipped pacman config offers the Omarchy ARM repo" +pass "every aarch64 pacman config offers the Omarchy ARM repo" # The shipped config only reaches /etc during post-install, which runs after the # package set. Adding the repo any later leaves herdr building zig from source # for two hours, so the order in main() is the whole point of the fix. -install_main=$(sed -n '/^main() {/,/^}/p' "$ROOT/install.sh") +install_main=$(sed -n '/^main() {/,/^}/p' "$ROOT/install/aarch64/install.sh") repo_call=$(grep -n '^ ensure_arm_package_repo$' <<<"$install_main" | cut -d: -f1) set_call=$(grep -n '^ install_default_package_set$' <<<"$install_main" | cut -d: -f1) [[ -n $repo_call && -n $set_call ]] || fail "the installer adds the ARM repo and installs the set" diff --git a/test/shell.d/apple-hid-race-test.sh b/test/shell.d/apple-hid-race-test.sh index c95e7780351..1c6015f6725 100755 --- a/test/shell.d/apple-hid-race-test.sh +++ b/test/shell.d/apple-hid-race-test.sh @@ -87,7 +87,8 @@ run_leaf() { : >"$calls" printf '%s' "$model" >"$compatible" - ARCH="$arch" TEST_LOG="$calls" PATH="$stub_bin:$PATH" \ + OMARCHY_UNAME_M="$arch" OMARCHY_APPLE_COMPATIBLE="$compatible" \ + ARCH="$arch" TEST_LOG="$calls" PATH="$stub_bin:$ROOT/bin:$PATH" \ bash -eE -o pipefail -c 'source "$1"' bash "$sandboxed_leaf" "$calls" printf '%s' "$model" >"$compatible" - ARCH="$arch" TEST_LOG="$calls" PATH="$stub_bin:$PATH" \ + OMARCHY_UNAME_M="$arch" OMARCHY_APPLE_COMPATIBLE="$compatible" \ + ARCH="$arch" TEST_LOG="$calls" PATH="$stub_bin:$ROOT/bin:$PATH" \ MKINITCPIO_STATUS="$mkinitcpio_status" \ OMARCHY_PATH="$test_tmp/omarchy" OMARCHY_APPLE_HID_CONF="$conf" \ bash -euo pipefail "$migration" diff --git a/test/shell.d/arm-package-sources-test.sh b/test/shell.d/arm-package-sources-test.sh index 0c80fe5eca0..0282707fdb0 100644 --- a/test/shell.d/arm-package-sources-test.sh +++ b/test/shell.d/arm-package-sources-test.sh @@ -28,7 +28,7 @@ cmp -s "$test_tmp/expected" "$test_tmp/pacman.conf" || fail 'preparation idempot pass 'source preparation preserves regular repositories and restricts edge idempotently' cp "$test_tmp/pacman.conf.bak" "$test_tmp/original-backup" -cp "$ROOT/default/pacman/pacman-stable.conf" "$test_tmp/pacman.conf" +cp "$ROOT/default/pacman/aarch64/pacman-stable.conf" "$test_tmp/pacman.conf" omarchy_arm_prepare_package_sources "$test_tmp/pacman.conf" preserve-backup cmp -s "$test_tmp/original-backup" "$test_tmp/pacman.conf.bak" || fail 'channel refresh original backup preserved' pass 'preparation after channel replacement preserves the original backup' @@ -39,7 +39,7 @@ pass 'Aquamarine remains a regular-repository dependency' # Exercise the real default-package loop after the compatibility transaction. # The three selected packages must never reach yay as unqualified targets. -eval "$(sed -n '/^install_default_package_set() {/,/^seed_user_defaults() {/p' "$ROOT/install.sh" | sed '$d')" +eval "$(sed -n '/^install_default_package_set() {/,/^seed_user_defaults() {/p' "$ROOT/install/aarch64/install.sh" | sed '$d')" checkout=$ROOT log() { :; } warn() { :; } @@ -58,7 +58,7 @@ done grep -q 'wf-recorder' "$test_tmp/yay" || fail 'regular package path still runs' pass 'default package loop preserves the compatibility transaction selection' -for config in "$ROOT"/default/pacman/pacman*.conf; do +for config in "$ROOT"/default/pacman/aarch64/pacman*.conf; do section=$(sed -n '/^\[omarchy\]$/,/^$/p' "$config") [[ $section == *"Usage = Sync"* && $section == *"SigLevel = Required DatabaseOptional"* ]] || fail "restricted signed edge in $config" done diff --git a/test/shell.d/asahi-audio-install-test.sh b/test/shell.d/asahi-audio-install-test.sh index 9e732ab3482..61a57be74ed 100644 --- a/test/shell.d/asahi-audio-install-test.sh +++ b/test/shell.d/asahi-audio-install-test.sh @@ -81,8 +81,9 @@ run_audio_setup() { local script="$1" arch="$2" machine="$3" install_succeeds="${4:-1}" printf '%s\0' "$machine" >"$compatible" - PATH="$stub_bin:$PATH" \ + PATH="$stub_bin:$ROOT/bin:$PATH" \ TEST_ARCH="$arch" \ + OMARCHY_UNAME_M="$arch" \ TEST_LOG="$calls" \ AUDIO_INSTALLED_MARKER="$installed_marker" \ PACKAGE_INSTALL_SUCCEEDS="$install_succeeds" \ diff --git a/test/shell.d/bar-notch-test.sh b/test/shell.d/bar-notch-test.sh index d19a34c65ec..69238f5fc67 100755 --- a/test/shell.d/bar-notch-test.sh +++ b/test/shell.d/bar-notch-test.sh @@ -39,6 +39,11 @@ assert( /notchFloor: root\.appleSiliconHost && root\.position === "top"/.test(barSource), 'bar floors only top bars on Apple Silicon machines' ) +assert( + /command: \[Quickshell\.env\("OMARCHY_PATH"\) \+ "\/bin\/omarchy-hw-apple-silicon"\]/.test(barSource) && + /onExited: function\(exitCode\) \{ root\.appleSiliconHost = exitCode === 0 \}/.test(barSource), + 'bar detects Apple Silicon directly through OMARCHY_PATH' +) assert( /BarModel\.notchHeight\(screen\.name, screen\.width, screen\.height, screen\.devicePixelRatio\)/.test(barSource), 'bar derives the floor from its own screen geometry' diff --git a/test/shell.d/brcmfmac-supplicant-test.sh b/test/shell.d/brcmfmac-supplicant-test.sh index 3bd5eaea622..cf4b47598d6 100755 --- a/test/shell.d/brcmfmac-supplicant-test.sh +++ b/test/shell.d/brcmfmac-supplicant-test.sh @@ -91,7 +91,7 @@ run_leaf() { -e "s|/etc/modprobe.d|$test_tmp/etc/modprobe.d|g" \ "$leaf" >"$script" - WIFI_ID="$wifi_id" T2_HARDWARE="$t2" ARCH="$arch" PATH="$stub_bin:$PATH" \ + WIFI_ID="$wifi_id" T2_HARDWARE="$t2" ARCH="$arch" PATH="$stub_bin:$ROOT/bin:$PATH" \ bash -eE -o pipefail -c 'source "$1"' bash "$script" /dev/null +[[ ! -f $conf ]] || fail "unknown architecture must not receive the Intel Wi-Fi quirk" +pass "unknown architecture is left alone even with matching Intel hardware IDs" + +# Simulate the command-not-found status without allowing the host's installed +# detector to leak into the test through PATH. +omarchy-hw-arch() { return 127; } +export -f omarchy-hw-arch +run_leaf "Apple Inc." 4433 1 aarch64 >/dev/null +unset -f omarchy-hw-arch +[[ ! -f $conf ]] || fail "missing architecture detector must not receive the Intel Wi-Fi quirk" +pass "missing architecture detection leaves Apple Silicon Wi-Fi alone" + # Older Macs report the vendor differently. run_leaf "Apple Computer, Inc." 43ba 0 >/dev/null [[ -f $conf ]] || fail "the older Apple vendor string is recognized" @@ -148,7 +161,7 @@ run_migration() { printf '%s' "$vendor" >"$test_tmp/dmi/sys_vendor" : >"$calls" - WIFI_ID="$wifi_id" T2_HARDWARE="$t2" ARCH="$arch" PATH="$stub_bin:$PATH" TEST_LOG="$calls" \ + WIFI_ID="$wifi_id" T2_HARDWARE="$t2" ARCH="$arch" PATH="$stub_bin:$ROOT/bin:$PATH" TEST_LOG="$calls" \ OMARCHY_BRCMFMAC_DMI_VENDOR="$test_tmp/dmi/sys_vendor" \ OMARCHY_BRCMFMAC_CONF="$conf" \ bash -euo pipefail "$migration" >/dev/null diff --git a/test/shell.d/fix-fkeys-test.sh b/test/shell.d/fix-fkeys-test.sh new file mode 100755 index 00000000000..334f51556c2 --- /dev/null +++ b/test/shell.d/fix-fkeys-test.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +leaf="$ROOT/install/hardware/fix-fkeys.sh" + +grep -qF 'omarchy-hw-apple-silicon' "$leaf" || + fail "fnmode setup keys off Apple Silicon, not a generic uname" +grep -qF 'modinfo hid_apple' "$leaf" && + fail "fnmode setup must not treat a shipped hid_apple module as Apple hardware" || true +grep -qF '/sys/module/hid_apple' "$leaf" || + fail "fnmode setup treats a loaded hid_apple module as T2/in-use evidence" +pass "fnmode setup does not leak onto generic x86 via modinfo" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +stub_bin="$test_tmp/bin" +conf="$test_tmp/hid_apple.conf" +module="$test_tmp/module" +mkdir -p "$stub_bin" + +cat >"$stub_bin/sudo" <<'SH' +#!/bin/bash +"$@" +SH +chmod +x "$stub_bin/sudo" + +run_leaf() { + local arch="$1" apple_dt="$2" loaded="$3" + rm -f "$conf" + rm -rf "$module" + (( loaded == 1 )) && mkdir -p "$module" + printf '%s\n' "$apple_dt" >"$test_tmp/compatible" + + PATH="$stub_bin:$ROOT/bin:$PATH" \ + OMARCHY_UNAME_M="$arch" \ + OMARCHY_APPLE_COMPATIBLE="$test_tmp/compatible" \ + OMARCHY_HID_APPLE_MODULE_PATH="$module" \ + OMARCHY_HID_APPLE_CONF_PATH="$conf" \ + bash -euo pipefail -c 'source "$1"' bash "$leaf" +} + +run_leaf x86_64 'apple,j413' 0 +[[ ! -f $conf ]] || fail "x86 without a loaded hid_apple module is left alone" "$(cat "$conf")" +pass "x86 without a loaded hid_apple module is left alone" + +run_leaf x86_64 'not-apple' 1 +[[ -f $conf ]] || fail "x86 with hid_apple loaded gets fnmode=2" +grep -qF 'fnmode=2' "$conf" || fail "x86 fnmode write is fnmode=2" "$(cat "$conf")" +pass "x86 with hid_apple loaded gets upstream fnmode=2" + +run_leaf aarch64 'apple,j413' 0 +[[ -f $conf ]] || fail "Apple Silicon gets fnmode=1 even before hid_apple loads" +grep -qx 'options hid_apple fnmode=1' "$conf" || fail "Apple Silicon fnmode write is fnmode=1" "$(cat "$conf")" +pass "Apple Silicon gets fnmode=1 even before hid_apple loads" + +run_leaf aarch64 'raspberrypi,4-model-b' 0 +[[ ! -f $conf ]] || fail "non-Apple aarch64 is left alone" "$(cat "$conf")" +pass "non-Apple aarch64 is left alone" + +run_leaf aarch64 'raspberrypi,4-model-b' 1 +[[ ! -f $conf ]] || fail "non-Apple aarch64 with hid_apple loaded is left alone" "$(cat "$conf")" +pass "non-Apple aarch64 does not take the x86 fnmode setting" + +run_leaf riscv64 'not-apple' 1 +[[ ! -f $conf ]] || fail "unknown architecture with hid_apple loaded is left alone" "$(cat "$conf")" +pass "unknown architecture does not take the x86 fnmode setting" + +omarchy-hw-arch() { return 127; } +export -f omarchy-hw-arch +run_leaf x86_64 'not-apple' 1 +unset -f omarchy-hw-arch +[[ ! -f $conf ]] || fail "missing architecture detector must not set x86 fnmode" +pass "missing architecture detection leaves loaded hid_apple alone" diff --git a/test/shell.d/hw-arch-test.sh b/test/shell.d/hw-arch-test.sh new file mode 100755 index 00000000000..3facf148d7a --- /dev/null +++ b/test/shell.d/hw-arch-test.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +tmp_dir=$(mktemp -d) +trap 'rm -rf "$tmp_dir"' EXIT + +hw() { + local name="$1" + shift + PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-hw-$name" "$@" +} + +# x86_64: architecture printer and both booleans. +arch=$(OMARCHY_UNAME_M=x86_64 hw arch) +[[ $arch == "x86_64" ]] || fail "x86_64 prints x86_64" "actual: $arch" +pass "x86_64 prints x86_64" + +OMARCHY_UNAME_M=x86_64 hw aarch64 && fail "x86_64 is not aarch64" || true +pass "x86_64 is not aarch64" + +# A fake apple device-tree on x86 must not count as Apple Silicon. +printf 'apple,j413\n' >"$tmp_dir/compatible" +OMARCHY_UNAME_M=x86_64 OMARCHY_APPLE_COMPATIBLE="$tmp_dir/compatible" hw apple-silicon && + fail "x86_64 with an apple DT is not Apple Silicon" || true +pass "x86_64 with an apple DT is not Apple Silicon" + +# aarch64 without apple DT: ARM path, not Apple hardware. +arch=$(OMARCHY_UNAME_M=aarch64 hw arch) +[[ $arch == "aarch64" ]] || fail "aarch64 prints aarch64" "actual: $arch" +pass "aarch64 prints aarch64" + +OMARCHY_UNAME_M=aarch64 hw aarch64 || fail "aarch64 detects aarch64" +pass "aarch64 detects aarch64" + +OMARCHY_UNAME_M=aarch64 OMARCHY_APPLE_COMPATIBLE="$tmp_dir/missing" hw apple-silicon && + fail "aarch64 without apple DT is not Apple Silicon" || true +pass "aarch64 without apple DT is not Apple Silicon" + +# arm64 is an alias of aarch64. +arch=$(OMARCHY_UNAME_M=arm64 hw arch) +[[ $arch == "aarch64" ]] || fail "arm64 canonicalizes to aarch64" "actual: $arch" +pass "arm64 canonicalizes to aarch64" + +OMARCHY_UNAME_M=arm64 hw aarch64 || fail "arm64 detects as aarch64" +pass "arm64 detects as aarch64" + +for unsupported in riscv64 armv7l unknown; do + if arch=$(OMARCHY_UNAME_M="$unsupported" hw arch); then + fail "unsupported architectures must fail detection" "$unsupported returned: $arch" + fi + [[ -z $arch ]] || fail "unsupported architectures print no canonical name" "$arch" +done +pass "unsupported architectures cannot be mistaken for x86_64" + +# A failed uname must fail even if it wrote a recognized architecture first. +uname() { printf '%s\n' x86_64; return 1; } +export -f uname +if arch=$(OMARCHY_UNAME_M= hw arch); then + fail "failed uname must fail architecture detection" "$arch" +fi +unset -f uname +[[ -z $arch ]] || fail "failed detection prints no canonical name" "$arch" +pass "failed uname cannot be mistaken for x86_64" + +# aarch64 + apple DT: Apple Silicon. +OMARCHY_UNAME_M=aarch64 OMARCHY_APPLE_COMPATIBLE="$tmp_dir/compatible" hw apple-silicon || + fail "aarch64 with apple DT is Apple Silicon" +pass "aarch64 with apple DT is Apple Silicon" + +# Laptop detection: Apple Silicon counts even without ACPI lid or DMI chassis. +OMARCHY_UNAME_M=x86_64 \ + OMARCHY_DMI_CHASSIS_TYPE_PATH="$tmp_dir/missing" \ + OMARCHY_APPLE_COMPATIBLE="$tmp_dir/compatible" \ + hw laptop && fail "x86_64 without lid or chassis is not a laptop" || true +pass "x86_64 without lid or chassis is not a laptop" + +OMARCHY_UNAME_M=aarch64 \ + OMARCHY_DMI_CHASSIS_TYPE_PATH="$tmp_dir/missing" \ + OMARCHY_APPLE_COMPATIBLE="$tmp_dir/compatible" \ + hw laptop || fail "Apple Silicon is a laptop without ACPI lid or DMI" +pass "Apple Silicon is a laptop without ACPI lid or DMI" diff --git a/test/shell.d/hw-laptop-test.sh b/test/shell.d/hw-laptop-test.sh index c6e62118ba4..e088ecffe47 100644 --- a/test/shell.d/hw-laptop-test.sh +++ b/test/shell.d/hw-laptop-test.sh @@ -21,7 +21,8 @@ chmod +x "$stub_bin/busctl" run_laptop() { OMARCHY_DMI_CHASSIS_TYPE_PATH="$dmi_chassis" \ OMARCHY_ACPI_LID_PATH="$acpi_lid" \ - PATH="$stub_bin:$PATH" \ + OMARCHY_UNAME_M="${OMARCHY_UNAME_M:-x86_64}" \ + PATH="$stub_bin:$ROOT/bin:$PATH" \ "$ROOT/bin/omarchy-hw-laptop" } @@ -44,6 +45,15 @@ if run_laptop; then fi pass "a desktop DMI chassis is not classified as a laptop" +rm -f "$dmi_chassis" +printf 'apple,j413\n' >"$test_tmp/compatible" +OMARCHY_UNAME_M=aarch64 OMARCHY_APPLE_COMPATIBLE="$test_tmp/compatible" \ + OMARCHY_DMI_CHASSIS_TYPE_PATH="$dmi_chassis" \ + PATH="$stub_bin:$ROOT/bin:$PATH" \ + "$ROOT/bin/omarchy-hw-laptop" || + fail "Apple Silicon with no DMI chassis is a laptop" +pass "Apple Silicon with no DMI chassis is a laptop" + printf 'closed\n' >"$acpi_lid/macbook/state" run_lid_closed not-a-property || fail "the ACPI fallback recognizes a closed lid" diff --git a/test/shell.d/install-mac-test.sh b/test/shell.d/install-mac-test.sh index 1067348521e..a921f60cf47 100755 --- a/test/shell.d/install-mac-test.sh +++ b/test/shell.d/install-mac-test.sh @@ -4,13 +4,39 @@ set -euo pipefail source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" -install_script="$ROOT/install.sh" +install_script="$ROOT/install/aarch64/install.sh" build_script="$ROOT/build-packages.sh" +grep -qF 'install/aarch64/install.sh' "$ROOT/install.sh" || + fail "root install.sh dispatches aarch64 to the Apple Silicon installer" +pass "root install.sh dispatches aarch64 to the Apple Silicon installer" + +x86_install=$(OMARCHY_UNAME_M=x86_64 bash "$ROOT/install.sh" 2>&1) && + fail "x86 install.sh must not succeed without the ISO pipeline" || true +[[ $x86_install == *omarchy.org* ]] || + fail "x86 install.sh points at the Omarchy ISO" "$x86_install" +pass "x86 install.sh points at the Omarchy ISO" + [[ -x $install_script ]] || fail "the Apple Silicon installer ships and is executable" [[ -x $build_script ]] || fail "the Apple Silicon package build script ships and is executable" pass "the Apple Silicon install scripts ship and are executable" +# After the move from repo-root install.sh, checkout must be the repo root +# (two levels above install/aarch64/), not install/aarch64 itself. +grep -qF '/../..' "$install_script" || + fail "the Apple Silicon installer walks up to the repo root for checkout" +script_dir=$(cd -- "$(dirname -- "$install_script")" && pwd) +checkout=$(cd -- "$script_dir/../.." && pwd) +[[ $checkout == "$ROOT" ]] || + fail "install/aarch64/install.sh is two levels below the repo root" "resolved: $checkout" +[[ -x $checkout/bin/omarchy-hw-arch ]] || + fail "checkout contains bin/omarchy-hw-arch" +[[ -x $checkout/build-packages.sh ]] || + fail "checkout contains build-packages.sh" +[[ -f $checkout/default/pacman/aarch64/pacman-stable.conf ]] || + fail "checkout contains default/pacman/aarch64/pacman-stable.conf" +pass "the Apple Silicon installer resolves checkout to the repo root" + # Quattro renamed the setup entry points once already, and set -e turns a call # to a command that no longer ships into a half-finished install. while read -r command_name; do diff --git a/test/shell.d/locale-setup-test.sh b/test/shell.d/locale-setup-test.sh index 95679b01c3d..9e970b622f0 100755 --- a/test/shell.d/locale-setup-test.sh +++ b/test/shell.d/locale-setup-test.sh @@ -12,10 +12,10 @@ migration=$(/usr/bin/grep -rl 'Give the machine a UTF-8 locale' "$ROOT/migration # Asahi Alarm ships LANG=C, so the installer has to set the locale itself -- # there is no ISO step here to do it. -/usr/bin/grep -q '^ ensure_utf8_locale$' "$ROOT/install.sh" || +/usr/bin/grep -q '^ ensure_utf8_locale$' "$ROOT/install/aarch64/install.sh" || fail "the installer sets a UTF-8 locale" -locale_call=$(/usr/bin/grep -n '^ ensure_utf8_locale$' "$ROOT/install.sh" | cut -d: -f1) -packages_call=$(/usr/bin/grep -n '^ install_default_package_set$' "$ROOT/install.sh" | cut -d: -f1) +locale_call=$(/usr/bin/grep -n '^ ensure_utf8_locale$' "$ROOT/install/aarch64/install.sh" | cut -d: -f1) +packages_call=$(/usr/bin/grep -n '^ install_default_package_set$' "$ROOT/install/aarch64/install.sh" | cut -d: -f1) (( locale_call < packages_call )) || fail "the locale is set before the install starts printing package output" pass "the installer sets a UTF-8 locale before the package pass" diff --git a/test/shell.d/pacman-includes-test.sh b/test/shell.d/pacman-includes-test.sh index 3c8fe54d5c7..90d85cc1a70 100755 --- a/test/shell.d/pacman-includes-test.sh +++ b/test/shell.d/pacman-includes-test.sh @@ -13,7 +13,7 @@ missing=() while read -r included; do base=${included##*/} grep -qF "$base" "$post_install" || missing+=("$included") -done < <(grep -h '^Include = /etc/pacman.d/' "$ROOT"/default/pacman/pacman*.conf | +done < <(grep -h '^Include = /etc/pacman.d/' "$ROOT"/default/pacman/pacman*.conf "$ROOT"/default/pacman/aarch64/pacman*.conf | awk '{ print $3 }' | sort -u) if (( ${#missing[@]} )); then @@ -23,12 +23,13 @@ fi pass "pacman config restore installs every mirrorlist it includes" # The source has to ship too, or the copy above silently does nothing. +# x86 lists live in default/pacman/; ARM lists live in default/pacman/aarch64/. while read -r included; do base=${included##*/} [[ $base == "mirrorlist" ]] && continue - [[ -f "$ROOT/default/pacman/$base" ]] || + [[ -f "$ROOT/default/pacman/$base" || -f "$ROOT/default/pacman/aarch64/$base" ]] || fail "the included mirrorlist ships in the repo" "missing: default/pacman/$base" -done < <(grep -h '^Include = /etc/pacman.d/' "$ROOT"/default/pacman/pacman*.conf | +done < <(grep -h '^Include = /etc/pacman.d/' "$ROOT"/default/pacman/pacman*.conf "$ROOT"/default/pacman/aarch64/pacman*.conf | awk '{ print $3 }' | sort -u) pass "every included mirrorlist ships in the repo" @@ -38,6 +39,6 @@ pass "every included mirrorlist ships in the repo" if grep -qE '^cp -f .*mirrorlist-\$\{OMARCHY_MIRROR' "$post_install"; then fail "pacman config restore does not overwrite the installed mirrorlist" fi -grep -qF 'grep -qxF "$mirror" /etc/pacman.d/mirrorlist' "$post_install" || +grep -qF 'grep -qxF "$mirror_line" /etc/pacman.d/mirrorlist' "$post_install" || fail "pacman config restore appends only mirrors that are missing" pass "pacman config restore keeps the mirrors the machine was installed with" diff --git a/test/shell.d/preinstalls-test.sh b/test/shell.d/preinstalls-test.sh index 7799e97d7b9..66498b35685 100755 --- a/test/shell.d/preinstalls-test.sh +++ b/test/shell.d/preinstalls-test.sh @@ -41,7 +41,7 @@ SH chmod +x "$mock_bin"/* -export PATH="$mock_bin:$PATH" +export PATH="$mock_bin:$ROOT/bin:$PATH" export HOME="$test_home" export OMARCHY_TEST_PKG_LOG="$pkg_log" diff --git a/test/shell.d/update-file-conflict-test.sh b/test/shell.d/update-file-conflict-test.sh index 9046dfe481a..30ea8fe5084 100755 --- a/test/shell.d/update-file-conflict-test.sh +++ b/test/shell.d/update-file-conflict-test.sh @@ -12,9 +12,9 @@ mkdir -p "$stub_bin" # Exercise the ARM update targets on every host, while keeping repository and # keyring preparation out of these conflict-recovery tests. -cat >"$stub_bin/uname" <<'STUB' +cat >"$stub_bin/omarchy-hw-aarch64" <<'STUB' #!/bin/bash -printf '%s\n' aarch64 +exit 0 STUB mkdir -p "$test_tmp/omarchy/install/helpers" @@ -56,7 +56,7 @@ fi echo "upgrade complete" STUB -chmod +x "$stub_bin/sudo" "$stub_bin/pacman" "$stub_bin/uname" +chmod +x "$stub_bin/sudo" "$stub_bin/pacman" "$stub_bin/omarchy-hw-aarch64" replaced="$test_tmp/replaced" diff --git a/test/shell.d/update-package-conflict-test.sh b/test/shell.d/update-package-conflict-test.sh index aeaaef03c41..16882c10e0c 100755 --- a/test/shell.d/update-package-conflict-test.sh +++ b/test/shell.d/update-package-conflict-test.sh @@ -14,9 +14,9 @@ mkdir -p "$stub_bin" # Exercise the ARM update targets on every host, while keeping repository and # keyring preparation out of these conflict-recovery tests. -cat >"$stub_bin/uname" <<'STUB' +cat >"$stub_bin/omarchy-hw-aarch64" <<'STUB' #!/bin/bash -printf '%s\n' aarch64 +exit 0 STUB mkdir -p "$test_tmp/omarchy/install/helpers" @@ -52,7 +52,7 @@ fi echo "upgrade complete" STUB -chmod +x "$stub_bin/sudo" "$stub_bin/pacman" "$stub_bin/uname" +chmod +x "$stub_bin/sudo" "$stub_bin/pacman" "$stub_bin/omarchy-hw-aarch64" # Everything a blocked qemu-common upgrade leaves on stderr, and no more. The # ":: ... Remove qemu-block-gluster? [y/N]" pacman asked is deliberately absent: diff --git a/tests/test-asahi-compatibility.sh b/tests/test-asahi-compatibility.sh index bc575ec7d67..a46a215f3c7 100644 --- a/tests/test-asahi-compatibility.sh +++ b/tests/test-asahi-compatibility.sh @@ -53,12 +53,12 @@ echo "=== Mirror defaults ===" bash -n "$ROOT/fix-mirrors.sh" || fail "fix-mirrors.sh does not parse" pass "fix-mirrors.sh is present and parses" -grep -q "mirror.archlinuxarm.org" "$ROOT/default/pacman/mirrorlist" || - fail "the default mirrorlist has no Arch Linux ARM mirror" -pass "the default mirrorlist points at Arch Linux ARM" +grep -q "mirror.archlinuxarm.org" "$ROOT/default/pacman/aarch64/mirrorlist" || + fail "the aarch64 mirrorlist has no Arch Linux ARM mirror" +pass "the aarch64 mirrorlist points at Arch Linux ARM" grep -q 'github.com/asahi-alarm/asahi-alarm/releases/download/\$arch' \ - "$ROOT/default/pacman/mirrorlist.asahi-alarm" || + "$ROOT/default/pacman/aarch64/mirrorlist.asahi-alarm" || fail "the Asahi Alarm mirrorlist has no \$arch release URL" pass "the Asahi Alarm mirrorlist keeps its \$arch release URL" @@ -74,13 +74,13 @@ grep -qE 'aarch64|arm64' "$arm_mirrors" || fail "arm-mirrors.sh does not mention aarch64" pass "the installer's ARM mirror step targets aarch64" -conf="$ROOT/default/pacman/pacman.conf" -[[ -f $conf ]] || fail "default/pacman/pacman.conf is missing" +conf="$ROOT/default/pacman/aarch64/pacman.conf" +[[ -f $conf ]] || fail "default/pacman/aarch64/pacman.conf is missing" grep -q "^Architecture = aarch64" "$conf" || - fail "pacman.conf does not set Architecture = aarch64" + fail "aarch64 pacman.conf does not set Architecture = aarch64" grep -q "^\[asahi-alarm\]" "$conf" || - fail "pacman.conf does not offer the asahi-alarm repo" -pass "the shipped pacman.conf targets Asahi Alarm on aarch64" + fail "aarch64 pacman.conf does not offer the asahi-alarm repo" +pass "the shipped aarch64 pacman.conf targets Asahi Alarm" echo echo "=== All Asahi compatibility checks passed ===" diff --git a/tests/test-pkg-publish.sh b/tests/test-pkg-publish.sh index fe9341b9ad7..599d77a80d1 100644 --- a/tests/test-pkg-publish.sh +++ b/tests/test-pkg-publish.sh @@ -6,7 +6,7 @@ set -uo pipefail TOOL="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)/bin/omarchy-pkg-publish-aarch64" -CONF="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)/default/pacman/pacman-stable.conf" +CONF="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)/default/pacman/aarch64/pacman-stable.conf" WORK=$(mktemp -d) trap 'rm -rf "$WORK"' EXIT pass=0