125 lines
2.5 KiB
Bash
Executable File
125 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
DRY_RUN=true
|
|
|
|
usage() {
|
|
echo "Usage: $0 [--commit|-c]"
|
|
echo " --commit, -c Apply changes (default is dry-run)"
|
|
exit 0
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--commit|-c) DRY_RUN=false ;;
|
|
--help|-h) usage ;;
|
|
*) echo "Unknown option: $1"; usage ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
|
|
confirm() {
|
|
local ans
|
|
read -rp "Apply this change? [y/N] " ans </dev/tty
|
|
case "$ans" in
|
|
[Yy]|[Yy][Ee][Ss]) return 0 ;; # yes
|
|
*) return 1 ;; # anything else = no
|
|
esac
|
|
}
|
|
|
|
show_diff() {
|
|
echo "--------------------------------------------------------------------------------"
|
|
diff -ru "$1" "$2" || true
|
|
echo "--------------------------------------------------------------------------------"
|
|
}
|
|
|
|
print_file_status() {
|
|
echo "- $1: $2"
|
|
}
|
|
|
|
sync_exec() {
|
|
local SRC="$1"
|
|
local DEST="$2"
|
|
local RET="$3"
|
|
if ! $DRY_RUN; then
|
|
confirm || return
|
|
fi
|
|
|
|
local opts=(-avu)
|
|
$DRY_RUN && opts+=("--dry-run")
|
|
|
|
echo "rsync $SRC $DEST $REL"
|
|
mkdir -p "$DEST/$(dirname "$REL")"
|
|
|
|
rsync "${opts[@]}" "$SRC" "$DEST/$(dirname "$REL")"| sed 's/^/[rsync] /'
|
|
}
|
|
|
|
sync_root() {
|
|
# local NAME="$1"
|
|
local DIR_A="$2"
|
|
local DIR_B="$(realpath $(dirname "$0"))"
|
|
local PATHS
|
|
PATHS="$(cat)"
|
|
|
|
echo "$DIR_A"
|
|
|
|
while IFS= read -r REL; do
|
|
[[ -z "$REL" ]] && continue
|
|
|
|
local A="$DIR_A/$REL"
|
|
local B="$DIR_B/$REL"
|
|
|
|
if [[ -e "$A" && -e "$B" ]]; then
|
|
if diff -rq "$A" "$B" >/dev/null; then
|
|
print_file_status $REL "up-to-date"
|
|
continue
|
|
fi
|
|
|
|
|
|
if [[ "$A" -nt "$B" ]]; then
|
|
print_file_status $REL "$A is newer than $B"
|
|
echo " (old) $B"
|
|
echo " (new) $A"
|
|
show_diff "$B" "$A"
|
|
FROM="$A"
|
|
TO="$DIR_B"
|
|
else
|
|
print_file_status $REL "$B is newer than $A"
|
|
echo " (old) $A"
|
|
echo " (new) $B"
|
|
show_diff "$A" "$B"
|
|
FROM="$B"
|
|
TO="$DIR_A"
|
|
fi
|
|
|
|
sync_exec $FROM $TO $REL
|
|
|
|
elif [[ -e "$A" ]]; then
|
|
print_file_status $REL "only found in $DIR_A"
|
|
sync_exec $A $DIR_B $REL
|
|
elif [[ -e "$B" ]]; then
|
|
print_file_status $REL "only found in $DIR_B"
|
|
sync_exec $B $DIR_A $REL
|
|
else
|
|
print_file_status $REL "file doesn't exist anywhere"
|
|
fi
|
|
|
|
echo
|
|
done <<< "$PATHS"
|
|
}
|
|
|
|
sync_root xdg_config "${XDG_CONFIG_HOME:-$HOME/.config}" <<'EOF'
|
|
nvim/init.lua
|
|
nvim/after/plugin/config.lua
|
|
emacs/init.el
|
|
i3/config
|
|
i3status/config
|
|
alacritty/catppuccin-mocha.toml
|
|
alacritty/alacritty.toml
|
|
EOF
|
|
|
|
sync_root home "$HOME" <<'EOF'
|
|
.gdbinit
|
|
EOF
|