hypr-nepharius/install.sh

395 lines
11 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config"
APP_DIR="$CONFIG_DIR/hypr-nepharius"
log() {
printf '\n==> %s\n' "$1"
}
warn_overwrite() {
cat <<'MSG'
Achtung: Dieses Setup überschreibt bestehende Desktop-Konfigurationen in ~/.config.
Aktuell ist das bewusst so, damit unser Stand auf dem Testsystem sauber und reproduzierbar landet.
Bitte starte das Script normal als User, nicht mit sudo. Einzelne Root-Schritte werden intern per sudo ausgeführt.
Temporär enthält der Installer auch einen Cleanup-Block für alte Caelestia-/Quickshell-Reste.
Den räumen wir wieder raus, sobald unsere Middleware-/Shell-Entscheidung final ist.
MSG
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "Fehlt: $1" >&2
exit 1
}
}
ensure_not_root() {
if [[ ${EUID:-$(id -u)} -eq 0 ]]; then
echo "Bitte ./install.sh nicht als root ausführen. Starte es als normaler User, sudo wird intern verwendet." >&2
exit 1
fi
}
ensure_core_dependencies() {
log "[1/7] Prüfe Basis-Abhängigkeiten"
if ! command -v pacman >/dev/null 2>&1; then
echo "Dieses Install-Script ist aktuell für Arch Linux / pacman gedacht." >&2
exit 1
fi
local missing=()
for cmd in git curl bash; do
if ! command -v "$cmd" >/dev/null 2>&1; then
missing+=("$cmd")
fi
done
if (( ${#missing[@]} > 0 )); then
log "Installiere fehlende Basis-Abhängigkeiten: ${missing[*]}"
sudo pacman -Sy --needed --noconfirm "${missing[@]}"
else
log "Keine fehlenden Basis-Abhängigkeiten"
fi
}
ensure_yay() {
log "[2/7] Prüfe yay"
if command -v yay >/dev/null 2>&1; then
log "yay bereits vorhanden"
return
fi
log "yay fehlt, installiere yay"
sudo pacman -Sy --needed --noconfirm base-devel
local tmpdir
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' RETURN
git clone https://aur.archlinux.org/yay.git "$tmpdir/yay"
cd "$tmpdir/yay"
makepkg -si --noconfirm
cd "$REPO_DIR"
log "yay wurde installiert"
}
install_arch_packages() {
require_cmd pacman
log "[3/10] Installiere Arch-Pakete"
if [[ ! -f "$REPO_DIR/packages/arch.txt" ]]; then
log "Keine arch.txt gefunden, überspringe"
return
fi
mapfile -t packages < <(grep -v '^\s*$' "$REPO_DIR/packages/arch.txt")
if (( ${#packages[@]} == 0 )); then
log "Keine Arch-Pakete definiert, überspringe"
return
fi
local kernel_headers=()
if pacman -Qq linux >/dev/null 2>&1; then
kernel_headers+=(linux-headers)
fi
if pacman -Qq linux-lts >/dev/null 2>&1; then
kernel_headers+=(linux-lts-headers)
fi
if pacman -Qq linux-zen >/dev/null 2>&1; then
kernel_headers+=(linux-zen-headers)
fi
if pacman -Qq linux-hardened >/dev/null 2>&1; then
kernel_headers+=(linux-hardened-headers)
fi
if (( ${#kernel_headers[@]} > 0 )); then
log "Erkannte Kernel-Header: ${kernel_headers[*]}"
packages+=("${kernel_headers[@]}")
else
log "Keine bekannten Arch-Kernel erkannt, Header-Ergänzung übersprungen"
fi
log "Arch-Pakete: ${#packages[@]} Einträge"
if sudo pacman -S --needed --noconfirm "${packages[@]}"; then
log "Arch-Pakete fertig"
else
status=$?
echo "pacman Exit-Code: $status" >&2
exit "$status"
fi
}
install_aur_packages() {
log "[4/10] Installiere AUR-Pakete"
if [[ ! -f "$REPO_DIR/packages/aur.txt" ]]; then
log "Keine aur.txt gefunden, überspringe"
return
fi
mapfile -t aur_packages < <(grep -v '^\s*$' "$REPO_DIR/packages/aur.txt")
if (( ${#aur_packages[@]} == 0 )); then
log "Keine AUR-Pakete definiert, überspringe"
return
fi
if [[ ${EUID:-$(id -u)} -eq 0 ]]; then
echo "AUR-Pakete dürfen nicht als root gebaut werden." >&2
exit 1
fi
log "AUR-Pakete: ${#aur_packages[@]} Einträge"
if yay -S --needed --noconfirm --answerclean None --answerdiff None --removemake "${aur_packages[@]}"; then
log "AUR-Pakete fertig"
else
status=$?
echo "yay Exit-Code: $status" >&2
if [[ $status -eq 10 ]]; then
echo "Hinweis: Exit-Code 10 bedeutet hier sehr wahrscheinlich, dass ein AUR-Build als root lief oder makepkg aus einem sudo/root-Kontext gestartet wurde." >&2
echo "Bitte install.sh als normaler User starten, nicht mit sudo." >&2
fi
exit "$status"
fi
}
prompt_yes_no() {
local prompt="$1"
local reply
read -r -p "$prompt [y/N]: " reply || true
[[ "$reply" =~ ^([yY][eE][sS]|[yY])$ ]]
}
install_optional_pacman_group() {
local label="$1"
local file="$2"
if [[ ! -f "$file" ]]; then
return 1
fi
mapfile -t packages < <(grep -v '^\s*$' "$file")
if (( ${#packages[@]} == 0 )); then
return 1
fi
if prompt_yes_no "Optionale Pacman-Gruppe installieren: ${label}?"; then
log "Installiere optionale Pacman-Gruppe: ${label}"
sudo pacman -S --needed --noconfirm "${packages[@]}"
return 0
else
log "Überspringe optionale Pacman-Gruppe: ${label}"
return 1
fi
}
install_optional_aur_group() {
local label="$1"
local file="$2"
if [[ ! -f "$file" ]]; then
return 1
fi
mapfile -t packages < <(grep -v '^\s*$' "$file")
if (( ${#packages[@]} == 0 )); then
return 1
fi
if prompt_yes_no "Optionale AUR-Gruppe installieren: ${label}?"; then
log "Installiere optionale AUR-Gruppe: ${label}"
yay -S --needed --noconfirm --answerclean None --answerdiff None --removemake "${packages[@]}"
return 0
else
log "Überspringe optionale AUR-Gruppe: ${label}"
return 1
fi
}
setup_optional_dev_ai() {
if ! prompt_yes_no "Optionales Dev/AI Bundle (OpenCode + Ollama) installieren?"; then
log "Überspringe optionales Dev-AI Setup"
return
fi
if ! install_optional_pacman_group "Dev/AI" "$REPO_DIR/packages/optional-arch-dev-ai.txt"; then
log "Pacman-Dev/AI nicht installiert oder fehlgeschlagen, versuche AUR-Fallback falls konfiguriert"
install_optional_aur_group "Dev/AI Fallback" "$REPO_DIR/packages/optional-aur-dev-ai.txt" || true
fi
if command -v systemctl >/dev/null 2>&1; then
sudo systemctl enable --now ollama.service >/dev/null 2>&1 || true
fi
if [ -x "$REPO_DIR/scripts/setup-opencode-ollama.sh" ]; then
"$REPO_DIR/scripts/setup-opencode-ollama.sh" || true
fi
if command -v ollama >/dev/null 2>&1; then
if prompt_yes_no "Ollama Cloud Login jetzt ausführen?"; then
ollama signin || true
fi
if prompt_yes_no "Empfohlene Coding-Modelle jetzt per ollama pull laden?"; then
ollama pull qwen2.5-coder:14b || true
ollama pull qwen2.5-coder:32b || true
ollama pull qwen2.5:14b-instruct || true
fi
fi
}
install_optional_packages() {
log "[5/10] Optionale Softwarepakete"
install_optional_pacman_group "Gaming" "$REPO_DIR/packages/optional-arch-gaming.txt"
install_optional_pacman_group "Apps" "$REPO_DIR/packages/optional-arch-apps.txt"
install_optional_aur_group "Gaming" "$REPO_DIR/packages/optional-aur-gaming.txt"
install_optional_aur_group "Apps" "$REPO_DIR/packages/optional-aur-apps.txt"
setup_optional_dev_ai
}
copy_dir() {
local src="$1"
local dest="$2"
mkdir -p "$(dirname "$dest")"
rm -rf "$dest"
cp -r "$src" "$dest"
}
ensure_icon_theme_available() {
log "[5/10] Prüfe GTK/Icon-Theme-Verfügbarkeit"
local icon_themes=("Tela-circle-green-dark" "Tela-circle-green" "Tela-green-dark" "Papirus-Dark" "Adwaita")
local icon_theme
for icon_theme in "${icon_themes[@]}"; do
if find /usr/share/icons "$HOME/.local/share/icons" -maxdepth 1 -mindepth 1 -type d 2>/dev/null | grep -q "/${icon_theme}$"; then
log "Icon-Theme gefunden: ${icon_theme}"
return
fi
done
echo "Fehler: Keines der erwarteten Icon-Themes wurde nach der Paketinstallation gefunden." >&2
echo "Geprüft: ${icon_themes[*]}" >&2
echo "Bitte prüfe, ob das gewünschte Tela/Papirus-Theme auf dem Zielsystem wirklich verfügbar/installierbar ist." >&2
exit 1
}
cleanup_old_shells() {
log "[6/10] Räume alte Shell-/Middleware-Reste weg (temporär)"
sudo pacman -Rns --noconfirm caelestia-shell caelestia-cli quickshell-git >/dev/null 2>&1 || true
rm -rf "$HOME/.config/caelestia" "$HOME/.local/state/caelestia"
log "Temporärer Cleanup fertig"
}
install_configs() {
log "[7/10] Kopiere Konfigurationen frisch nach ~/.config"
for dir in hypr hyprmod caelestia kitty mako launcher waybar kanshi; do
if [ -d "$REPO_DIR/config/$dir" ]; then
copy_dir "$REPO_DIR/config/$dir" "$CONFIG_DIR/$dir"
echo " copied: ~/.config/$dir"
else
echo " missing in repo: config/$dir"
fi
done
if [ -d "$REPO_DIR/config/gtk-3.0" ]; then
copy_dir "$REPO_DIR/config/gtk-3.0" "$CONFIG_DIR/gtk-3.0"
echo " copied: ~/.config/gtk-3.0"
else
echo " missing in repo: config/gtk-3.0"
fi
if [ -d "$REPO_DIR/config/gtk-4.0" ]; then
copy_dir "$REPO_DIR/config/gtk-4.0" "$CONFIG_DIR/gtk-4.0"
echo " copied: ~/.config/gtk-4.0"
else
echo " missing in repo: config/gtk-4.0"
fi
if [ -d "$REPO_DIR/config/sddm/theme/forest-cyber" ]; then
sudo mkdir -p /usr/share/sddm/themes/forest-cyber
sudo cp -r "$REPO_DIR/config/sddm/theme/forest-cyber/." /usr/share/sddm/themes/forest-cyber/
echo " copied: /usr/share/sddm/themes/forest-cyber"
else
echo " missing in repo: config/sddm/theme/forest-cyber"
fi
if [ -f "$REPO_DIR/config/sddm.conf" ]; then
sudo mkdir -p /etc
sudo cp "$REPO_DIR/config/sddm.conf" /etc/sddm.conf
echo " copied: /etc/sddm.conf"
else
echo " missing in repo: config/sddm.conf"
fi
mkdir -p "$APP_DIR"
copy_dir "$REPO_DIR/scripts" "$APP_DIR/scripts"
copy_dir "$REPO_DIR/wallpapers" "$APP_DIR/wallpapers"
if [ -f "$REPO_DIR/config/.gtkrc-2.0" ]; then
cp "$REPO_DIR/config/.gtkrc-2.0" "$HOME/.gtkrc-2.0"
echo " copied: ~/.gtkrc-2.0"
fi
echo " copied: ~/.config/hypr-nepharius/scripts"
echo " copied: ~/.config/hypr-nepharius/wallpapers"
if [ -x "$APP_DIR/scripts/apply-gtk-theme.sh" ]; then
"$APP_DIR/scripts/apply-gtk-theme.sh"
echo " applied: GTK theme settings"
else
echo " skipped: GTK theme apply script missing or not executable"
fi
log "Config-Copy fertig"
}
enable_services() {
log "[8/10] Aktiviere wichtige Services"
sudo systemctl enable "hhd@${USER}.service" || true
sudo systemctl enable sddm.service || true
log "Service-Aktivierung fertig"
}
print_summary() {
log "[9/10] Installationszusammenfassung"
echo "- Pakete installiert: arch + aur"
echo "- Configs kopiert nach ~/.config"
echo "- Scripts/Wallpapers kopiert nach ~/.config/hypr-nepharius"
echo "- SDDM und hhd@${USER}.service aktiviert"
echo "- Sichtbare Module aktuell: Hyprland, Kitty, Mako, Rofi, Hyprlock, Wallpaper-Menü, Waybar"
echo "- Temporärer Cleanup aktiv: Caelestia/Quickshell-Reste werden entfernt"
echo "- Vorbereitete Module: Hyprmod, forest-cyber SDDM Theme, Plymouth Theme"
}
reload_hyprland() {
log "[10/10] Lade Hyprland neu, falls aktiv"
if command -v hyprctl >/dev/null 2>&1 && [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then
hyprctl reload && log "Hyprland wurde neu geladen"
else
log "Hyprland läuft gerade nicht in dieser Shell, Reload übersprungen"
fi
}
main() {
warn_overwrite
ensure_not_root
ensure_core_dependencies
ensure_yay
install_arch_packages
install_aur_packages
install_optional_packages
ensure_icon_theme_available
cleanup_old_shells
install_configs
enable_services
print_summary
reload_hyprland
log "Fertig. Falls nötig bitte Session einmal neu starten."
}
main "$@"