summaryrefslogtreecommitdiff
path: root/install.sh
blob: 86435cf8a279e42b5322af2ff308addbd7852b42 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env bash
set -euo pipefail

REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TMP_ERR="$(mktemp)"
trap 'rm -f "$TMP_ERR"' EXIT

# Packages whose config lives in a well-formed directory (stowable from repo root)
STOW_PKGS=(
  darkman doom fastfetch foot gtk matugen mpv niri nvim rmpc starship
  tmux vicinae wallust waybar xdg-desktop-portal yazi zshrc
)

# Empty portage dirs, recreated because git does not track empty directories
PORTAGE_EMPTY_DIRS=(
  package.mask
  postsync.d
  profile/package.use.force
)

log()  { printf '\033[1;32m[install]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*"; }
die()  { printf '\033[1;31m[fatal]\033[0m %s\n' "$*" >&2; exit 1; }

run_root() {
  if [[ $EUID -eq 0 ]]; then
    "$@"
  elif command -v sudo >/dev/null 2>&1; then
    sudo "$@"
  else
    die "need root (use: $0 as root, or install sudo)"
  fi
}

need_stow() {
  if command -v stow >/dev/null 2>&1; then
    log "GNU Stow found: $(stow --version 2>/dev/null | head -n1 || true)"
    return
  fi
  warn "GNU Stow not installed — installing app-admin/stow"
  run_root emerge --ask app-admin/stow
}

stow_dotfiles() {
  cd "$REPO_DIR"
  local ok=0 fail=0
  for pkg in "${STOW_PKGS[@]}"; do
    if [[ ! -d "$pkg" ]]; then
      warn "package dir '$pkg' missing — skipped"
      continue
    fi
    if stow -R -v "$pkg" >"$TMP_ERR" 2>&1; then
      printf '  %s\n' "$(grep '^LINK' "$TMP_ERR" || true)"
      ok=$((ok + 1))
    else
      warn "stow '$pkg' failed — resolve manually:"
      sed 's/^/    /' "$TMP_ERR" || true
      fail=$((fail + 1))
    fi
  done
  log "stowed: $ok ok, $fail with conflicts"
}

restore_portage() {
  log "copying /etc/portage config from repo"
  run_root cp -a "$REPO_DIR/portage/etc/portage/." /etc/portage/

  log "copying /var/lib/portage/world from repo"
  run_root cp -a "$REPO_DIR/portage/var/lib/portage/world" /var/lib/portage/world

  run_root find /etc/portage -type f -name .gitkeep -delete

  for d in "${PORTAGE_EMPTY_DIRS[@]}"; do
    run_root mkdir -p "/etc/portage/$d"
  done
}

restore_system_configs() {
  log "installing /etc/fstab from repo"
  run_root cp -a "$REPO_DIR/fstab/etc/fstab" /etc/fstab

  if [[ -f "$REPO_DIR/config.toml" ]]; then
    log "installing /etc/greetd/config.toml from repo"
    run_root mkdir -p /etc/greetd
    run_root cp -a "$REPO_DIR/config.toml" /etc/greetd/config.toml
  fi
}

check_notes() {
  if [[ ! -x "$HOME/.local/bin/start-niri.sh" ]]; then
    warn "~/.local/bin/start-niri.sh not found; greetd (config.toml) and PATH reference it."
    warn "  create it manually or place it in a stowed package before the session is usable."
  fi
  if grep -q '/home/seraphim' "$REPO_DIR/config.toml" 2>/dev/null; then
    warn "config.toml hardcodes /home/seraphim paths — adjust for your username if different."
  fi
  if grep -q '/march=znver3' "$REPO_DIR/portage/etc/portage/make.conf"; then
    warn "make.conf targets Zen 3 (znver3) and CPU_FLAGS_X86 — review if other hardware."
  fi
}

emerge_world() {
  local ans
  read -r -p "Run 'emerge --sync && emerge -uDN @world' now? [y/N] " ans
  if [[ "${ans,,}" =~ ^y ]]; then
    run_root emerge --sync
    run_root emerge -uDN @world
  else
    log "skip — run manually: emerge --sync && emerge -uDN @world"
  fi
}

main() {
  need_stow
  stow_dotfiles
  restore_portage
  restore_system_configs
  check_notes
  emerge_world
  log "done."
}

main "$@"