-
Notifications
You must be signed in to change notification settings - Fork 2
/
setup
executable file
·121 lines (107 loc) · 3.92 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
#!/usr/bin/env zsh
# This script sets up XDG directories and symlinks certain dotfiles to HOME.
setopt NULL_GLOB
here=${0:A:h}
source $here/env
source $here/provision.d/messaging_helpers
# Create data and cache dirs (some programs are not smart enough to create
# directories themselves, and nonexistent directories are silently ignored).
print_progress "Creating program-specific data and cache directories..."
data_dirs=(aspell bash fasd ipython iterm2 less mail node pry pylint wget zsh)
cache_dirs=(cron fontconfig gem grip matplotlib npm)
for dir in $data_dirs; do
[[ -d $XDG_DATA_HOME/$dir ]] && continue
mkdir -p $XDG_DATA_HOME/$dir
print "Created '$XDG_DATA_HOME/$dir'" >&2
done
for dir in $cache_dirs; do
[[ -d $XDG_CACHE_HOME/$dir ]] && continue
mkdir -p $XDG_CACHE_HOME/$dir
print "Created '$XDG_CACHE_HOME/$dir'" >&2
done
# Change mode of all directories in $XDG_CONFIG_HOME, $XDG_DATA_HOME, and
# $XDG_CACHE_HOME to 700.
print_progress "Changing program-specific directory modes to 700..."
chmod 700 $XDG_CONFIG_HOME $XDG_DATA_HOME $XDG_CACHE_HOME
for dir in $XDG_CONFIG_HOME/*/ $XDG_DATA_HOME/*/ $XDG_CACHE_HOME/*/; do
chmod 700 $dir
done
# Symlink uncustomizable XDG offenders to $HOME.
typeset -A destination
set -A destination \
bash/bash_profile .bash_profile \
bash/bashrc .bashrc \
emacs .emacs.d \
ghc/ghci.conf .ghc/ghci.conf \
gnupg/gpg.conf .gnupg/gpg.conf \
mutt/muttrc .muttrc \
parallel .parallel \
pyenv/version .pyenv/version \
pypi/pypirc .pypirc \
tmux/tmux.conf .tmux.conf \
zsh/zshenv .zshenv \
zsh/zprofile .zprofile \
zsh/zshrc .zshrc \
zsh/zlogin .zlogin \
zsh/zlogout .zlogout \
zsh/prezto .zprezto
# virtualenvwrapper hooks
if [[ -n $VIRTUALENVWRAPPER_HOOK_DIR ]]; then
# virtualenvwrapper hook directory relative to HOME
venvhookdir=${VIRTUALENVWRAPPER_HOOK_DIR#$HOME/}
elif [[ -n $WORKON_HOME ]]; then
venvhookdir=${WORKON_HOME#$HOME/}
else
venvhookdir=.virtualenvs
fi
destination[pyenv/virtualenvwrapper_hooks]=$venvhookdir
# items that may be linked but are not part of this repo are marked as optional
typeset -A optional
set -A optional \
pyenv/version 1 \
pypi/pypirc 1
# This function symlinks source to destination (so that the destination is
# eventually a symlink pointing to source), backing up destination if it
# already exists.
#
# It takes two positional arguments, src and dst, and performs the following:
#
# * If src does not exist, report error and do nothing;
# * If dst already exists:
# * If dst is a (non-symlink) directory, report error and do nothing;
# * Append .bak to the existing dst if it is not a symlink, and remove it otherwise;
# * Symlink src to dst.
#
# Note that src should either be an absolute path or relative to dst. Absolute
# path is recommended.
backup_and_symlink () {
src=$1
dst=$2
[[ -e $src ]] || { print_error "'$src' does not exist"; return 1; }
[[ -d $dst && ! -h $dst ]] && { print_error "Not overwriting destination directory '$dst'"; return 1; }
[[ -e $dst && ! -h $dst ]] && { mv $dst $dst.bak; print_warning "'$dst' backed up to '$dst.bak'"; }
[[ -h $dst ]] && rm $dst
print "$src <== $dst" >&2
mkdir -p "$(dirname $dst)"
ln -s $src $dst
}
print_progress "Symlinking dotfiles and dot directories..."
success_count=0
failure_count=0
skipped_count=0
for src in ${(ko)destination}; do
# skip if src is optional and does not exist
if (( optional[$src] )) && [[ ! -e $XDG_CONFIG_HOME/$src ]]; then
((skipped_count++))
print_warning "'$XDG_CONFIG_HOME/$src' not present; skipped"
continue
fi
dst=$destination[$src]
if backup_and_symlink $XDG_CONFIG_HOME/$src $HOME/$dst; then
((success_count++))
else
((failure_count++))
fi
done
print_progress "Successfully linked ${success_count} items, failed on ${failure_count} items, skipped ${skipped_count} optional items"
exit $((failure_count > 0))