#!/usr/bin/env bash set -e # Nomarchy Installer # Professionalized with Gum # Function to display stylized headers header() { clear gum style \ --foreground 212 --border-foreground 212 --border double \ --align center --width 50 --margin "1 2" --padding "2 4" \ "NOMARCHY" "The Omarchy-flavored NixOS" } # Function to show a section header section() { echo gum style --foreground 10 --bold "» $1" } header section "Environment Check" gum spin --spinner dot --title "Verifying internet connection..." -- sleep 1 while ! ping -c 1 8.8.8.8 &> /dev/null; do gum style --foreground 9 "Error: No internet connection detected." CHOICE=$(gum choose "Open Network Manager (nmtui)" "Retry Connection" "Exit Installer") if [ "$CHOICE" = "Open Network Manager (nmtui)" ]; then nmtui elif [ "$CHOICE" = "Exit Installer" ]; then echo "Exiting installer." exit 1 fi done echo "✓ Internet connection verified." # 0. Environment Setup NOMARCHY_REPO="" if [ -d "/etc/nomarchy" ]; then NOMARCHY_REPO="/etc/nomarchy" elif [ -d "$(dirname "$0")/.." ] && [ -f "$(dirname "$0")/../flake.nix" ]; then NOMARCHY_REPO="$(realpath "$(dirname "$0")/..")" fi if [ -z "$NOMARCHY_REPO" ]; then gum style --foreground 9 "Error: Nomarchy repository not found." exit 1 fi # 1. Hardware Detection section "Hardware Detection" PRODUCT_NAME=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "Unknown") CPU_VENDOR=$(lscpu | grep "Vendor ID" | awk '{print $3}') echo "Detected Device: $PRODUCT_NAME" echo "Detected CPU: $CPU_VENDOR" HARDWARE_MODULES="" NOMARCHY_HW_OPTS="" if [[ "$CPU_VENDOR" == "AuthenticAMD" ]]; then HARDWARE_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-amd" elif [[ "$CPU_VENDOR" == "GenuineIntel" ]]; then HARDWARE_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-intel" fi echo "Select your hardware vendor for optimized profiles:" VENDOR=$(gum choose --header "Hardware Vendor" \ "acer" "apple" "asus" "dell" "framework" "google" "hp" "lenovo" "microsoft" "msi" "purism" "samsung" "starlabs" "system76" "toshiba" "None/Generic") if [ "$VENDOR" != "None/Generic" ]; then case $VENDOR in dell) MODEL=$(gum choose "xps-13-9300" "xps-13-9310" "xps-13-9343" "xps-13-9360" "xps-13-9370" "xps-13-9380" "xps-15-7590" "xps-15-9500" "xps-15-9510" "xps-15-9550" "precision-5510" "precision-5530") HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.dell-$MODEL" [[ "$MODEL" == *"xps"* ]] && NOMARCHY_HW_OPTS="nomarchy.hardware.isXPS = true;" ;; lenovo) MODEL=$(gum choose "thinkpad-x1-carbon-gen7" "thinkpad-x1-carbon-gen8" "thinkpad-x1-carbon-gen9" "thinkpad-x1-carbon-gen10" "thinkpad-x1-extreme" "thinkpad-t480" "thinkpad-t490" "thinkpad-t14-amd" "thinkpad-t14-intel" "thinkpad-p1-gen3") HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.lenovo-$MODEL" ;; framework) MODEL=$(gum choose "13-7040-amd" "13-intel-12th-gen" "13-intel-13th-gen" "16-7040-amd") HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.framework-$MODEL" NOMARCHY_HW_OPTS="nomarchy.hardware.isFramework = true;" ;; microsoft) MODEL=$(gum choose "surface-pro-7" "surface-pro-8" "surface-pro-9" "surface-laptop-3" "surface-laptop-4") HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.microsoft-$MODEL" ;; apple) MODEL=$(gum choose "macbook-pro-12-1" "macbook-air-6-2" "t2") if [ "$MODEL" == "t2" ]; then NOMARCHY_HW_OPTS="nomarchy.hardware.isT2Mac = true;" else HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.apple-$MODEL" fi ;; *) INPUT_MOD=$(gum input --placeholder "Enter nixos-hardware module path") HARDWARE_MODULES="$HARDWARE_MODULES\n $INPUT_MOD" ;; esac fi # 2. Storage Setup section "Storage & Partitioning" DRIVES=$(lsblk -d -n -p -o NAME,SIZE | grep -v loop) TARGET_DRIVE=$(echo "$DRIVES" | gum choose --header "Select target drive" | awk '{print $1}') if [ -z "$TARGET_DRIVE" ]; then exit 1; fi LAYOUT=$(gum choose "Standard Ext4" "Encrypted BTRFS (LUKS2)") IMPERMANENCE="No" if [ "$LAYOUT" = "Standard Ext4" ]; then DISKO_FILE="installer/disko-ext4.nix" else DISKO_FILE="installer/disko-btrfs-luks.nix" echo "Enable Impermanence? (Erase root on every boot)" IMPERMANENCE=$(gum choose "No" "Yes") fi # 3. User & Localization section "User & Localization" USERNAME=$(gum input --placeholder "Enter target username (no spaces)") if [ -z "$USERNAME" ]; then exit 1; fi echo "Select Timezone:" TIMEZONES=$(timedatectl list-timezones || echo "UTC") TIMEZONE=$(echo "$TIMEZONES" | gum filter --placeholder "Type to search...") [ -z "$TIMEZONE" ] && TIMEZONE="UTC" echo "Select Keyboard Layout:" KEYBOARD_LAYOUT=$(gum choose "us" "uk" "de" "fr" "es" "it" "br-abnt2" "latam" "Other...") if [ "$KEYBOARD_LAYOUT" = "Other..." ]; then KEYBOARD_LAYOUT=$(gum input --placeholder "Enter layout (e.g. jp)") fi # 4. Software Profiles section "Software Profiles" echo "Select additional profiles (Space to toggle):" PROFILES=$(gum choose --no-limit "Development (VSCode, Docker, DBs)" "Gaming (Steam, Lutris)" "Media Production (OBS, Kdenlive)") PROFILE_HOME_PKGS="" PROFILE_SYSTEM_CONFIG="" [[ $PROFILES == *"Development"* ]] && PROFILE_HOME_PKGS="$PROFILE_HOME_PKGS\n vscode\n docker-compose\n dbeaver-bin" && PROFILE_SYSTEM_CONFIG="$PROFILE_SYSTEM_CONFIG\n virtualisation.docker.enable = true;" [[ $PROFILES == *"Gaming"* ]] && PROFILE_HOME_PKGS="$PROFILE_HOME_PKGS\n lutris\n protonup-qt\n mangohud" && PROFILE_SYSTEM_CONFIG="$PROFILE_SYSTEM_CONFIG\n programs.steam.enable = true;" [[ $PROFILES == *"Media Production"* ]] && PROFILE_HOME_PKGS="$PROFILE_HOME_PKGS\n obs-studio\n kdenlive\n gimp\n audacity" [[ "$IMPERMANENCE" == "Yes" ]] && PROFILE_SYSTEM_CONFIG="$PROFILE_SYSTEM_CONFIG\n nomarchy.system.impermanence.enable = true;" # 5. Review section "Review Configuration" echo "Target Drive: $TARGET_DRIVE" echo "Layout: $LAYOUT (Impermanence: $IMPERMANENCE)" echo "User: $USERNAME" echo "Timezone: $TIMEZONE" echo "Profiles: $PROFILES" if ! gum confirm "Ready to begin installation?"; then echo "Aborted." exit 0 fi # 6. Execution section "Executing Installation" # 6.1. Partitioning gum spin --spinner pulse --title "Partitioning $TARGET_DRIVE..." -- bash -c " DISKO_NIX=\"$NOMARCHY_REPO/$DISKO_FILE\" TMP_DISKO=\$(mktemp --suffix=.nix) sed \"s|@TARGET_DRIVE@|$TARGET_DRIVE|g\" \"\$DISKO_NIX\" > \"\$TMP_DISKO\" sudo env PATH=\"\$PATH\" disko --mode disko \"\$TMP_DISKO\" " # 6.2. Scaffold Config gum spin --spinner pulse --title "Generating NixOS configuration..." -- bash -c " mkdir -p /mnt/etc/nixos/ cat < /mnt/etc/nixos/login-preference.nix { services.displayManager.autoLogin.enable = true; services.displayManager.autoLogin.user = \"$USERNAME\"; } EOF cat < /mnt/etc/nixos/localization.nix { time.timeZone = \"$TIMEZONE\"; services.xserver.xkb.layout = \"$KEYBOARD_LAYOUT\"; console.keyMap = \"$KEYBOARD_LAYOUT\"; } EOF cat < /mnt/etc/nixos/hardware-selection.nix { inputs, ... }: { imports = [ \$(echo -e \"$HARDWARE_MODULES\") ]; $NOMARCHY_HW_OPTS } EOF nixos-generate-config --root /mnt cat < /mnt/etc/nixos/system.nix { pkgs, ... }: { \$(echo -e \"$PROFILE_SYSTEM_CONFIG\") environment.systemPackages = with pkgs; []; } EOF cat < /mnt/etc/nixos/home.nix { pkgs, ... }: { home.packages = with pkgs; [ \$(echo -e \"$PROFILE_HOME_PKGS\") ]; } EOF cat < /mnt/etc/nixos/flake.nix { description = \"My Nomarchy - Downstream Configuration\"; inputs = { nixpkgs.url = \"github:nixos/nixpkgs/nixos-25.11\"; nomarchy.url = \"git+https://git.bemagri.xyz/bernardo/Nomarchy.git\"; nixos-hardware.url = \"github:NixOS/nixos-hardware/master\"; home-manager = { url = \"github:nix-community/home-manager/release-25.11\"; inputs.nixpkgs.follows = \"nixpkgs\"; }; }; outputs = { self, nixpkgs, nomarchy, home-manager, ... }@inputs: { nixosConfigurations.default = nixpkgs.lib.nixosSystem { specialArgs = { inputs = nomarchy.inputs // inputs; }; modules = [ { nixpkgs.hostPlatform = \"x86_64-linux\"; } ./hardware-configuration.nix ./hardware-selection.nix ./login-preference.nix ./localization.nix nomarchy.nixosModules.system ./system.nix home-manager.nixosModules.home-manager { home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; home-manager.users.$USERNAME = { imports = [ nomarchy.nixosModules.home ./home.nix ]; home.username = \"$USERNAME\"; home.homeDirectory = \"/home/$USERNAME\"; home.stateVersion = \"25.11\"; }; } ]; }; }; } EOF " # 6.3. Git Init cd /mnt/etc/nixos/ git init git add . git config user.name "Nomarchy Installer" git config user.email "installer@nomarchy" git commit -m "Initial Nomarchy generation" # 6.4. Impermanence logic if [[ "$IMPERMANENCE" == "Yes" ]]; then echo "Redirecting to persistent storage..." mkdir -p /mnt/persist/etc mv /mnt/etc/nixos /mnt/persist/etc/ mkdir -p /mnt/etc ln -s /persist/etc/nixos /mnt/etc/nixos fi # 6.5. Install section "Installing System" echo "Starting nixos-install. This will take some time..." sudo nixos-install --flake /mnt/etc/nixos#default --no-root-passwd # 7. Finished header gum style --foreground 10 --bold "INSTALLATION COMPLETE!" echo "Nomarchy has been successfully installed on $TARGET_DRIVE." echo echo "What's next?" echo "1. Remove the installation media." echo "2. Reboot your computer." echo "3. Log in and run 'nomarchy-update' to finish setup." echo if gum confirm "Reboot now?"; then reboot fi