-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsymlink.sh
executable file
·180 lines (158 loc) · 5.34 KB
/
symlink.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
#! /bin/bash
# layout variables
RED="\033[0;31m"
GREEN="\033[0;32m"
YELLOW="\033[0;33m"
BLUE="\033[0;34m"
MAGENTA="\033[0;35m"
CYAN="\033[0;36m"
GREY="\033[0;37m"
COLORRESET="\033[0m"
SPACER=" "
###############################################################################################
function dryrun () {
if [ "$DRY_RUN" ]; then
echo -e "$YELLOW $*"
return 0
fi
eval "$@"
}
###############################################################################################
function absolute_path()
{
# remove trailing slash
path=$( echo "$1" | sed -e "s/\/*$//" )
# make absolute
[ "${path/#\//}" != "$path" ] || path="$PWD/$path"
# return
echo $path
}
###############################################################################################
function symlink()
{
if [ ! -z "$1" ]; then
prefix=$1
else
prefix=$PWD
fi
if [ $(find $prefix -maxdepth 1 -name '*.symlink' -or -name '*.symlink.private' | wc -l) != 0 ]; then
echo -e "$GREEN-$COLORRESET found some .symlink files in $prefix, start symlinking"
else
echo -e "$RED-$COLORRESET found no .symlink files in $prefix, nothing to symlink"
return 0
fi
backupall=false
deleteall=false
skipall=false
backupdir=$prefix/backup
for file in $(find $prefix -maxdepth 1 -name '*.symlink' -or -name '*.symlink.private'); do
# target is the planned home directory link
# purefile name is needed in case we work with a prefix
target_base="`basename ${file%.symlink}`"
purefilename="`basename ${file%.symlink}`"
if [[ "$target_base" == *.dotfile* ]]; then
target_base=".${target_base%.dotfile*}"
purefilename=${purefilename%.dotfile*}
fi
target="$HOME/$target_base"
# if the target is already linked to our .dotfiles directory skip it
if [ "`readlink $target`" == "$file" ]; then
continue
fi
# we have an existing .dotfile
if [ -e "$target" ]; then
# go down the fast lane if the user has already wished to do something
# to all files
if $backupall ; then
echo -e "$SPACER$YELLOW-$COLORRESET moving $target to backup"
dryrun mkdir -p $backupdir
dryrun mv $target $backupdir/
echo -e "$SPACER$GREEN+$COLORRESET $file $RED->$COLORRESET $target"
dryrun ln -s $file $target
elif $deleteall ; then
echo -e "$SPACER$RED-$COLORRESET deleting existing $target"
dryrun rm -r $target
echo -e "$SPACER$GREEN+$COLORRESET $file $RED->$COLORRESET $target"
dryrun ln -s $file $target
elif $skipall ; then
echo -e "$SPACER$YELLOW-$COLORRESET skipping ${file%.*}"
else
# no general decision saved, let's ask
# lower case: decision for the current file
# upper case: decision for the current and all following file conflicts
echo "$target exists. What to do? (b)ackup, (d)elete, (s)kip. Or for this and further existing files (B)ackup, (S)kip, (D)elete"
read filedecision
case $filedecision in
b)
echo -e "$SPACER$YELLOW-$COLORRESET moving $target to $backupdir/.$purefilename"
dryrun mkdir -p $backupdir
dryrun mv $target $backupdir/
echo -e "$SPACER$GREEN+$COLORRESET $file $RED->$COLORRESET $target"
dryrun ln -s $file $target
;;
B)
echo backup all
backupall=true
echo -e "$SPACER$YELLOW-$COLORRESET moving $target to .dotfiles/backup/.$purefilename"
dryrun mkdir -p $backupdir
dryrun mv $target $backupdir/
echo -e "$SPACER$GREEN+$COLORRESET $file $RED->$COLORRESET $target"
dryrun ln -s $file $target
;;
d)
echo -e "$SPACER$RED-$COLORRESET $target"
dryrun rm -r $target
echo -e "$SPACER$GREEN+$COLORRESET $file $RED->$COLORRESET $target"
dryrun ln -s $file $target
;;
D)
echo deleting all
deleteall=true
echo -e "$SPACER$RED-$COLORRESET $target"
dryrun rm -r $target
echo -e "$SPACER$GREEN+$COLORRESET $file $RED->$COLORRESET $target"
dryrun ln -s $file $target
;;
s)
echo -e "$SPACER$YELLOW-$COLORRESET skipping ${file%.*}"
continue
;;
S)
echo skipping all
skipall=true
echo -e "$SPACER$YELLOW-$COLORRESET skipping ${file%.*}"
continue
;;
*)
echo -e "$RED-$COLORRESET wrong input, skipping"
continue
;;
esac
fi
# no existing .dotfile in ~, link found file
else
echo -e "$SPACER$GREEN+$COLORRESET $file $RED->$COLORRESET $target"
dryrun ln -s $file $target
fi
done
return 0
}
###############################################################################################
function recursive_symlink()
{
current_dir=$1
symlink $current_dir
# recurse
current_dir_base=`basename $current_dir`
for dir in $(find $current_dir -maxdepth 1 -type d -not -name $(basename $current_dir) -not -name .git); do
recursive_symlink $dir
done
}
###############################################################################################
# main execution
if [ ! -z "$1" ]; then
prefix=$(absolute_path $1)
else
prefix=$PWD
fi
recursive_symlink $prefix