-
Notifications
You must be signed in to change notification settings - Fork 6
/
setup
executable file
·151 lines (132 loc) · 4.68 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
#!/bin/bash
function help() {
echo "======================================================================="
echo ".dotfiles/bin/setup"
echo " by Todd Gamblin, [email protected]"
echo "======================================================================="
echo "This script links and unlinks dotfiles into your home directory."
echo
echo "The .dotfiles repository is laid out like this:"
echo
echo " .dotfiles/"
echo " bin/"
echo " help"
echo " home/"
echo " ... actual dotfiles ..."
echo " link"
echo " unlink"
echo
echo "help, link, and unlink are symbolic links to the setup script, which"
echo "does three things, depending on which symlink you call it with."
echo "They are as follows:"
echo
echo "link"
echo " If you call this command as 'link', it will create symlnks in"
echo " your home directory to all of the files in .dotfiles/home."
echo " This can be used to bootstrap a home directory on a new machine,"
echo " e.g.:"
echo
echo " git clone [email protected]:tgamblin/dotfiles.git .dotfiles"
echo " .dotfiles/link"
echo
echo " If there are files in the way, the script will create a directory"
echo " called ~/.dotfiles-backup, where it moves the original versions"
echo " of your files."
echo
echo " 'link' is idempotent if called twice in a row."
echo
echo "unlink"
echo " Unlink removes symbolic links created by this script and restores"
echo " any files in ~/.dotfiles-backup to their original locations."
echo " If you call it without having created symlinks into the .dotfiles"
echo " repo, it will do nothing (so as not to damage your home directory)."
echo
echo "help"
echo " Calling this script as '.dotfiles/help' will print this message."
echo
}
#
# Prints an error message and dies.
#
function error() {
echo "ERROR: $1"
exit 1
}
#
# Get readlink -f behavior when readlink doesn't support it
#
function readlink_f {
_target_file=$1
cd `dirname $_target_file`
_target_file=`basename $_target_file`
# Iterate down a (possible) chain of symlinks
while [ -L "$_target_file" ]; do
_target_file=`readlink $_target_file`
cd `dirname $_target_file`
_target_file=`basename $_target_file`
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
_phys_dir=`pwd -P`
_result=$_phys_dir/$_target_file
echo $_result
}
# Directory to link files into
link_dest=$HOME
# Ensure that the script, as called, is a symlink
[[ -L "$0" ]] || error "Something isn't right: $0 is not a link."
# Location of the repository the link script lives in
repository=$(dirname $(dirname $(readlink_f "$0")))
# The directory in the repository where files to be linked
# into the home directory live.
repo_home="$repository/home"
# Default name of directory to store backups in
backup_dir=$link_dest/.dotfiles-backup
# Ensure that the repository home exists.
[[ -d "$repo_home" ]] || error "Couldn't find $repo_home!"
# Check whether we can write to the link destination.
[[ -w "$link_dest" ]] || error "$link_dest is not writable!"
# If the repo is inside link destination, use a relative path.
rel_repo=\
$(echo $repo_home | perl -pe "\$s=quotemeta(\"${link_dest}/\"); s/\$s//;")
# Command is the symlink through which we ran this script.
cmd=$(basename $0)
[[ -n "$cmd" ]] || cmd="help"
case $cmd in
link | unlink)
echo "${cmd}ing dotfiles"
echo " from: $repo_home"
echo " into: $link_dest"
for file in $(\ls -A $repo_home); do
dest="$link_dest/$file"
src="$rel_repo/$file"
if [ "$cmd" = "link" ]; then
# If the file already exists, move it.
if [ -e "$dest" -a \( "$(readlink $dest)" != "$src" \) ]; then
[[ -d "$backup_dir" ]] || mkdir "$backup_dir"
mv "$dest" "$backup_dir/$file"
fi
# Link the file into the destination location, if the link
# isn't already there.
if [ ! -e "$dest" ]; then
ln -s "$src" "$dest"
fi
else
# Remove our symlink if it exists, then restore backup
if [ -L "$dest" -a \( "$(readlink $dest)" = "$src" \) ]; then
if [ -e "$backup_dir/$file" ]; then
# Restrore the backup if it exists
rm "$dest"
mv "$backup_dir/$file" "$dest"
else
# Just remove the link if not
rm "$dest"
fi
fi
fi
done
;;
*)
help
;;
esac