dotfiles/plow/plow.bash

121 lines
1.9 KiB
Bash
Raw Normal View History

2024-12-18 23:15:20 +00:00
#!/usr/bin/env bash
2024-04-21 19:07:19 +00:00
set -o errexit
set -o nounset
set -o pipefail
2025-01-05 14:22:27 +00:00
progname="$0"
error() {
local line
for line in "$@"; do
echo "$progname: $line" 1>&2
done
exit 1
}
2024-04-21 19:07:19 +00:00
shopt -s nullglob globstar
2025-01-05 14:22:27 +00:00
if [[ ! -v PLOW_CACHE ]]; then
PLOW_CACHE=.plowcache
fi
opts=$(
getopt \
--options f:t:Fivm: \
--longoptions from:,to:,force,interactive,verbose,directory-mode: \
--name "$0" \
-- "$@"
)
2024-04-21 19:07:19 +00:00
eval set -- "$opts"
2024-12-18 23:15:20 +00:00
from=${PLOW_FROM:-$PWD}
to=${PLOW_TO:-$HOME}
2024-04-21 19:07:19 +00:00
lnflags=()
mkdirflags=()
2025-01-05 14:22:27 +00:00
rmflags=()
2024-04-21 19:07:19 +00:00
while true; do
case "$1" in
-f | --from)
from=$2
shift 2
;;
-t | --to)
to=$2
shift 2
;;
-F | --force)
lnflags+=(--force)
2025-01-05 14:22:27 +00:00
rmflags+=(--force)
2024-04-21 19:07:19 +00:00
shift
;;
-i | --interactive)
lnflags+=(--interactive)
2025-01-05 14:22:27 +00:00
rmflags+=(--interactive)
2024-04-21 19:07:19 +00:00
shift
;;
-v | --verbose)
lnflags+=(--verbose)
mkdirflags+=(--verbose)
2025-01-05 14:22:27 +00:00
rmflags+=(--verbose)
2024-04-21 19:07:19 +00:00
shift
;;
-m | --directory-mode)
mkdirflags+=(--mode "$2")
shift 2
;;
--)
shift
break
;;
esac
done
2024-12-18 23:15:20 +00:00
from=$(realpath --strip -- "$from")
to=$(realpath --strip -- "$to")
2024-04-21 19:07:19 +00:00
if (( $# > 0 )); then
choices=("$@")
else
choices=()
for dir in "$from"/*/; do
choices+=("$(basename -- "$dir")")
done
fi
shopt -s dotglob
2025-01-05 14:22:27 +00:00
cache=()
if [[ -n "$PLOW_CACHE" ]]; then
if [[ -e "$PLOW_CACHE" ]]; then
while IFS= read -r link; do
cache+=("$link")
done < "$PLOW_CACHE"
fi
: > "$PLOW_CACHE"
fi
2024-04-21 19:07:19 +00:00
for choice in "${choices[@]}"; do
prefix=$from/$choice
for target in "$prefix"/**/*; do
if [[ -f "$target" ]]; then
link=$to${target#"$prefix"}
2025-01-05 14:22:27 +00:00
parent=$(dirname -- "$link")
mkdir --parents "${mkdirflags[@]}" -- "$parent"
2024-04-21 19:07:19 +00:00
ln --symbolic "${lnflags[@]}" -- "$target" "$link"
2025-01-05 14:22:27 +00:00
if [[ -n "$PLOW_CACHE" ]]; then
echo "$link" >> "$PLOW_CACHE"
fi
2024-04-21 19:07:19 +00:00
fi
done
done
2025-01-05 14:22:27 +00:00
for link in "${cache[@]}"; do
if [[ -L "$link" && ! -f "$link" ]]; then
rm "${rmflags[@]}" -- "$link"
fi
done