-
Notifications
You must be signed in to change notification settings - Fork 3
/
install.zsh
executable file
·161 lines (132 loc) · 5.46 KB
/
install.zsh
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
#!/usr/bin/env zsh
# Simple indempotent instllation.
#
# First, replace all rc files with a template file and over write it. Do this
# instead of trying to add a source file line to the default rc file. The
# default file is a sandwich, machine specific before rc, dotfiles rc, machine
# specific after rc. The before and after are in dotfiles/rc/before and
# dotfiles/rc/after. You simply touch them if they do not already exist. Let's
# start with just after, since you can undo most things in rc files.
#
# When installing these sandwiches, check to see if the existing file is already
# a sandwich, if not, move it to an outgoing home directly. Let the user know
# that a file was to be overwitten so we moved it out of the way.
function abend {
printf "fatal: %s\n" "$1" 2>&1 && exit 1
}
git_version=$(git --version 2>/dev/null)
if [ $? -ne 0 ]; then
abend "git is not installed"
fi
git_version="${git_version#git version }"
if ! { [[ "$git_version" == 2.* ]] || [[ "$git_version" == 1.[8-9].* ]] || [[ "$git_version" == 1.7.1[0-9].* ]]; }; then
abend "git is at version $git_version but must be at least 1.7.10"
fi
if [[ $(basename $SHELL) != "zsh" ]]; then
# TODO Convert to `zsh -c "$(curl https://zsh.prettybots.com)"`
# With this you can know that zsh is installed and the zsh that the user
# wants to use. You can change shell with...
case "$(sudo -n echo 1 2>&1)" in
1 )
printf 'Changing your shell to Zsh.'
;;
*assword* )
printf 'We are going to use `sudo chsh` to change your shell, but we need your password to do so.\n'
;;
* )
abend 'You can only use these dotfiles with Zsh. Please change your shell.'
;;
esac
if [[ "$1" = "sudo" ]]; then
sudo chsh -s $(which zsh) $USER
else
if [[ "$OSTYPE" = "linux-gnu" ]]; then
abend "you need to: sudo usermod --shell $(which zsh) $USER"
else
abend "you need to: sudo chsh -s $(which zsh) $USER"
fi
fi
fi
# Configure SSH for GitHub.
umask 077
mkdir -p ~/.ssh
if [[ ! -e ~/.ssh/known_hosts ]]; then
touch ~/.ssh/known_hosts
fi
# If we have a key for `github.com` already, do nothing.
if [[ $(ssh-keygen -F github.com | wc -c) -eq 0 ]]; then
# Get the public key from the `github.com` server.
key=$(ssh-keyscan -t ed25519 github.com 2> /dev/null | cut -f3 -d' ')
# Create a comma delimited list of host ip addresses and the domain.
hosts=$(echo $(dig -t a +short github.com | tr '\n' ',')github.com)
# Write the known host entry with the host list and domain to a temporary
# file so we can use `ssh-keygen -f` to check the fingerprint.
tmp=$(mktemp -d)
trap "rm -rf $tmp" EXIT
echo "$hosts ssh-ed25519 $key" >> "$tmp/known_hosts"
# Get that fingerprint.
fp=$(ssh-keygen -t ed25519 -q -l -f "$tmp/known_hosts" -F github.com | cut -f3 -d' ')
# https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
if [[ $fp = "SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU" ]]; then
# If the fingerprint is good, write the same line to our known hosts file.
echo "$hosts ssh-ed25519 $key" >> ~/.ssh/known_hosts
else
# If the fingerprint is bad, panic.
echo 'Bad GitHub SSH fingerprint!' 1>&2
cat "$tmp/known_hosts" 1>&2
exit 1
fi
fi
umask 022
if [[ ! -e "$HOME/.vim/autoload/plug.vim" ]]; then
curl -sfLo "$HOME/.vim/autoload/plug.vim" --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
fi
if [[ ! -e "$HOME/.dotfiles" ]]; then
git clone --recursive [email protected]:flatheadmill/dotfiles.git "$HOME/.dotfiles"
fi
stamp=$(date +'%F-%T' | sed 's/:/-/g')
# todo: Wouldn't it be nice for this to sweep up anything that gets appended
# by an install into the `rc` file? Probably just need to take the results of
# a diff and append that. Makes this not quite indempotent, but useful.
function create_rc {
local home_file=$1 skel_file=$2
local home_path="$HOME/$home_file"
local skel_path="$HOME/.dotfiles/skel/$skel_file"
if [[ -e $home_path ]] && ! diff "$home_path" "$skel_path" > /dev/null; then
mkdir -p "$HOME/.dotfiles/replaced/$stamp"
mv "$home_path" "$HOME/.dotfiles/replaced/$stamp/$skel_file"
fi
cp "$skel_path" "$home_path"
local local_path="$HOME/.dotfiles/rc/$skel_file"
if [ ! -e "$local_path" ]; then
mkdir -p "$HOME/.dotfiles/rc"
touch "$local_path"
fi
}
create_rc .zshenv zshenv.zsh
create_rc .zprofile zprofile.zsh
create_rc .zshrc zshrc.zsh
create_rc .tmux.conf tmux.conf
create_rc .gitconfig gitconfig
create_rc .vimrc vimrc
mkdir -p ~/.dotfiles/vendor
if [[ ! -e ~/.dotfiles/vendor/minimal.zsh ]]; then
curl -sL https://raw.githubusercontent.com/subnixr/minimal/master/minimal.zsh > ~/.dotfiles/vendor/minimal.zsh
fi
if [[ ! -d ~/.tmux/plugins/tpm ]]; then
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
fi
mkdir -p ~/.usr/bin ~/.usr/tmp
touch ~/.usr/tmp/tmux.run.log
if [[ -e "$HOME/.dotfiles/replaced/$stamp/$skel_file" ]]; then
cat <<' EOF' | sed 's/^ //'
Existing configuration files where replaced. The replaced files have been
moved to:
~/.dotfiles/replaced/$stamp
Fish out anything you want to keep and move it to the file with the same name in
the directory:
~/.dotfiles/rc
This is where your machine specific settings should be kept.
EOF
fi