#!/usr/bin/bash set -euo pipefail # Detect fish shell and ask user to switch to bash (bash-only syntax) if [ -n "${FISH_VERSION:-}" ] || case "${SHELL:-}" in *fish*) ;; *) false ;; esac; then echo "Warning: fish shell detected." echo "This script is written for bash and may have syntax issues under fish." echo "Please switch to bash first and re-run it, e.g.: bash $0" if [ -t 0 ] && [ -e /dev/tty ]; then read -r -p "Press Enter to continue anyway, or Ctrl+C to cancel..." /dev/null || ! command -v git >/dev/null || ! command -v curl >/dev/null || ! command -v fzf >/dev/null; then if command -v pacman >/dev/null; then echo "pacman detected. Installing prerequisites" if ! sudo pacman -S --needed --noconfirm fish git curl fzf; then echo "Failed to install prerequisites (fish, git, curl, fzf). Install them manually, then re-run this script." exit 1 fi elif command -v apt >/dev/null; then echo "apt detected. Installing prerequisites" if ! sudo apt update || ! sudo apt install git curl fish fzf -y; then echo "Failed to install prerequisites (fish, git, curl, fzf). Install them manually, then re-run this script." exit 1 fi else echo "No supported package manager found (pacman/apt)." echo "Please install fish, git, curl and fzf manually, then re-run this script." exit 1 fi fi if ! command -v fish >/dev/null; then echo "error: fish could not be installed (no supported package manager, or install failed)." >&2 echo "Install fish manually, then re-run this script." >&2 exit 1 fi # Clone the end-4 dotfiles repository into the temp workspace if ! git clone --depth=1 https://github.com/end-4/dots-hyprland.git "$WORK_DIR/dots-hyprland"; then echo "error: failed to clone https://github.com/end-4/dots-hyprland.git" >&2 exit 1 fi # Sync fresh end-4 files into this repo's configs/ (only when running from a # local checkout, and only for files that do not exist yet) if [ -n "$SCRIPT_DIR" ] && [ -d "$SCRIPT_DIR/configs" ]; then for rel in \ fish/config.fish \ fish/auto-Hypr.fish \ fish/fish_variables \ hypr/hyprland/colors.lua \ hypr/hyprlock/colors.conf; do if [ ! -f "$SCRIPT_DIR/configs/$rel" ] && [ -f "$WORK_DIR/dots-hyprland/dots/.config/$rel" ]; then mkdir -p "$(dirname "$SCRIPT_DIR/configs/$rel")" cp "$WORK_DIR/dots-hyprland/dots/.config/$rel" "$SCRIPT_DIR/configs/$rel" fi done fi # Run end-4 setup script with flags to skip unnecessary components. # SKIP_END4_SETUP=1 is a test hook used by tests/smoke.sh to validate this # script's own logic without running end-4's heavyweight installer. echo "WARNING: the end-4 installer runs with --force and --skip-backup;" echo "it may overwrite an existing Hyprland configuration without a backup." if [ "${SKIP_END4_SETUP:-0}" = "1" ]; then echo "(SKIP_END4_SETUP=1 - skipping the end-4 installer)" else ( cd "$WORK_DIR/dots-hyprland" ./setup install --force --skip-plasmaintg --skip-backup --skip-quickshell --skip-hyprland --skip-hyprland-entry ) fi # Resolve a config file: prefer this repo's copy, fall back to the end-4 clone cfg_src() { local rel="$1" if [ -n "$SCRIPT_DIR" ] && [ -e "$SCRIPT_DIR/configs/$rel" ]; then printf '%s\n' "$SCRIPT_DIR/configs/$rel" elif [ -e "$WORK_DIR/dots-hyprland/dots/.config/$rel" ]; then printf '%s\n' "$WORK_DIR/dots-hyprland/dots/.config/$rel" else return 1 fi } # Copy a config file into $HOME if it does not exist yet install_file() { local rel="$1" dest="$2" src if [ -e "$dest" ]; then return 0 fi if ! src="$(cfg_src "$rel")"; then echo "warning: $rel not found in configs/ or the end-4 clone, skipping" >&2 return 0 fi mkdir -p "$(dirname "$dest")" cp "$src" "$dest" } # Copy fish config files to user config if they don't exist install_file fish/config.fish "$HOME/.config/fish/config.fish" install_file fish/auto-Hypr.fish "$HOME/.config/fish/auto-Hypr.fish" if cfg_src fish/functions >/dev/null 2>&1 && [ ! -d "$HOME/.config/fish/functions" ]; then mkdir -p "$HOME/.config/fish" cp -r "$(cfg_src fish/functions)" "$HOME/.config/fish/" fi if cfg_src fish/conf.d >/dev/null 2>&1 && [ ! -d "$HOME/.config/fish/conf.d" ]; then mkdir -p "$HOME/.config/fish" cp -r "$(cfg_src fish/conf.d)" "$HOME/.config/fish/" fi # Copy color configs to user config if they don't exist. # end-4 renamed hyprland's colors.conf to colors.lua and keeps hyprlock's # colors under hypr/hyprlock/ - warn and skip if upstream moves again. install_file hypr/hyprland/colors.lua "$HOME/.config/hypr/hyprland/colors.lua" install_file hypr/hyprlock/colors.conf "$HOME/.config/hypr/hyprlock/colors.conf" # Install the Fisher plugin manager and nvm.fish, running inside fish (this is # bash). The repo configs may already ship these functions (copied above) - # fisher refuses to install over existing files, so only bootstrap what is # actually missing instead of forcing a re-install. if fish -c 'type -q fisher' 2>/dev/null; then echo "Fisher is already available in fish (from configs/), skipping bootstrap." else if ! curl -fsSL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish \ -o "$WORK_DIR/fisher.fish"; then echo "error: failed to download the fisher.fish installer" >&2 exit 1 fi if ! fish -c "source '$WORK_DIR/fisher.fish' && fisher install jorgebucaran/fisher"; then echo "error: failed to install Fisher into fish" >&2 exit 1 fi fi if fish -c 'type -q nvm' 2>/dev/null; then echo "nvm.fish is already available in fish, skipping install." elif ! fish -c 'fisher install jorgebucaran/nvm.fish'; then echo "error: failed to install nvm.fish into fish" >&2 exit 1 fi echo "fish setup complete."