-
Notifications
You must be signed in to change notification settings - Fork 4
/
link.sh
executable file
·132 lines (121 loc) · 2.99 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
#!/usr/bin/env bash
# This script interactively copies every source to its target, as defined in the link.conf file.
ARGS="hc:ynb"
CONFIGFILE="link.conf"
ALWAYSINSTALL=false
NEVERINSTALL=false
BACKUP=false
EXPLICIT_INSTALL=false
INSTALL_LIST=""
HELPMSG='This script interactively creates symlinks.
Usage:
-h: Show help
-c FILE: The configuration file to use. Defaults to link.conf
-y: Always install.
-n: Dry run. This never installs anything, just see what happens.
-b: Backup existing files before overwriting. Disabled by default.
If you want to install files by name, just pass them as trailing argument.
'
WHITE='\e[0m'
RED='\e[01;31m'
GREEN='\e[01;32m'
YELLOW='\e[01;33m'
BLUE='\e[01;34m'
# Exit on error
set -e
error() {
echo -e "$RED$*$WHITE" 1>&2
exit 1
}
# First get options passed from CLI
while getopts $ARGS OPT; do
case $OPT in
h)
printf "%s" "$HELPMSG"
exit 0
;;
c)
CONFIGFILE=$OPTARG
if ! [ -f "$CONFIGFILE" ]; then
error "$OPTARG is not a file"
fi
;;
y)
ALWAYSINSTALL=true
;;
n)
ALWAYSINSTALL=true
NEVERINSTALL=true
;;
b)
BACKUP=true
;;
:)
error "Error: -$OPT requires an argument"
;;
?)
error "Error: Unknown option -$OPT"
;;
esac
done
# trailing arguments
shift "$(( $OPTIND - 1 ))"
INSTALL_LIST="$(echo "$@" | sed 's/\s\+/\n/g')"
if ! [[ -z "$INSTALL_LIST" ]]; then
EXPLICIT_INSTALL=true
fi
# Now that we have finished parsing the CLI args, continue with stowing everything
# First load the config file
SOURCES=$(cut -d ' ' -f1 "$CONFIGFILE")
DESTS=$(cut -d ' ' -f2 "$CONFIGFILE")
for ((i = 1; i <= $(echo "$SOURCES"| wc -l); i++)); do
# extract source and destination
SOURCE=$(printf "%s" "$SOURCES"| sed $i"q;d")
DEST=$(printf "%s" "$DESTS"| sed $i"q;d")
# expand ~ and $HOME
DEST="${DEST/#\~/$HOME}"
DEST="${DEST/#'$HOME'/$HOME}"
# skip if not in explicit install list
if "$EXPLICIT_INSTALL"; then
FOUND=false
for expl in $INSTALL_LIST; do
if [[ "$expl" == "$SOURCE" ]]; then
FOUND=true
break
fi
done
if ! "$FOUND"; then
continue
fi
fi
echo -e "\nAttempting to install $BLUE$SOURCE$WHITE at $RED$DEST$WHITE"
if [ -e "$DEST" ]; then
echo -e "${YELLOW}WARNING$WHITE: $RED$DEST$WHITE already exists!"
if "$BACKUP"; then
BACKUPFILE="$DEST.backup"
echo -e "Creating backup of $RED$DEST$WHITE as $GREEN$BACKUPFILE$WHITE"
cp -r "$DEST" "$BACKUPFILE" || echo -e "${RED}ERROR$WHITE: Could not create backup"
fi
fi
answer="y"
if ! "$ALWAYSINSTALL"; then
echo -e "${GREEN}Install?$WHITE ((y)es, (N)o, go (b)ack) \c"
read -r answer
fi
if [ "$answer" == "b" ]; then
i=$((i - 2))
fi
if "$NEVERINSTALL"; then
answer="n"
fi
if [ "$answer" == "y" ]; then
if ! { [ -e "$DEST" ] || [ -h "$DEST" ]; }; then
mkdir -p "$DEST" || echo -e "${RED}ERROR$WHITE: No permission in this directory"
fi
rm -r "$DEST" || echo -e "${RED}ERROR$WHITE: No permission to delete this file"
# finally install
ln -s "$PWD/$SOURCE" "$DEST" || echo -e "${RED}ERROR$WHITE: Could not create symlink"
else
echo "Skipping..."
fi
done