-
Notifications
You must be signed in to change notification settings - Fork 0
/
install.sh
executable file
·289 lines (232 loc) · 7.07 KB
/
install.sh
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#!/bin/bash
set -e
shopt -s dotglob
if ! command -v perl >/dev/null 2>&1; then
echo "Perl is required to run this script. Install it and try again."
exit 1
fi
SCRIPT_PATH=$(
cd "$(dirname "$0")"
pwd -L
)
function relpath {
local path=$1
local base=$2
perl -MFile::Spec -e 'print File::Spec->abs2rel(@ARGV)' "$path" "$base"
}
function for-each-file-in {
local dir=$1
shift
for path in "$dir"/*; do
if ! [ -e "$path" ]; then
continue
fi
if [ -d "$path" ]; then
for-each-file-in "$path" "$@"
elif [ -f "$path" ]; then
"$@" "$path"
fi
done
}
function check-symlink-parent-conflict {
local target_path
local target_dir=$1
local source_path=$2
local source_dirname
source_dirname=$(basename "$source_path")
target_path=$target_dir/$source_dirname
if [ -L "$target_path" ]; then
echo "$target_path is a symlink."
FOUND_CONFLICT=1
elif [ -f "$target_path" ]; then
echo "$target_path is a file."
FOUND_CONFLICT=1
fi
}
function check-symlink-file-conflict {
local target_path
local target_dir=$1
local source_root=$2
local source_path=$3
local source_relpath
source_relpath=$(relpath "$source_path" "$source_root")
target_path=$target_dir/$source_relpath
if [ -L "$target_path" ]; then
echo "$target_path is a symlink."
FOUND_CONFLICT=1
elif [ -f "$target_path" ]; then
echo "$target_path is a file."
FOUND_CONFLICT=1
elif [ -d "$target_path" ]; then
echo "$target_path is a directory."
FOUND_CONFLICT=1
fi
}
function check-symlink-dir-conflict {
local target_path=$1
if [ -L "$target_path" ]; then
echo "$target_path is a symlink."
FOUND_CONFLICT=1
elif [ -f "$target_path" ]; then
echo "$target_path is a file."
FOUND_CONFLICT=1
elif [ -d "$target_path" ]; then
echo "$target_path is a directory."
FOUND_CONFLICT=1
fi
}
function symlink-dir {
local target_path=$1
local target_dir
local source_path=$2
local source_dir
target_dir=$(dirname "$target_path")
source_dir=$(dirname "$source_path")
mkdir -p "$target_dir"
ln -sniFv "$source_path" "$target_path" || true
}
function symlink-file {
local target_path
local target_dir=$1
local source_root=$2
local source_path=$3
local source_relpath
source_relpath=$(relpath "$source_path" "$source_root")
target_path=$target_dir/$source_relpath
mkdir -p "$(dirname "$target_path")"
ln -siFv "$source_path" "$target_path" || true
}
function make-dir-symlink {
local source_dir
local source_dirname=$1
local target_dir=$2
source_dir=$SCRIPT_PATH/$source_dirname
echo "Symlinking $source_dirname to $target_dir..."
echo "Checking for possible conflicts..."
echo
if [ -d "$target_dir" ] && ! [ -L "$target_dir" ]; then
echo "The target directory $target_dir is already a directory. Skipping."
else
FOUND_CONFLICT=
check-symlink-dir-conflict "$target_dir"
if [ "$FOUND_CONFLICT" ]; then
echo
while true; do
local create_symlinks=
read -rp "Do you want to attempt to overwrite the above with a symlink to dotfiles? [y/N] " create_symlinks
if [ "$create_symlinks" = "y" ] || [ "$create_symlinks" = "Y" ]; then
echo
echo "Creating directory symlink..."
echo
symlink-dir "$target_dir" "$source_dir"
break
elif ! [ "$create_symlinks" ] || [ "$create_symlinks" = "n" ] || [ "$create_symlinks" = "N" ]; then
break
fi
done
else
echo "No conflicts found. Creating directory symlink..."
echo
symlink-dir "$target_dir" "$source_dir"
fi
fi
echo
}
function make-file-symlinks {
local source_dir
local source_dirname=$1
local target_dir=$2
source_dir=$SCRIPT_PATH/$source_dirname
echo "Symlinking $source_dirname files to $target_dir..."
echo "Checking for possible conflicts..."
echo
FOUND_CONFLICT=
check-symlink-parent-conflict "$target_dir" "$source_dir"
if [ "$FOUND_CONFLICT" ]; then
echo "The target directory $target_dir is a file or is already a symlink. Skipping."
else
FOUND_CONFLICT=
for-each-file-in "$source_dir" check-symlink-file-conflict "$target_dir" "$source_dir"
if [ "$FOUND_CONFLICT" ]; then
echo
while true; do
local create_symlinks=
read -rp "Do you want to attempt to overwrite the above with symlinks to dotfiles? [y/N] " create_symlinks
if [ "$create_symlinks" = "y" ] || [ "$create_symlinks" = "Y" ]; then
echo
echo "Creating symlinks..."
echo
for-each-file-in "$source_dir" symlink-file "$target_dir" "$source_dir"
break
elif ! [ "$create_symlinks" ] || [ "$create_symlinks" = "n" ] || [ "$create_symlinks" = "N" ]; then
break
fi
done
else
echo "No conflicts found. Creating symlinks..."
echo
for-each-file-in "$source_dir" symlink-file "$target_dir" "$source_dir"
fi
fi
echo
}
while true; do
INSTALL_PACKAGES=
read -rp "Do you want to install packages from dotfiles? [y/N] " INSTALL_PACKAGES
if [ "$INSTALL_PACKAGES" = "y" ] || [ "$INSTALL_PACKAGES" = "Y" ]; then
if [[ "$(uname -s)" == "Darwin" ]]; then
if ! command -v brew >/dev/null 2>&1; then
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
eval "$(brew shellenv)"
FPATH=$(brew --prefix)/share/zsh/site-functions:$FPATH
brew bundle install --file="$SCRIPT_PATH/homebrew/Brewfile" --no-lock --verbose
fi
break
elif ! [ "$INSTALL_PACKAGES" ] || [ "$INSTALL_PACKAGES" = "n" ] || [ "$INSTALL_PACKAGES" = "N" ]; then
break
fi
done
make-file-symlinks home "$HOME"
make-file-symlinks bin "$HOME/bin"
make-file-symlinks bundle "$HOME/.bundle"
make-file-symlinks cargo "$HOME/.cargo"
make-file-symlinks ssh "$HOME/.ssh"
make-file-symlinks ssh/config.d "$HOME/.ssh/config.d"
make-file-symlinks starship "$HOME/.config"
if command -v code >/dev/null 2>&1; then
while true; do
INSTALL_PACKAGES=
read -rp "Do you want to install VSCode extensions from dotfiles? [y/N] " INSTALL_PACKAGES
if [ "$INSTALL_PACKAGES" = "y" ] || [ "$INSTALL_PACKAGES" = "Y" ]; then
xargs -n 1 code --install-extension <"$SCRIPT_PATH/vscode/extension-list"
break
elif ! [ "$INSTALL_PACKAGES" ] || [ "$INSTALL_PACKAGES" = "n" ] || [ "$INSTALL_PACKAGES" = "N" ]; then
break
fi
done
fi
if [[ "$(uname -s)" == "Darwin" ]]; then
make-file-symlinks vscode/user "$HOME/Library/Application Support/Code/User"
fi
if command -v rbenv >/dev/null 2>&1; then
eval "$(rbenv init -)"
make-file-symlinks rbenv "$(rbenv root)"
fi
if [[ "$(uname -s)" == "Darwin" ]]; then
echo "Now set up Raycast and iTerm and you're done!"
echo
echo "Raycast's settings are here:"
echo " $SCRIPT_PATH/raycast"
echo
echo "In Raycast:"
echo " Import Preferences & Data"
echo
echo "iTerm's preferences are here:"
echo " $SCRIPT_PATH/iterm"
echo
echo "In iTerm's preferences dialogue:"
echo " General > Preferences > Load preferences from a custom folder or URL"
else
echo "Done!"
fi