-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdotf
executable file
·112 lines (95 loc) · 2.65 KB
/
dotf
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
#!/usr/bin/env bash
# Link or unlink dotfiles
set -o errexit
set -o nounset
set -o pipefail
usage() {
echo "Usage: $0 <link | unlink> [--dry-run] PACKAGES..."
exit 1
}
# Text colors
color_reset='\033[0m'
color_green='\033[1;32m'
color_red='\033[1;31m'
DOTFILES_PATH="$(cd "$(dirname "$0")"; pwd)" # get absolute path
PACKAGES_PATH="$DOTFILES_PATH/packages"
DRYRUN=0
main() {
local positional_args=()
while [[ "$#" -gt 0 ]]; do
case "$1" in
--dry-run)
DRYRUN=1
shift
;;
-*|--*)
echo "Unknown option $1"
exit 1
;;
*)
positional_args+=("$1")
shift
;;
esac
done
set -- "${positional_args[@]}" # restore positional parameters
if [[ "$#" -lt 2 ]]; then
usage
fi
local action="$1"
if [[ "$action" != link && "$action" != unlink ]]; then
usage
fi
shift
for package in "$@"; do
local path="$PACKAGES_PATH/$package"
if [ ! -d "$path" ]; then
echo -e "No such package ${color_red}${package}${color_reset}"
continue
fi
echo -e "Package: ${color_green}${package}${color_reset}"
do_package "$action" "$path"
done
}
do_package() {
local action="$1"
local package_path="$2" # must be absolute
while IFS= read -r -d '' src; do
# we could more easily get src_pruned using `find -printf "%P\0`, but -printf is not supported by MacOS find.
local src_pruned="${src#"$package_path/"}"
local target="$HOME"/"$src_pruned"
if [ -L "$target" ]; then
if [ "$target" -ef "$src" ]; then
# This link points to the right src
if [ "$action" = "unlink" ]; then
if [ "$DRYRUN" = 1 ]; then
echo "- dry run: rm '$target'"
else
echo -en "${color_green}✓ ${color_reset}"
rm -v "$target"
fi
elif [ "$action" = "link" ]; then
echo "- '$target' is already symlinked to '$src'"
fi
else
echo -e "${color_red}x ${color_reset}'$target' exists and is not a symlink to '$src'"
continue
fi
elif [ -e "$target" ]; then
# target is a file/directory that is not a symlink
echo -e "${color_red}x ${color_reset}'$target' exists and is not a symlink to '$src'"
continue
else
if [ "$action" = "link" ]; then
if [ "$DRYRUN" = 1 ]; then
echo "- dry run: ln -s '$src' '$target'"
else
mkdir -v -p "$(dirname "$target")"
echo -en "${color_green}✓ ${color_reset}"
ln -sv "$src" "$target"
fi
fi
fi
done < <(find "$package_path" -type f -print0 | sort --zero-terminated) # sort for deterministic order
}
main "$@"