153 lines
3.0 KiB
Bash
Executable File
153 lines
3.0 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
SOURCE="$(realpath "$0")"
|
|
STORE_PATH="$(dirname "$SOURCE")/../"
|
|
STORE_PATH="$(realpath "$STORE_PATH")"
|
|
STORE_ENTRIES_FILE="${STORE_PATH}/paths"
|
|
ABS_HOME="$(readlink -f "$HOME")"
|
|
|
|
method=""
|
|
path=""
|
|
do_commit=false
|
|
commit_message="."
|
|
pull_to=""
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
"-c")
|
|
do_commit=true
|
|
;;
|
|
|
|
"-m="*)
|
|
commit_message="${arg#*=}"
|
|
;;
|
|
|
|
"-pt="*)
|
|
pull_to="${arg#*=}"
|
|
pull_to="$(realpath "$pull_to")"
|
|
;;
|
|
|
|
*)
|
|
if [ -z "$method" ]; then
|
|
method="$arg"
|
|
else
|
|
path="$arg"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
if [ -z "$path" ]; then
|
|
path="."
|
|
fi
|
|
path="$(realpath --no-symlinks "$path")"
|
|
|
|
add() {
|
|
entry="$path"
|
|
check-cyclical-entry
|
|
check-duplicate-entry
|
|
|
|
printf %s\\n "$entry" >> "$STORE_ENTRIES_FILE"
|
|
printf %s\\n "Added path: $entry"
|
|
}
|
|
|
|
check-cyclical-entry() {
|
|
case "$STORE_PATH" in
|
|
"$entry"*)
|
|
printf 'Cannot cyclically archive: "%s" contains dotfiles directory'\\n "$path" >&2
|
|
exit
|
|
;;
|
|
esac
|
|
}
|
|
|
|
check-duplicate-entry() {
|
|
while IFS='' read -r line || [ -n "$line" ]; do
|
|
case $entry in
|
|
"$line"*)
|
|
printf %s\\n "Item already within path: ${line}" >&2
|
|
exit
|
|
;;
|
|
esac
|
|
done < "$STORE_ENTRIES_FILE"
|
|
}
|
|
|
|
update-dest() {
|
|
dest="$STORE_PATH/root$entry"
|
|
}
|
|
|
|
push() {
|
|
while IFS='' read -r entry || [ -n "$entry" ]; do
|
|
check-cyclical-entry
|
|
|
|
update-dest
|
|
dest_dir="$(dirname "$dest")"
|
|
rsync -rv --itemize-changes "$entry" "$dest_dir"
|
|
done < "$STORE_ENTRIES_FILE"
|
|
}
|
|
|
|
pull() {
|
|
printf %s\\n "Diffs:"
|
|
show-diff
|
|
pull-prompt
|
|
}
|
|
|
|
entry-in-pull-path() {
|
|
entry="${pull_to}${entry}"
|
|
}
|
|
|
|
pull-prompt() {
|
|
printf "Is this ok? [y/N/d(etails)] "
|
|
read -r response
|
|
case "$response" in
|
|
d*|D*)
|
|
show-diff-detail
|
|
pull-prompt
|
|
;;
|
|
|
|
y*|Y*)
|
|
confirmed-pull
|
|
;;
|
|
|
|
*)
|
|
printf %s\\n "No action taken"
|
|
exit
|
|
;;
|
|
esac
|
|
}
|
|
|
|
show-diff() {
|
|
while IFS='' read -r entry || [ -n "$entry" ]; do
|
|
update-dest
|
|
entry-in-pull-path
|
|
diff -rq "$entry" "$dest" | awk '
|
|
/^Only in/ { print $0 " (this will not be overwritten)"; next }
|
|
{ print }
|
|
'
|
|
done < "$STORE_ENTRIES_FILE"
|
|
}
|
|
|
|
show-diff-detail() {
|
|
while IFS='' read -r entry || [ -n "$entry" ]; do
|
|
update-dest
|
|
entry-in-pull-path
|
|
diff -ru "$entry" "$dest"
|
|
done < "$STORE_ENTRIES_FILE" | less
|
|
}
|
|
|
|
confirmed-pull() {
|
|
while IFS='' read -r entry || [ -n "$entry" ]; do
|
|
check-cyclical-entry
|
|
|
|
update-dest
|
|
entry-in-pull-path
|
|
entry_dir="$(dirname "$entry")"
|
|
mkdir -p "$entry_dir"
|
|
rsync -rv --itemize-changes "$dest" "$entry_dir"
|
|
done < "$STORE_ENTRIES_FILE"
|
|
}
|
|
|
|
case "$method" in
|
|
"add") add ;;
|
|
"remove") remove ;;
|
|
"push") push ;;
|
|
"pull") pull ;;
|
|
esac
|