49 lines
1.4 KiB
Bash
Executable File
49 lines
1.4 KiB
Bash
Executable File
#!/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"
|