-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlink.sh
executable file
·189 lines (162 loc) · 5.04 KB
/
link.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
#!/usr/bin/env bash
# ==============================================================================
function usage() { cat <<- DOCUMENT
Usage: $PROGNAME [-h] [-t] [-c link.conf]
AUTHOR: Sang Han
CREATED: 01/09/2014
REVISION: 1.4
DESCRIPTION:
Program for automating users preferred login shell enviornment.
Symbolically links the startup files located within dotfiles
repository and links them to to users \$HOME variable prepended
with a dot. If the startup file already and a collision occurs,
user will be prompted for deletion.
HOME DIRECTORY: $HOME
REQUIREMENTS:
- .conf (Config File)
OPTIONS:
-h [help]
Outputs usage directions
-t [test]
A dry run, does not actually make changes to the filesystem
-v [verbose]
Prints out all test output to screen
-c [config]
Reference external configuration file as metadata
-f [force]
Always replace files: Warning this is dangerous
EXAMPLES:
Run unit tests and prints out all assigned values and variables
./${PROGNAME} -t
Run program:
./$PROGNAME
Use your own config file:
./$PROGNAME -c config_file
DOCUMENT
}
# ==============================================================================
# Global Variables
# ==============================================================================
readonly PROGNAME=$(basename "${BASH_SOURCE}")
readonly PROGDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ==============================================================================
# Tests
# ==============================================================================
function test_variables() {
declare -a variables=(${*})
for var in "${variables[@]}"; do
printf "%30s = %s\n" \
"$(tput setaf 9)\$${var}$(tput sgr0)" \
"$(tput setaf 3)${!var}$(tput sgr0)"
done
}
function test_source() {
if [ -f "$LINK_SOURCE" ]; then
printf "$(tput setaf 4)\
\$LINK_SOURCE\
$(tput sgr0)\
file exists at %s\n" \
"${LINK_SOURCE}"
else
printf "$(tput setaf 1)\
\$LINK_SOURCE\
$(tput sgr0)\
file does not exists at %s\n" \
"${LINK_SOURCE}"
fi
}
function test_dest() {
if [ -f "$LINK_DEST" ]; then
printf "$(tput setaf 4)\
\$LINK_DEST\
$(tput sgr0)\
file exists at %s\n\n" \
"${LINK_DEST}"
else
printf "$(tput setaf 1)\
\$LINK_DEST\
$(tput sgr0)\
file does not exists at %s\n\n" \
"${LINK_DEST}"
fi
}
function prompt_delete() {
if ((FORCE==1)); then
rm -rf "${LINK_DEST}" 2>/dev/null
link_files
return
fi
read -p "File $LINK_DEST already exists, would you like to delete it? \
[Yy]/[Nn]: " RESPONSE
if [[ $RESPONSE =~ [Yy] ]]; then
rm "${LINK_DEST}" && link_files
else
return
fi
}
# ===========================================================================
# Link Files
# ===========================================================================
function link_files() {
ln -s "${LINK_SOURCE}" "${LINK_DEST}"
}
# ===============================================================================
# Parameters
# ===============================================================================
declare -i TEST=0 VERBOSE=0 FORCE=0
declare -a FILELIST
while getopts "c:htvf" OPTION; do
case ${OPTION} in
h) usage
exit 0
;;
t) TEST=1
;;
c) CONFIG_FILE="${OPTARG}"
;;
v) VERBOSE=1
;;
f) FORCE=1
;;
\?) echo "Invalid option: -${OPTARG}" >&2
exit 1
;;
esac
done
shift $(($OPTIND-1))
# ===============================================================================
# Main
# ===============================================================================
function main() {
# Grab Config File
FILELIST=( $(cat "${CONFIG_FILE:-"${PROGDIR}/link.conf"}") )
if ((TEST==1 || VERBOSE==1)); then
test_variables TEST PROGNAME PROGDIR FILELIST CONFIG_FILE FORCE
printf "\n"
fi
# Parent directory name is stripped
for FILE in "${FILELIST[@]}"; do
{
local LINK_SOURCE="${PROGDIR}/${FILE}"
local LINK_DEST="${HOME}/.${FILE##*/}"
test -d "${LINK_SOURCE}" && LINK_SOURCE="${LINK_SOURCE}"'/'
if [ -e ${LINK_SOURCE} ]; then
{
# print out source and destination only
if ((TEST==1)); then
test_source && test_dest
continue
fi
if ((VERBOSE==1)); then
test_source && test_dest
fi
# Magic
link_files >/dev/null 2>&1 || prompt_delete
}
fi
}
done
}
if [ "$0" = "${BASH_SOURCE}" ]; then
main
fi