-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup
executable file
·337 lines (298 loc) · 9.17 KB
/
setup
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#!/bin/bash
if [ "$EUID" -eq 0 ]; then
echo "Running as root is disallowed."
exit 1
fi
DOTFILES_ROOT_DIR=$(pwd)
# Check for dotfiles root
GIT_DIR=$(grep ivan-ristovic/dotfiles .git/config)
if [ -z "$GIT_DIR" ]; then
echo "Not in dotfiles directory. Exiting ..."
exit 1
fi
# Check if core dirs are present
required_dirs=("shlib" "dotfiles" "install" "patches" "systemd")
for dir in "${required_dirs[@]}"; do
if [ ! -d "$dir" ]; then
echo "$dir/ directory is not present. Exiting ..."
exit 1
fi
done
unset required_dirs
# Init submodules
submodules=("shlib")
if git submodule status | grep --quiet '^-'; then
echo "Submodule(s) not initialized. Initializing..."
for submodule in "${submodules[@]}"; do
pushd "$submodule"
git submodule init
git submodule update
popd
done
fi
unset submodules
# Load utils
export SHLIB_ROOT="$PWD/shlib/lib"
source "utils.sh"
function usage ()
{
echo -e "usage: $0"
echo -e "\t[--user username | -u username]"
echo -e "\t[--dotfiles | --packages install_list_path | --patch[es] --services | --complete]"
echo -e "\t[--verbose | -v] [--strict | -s]"
echo -e "\t[--log | -l]"
echo -e "\t[--help | -h]"
echo
echo " LEGEND:"
echo -e "\t--help -h prints this manual"
echo -e "\t--strict -s halt on error (set -e)"
echo -e "\t--repair -r repair dotfile symlinks"
echo -e "\t--verbose -v runs the script in debug mode (set -x)"
echo -e "\t--remote update git remote URL"
echo -e "\t--log -l output log to logfile"
echo
echo -e "\t--dotfiles link dotfiles (default)"
echo -e "\t--packages --install install packages from the given install list"
echo -e "\t--patch --patches perform patches"
echo -e "\t--complete --all perform all of the above"
exit 2
}
GIT_REMOTE="[email protected]:ivan-ristovic/dotfiles.git"
STOW_EXTRA_ARGS=""
SETUP_OVERRIDE=false
SETUP_DOTFILES=false
SETUP_PACKAGES=false
SETUP_PATCHES=false
SETUP_SERVICES=false
SETUP_USER=${SUDO_USER:-$(logname 2> /dev/null)}
SETUP_HOME_DIR="/home/$SETUP_USER"
SHORT_OPTS=v,s,u:,h,l,r
LONG_OPTS=user:,username:,dotfiles,link,stow,packages,install,dotfiles,patch,patches,services,all,complete,help,strict,repair,debug,verbose,remote,git,log
OPTS=$(getopt --alternative --name 'argument error' --options $SHORT_OPTS --longoptions $LONG_OPTS -- "$@")
if [ $? -ne 0 ]; then
std::fat "failed to parse provided arguments"
fi
eval set -- $OPTS
while :
do
case "$1" in
--all | --complete)
SETUP_OVERRIDE=true
SETUP_DOTFILES=true
SETUP_PACKAGES=true
SETUP_PATCHES=true
SETUP_SERVICES=true
;;
--packages | --install)
SETUP_OVERRIDE=true
SETUP_PACKAGES=true
;;
--dotfiles | --link | --stow)
SETUP_OVERRIDE=true
SETUP_DOTFILES=true
;;
--patch | --patches)
SETUP_OVERRIDE=true
SETUP_PATCHES=true
;;
--services)
SETUP_OVERRIDE=true
SETUP_SERVICES=true
;;
--remote | --git)
if git remote set-url origin $GIT_REMOTE ; then
log::suc "Successfully updated remote: $GIT_REMOTE"
exit 0
else
log::err "Failed to update remote"
exit $?
fi
;;
-l | --log)
logfile="setup-$(date +%s).log"
log::msg "logging output to: $logfile"
exec 1> >(tee -a $logfile)
exec 2>&1
;;
-v | --verbose | --debug)
log::msg "debug mode enabled"
set -x;
;;
-r | --repair)
log::msg "repairing dotfile symlinks"
STOW_EXTRA_ARGS="-R"
;;
-s | --strict)
log::msg "strict mode enabled"
set -e;
;;
-u | --user | --username)
SETUP_USER="$2"
SETUP_HOME_DIR="/home/$SETUP_USER"
shift;
;;
-h | --help)
usage
;;
--)
shift;
break
;;
*)
log::err "unknown option: $1"
usage
;;
esac
shift;
done
# Check if install arg exists
if $SETUP_PACKAGES ; then
if [ $# -eq 0 ]; then
std::fat "missing install list(s) or entries to install"
fi
fi
# Check username
if [ -z "$SETUP_USER" ]; then
std::fat "cannot automatically detect user name - please provide one using the --username option"
fi
# Check home dir
if [ ! -d "$SETUP_HOME_DIR" ]; then
std::fat "invalid home directory: $SETUP_HOME_DIR"
fi
if ! $SETUP_OVERRIDE ; then
SETUP_PACKAGES=false
SETUP_DOTFILES=true
SETUP_PATCHES=false
SETUP_SERVICES=false
fi
log::msg "user: $SETUP_USER"
log::msg "home: $SETUP_HOME_DIR"
log::msg "list: $*"
export SETUP_USER
export SETUP_HOME_DIR
### Start setup
packages_requiring_linked_dotfiles=()
errored_entries=()
if $SETUP_PACKAGES ; then
log::suc "Starting installations; command: '$PM_INSTALL_CMD'"
function process_list ()
{
for entry in "$@"; do
cd "install"
SETUP_SCRIPT="$entry"
AUR_PREFIX="aur:"
if [[ "$entry" == "+"* ]]; then
cd "$DOTFILES_ROOT_DIR"
to_include=${entry#"+"}
log::msg "Importing setup script: $to_include"
process_list $(read_list "lists/$to_include")
elif [[ "$entry" == "!"* ]]; then
to_post_install=${entry#"!"}
log::msg "Post-link install for : $to_post_install"
packages_requiring_linked_dotfiles+=(${to_post_install})
elif [ -f "$SETUP_SCRIPT" ]; then
log::msg "Setting up via script : $entry"
source ./"$SETUP_SCRIPT"
elif [[ "$entry" == "$AUR_PREFIX"* ]]; then
pkg=${entry#"$AUR_PREFIX"}
log::msg "Installing from AUR : $pkg"
if inst_aur "$pkg"; then
log::suc "Successfully installed: $pkg"
else
errored_entries+=(${entry})
fi
else
log::msg "Installing package : $entry"
if inst "$PM" "$entry"; then
log::suc "Successfully installed: $entry"
else
errored_entries+=(${entry})
fi
fi
cd "$DOTFILES_ROOT_DIR"
sleep 1
done
}
for arg in "$@" ; do
if [[ "$arg" == "install/"* ]]; then
log::msg "Ignoring install/ pfix: $arg"
arg=${arg#"install/"}
fi
if [ -f "$arg" ]; then
process_list $(read_list "$arg")
else
process_list "$arg"
fi
done
log::suc "Installations finished."
fi
if $SETUP_DOTFILES ; then
# Ensure .config dir exists so that it is not
# symlinked (otherwise all programs would dump
# their config into the dotfiles directory)
mkdir -p "$SETUP_HOME_DIR/.config"
# Force overwrites of specified files (save backup to /tmp)
backup_dir=/tmp/dotfiles
rm -rf $backup_dir
force_overwrite_list=$(read_list ".link.force")
for entry in $force_overwrite_list; do
entry_path="$SETUP_HOME_DIR/$entry"
if [[ -f $entry_path && ! -h $entry_path ]]; then
mkdir -p $backup_dir
log::msg "Forcing overwrite of: $entry_path ; backup at $backup_dir"
mv "$entry_path" "$backup_dir"
fi
done
cd dotfiles
if stow --no-folding $STOW_EXTRA_ARGS -v . -t "$SETUP_HOME_DIR" ; then
log::suc "Dotfiles linked."
else
log::err "Failed linking dotfiles! Backup is kept at: $backup_dir"
fi
cd "$DOTFILES_ROOT_DIR"
unset backup_dir
unset force_overwrite_list
fi
if $SETUP_PATCHES ; then
patches_dir="patches"
patches_script="patch"
if [ -d "$patches_dir" ]; then
cd $patches_dir
if [ -f "$patches_script" ]; then
source ./"$patches_script"
else
log::err "$patches_dir/$patches_script script is not present."
fi
else
log::err "$patches_dir/ directory is not present."
fi
unset patches_dir
unset patches_script
cd "$DOTFILES_ROOT_DIR"
fi
if $SETUP_SERVICES ; then
services_dir="systemd"
services_script="setup_services"
if [ -d "$services_dir" ]; then
cd $services_dir
if [ -f "$services_script" ]; then
source ./"$services_script"
else
log::err "$services_dir/$services_script script is not present."
fi
else
log::err "$services_dir/ directory is not present."
fi
unset services_dir
unset services_script
cd "$DOTFILES_ROOT_DIR"
fi
if $SETUP_PACKAGES ; then
process_list "${packages_requiring_linked_dotfiles[@]}"
for errored_entry in "${errored_entries[@]}"; do
log::err "Failed to install: $errored_entry"
done
fi
unset SETUP_USER
unset SETUP_HOME_DIR
log::suc "Done! Have a nice day."