-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathinstall
More file actions
executable file
·263 lines (232 loc) · 9.13 KB
/
Copy pathinstall
File metadata and controls
executable file
·263 lines (232 loc) · 9.13 KB
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#!/bin/bash
# Given this is running inside a bash script, some of the errors are swallowed, so
# settings -e here might make it harder to debug stuff when errors happen. Given how
# the code is written, modular, it's totally fine if a piece of it fails. No reason to
# halt the entire process.
#
# set -e
# This is for making it possible to use stdin for user input during the installation.
exec < /dev/tty
# git/gitconfig signs every commit and tag with ~/.ssh/id_rsa (commit.gpgsign
# and gpg.format = ssh), and update_dotfiles below symlinks it to ~/.gitconfig.
# Without this key, the first `git commit` on a fresh machine dies with
# "Couldn't load public key". GitHub auth is `gh auth login`'s job now; this
# key exists purely for signing, which is why it runs on every platform.
if [ ! -f ~/.ssh/id_rsa.pub ]; then
echo "No signing key found. Generating ~/.ssh/id_rsa (no passphrase)... "
mkdir -p ~/.ssh && chmod 700 ~/.ssh
ssh-keygen -t rsa -b 4096 -C "" -f ~/.ssh/id_rsa -N "" -q
echo "done."
fi
# MacOS?
if [[ "$OSTYPE" == "darwin"* ]]; then
if [ ! -f ~/.bash_profile ]; then
echo "Creating ~/.bash_profile"
touch ~/.bash_profile
fi
# Install Homebrew early so it's guaranteed to be present, independent of
# whether the git clone below succeeds. installation/macos guards against
# reinstalling, so this is safe to run here too.
if ! command -v brew >/dev/null 2>&1; then
echo "Homebrew not found. Installing... "
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if [ -x /opt/homebrew/bin/brew ]; then
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.bash_profile
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [ -x /usr/local/bin/brew ]; then
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.bash_profile
eval "$(/usr/local/bin/brew shellenv)"
fi
fi
# GitHub auth through the CLI. `gh auth login` opens a browser and stores a
# token, which the credential helper in git/gitconfig then uses for HTTPS
# pushes. That replaces pasting an SSH public key into a web form by hand.
#
# Note there's no `gh auth setup-git` here: it writes the helper into
# ~/.gitconfig, which update_dotfiles symlinks to the tracked git/gitconfig,
# using an absolute /opt/homebrew/bin/gh path. git/gitconfig carries a
# portable version of those same blocks instead.
#
# The brew guard matters: if the Homebrew install above failed, `brew` isn't
# on PATH and this would print a bare "command not found".
if ! command -v gh >/dev/null 2>&1 && command -v brew >/dev/null 2>&1; then
echo "GitHub CLI not found. Installing... "
brew install gh
fi
if command -v gh >/dev/null 2>&1 && ! gh auth status >/dev/null 2>&1; then
echo ""
echo "Not logged into GitHub yet. Running 'gh auth login'... "
if ! gh auth login; then
echo "> gh auth login was cancelled or failed; HTTPS pushes won't authenticate." >&2
fi
fi
fi
if [ -d ~/.dotfiles ]
then
LAST_DIR=$(pwd)
echo "Directory ~/.dotfiles found, make sure git status is clean."
echo "git pulling from master"
cd ~/.dotfiles
git pull --rebase origin master
cd $LAST_DIR
else
# HTTPS, not SSH: `gh auth login` above installs a git credential helper,
# so HTTPS clones and pushes authenticate without an SSH key. It also works
# unauthenticated for this public repo, which keeps a fresh machine moving
# even if the GitHub login was skipped.
echo "Cloning kurko/dotfiles into ~/.dotfiles"
git clone https://github.com/kurko/dotfiles.git ~/.dotfiles
fi
echo ""
echo "sourcing ~/.dotfiles/bashrc_source... "
source ~/.dotfiles/bashrc_source
echo ""
echo "Updating aliases, links and scripts... "
update_dotfiles
# MacOS?
if [[ "$OSTYPE" == "darwin"* ]]; then
echo ""
echo "Installing MacOS software... "
source $DOTFILES/installation/macos
install_macos
elif [[ "$OSTYPE" == "linux-gnu" ]]; then
echo ""
echo "Installing Linux GNU software... "
source $DOTFILES/installation/linux_gnu
install_linux_gnu_packages
fi
source $DOTFILES/installation/os_agnostic_packages
install_os_agnostic_packages
# Vim and Neovim each look for plug.vim in their own autoload directory, so
# both need their own copy. The plugins themselves are shared: vimrc points
# plug#begin at ~/.vim/plugins for both editors.
install_vim_plug() {
local editor="$1"
local destination="$2"
if [ -f "$destination" ]
then
echo "$editor plugin manager: done. "
return
fi
echo ""
printf "%s plugin manager: " "$editor"
if curl -fLo "$destination" --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
then
echo "done. "
else
echo "> $editor plugin manager: download failed." >&2
fi
}
install_vim_plug "Vim" ~/.vim/autoload/plug.vim
install_vim_plug "Neovim" ~/.local/share/nvim/site/autoload/plug.vim
if command -v vim >/dev/null 2>&1
then
vim +'PlugInstall --sync' +qa
else
echo "> vim: not installed, skipping Vim plugin install." >&2
fi
if command -v nvim >/dev/null 2>&1
then
nvim --headless +'PlugInstall --sync' +qa
else
echo "> nvim: not installed, skipping Neovim plugin install." >&2
fi
if [ ! -d ~/.tmux/plugins/tpm ]
then
echo ""
echo "Install Tmux Plugin Manager on ~/.tmux/plugins/tpm... "
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
~/.tmux/plugins/tpm/bin/install_plugins
fi
# ----------------------------------------------------------------------------
# Post-install checklist: the manual, one-off steps this script can't do for
# you (needs a GitHub login, App Store sign-in, a shell change, etc.). Each
# item is conditional, so it only shows up while it's still pending.
# ----------------------------------------------------------------------------
print_post_install_checklist() {
local n=0
echo ""
echo "========================================================"
echo " POST-INSTALL CHECKLIST — a few things still need you"
echo "========================================================"
# Not logged into GitHub yet?
if ! command -v gh >/dev/null 2>&1; then
n=$((n + 1))
echo ""
echo "${n}. Install the GitHub CLI, then log in:"
echo " https://github.com/cli/cli#installation"
echo " gh auth login"
elif ! gh auth status >/dev/null 2>&1; then
n=$((n + 1))
echo ""
echo "${n}. Log into GitHub (needed to push, and to clone private repos):"
echo " gh auth login"
fi
# Rectangle Pro is paid: brew installs the app but can't enter the license.
# The preferences plist only appears after the first launch, so its absence
# means the app has never been opened and set up.
if [ -d "/Applications/Rectangle Pro.app" ] &&
[ ! -f ~/Library/Preferences/com.knollsoft.Hookshot.plist ]; then
n=$((n + 1))
echo ""
echo "${n}. Open Rectangle Pro and enter your license:"
echo " open -a 'Rectangle Pro'"
echo " https://rectangleapp.com/pro"
fi
# Login shell not bash?
case "$SHELL" in
*/bash) ;;
*)
n=$((n + 1))
echo ""
echo "${n}. Switch your login shell to bash (these dotfiles are bash-based):"
echo " chsh -s /bin/bash"
;;
esac
# Mac App Store apps (need you signed into the App Store).
if [[ "$OSTYPE" == "darwin"* ]]; then
mas_ids=""
[ -d "/Applications/Things3.app" ] || mas_ids="${mas_ids} 904280696"
[ -d "/Applications/Timery.app" ] || mas_ids="${mas_ids} 1425368544"
[ -d "/Applications/Super Agent.app" ] || mas_ids="${mas_ids} 1568262835"
[ -d "/Applications/iA Writer.app" ] || mas_ids="${mas_ids} 775737590"
if [ -n "$mas_ids" ]; then
n=$((n + 1))
echo ""
echo "${n}. Sign into the App Store, then install its apps"
echo " (Things3, Timery, Super Agent for Safari, iA Writer):"
echo " mas install${mas_ids}"
fi
fi
# Node is set up by installation/macos, so only mention it when the shim is
# actually broken (nodenv installed, but `node` still doesn't run). That's
# what breaks Copilot during nvim's PlugInstall.
if command -v nodenv >/dev/null 2>&1 && ! node --version >/dev/null 2>&1; then
n=$((n + 1))
echo ""
echo "${n}. Node isn't runnable. Install a version and set it as global:"
echo " nodenv install <version> && nodenv global <version>"
fi
# Optional language toolchains (skipped: heavy or interactive).
if command -v rbenv >/dev/null 2>&1; then
n=$((n + 1))
echo ""
echo "${n}. Optional — install when you need it:"
echo " rbenv install <version> && rbenv global <version> # Ruby"
fi
# Alacritty is built from source during install; only flag it if that failed.
if [ ! -d "/Applications/Alacritty.app" ]; then
n=$((n + 1))
echo ""
echo "${n}. Alacritty didn't build. Re-run ./install, or build it manually:"
echo " brew install rust scdoc"
echo " git clone https://github.com/alacritty/alacritty.git /tmp/alacritty \\"
echo " && (cd /tmp/alacritty && make app) \\"
echo " && cp -r /tmp/alacritty/target/release/osx/Alacritty.app /Applications/"
fi
echo ""
echo "Re-run ./install any time — it's idempotent."
echo "========================================================"
}
print_post_install_checklist