-
Notifications
You must be signed in to change notification settings - Fork 3
/
install.sh
executable file
·426 lines (387 loc) · 14.8 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
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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
#!/usr/bin/env bash
################################################################################
# _ _ _ _ _ ____ ____ ____ _ __ _ _
# | | | | | | | | | _ \ / ___| | _ \ ___ | |_ / _(_) | ___ ___
# | | | | | | |_| | |_) | | | | | |/ _ \| __| |_| | |/ _ \/ __|
# | |_| | |___| _ | __/| |___ | |_| | (_) | |_| _| | | __/\__ \
# \___/|_____|_| |_|_| \____| |____/ \___/ \__|_| |_|_|\___||___/
#
################################################################################
# Installation script for ULHPC dotfiles within the homedir of the user running
# this script.
# Adapted from the install script set for [Falkor/dotfiles](https://github.com/Falkor/dotfiles)
#set -x # Debug
### Global variables
VERSION=0.1
COMMAND=$(basename "$0")
VERBOSE=""
DEBUG=""
SIMULATION=""
OFFLINE=""
MODE=""
FORCE=""
### displayed colors
COLOR_GREEN="\033[0;32m"
COLOR_RED="\033[0;31m"
COLOR_YELLOW="\033[0;33m"
COLOR_VIOLET="\033[0;35m"
COLOR_BACK="\033[0m"
### Local variables
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DOTFILES=~/.dotfiles
GIT_URL="https://github.com/ULHPC/dotfiles.git"
GIT_BRANCH="${TRAVIS_BRANCH:-master}"
# What to take care of (default is empty)
WITH_BASH=""
WITH_VIM=""
WITH_GIT=""
WITH_SCREEN=""
WITH_SSH=""
#######################
### print functions ###
#######################
######
# Print information in the following form: '[$2] $1' ($2=INFO if not submitted)
# usage: info text [title]
##
info() {
[ -z "$1" ] && print_error_and_exit "[${FUNCNAME[0]}] missing text argument"
local text=$1
local title=$2
# add default title if not submitted but don't print anything
[ -n "$text" ] && text="${title:==>} $text"
echo -e "${COLOR_GREEN}$text${COLOR_BACK}"
}
debug() { [ -n "$DEBUG" ] && info "$1" "[${COLOR_YELLOW}DEBUG${COLOR_BACK}]"; }
verbose() { [ -n "$VERBOSE" ] && info "$1"; }
error() { info "$1" "[${COLOR_RED}ERROR${COLOR_BACK}]"; }
warning() { info "$1" "[${COLOR_VIOLET}WARNING${COLOR_BACK}]"; }
print_error_and_exit() {
local text=$1
[ -z "$1" ] && text=" Bad format"
error "$text. '$COMMAND -h' for help."
exit 1
}
print_version() {
cat <<EOF
This is ULHPC/dotfiles/$COMMAND version "$VERSION".
Copyright (c) 2011-2016 Sebastien Varrette (sebastien.varrette@uni.lu)
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
}
print_help() {
less <<EOF
NAME
$COMMAND -- install (or remove) ULHPC dotfiles in the current user's homedir
SYNOPSIS
$COMMAND [-V | -h]
$COMMAND [--debug] [-v] [-n] [-d DIR] [--offline] [options]
$COMMAND --delete [-d DIR] [options]
OPTIONS
--debug
Debug mode. Causes $COMMAND to print debugging messages.
-h --help
Display a help screen and quit.
-n --dry-run
Simulation mode.
-v --verbose
Verbose mode.
-f --force
Force mode -- do not raise questions ;)
-V --version
Display the version number then quit.
-d --dir DIR
Set the dotfiles directory (Default: ~/.dotfiles)
--delete --remove --uninstall
Remove / Restore the installed components
--offline
Proceed in offline mode (assuming you have already cloned the repository)
--all -a
Install / delete ALL ULHPC dotfiles
--bash --with-bash
ULHPC Bourne-Again shell (Bash) configuration ~/.bashrc
--vim --with-vim
ULHPC VIM configuration ~/.vimrc
--git --with-git
ULHPC Git configuration ~/.gitconfig[.local]
--screen --with-screen
ULHPC GNU Screen configuration ~/.screenrc
--ssh --with-ssh
ULHPC ssh configuration ~/.ssh/config
EXAMPLES
To install/remove all available dotfiles:
$COMMAND [--delete] --all
To install ONLY the vim/git and screen dotfiles:
$COMMAND [--delete] --vim --git --screen
AUTHOR
UL HPC Management Team (hpc-sysadmins@uni.lu) aka.
S.Varrette, H. Cartiaux, V. Plugaru and S. Diehl at the time of writting
REPORTING BUGS
Please report bugs using the Issue Tracker of the project:
<https://github.com/ULHPC/dotfiles/issues>
COPYRIGHT
This is free software; see the source for copying conditions. There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
EOF
}
#########################
### toolbox functions ###
#########################
#####
# execute a local command
# usage: execute command
###
execute() {
[ $# -eq 0 ] && print_error_and_exit "[${FUNCNAME[0]}] missing command argument"
debug "[${FUNCNAME[0]}] $*"
[ -n "${SIMULATION}" ] && echo "(simulation) $*" || eval "$@"
local exit_status=$?
debug "[${FUNCNAME[0]}] exit status: $exit_status"
return $exit_status
}
####
# ask to continue. exit 1 if the answer is no
# usage: really_continue text
##
really_continue() {
echo -e -n "[${COLOR_VIOLET}WARNING${COLOR_BACK}] $1 Are you sure you want to continue? [Y|n] "
read ans
case $ans in
n*|N*) exit 1;;
esac
}
#####
# Check availability of binaries passed as arguments on the current system
# usage: check_bin prog1 prog2 ...
##
check_bin() {
[ $# -eq 0 ] && print_error_and_exit "[${FUNCNAME[0]}] missing argument"
for appl in "$@"; do
echo -n -e "=> checking availability of the command '$appl' on your system \t"
local tmp=$(which "${appl}")
[ -z "$tmp" ] && print_error_and_exit "Please install $appl or check \$PATH." || echo -e "[${COLOR_GREEN} OK ${COLOR_BACK}]"
done
}
####
# Add (or remove) a given link pointing to the corresponding dotfile.
# A backup of the file is performed if it previoiusly existed.
# Upon removal, the link is deleted only if it targets the expected dotfile
##
add_or_remove_link() {
[ $# -ne 2 ] && print_error_and_exit "[${FUNCNAME[0]}] missing argument(s). Format: ${FUNCNAME[0]} <src> <dst>"
local src=$1
local dst=$2
if [ "${MODE}" == "--delete" ]; then
debug "removing dst='${dst}' (if symlink pointing to src='${src}' =? $(readlink "${dst}"))"
if [[ -h "${dst}" && "$(readlink "${dst}")" == "${src}" ]]; then
warning "removing the symlink '${dst}'"
[ -n "${VERBOSE}" ] && really_continue
execute "rm '${dst}'"
if [ -f "${dst}.bak" ]; then
warning "restoring ${dst} from ${dst}.bak"
execute "mv ${dst}.bak ${dst}"
fi
fi
else
[ ! -e "${src}" ] && print_error_and_exit "Unable to find the dotfile '${src}'"
debug "attempt to add '$dst' symlink (pointing to '$src')"
# return if the symlink already exists
[[ -h "${dst}" && "$(readlink "${dst}")" == "${src}" ]] && return
if [ -e "${dst}" ]; then
warning "The file '${dst}' already exists and will be backuped (as ${dst}.bak)"
execute "mv ${dst}{,.bak}"
fi
execute "ln -sf ${src} ${dst}"
fi
}
add_or_remove_copy() {
[ $# -ne 2 ] && print_error_and_exit "[${FUNCNAME[0]}] missing argument(s). Format: ${FUNCNAME[0]} <src> <dst>"
local src=$1
local dst=$2
[ ! -f "${src}" ] && print_error_and_exit "Unable to find the dotfile '${src}'"
if [ "${MODE}" == "--delete" ]; then
debug "removing dst='${dst}'"
if [[ -f $dst ]]; then
warning "removing the file '$dst'"
[ -n "${VERBOSE}" ] && really_continue
execute "rm ${dst}"
if [ -f "${dst}.bak" ]; then
warning "restoring ${dst} from ${dst}.bak"
execute "mv ${dst}.bak ${dst}"
fi
fi
else
debug "copying '$dst' from '$src'"
check_bin shasum
# return if the symlink already exists
local checksum_src=$(shasum "${src}" | cut -d ' ' -f 1)
local checksum_dst=$(shasum "${dst}" | cut -d ' ' -f 1)
if [ "${checksum_src}" == "${checksum_dst}" ]; then
echo " - NOT copying '$dst' from '$src' since they are the same files"
return
fi
if [ -f "${dst}" ]; then
warning "The file '$dst' already exists and will be backuped (as ${dst}.bak)"
execute "cp ${dst}{,.bak}"
fi
execute "cp ${src} ${dst}"
fi
}
# courtesy of https://github.com/holman/dotfiles/blob/master/script/bootstrap
setup_gitconfig_local () {
local gitconfig_local=${1:-"$HOME/.gitconfig.local"}
local dotfile_gitconfig_local="${DOTFILES}/git/$(basename "${gitconfig_local}")"
if [ -f "${dotfile_gitconfig_local}" ]; then
add_or_remove_link "${dotfile_gitconfig_local}" "${gitconfig_local}"
return
fi
if [ ! -f "${gitconfig_local}" ]; then
info "setup Local / private gitconfig '${gitconfig_local}'"
[ -n "${SIMULATION}" ] && return
cat > "${gitconfig_local}" <<'EOF'
# -*- mode: gitconfig; -*-
################################################################################
# .gitconfig.local -- Private part of the GIT configuration
# . to hold username / credentials etc .
# NOT meant to be staged for commit under github
# _ _ __ _ _ _
# __ _(_) |_ ___ ___ _ __ / _(_) __ _ | | ___ ___ __ _| |
# / _` | | __/ __/ _ \| '_ \| |_| |/ _` | | |/ _ \ / __/ _` | |
# | (_| | | || (_| (_) | | | | _| | (_| |_| | (_) | (_| (_| | |
# (_)__, |_|\__\___\___/|_| |_|_| |_|\__, (_)_|\___/ \___\__,_|_|
# |___/ |___/
#
# See also: http://github.com/ULHPC/dotfiles
################################################################################
EOF
local git_credential='cache'
local git_authorname=
local git_email=
local passwd_field=
if [ "$(uname -s)" == "Darwin" ]; then
git_authorname=$(dscl . -read "/Users/$(whoami)" RealName | tail -n1)
git_credential='osxkeychain'
elif [ "$(uname -s)" == "Linux" ]; then
passwd_field=$(getent passwd "$(whoami)" | cut -d ':' -f 5 | cut -d ',' -f 1)
git_authorname="$(echo -n "${passwd_field}" | sed -e 's/\(.*\) <.*$/\1/g')"
git_email="$(echo -n "${passwd_field}" | sed -e 's/[^<]*<\(.*\)>/\1/g')"
fi
[ -n "${GIT_AUTHOR_NAME}" ] && git_authorname="${GIT_AUTHOR_NAME}"
[ -n "${GIT_AUTHOR_EMAIL}" ] && git_email="${GIT_AUTHOR_EMAIL}"
if [ -z "${git_authorname}" ]; then
echo -e -n "[${COLOR_VIOLET}WARNING${COLOR_BACK}] Enter you Git author name: "
read -e git_authorname
fi
if [ -z "${git_email}" ]; then
echo -e -n "[${COLOR_VIOLET}WARNING${COLOR_BACK}] Enter you Git author email: "
read -e git_email
fi
cat >> "${gitconfig_local}" <<EOF
[user]
name = $git_authorname
email = $git_email
helper = $git_credential
# signingkey = <gpg-key-id>
EOF
fi
}
################################################################################
################################################################################
# Let's go
ACTION="install"
# Check for options
while [ $# -ge 1 ]; do
case $1 in
-h | --help) print_help; exit 0;;
-V | --version) print_version; exit 0;;
--debug) DEBUG="--debug";
VERBOSE="--verbose";;
-v | --verbose) VERBOSE="--verbose";;
-f | --force) FORCE="--force";;
-n | --dry-run) SIMULATION="--dry-run";;
--offline) OFFLINE="--offline";;
--delete | --remove | --uninstall)
ACTION="uninstall"; OFFLINE="--offline"; MODE="--delete";;
-d | --dir | --dotfiles)
shift; DOTFILES=$1;;
--with-bash | --bash) WITH_BASH='--with-bash';;
--with-vim | --vim) WITH_VIM='--with-vim';;
--with-git | --git) WITH_GIT='--with-git';;
--with-screen| --screen) WITH_SCREEN='--with-screen';;
--with-ssh | --ssh) WITH_SSH='--with-ssh';;
-a | --all)
WITH_BASH='--with-bash';
WITH_VIM='--with-vim';
WITH_GIT='--with-git';
WITH_SCREEN='--with-screen';
WITH_SSH='--with-ssh';;
esac
shift
done
[ -z "${DOTFILES}" ] && print_error_and_exit "Wrong dotfiles directory (empty)"
echo "${DOTFILES}" | grep '^\/' > /dev/null
greprc=$?
if [ $greprc -ne 0 ]; then
warning "Assume dotfiles directory '${DOTFILES}' is relative to the home directory"
DOTFILES="$HOME/${DOTFILES}"
fi
info "About to ${ACTION} ULHPC dotfiles from ${DOTFILES}"
[ -z "${FORCE}" ] && really_continue
if [ "${SCRIPTDIR}" != "${DOTFILES}" ]; then
if [ -d "${SCRIPTDIR}/.git" ] && [ ! -e "${DOTFILES}" ]; then
# We are (hopefully) in a clone of the ULHPC dotfile repository.
# Make $DOTFILES be a symlink to this clone.
info "make '${DOTFILES}' a symlink to ${SCRIPTDIR}"
execute "ln -s ${SCRIPTDIR} ${DOTFILES}"
fi
fi
# OR clone it there
[[ ! -d "${DOTFILES}" ]] && execute "git clone -b ${GIT_BRANCH} ${GIT_URL} ${DOTFILES}"
# Update the repository if already present
[[ -z "${OFFLINE}" && -d "${DOTFILES}" ]] && execute "( cd ${DOTFILES} ; git pull ; git submodule init ; git submodule update )"
cd ~
if [ -z "${WITH_BASH}${WITH_VIM}${WITH_GIT}${WITH_SCREEN}${WITH_SSH}" ]; then
warning " "
warning "By default, this installer does nothing except updating ${DOTFILES}."
warning "Use '$0 --all' to install all available configs. OR use a discrete set of options."
warning "Ex: '$0 $MODE --with'"
warning " "
exit 0
fi
## Bash
if [ -n "${WITH_BASH}" ]; then
info "${ACTION} ULHPC Bourne-Again shell (Bash) configuration ~/.bashrc ~/.inputrc ~/.bash_profile ~/.profile ~/.bash_logout"
add_or_remove_link "${DOTFILES}/bash/.bashrc" ~/.bashrc
add_or_remove_link "${DOTFILES}/bash/.inputrc" ~/.inputrc
add_or_remove_link "${DOTFILES}/bash/.bash_profile" ~/.bash_profile
add_or_remove_link "${DOTFILES}/bash/.profile" ~/.profile
add_or_remove_link "${DOTFILES}/bash/.bash_logout" ~/.bash_logout
fi
## VI iMproved ([m]Vim)
if [ -n "${WITH_VIM}" ]; then
info "${ACTION} ULHPC VIM configuration ~/.vimrc"
add_or_remove_link "${DOTFILES}/vim/.vimrc" ~/.vimrc
fi
## Git
if [ -n "${WITH_GIT}" ]; then
info "${ACTION} ULHPC Git configuration ~/.gitconfig[.local]"
add_or_remove_link "${DOTFILES}/git/.gitconfig" ~/.gitconfig
if [ "${MODE}" != "--delete" ]; then
setup_gitconfig_local ~/.gitconfig.local
else
add_or_remove_copy ' ' ~/.gitconfig.local
fi
fi
## GNU Screen
if [ -n "${WITH_SCREEN}" ]; then
info "${ACTION} ULHPC GNU Screen configuration ~/.screenrc"
add_or_remove_link "${DOTFILES}/screen/.screenrc" ~/.screenrc
fi
## SSH
if [ -n "${WITH_SSH}" ]; then
info "${ACTION} ULHPC SSH configuration ~/.ssh/config"
mkdir -p ~/.ssh
add_or_remove_link "${DOTFILES}/ssh/config" ~/.ssh/config
fi