136 lines
4.7 KiB
Bash
Executable File
136 lines
4.7 KiB
Bash
Executable File
#!/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-<timestamp>/.
|
|
# ===========================================================================
|
|
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
|