Fix fish.sh prerequisites, fisher install, and CWD-dependent paths

- prerequisite condition tested fish (was inverted: 'zsh missing and
  git/curl/fzf present', so fish was never installed on a working machine)
- run fisher bootstrap inside fish via 'fish -c' (was: 'curl | source' in
  bash, which always failed with 'filename argument required')
- download fisher.fish with curl -fsSL to a temp file first (fail on HTTP error)
- resolve configs/ via BASH_SOURCE; when piped (curl | bash) fall back to
  the end-4 clone instead of failing on relative paths from an arbitrary CWD
- clone dots-hyprland into mktemp -d, never into the caller's CWD; git -C
  style usage so a failed pull can't strand the script's working directory
- set -euo pipefail from the top with a guarded/unguarded audit
- warn visibly that end-4 still runs with --force --skip-backup (kept per decision)
- mkdir -p before config copies; tty-guarded fish warning; ${1:-}
This commit is contained in:
alvinlollo
2026-10-08 14:06:51 +11:00
parent 49e00110bf
commit 99d94ab615
+106 -57
View File
@@ -1,15 +1,19 @@
#!/usr/bin/bash #!/usr/bin/bash
set -euo pipefail
# Detect fish shell and ask user to switch to bash (bash-only syntax) # Detect fish shell and ask user to switch to bash (bash-only syntax)
if [ -n "${FISH_VERSION:-}" ] || case "$SHELL" in *fish*) ;; *) false ;; esac; then if [ -n "${FISH_VERSION:-}" ] || case "${SHELL:-}" in *fish*) ;; *) false ;; esac; then
echo "Warning: fish shell detected." echo "Warning: fish shell detected."
echo "This script is written for bash and may have syntax issues under fish." 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" 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/tty || true read -r -p "Press Enter to continue anyway, or Ctrl+C to cancel..." </dev/tty || true
fi fi
fi
skip_watermark=false skip_watermark=false
if [ "$1" = "--skip-watermark" ]; then if [ "${1:-}" = "--skip-watermark" ]; then
skip_watermark=true skip_watermark=true
fi fi
@@ -23,94 +27,139 @@ if [ "$skip_watermark" = false ]; then
|___/ |___/
--------------- FISH Install Script --------------- --------------- FISH Install Script ---------------
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE UNDER THE GPL-2.0 LICENCE, THERE IS NO WARRANTY BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE UNDER THE GPL-2.0 LICENSE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. See the LICENCE for more detail FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. See the LICENSE for more detail
' '
fi fi
# Show disclaimer # Show disclaimer
echo "This script will add fish functions and install fish" echo "This script will add fish functions and install fish"
# Enable exit on error # Resolve where this script (and its configs/) live. When the script arrives
set -eu # over a pipe (curl | bash) there is no local checkout, so repo-config syncing
# is skipped and only the user's home directory is populated.
if [ -n "${BASH_SOURCE[0]:-}" ] && [ -f "${BASH_SOURCE[0]}" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
else
SCRIPT_DIR=""
fi
# Install prerequisites if installed skips # Never clone or write into the caller's current directory
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT
if ! command -v zsh >/dev/null && command -v git >/dev/null && command -v curl >/dev/null && command -v fzf >/dev/null; then # Install prerequisites if any of them are missing
if ! command -v fish >/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 if command -v pacman >/dev/null; then
echo "pacman detected. Installing prerequisites" echo "pacman detected. Installing prerequisites"
sudo pacman -S fish git curl fzf --noconfirm 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 fi
elif command -v apt >/dev/null; then
if command -v apt >/dev/null; then
echo "apt detected. Installing prerequisites" echo "apt detected. Installing prerequisites"
sudo apt install git curl fish fzf -y 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 fi
fi
# Clone or pull end-4 dotfiles repository
if [ -d dots-hyprland ]; then
cd dots-hyprland && git pull && cd ..
else else
git clone https://github.com/end-4/dots-hyprland.git 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 fi
# Copy fish config files from end-4 to git repo if they don't exist if ! command -v fish >/dev/null; then
if [ ! -f configs/fish/config.fish ]; then echo "error: fish could not be installed (no supported package manager, or install failed)." >&2
cp dots-hyprland/dots/.config/fish/config.fish configs/fish/config.fish echo "Install fish manually, then re-run this script." >&2
exit 1
fi fi
if [ ! -f configs/fish/auto-Hypr.fish ]; then # Clone the end-4 dotfiles repository into the temp workspace
cp dots-hyprland/dots/.config/fish/auto-Hypr.fish configs/fish/auto-Hypr.fish 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 fi
if [ ! -f configs/fish/fish_variables ]; then # Sync fresh end-4 files into this repo's configs/ (only when running from a
cp dots-hyprland/dots/.config/fish/fish_variables configs/fish/fish_variables # 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.conf \
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 fi
done
# Copy color configs from end-4 to git repo if they don't exist
if [ ! -f configs/hypr/hyprland/colors.conf ]; then
cp dots-hyprland/dots/.config/hypr/hyprland/colors.conf configs/hypr/hyprland/colors.conf
fi
if [ ! -f configs/hypr/hyprlock/colors.conf ]; then
cp dots-hyprland/dots/.config/hypr/hyprlock/colors.conf configs/hypr/hyprlock/colors.conf
fi fi
# Run end-4 setup script with flags to skip unnecessary components # Run end-4 setup script with flags to skip unnecessary components
dots-hyprland/setup install --force --skip-plasmaintg --skip-backup --skip-quickshell --skip-hyprland --skip-hyprland-entry echo "WARNING: the end-4 installer runs with --force and --skip-backup;"
echo "it may overwrite an existing Hyprland configuration without a backup."
(
cd "$WORK_DIR/dots-hyprland"
./setup install --force --skip-plasmaintg --skip-backup --skip-quickshell --skip-hyprland --skip-hyprland-entry
)
# Create fish config directory # Resolve a config file: prefer this repo's copy, fall back to the end-4 clone
mkdir -p "$HOME/.config/fish" 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 # Copy fish config files to user config if they don't exist
if [ ! -f "$HOME/.config/fish/config.fish" ]; then install_file fish/config.fish "$HOME/.config/fish/config.fish"
cp configs/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 fi
if [ -d configs/fish/functions ] && [ ! -d "$HOME/.config/fish/functions" ]; then if cfg_src fish/conf.d >/dev/null 2>&1 && [ ! -d "$HOME/.config/fish/conf.d" ]; then
cp -r configs/fish/functions "$HOME/.config/fish/" mkdir -p "$HOME/.config/fish"
fi cp -r "$(cfg_src fish/conf.d)" "$HOME/.config/fish/"
if [ -d configs/fish/conf.d ] && [ ! -d "$HOME/.config/fish/conf.d" ]; then
cp -r configs/fish/conf.d "$HOME/.config/fish/"
fi
if [ ! -f "$HOME/.config/fish/auto-Hypr.fish" ]; then
cp configs/fish/auto-Hypr.fish "$HOME/.config/fish/"
fi fi
# Copy color configs to user config if they don't exist # Copy color configs to user config if they don't exist
if [ ! -f "$HOME/.config/hypr/hyprland/colors.conf" ]; then install_file hypr/hyprland/colors.conf "$HOME/.config/hypr/hyprland/colors.conf"
cp configs/hypr/hyprland/colors.conf "$HOME/.config/hypr/hyprland/colors.conf" install_file hypr/hyprlock/colors.conf "$HOME/.config/hypr/hyprlock/colors.conf"
# Install Fisher plugin manager + plugins, running inside fish (this is bash)
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 fi
if [ ! -f "$HOME/.config/hypr/hyprlock/colors.conf" ]; then if ! fish -c "source '$WORK_DIR/fisher.fish' && fisher install jorgebucaran/fisher jorgebucaran/nvm.fish"; then
cp configs/hypr/hyprlock/colors.conf "$HOME/.config/hypr/hyprlock/colors.conf" echo "error: failed to install Fisher and nvm.fish into fish" >&2
exit 1
fi fi
# Install Fisher plugin manager for fish shell echo "fish setup complete."
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher
# Install plugins using Fisher
fisher install jorgebucaran/nvm.fish