171 lines
4.6 KiB
Bash
Executable file
171 lines
4.6 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
if [ -z "$(which realpath)" ]; then
|
|
realpath() {
|
|
path=$1
|
|
if [ "${path[0]}" == "/" ]; then
|
|
echo $path;
|
|
elif [ "${path[0]}" == "~" ]; then
|
|
echo $HOME/${path:2}
|
|
elif [ "${path:0:2}" == ".." ]; then
|
|
echo $(dirname $(pwd))/${path:3}
|
|
elif [ "${path[0]}" == "." ]; then
|
|
echo $(pwd)/${path:2}
|
|
else
|
|
echo $(pwd)/$path
|
|
fi
|
|
}
|
|
fi
|
|
|
|
|
|
stow() {
|
|
local stowrepo=$1
|
|
local stowtarget=$2
|
|
|
|
[ "$VERBOSE" -gt 1 ] && echo "Entering $stowrepo..."
|
|
|
|
local files=()
|
|
while read line; do
|
|
if [ "$line" != "." -a "$line" != ".." ]; then
|
|
files+=("$line")
|
|
fi
|
|
done < <(ls -a $stowrepo)
|
|
|
|
[ "$VERBOSE" -gt 1 ] && echo "Filelist: ${files[@]}"
|
|
|
|
for file in "${files[@]}"; do
|
|
local file=$(basename "$file")
|
|
local ctarget="$stowtarget/$file"
|
|
local csource="$stowrepo/$file"
|
|
if [ -e "$ctarget" ]; then
|
|
if [ -L "$ctarget" -a "$(readlink -f "$ctarget")" == "$(realpath "$csource")" ]; then # Link already exists. Skip
|
|
[ $VERBOSE -gt 0 ] && echo "Skipping $ctarget..."
|
|
elif [ -d "$ctarget" -a -d "$csource" ]; then # Dictionary exists. Enter
|
|
stow "$csource" "$ctarget"
|
|
else # No can do.
|
|
echo "Aborting. $ctarget exists, but is not owned by dotstow"; exit 1
|
|
fi
|
|
else
|
|
if [ "$SIMULATE" -gt 0 ] || ln -s "$(realpath "$csource")" "$ctarget"; then
|
|
[ $VERBOSE -gt 0 ] && echo "Linking $ctarget to $csource"
|
|
else
|
|
echo "Could not link $ctarget to $csource"; exit 1
|
|
fi
|
|
fi
|
|
done
|
|
|
|
[ "$VERBOSE" -gt 1 ] && echo "Leaving $stowrepo..."
|
|
}
|
|
|
|
destow() {
|
|
local stowrepo=$1
|
|
local stowtarget=$2
|
|
|
|
[ "$VERBOSE" -gt 1 ] && echo "Entering $stowrepo..."
|
|
|
|
local files=()
|
|
while read line; do
|
|
if [ "$line" != "." -a "$line" != ".." ]; then
|
|
files+=("$line")
|
|
fi
|
|
done < <(ls -a $stowrepo)
|
|
|
|
[ "$VERBOSE" -gt 1 ] && echo "Filelist: ${files[@]}"
|
|
|
|
for file in "${files[@]}"; do
|
|
local file=$(basename "$file")
|
|
local ctarget="$stowtarget/$file"
|
|
local csource="$stowrepo/$file"
|
|
|
|
if [ ! -e "$ctarget" ]; then # Target doesn't exists. skip
|
|
[ $VERBOSE -gt 0 ] && echo "$ctarget does not exist. Skipping..."
|
|
elif [ ! -L "$ctarget" ]; then
|
|
if [ -d "$ctarget" -a -d "$csource" ]; then
|
|
destow "$csource" "$ctarget"
|
|
else
|
|
echo "$ctarget exists, but is not owned by dotstow (Not a link)"; exit 1
|
|
fi
|
|
elif [ "$(readlink -f "$ctarget")" != "$(realpath "$csource")" ]; then
|
|
[ "$VERBOSE" -gt 0 ] && echo "$(readlink -f "$ctarget")" != "$(realpath "$csource")"
|
|
echo "$ctarget exists, but is not owned by dotstow (Wrong link)"; exit 1
|
|
else
|
|
if [ "$SIMULATE" -gt 0 ] || rm -f "$ctarget"; then
|
|
[ $VERBOSE -gt 0 ] && echo "Unlinking $ctarget"
|
|
else
|
|
echo "Could not unlink $ctarget"; exit 1
|
|
fi
|
|
fi
|
|
done
|
|
|
|
[ "$VERBOSE" -gt 1 ] && echo "Leaving $stowrepo..."
|
|
}
|
|
|
|
restow() {
|
|
destow "$1" "$2"
|
|
stow "$1" "$2"
|
|
}
|
|
|
|
TARGET="$HOME"
|
|
VERBOSE=0
|
|
REPO="$(dirname $0)"
|
|
COMMAND=stow
|
|
HELP=0
|
|
SIMULATE=0
|
|
|
|
while getopts DSRvhnt: opt; do
|
|
case $opt in
|
|
D)
|
|
COMMAND=destow
|
|
;;
|
|
S)
|
|
COMMAND=stow
|
|
;;
|
|
R)
|
|
COMMAND=restow
|
|
;;
|
|
t)
|
|
TARGET="$OPTARG"
|
|
;;
|
|
v)
|
|
let VERBOSE++
|
|
;;
|
|
h)
|
|
HELP=1
|
|
;;
|
|
n)
|
|
SIMULATE=1
|
|
;;
|
|
\?)
|
|
echo "Invalid option: -$OPTARG" >&2
|
|
exit 1
|
|
;;
|
|
:)
|
|
echo "Option -$OPTARG required an argument." >&2
|
|
;;
|
|
esac
|
|
done
|
|
shift $[ $OPTIND-1 ]
|
|
|
|
TARGET=${TARGET/%\//} # Remove trailing slashes
|
|
|
|
if [ "$HELP" -eq 1 -o "${#@}" -eq 0 ]; then
|
|
echo -e "Usage: ./dotstow.sh [-DSRvhn] [-t target] stows..."
|
|
echo -e "\t-D: Destow"
|
|
echo -e "\t-S: Stow"
|
|
echo -e "\t-R: Restow"
|
|
echo -e "\t-t: target folder (default ~)"
|
|
echo -e "\t-v: verbose"
|
|
echo -e "\t-h: show this help"
|
|
echo -e "\t-n: simulated/dry-run"
|
|
echo -e "\tstows: stow folders relative to dotstow.sh"
|
|
fi
|
|
|
|
for stow in $@; do
|
|
if [ ! -d "$REPO/$stow" ]; then
|
|
echo "Stow $stow not found." >&2
|
|
exit 2
|
|
fi
|
|
$COMMAND "$REPO/$stow" "$TARGET"
|
|
done
|
|
|
|
[ "$SIMULATE" -gt 0 ] && echo "Warning: Simulated. No actual changes to the filesystem have been done."
|