#!/usr/bin/env bash set -euo pipefail repo_root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) backup_root=${XDG_STATE_HOME:-"$HOME/.local/state"}/dotfiles-backups/$(date +%Y%m%d-%H%M%S) link_path() { local source_path=$1 local target_path=$2 mkdir -p "$(dirname "$target_path")" if [[ -L "$target_path" ]]; then local resolved resolved=$(readlink -f "$target_path") if [[ "$resolved" == "$source_path" ]]; then printf 'skip %s\n' "$target_path" return 0 fi fi if [[ -e "$target_path" && ! -L "$target_path" ]]; then local backup_path="$backup_root/${target_path#$HOME/}" mkdir -p "$(dirname "$backup_path")" mv "$target_path" "$backup_path" printf 'backup %s -> %s\n' "$target_path" "$backup_path" elif [[ -L "$target_path" ]]; then rm "$target_path" fi ln -s "$source_path" "$target_path" printf 'link %s -> %s\n' "$target_path" "$source_path" } while IFS= read -r entry; do [[ -z "$entry" ]] && continue link_path "$repo_root/config/$entry" "$HOME/.config/$entry" done < <(cd "$repo_root/config" && printf '%s\n' *) if [[ -d "$repo_root/home" ]]; then while IFS= read -r entry; do [[ -z "$entry" ]] && continue link_path "$repo_root/home/$entry" "$HOME/$entry" done < <(cd "$repo_root/home" && printf '%s\n' .[^.]* *) fi printf '\nDone. Backups, if any, are in %s\n' "$backup_root"