#!/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 ""