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