#!/usr/bin/env bash # =========================================================================== # arch-i3 — bootstrap a complete i3 desktop on a fresh Arch Linux install # # ./install.sh run every stage # ./install.sh --dry-run print what would happen, change nothing # ./install.sh --only 30,50 run just those stages # ./install.sh --skip 20 run everything except that stage # ./install.sh --list show the stages and exit # ./install.sh -y never prompt # # Safe to re-run: package installs use --needed, and every config file that # would be overwritten is first moved into ~/.config-backup-/. # =========================================================================== set -Eeuo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" export DRY_RUN=0 ASSUME_YES=0 ENABLE_MULTILIB=0 ONLY="" SKIP="" usage() { sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0; } while [[ $# -gt 0 ]]; do case "$1" in -n|--dry-run) DRY_RUN=1 ;; -y|--yes) ASSUME_YES=1 ;; --multilib) ENABLE_MULTILIB=1 ;; --only) ONLY="${2:?--only needs a stage list}"; shift ;; --skip) SKIP="${2:?--skip needs a stage list}"; shift ;; --list) LIST=1 ;; -h|--help) usage ;; *) echo "unknown option: $1 (try --help)" >&2; exit 2 ;; esac shift done source "$REPO_ROOT/scripts/lib.sh" STAGES=( "00:preflight:00-preflight.sh:sanity checks, mirrors, pacman -Syu" "10:packages:10-packages.sh:install everything from the official repos" "20:aur:20-aur.sh:bootstrap yay, install i3lock-color + betterlockscreen" "30:dotfiles:30-dotfiles.sh:deploy configs, scripts and wallpapers" "40:services:40-services.sh:enable services, groups, font + lock cache" "50:theme:50-theme.sh:apply the Catppuccin Macchiato theme" ) if [[ -n "${LIST:-}" ]]; then printf '%sStages%s\n' "$C_BOLD" "$C_RESET" for s in "${STAGES[@]}"; do IFS=: read -r num name _ desc <<<"$s" printf ' %s%-4s%s %-10s %s\n' "$C_MAUVE" "$num" "$C_RESET" "$name" "$desc" done exit 0 fi selected() { local num="$1" name="$2" if [[ -n "$ONLY" ]]; then [[ ",$ONLY," == *",$num,"* || ",$ONLY," == *",$name,"* ]] || return 1 fi if [[ -n "$SKIP" ]]; then [[ ",$SKIP," == *",$num,"* || ",$SKIP," == *",$name,"* ]] && return 1 fi return 0 } # --- banner ---------------------------------------------------------------- cat <<'BANNER' ___ _ _ ____ / _ | ________ / / (_) __/ / __ |/ __/ __/ / _ \ / /_ | /_/ |_|_/ \__/ /_//_/ /_/____/ i3 · polybar · rofi · dunst · kitty Catppuccin Macchiato · Inconsolata Nerd Font BANNER [[ "$DRY_RUN" == "1" ]] && warn "DRY RUN — nothing will be changed" require_arch require_not_root # --- confirmation ---------------------------------------------------------- echo log "This will install $(read_pkg_list "$PACKAGES_DIR/pacman.txt" | wc -l | tr -d ' ') repo packages and" log "$(read_pkg_list "$PACKAGES_DIR/aur.txt" | wc -l | tr -d ' ') AUR packages, then write configs into ~/.config." log "Existing configs are backed up, never deleted." echo confirm "Proceed?" || die "aborted by user" # --- run stages ------------------------------------------------------------ START="$SECONDS" FAILED=() for s in "${STAGES[@]}"; do IFS=: read -r num name script desc <<<"$s" if ! selected "$num" "$name"; then skip "stage $num ($name) — skipped" continue fi echo printf '%s┌─ stage %s · %s %s%s\n' "$C_BOLD$C_MAUVE" "$num" "$name" "─────────────────────" "$C_RESET" if ! bash "$REPO_ROOT/scripts/$script"; then warn "stage $num ($name) failed" FAILED+=("$num:$name") confirm "continue with the remaining stages?" || die "aborted after stage $num" fi done # --- summary --------------------------------------------------------------- echo ELAPSED=$(( SECONDS - START )) if [[ ${#FAILED[@]} -eq 0 ]]; then log "${C_GREEN}Done${C_RESET} in ${ELAPSED}s." else warn "finished in ${ELAPSED}s with ${#FAILED[@]} failed stage(s): ${FAILED[*]}" fi cat <<'NEXT' Next steps ────────── 1. Log out of the TTY and back in so the new groups take effect. 2. Start the session with: startx (or install a display manager — see the README) 3. First keys to try: Super + Return kitty Super + d rofi app launcher Super + e thunar Super + Shift + e power menu Super + Shift + x lock the screen Super + Shift + r restart i3 after editing the config 4. Personal tweaks belong in ~/.config/i3/config.d/*.conf — that directory is never overwritten by this installer. NEXT