link/lib.sh (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# shellcheck shell=bash
# shellcheck disable=SC2034 # the paths below are for whichever script sources this
#
# Shared by link.sh and the link/*.sh parts: the dry-run flag, colours, link and
# link_all, and the paths they all use. Source it with the script's own
# arguments:
#
# source "$(dirname "$0")/lib.sh" "$@"
#
# Dry run unless the first argument is `yes`.
#
# Other repos' link.sh source this file instead of keeping copies, finding it
# through $DOT_LINK_LIB, which link.sh exports for them. Keep these names and
# the `yes` convention stable, or change them there as well.
is_dry_run="y"
if [[ "${1:-}" == "yes" ]]
then
is_dry_run=""
fi
color() {
color_code="$1"
shift
# Black 0;30 Dark Gray 1;30
# Red 0;31 Light Red 1;31
# Green 0;32 Light Green 1;32
# Brown/Orange 0;33 Yellow 1;33
# Blue 0;34 Light Blue 1;34
# Purple 0;35 Light Purple 1;35
# Cyan 0;36 Light Cyan 1;36
# Light Gray 0;37 White 1;37
yes_color="\033[${color_code}m"
no_color='\033[0m'
echo -e "${yes_color}$*${no_color}"
}
green() {
color '0;32' "$@"
}
yellow() {
color '1;33' "$@"
}
red() {
color '0;31' "$@"
}
# Link up dotfiles
link() {
local target="$1"
local link="$2"
if [[ -z "$1" ]]
then
>&2 echo "Error: need valid target"
return 1
fi
if [[ -z "$2" ]]
then
>&2 echo "Error: need valid link"
return 1
fi
target="$(realpath "${target}")"
if [[ -n "${is_dry_run}" ]]
then
local actual
actual="$(readlink "$link" || true)"
if [[ -n "${actual}" ]] ; then
actual="$(realpath "$actual" || true)"
fi
if [[ -L "$link" && "$target" == "$actual" ]]
then
green "$link already exists and is correct"
return
elif [[ -e "$link" ]]
then
if diff "$link" "$target" > /dev/null
then
yellow "$link already exists and will be deleted first but contents are the same. $target != $actual"
else
red "$link WILL CHANGE"
fi
else
yellow "$link will be created"
fi
else
mkdir -p "$(dirname "$2")"
rm -rf "$2"
ln -sf "$1" "$2"
fi
}
link_all() {
from="$1"
to="$2"
# Process substitution rather than a pipe, so `link` runs in this shell and
# not a subshell; NUL-delimited so names with spaces survive (SC2044/SC2086).
while IFS= read -r -d '' f
do
link "$f" "$to/$(basename "$f")"
done < <(find "$from" -mindepth 1 -maxdepth 1 -print0)
}
# Run another script with this interface, dry or not as this one is.
run_link() {
if [[ -n "${is_dry_run}" ]]
then
"$1"
else
"$1" yes
fi
}
dotfiles_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
config_dir="$dotfiles_dir/config"
xdg_config_dir="${XDG_CONFIG_HOME:-$HOME/.config}"
# iCloud Drive, on a Mac signed into it; absent everywhere else.
icloud_dir="$HOME/Library/Mobile Documents/com~apple~CloudDocs"
|