250 lines
12 KiB
Fish
250 lines
12 KiB
Fish
#!/usr/bin/env fish
|
|
#
|
|
# install.fish — Dotfiles bootstrap script
|
|
# =============================================================================
|
|
#
|
|
# Quick install (copy-paste this one-liner):
|
|
#
|
|
# curl -fsSL https://git.toomuchtaco.net/taco/dots/raw/branch/main/install.fish | fish
|
|
#
|
|
# What this script does:
|
|
# 1. Checks prerequisites: Fish shell, Git, and a few common tools
|
|
# 2. Tries SSH clone (git@gitssh.toomuchtaco.net:taco/dots.git); falls back
|
|
# to HTTPS (https://git.toomuchtaco.net/taco/dots.git) and rewrites the
|
|
# remote origin to SSH so future pushes use the right URL
|
|
# 3. Replaces or updates ~/.config/fish/ with the contents of the repo
|
|
# 4. Sources the new config and runs `dotfiles init` to install templates
|
|
# (~/.tmux.conf, ~/.gitconfig, ~/.config/starship.toml, etc.)
|
|
# 5. Warns if SSH key is needed and points to the keyme helper
|
|
# 6. Prints next steps
|
|
#
|
|
# You can pass a custom repo URL as the first argument:
|
|
#
|
|
# curl -fsSL https://git.toomuchtaco.net/taco/dots/raw/branch/main/install.fish | fish -s -- https://github.com/you/dotfiles
|
|
#
|
|
# =============================================================================
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Configuration
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
# Default repository URLs (overridable via first argument).
|
|
set -l SSH_REPO "git@gitssh.toomuchtaco.net:taco/dots.git"
|
|
set -l HTTPS_REPO "https://git.toomuchtaco.net/taco/dots.git"
|
|
if set -q argv[1]
|
|
set SSH_REPO "$argv[1]"
|
|
set HTTPS_REPO "$argv[1]"
|
|
end
|
|
|
|
set -l REPO_BRANCH "main"
|
|
set -l FISH_CONFIG_DIR "$HOME/.config/fish"
|
|
|
|
# ANSI colour codes for pretty output.
|
|
set -l RST (set_color normal)
|
|
set -l GRN (set_color green)
|
|
set -l YLW (set_color yellow)
|
|
set -l RED (set_color red)
|
|
set -l BOLD (set_color --bold)
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Helper: print a formatted step header
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
function _step -d "Print a step header"
|
|
echo ""
|
|
echo (set_color --bold)"[$argv[1]]$RST $argv[2..]"
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# 1. Prerequisites check
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
echo ""
|
|
echo "$BOLD━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$RST"
|
|
echo "$BOLD Dotfiles Installer$RST"
|
|
echo "$BOLD━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$RST"
|
|
|
|
_step "1/5" "Checking prerequisites ..."
|
|
|
|
# Fish itself — we're running in it, but just in case.
|
|
if not set -q FISH_VERSION
|
|
echo "$RED ERROR: Fish shell is required but not running.$RST"
|
|
echo " Install fish and re-run this script."
|
|
exit 1
|
|
end
|
|
echo "$GRN ✓$RST Fish $FISH_VERSION"
|
|
|
|
# Git
|
|
if not command -v git &>/dev/null
|
|
echo "$RED ERROR: Git is required but not installed.$RST"
|
|
echo " Install it with your package manager, then re-run."
|
|
exit 1
|
|
end
|
|
echo "$GRN ✓$RST Git "(git --version | cut -d' ' -f3)
|
|
|
|
# Optional but nice-to-have tools
|
|
for tool in tmux starship
|
|
if command -v $tool &>/dev/null
|
|
echo " ⬡ $tool detected (templates available)"
|
|
else
|
|
echo " ⬡ $tool not found (optional — templates exist but are skipped)"
|
|
end
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# 2. Fetch the repository
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
_step "2/5" "Fetching dotfiles ..."
|
|
|
|
set -l tmpdir (mktemp -d)
|
|
set -l CLONED_SSH 0
|
|
|
|
# Try SSH first (private repo, full read/write access).
|
|
echo " Trying SSH: $SSH_REPO"
|
|
if command git clone --branch "$REPO_BRANCH" "$SSH_REPO" "$tmpdir"
|
|
echo "$GRN ✓$RST Repository cloned via SSH."
|
|
set CLONED_SSH 1
|
|
else
|
|
echo "$YLW ⚠ SSH clone failed.$RST"
|
|
echo " (SSH key may not be loaded — this is expected on first install)"
|
|
echo ""
|
|
|
|
# Fall back to HTTPS (public read-only access).
|
|
echo " Trying HTTPS: $HTTPS_REPO"
|
|
if command git clone --branch "$REPO_BRANCH" "$HTTPS_REPO" "$tmpdir"
|
|
echo "$GRN ✓$RST Repository cloned via HTTPS."
|
|
echo ""
|
|
echo " Switching remote origin to SSH path for future pushes ..."
|
|
command git -C "$tmpdir" remote set-url origin "$SSH_REPO"
|
|
echo "$GRN ✓$RST Remote origin updated to: $SSH_REPO"
|
|
else
|
|
echo "$RED ERROR: All clone methods failed.$RST"
|
|
echo " Manually clone the repo and re-run this script:"
|
|
echo " git clone $SSH_REPO $FISH_CONFIG_DIR"
|
|
command rm -rf "$tmpdir"
|
|
exit 1
|
|
end
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# 3. Install files into ~/.config/fish/
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
_step "3/5" "Installing files to $FISH_CONFIG_DIR ..."
|
|
|
|
# Ensure the config directory exists.
|
|
mkdir -p "$FISH_CONFIG_DIR"
|
|
|
|
# Back up any existing config before overwriting.
|
|
set -l backup_dir "$HOME/.config/fish.backup."(date +%s)
|
|
if test -d "$FISH_CONFIG_DIR"
|
|
and not test -L "$FISH_CONFIG_DIR"
|
|
and count "$FISH_CONFIG_DIR"/* &>/dev/null
|
|
command cp -r "$FISH_CONFIG_DIR" "$backup_dir"
|
|
echo " Existing config backed up to $backup_dir"
|
|
end
|
|
|
|
# Copy the repo contents into place.
|
|
# The repo is expected to have this structure:
|
|
# install.fish (this script — at repo root)
|
|
# .config/fish/ (the fish config directory)
|
|
command cp -r "$tmpdir/.config/fish/." "$FISH_CONFIG_DIR/"
|
|
|
|
# Also copy the install script itself and README to the config dir for
|
|
# future reference.
|
|
command cp "$tmpdir/install.fish" "$FISH_CONFIG_DIR/install.fish" 2>/dev/null
|
|
if test -f "$tmpdir/README.md"
|
|
command cp "$tmpdir/README.md" "$FISH_CONFIG_DIR/README.md"
|
|
end
|
|
|
|
echo "$GRN ✓$RST Files installed."
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# 4. Initialise managed dotfiles
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
_step "4/5" "Initialising managed dotfiles (~/.tmux.conf, ~/.gitconfig, ...) ..."
|
|
|
|
# Load the dotfiles function so its built-in defaults (DOTFILES_DIR,
|
|
# DOTFILES_BACKUP_DIR, DOTFILES_REPO_URL) are available and the
|
|
# `dotfiles` command can run. Auto-load won't fire in a curl-piped
|
|
# non-interactive context, so we source it explicitly.
|
|
if test -f "$FISH_CONFIG_DIR/functions/dotfiles.fish"
|
|
source "$FISH_CONFIG_DIR/functions/dotfiles.fish"
|
|
end
|
|
|
|
# Also source config.fish for the `gitme` helper and any local overrides.
|
|
if test -f "$FISH_CONFIG_DIR/config.fish"
|
|
source "$FISH_CONFIG_DIR/config.fish"
|
|
end
|
|
|
|
# If a custom SSH_REPO was provided via argv[1], persist it so
|
|
# `dotfiles publish` and `dotfiles sync` use the right remote.
|
|
# (Otherwise the default in dotfiles.fish applies automatically.)
|
|
if set -q argv[1]
|
|
dotfiles repo "$SSH_REPO" 2>/dev/null
|
|
end
|
|
|
|
# Run init for every managed template.
|
|
dotfiles init
|
|
|
|
echo "$GRN ✓$RST Dotfiles initialised."
|
|
echo ""
|
|
echo " Installed templates:"
|
|
for f in (find "$DOTFILES_DIR" -type f | sort)
|
|
set -l name (string replace "$DOTFILES_DIR/" "" "$f")
|
|
echo " $(set_color green)•$(set_color normal) ~/.$name"
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# 5. Done — print next steps
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
|
|
_step "5/5" "Cleaning up ..."
|
|
command rm -rf "$tmpdir"
|
|
echo "$GRN ✓$RST Done."
|
|
|
|
echo ""
|
|
echo "$BOLD━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$RST"
|
|
echo "$GRN Installation complete!$RST"
|
|
echo "$BOLD━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$RST"
|
|
echo ""
|
|
echo " $YLW""Next steps:$RST"
|
|
echo ""
|
|
echo " $(set_color green)1.$RST Start a new fish shell: exec fish"
|
|
echo " $(set_color green)2.$RST Check managed files: dotfiles status"
|
|
echo " $(set_color green)3.$RST Edit a dotfile: dotfiles edit tmux"
|
|
echo " $(set_color green)4.$RST Pull remote updates: dotfiles sync"
|
|
echo " $(set_color green)5.$RST Push your changes: dotfiles publish"
|
|
echo ""
|
|
|
|
# If we fell back to HTTPS, SSH auth isn't set up yet.
|
|
if test "$CLONED_SSH" -eq 0
|
|
echo " $YLW""⚠ SSH key required for push access$RST"
|
|
echo ""
|
|
echo " To push changes, you need an SSH key set up for Gitea."
|
|
echo " Run this built-in helper to generate one and configure SSH:"
|
|
echo ""
|
|
echo " $(set_color --bold)keyme$RST"
|
|
echo ""
|
|
echo " It will create ~/.ssh/id_ed25519_gitea, update ~/.ssh/config,"
|
|
echo " and print the public key for you to add at:"
|
|
echo " $(set_color cyan)https://git.toomuchtaco.net/user/settings/keys$RST"
|
|
echo ""
|
|
end
|
|
|
|
echo " $YLW""New to the dotfiles system?$RST"
|
|
echo " dotfiles help"
|
|
echo ""
|
|
echo " $YLW""Need to set your Git identity?$RST"
|
|
echo " dotfiles edit gitconfig"
|
|
echo " # Change the [user] section, then: dotfiles update gitconfig"
|
|
echo ""
|