-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinstall
executable file
·467 lines (416 loc) · 15.4 KB
/
install
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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
#!/usr/bin/env bash
# XXX TODO: for 'TODO' items, it would be nice to print a message explaining
# what's not already automated, prompting the user to do it manually.
# ...also, it would be great to make this configurable, to skip stuff;
# it's essentially all idempotent, but sometimes it gets stuck on a network op;
# ctl-c doesn't work because of `set -e`
# TODO: nushell & carapace
if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then
# There aren't _too_ many things that rely on Bash 4.
# But on the other hand, I don't ever plan to use Bash 3 as my primary shell.
echo "ERROR: Bash version is $BASH_VERSION, but only 4 and above are supported." >&2
exit 2
fi
set +e
set +u
. ~/public-config/dotfiles/bash.d/source_first.0.bootstrap
set -e
set -u
# We use aliases in this script.
shopt -s expand_aliases
install_tools=false
while [[ ! -z "${1+x}" ]]; do
PARAM=`echo $1 | awk -F= '{print $1}'`
case $PARAM in
-t | --tools)
install_tools=true
;;
*)
echo "Usage: $0 [-t|--tools]"
exit 1
;;
esac
shift
done
# TODO this confirmation should be persistent, and probably should be tied to
# my list of "known personas" that's currently in my 'base' bash rc file.
echo '$HOME' " is currently $HOME. Press any key to continue or Ctl-C to quit."
if $WINDOWS; then
# TODO: don't give this warning unless the `public-config` directory's
# parent is somewhere other than `$HOME`.
# (Note: this whole script appears to assume the location of the
# `public-config` dir...)
cat <<WIN_HOME_INSTRUCTIONS
To set the HOME variable to your user-profile directory, manually create
it and assign it to '%USERPROFILE%'.
WIN_HOME_INSTRUCTIONS
alias universal_symlink=win_symlink
else
alias universal_symlink='ln -s'
fi
read dummy
link_s () {
if [[ $# -eq 1 ]]; then
new_link="$(basename "${1}")"
elif [[ $# -eq 2 ]]; then
new_link="${2}"
else
echo "ERROR: symlink creation requires one or two arguments!" >&2
# Currently, we *exit* with *error*...because this is a script bug.
exit 64
fi
if [[ -h "${new_link}" ]]; then rm "${new_link}"; fi
if [[ -e "${new_link}" ]]; then
# XXX TODO: Provide option to force overwrite.
echo "ERROR: Can't overwrite non-symlink file: ${new_link}" >&2
return 23
else
universal_symlink "${1}" "${new_link}"
fi
}
cd ~
shopt -s nullglob
# `.bashrc` almost always exists as a non-symlinked file.
# On Windows, shells don't have permission to create symlinks by default, so
# setting up the symlinks can fail. When that happens, we don't want to have
# lost the original bashrc.
if [[ (-e ~/.bashrc) && !(-h ~/.bashrc) ]]; then
orig_bashrc="$(mktemp -t bashrc.XXX)"
cat ~/.bashrc > "$orig_bashrc"
rm -f ~/.bashrc
restore_orig_bashrc () {
echo "Restoring original .bashrc file"
rm -f ~/.bashrc
mv "$orig_bashrc" ~/.bashrc
}
trap restore_orig_bashrc ERR
trap "rm -f '$orig_bashrc'" EXIT
fi
# TODO: consider using a dotfiles manager; probably either toml-bombadil or chezmoi
for prog in bash input gdb irb vim zsh git ack ycm ripgrep profile sh; do
echo Installing rc files for ${prog}
for file in ~/public-config/dotfiles/${prog}* ~/private-config/dotfiles/${prog}*; do
rcname=".$(basename "${file}")"
link_s "${file}" ${rcname}
done
done
if [[ -v orig_bashrc ]]; then
# We've successfully overwritten the old bashrc file.
rm -f "$orig_bashrc"
trap - ERR
trap - EXIT
fi
NVIM_PATH=~/.config/nvim
if ${WINDOWS}; then
# TODO change Windows options using Powershell, e.g. show file extensions
# in Explorer:
# http://stackoverflow.com/a/8110982/1858225
link_s .vim vimfiles
NVIM_PATH="$LOCALAPPDATA/nvim"
fi
# Config files that don't live directly in $HOME
mkdir -p "${NVIM_PATH}"
link_s ~/public-config/dotfiles/nvim "${NVIM_PATH}/init.vim"
mkdir -p ~/.config
link_s ~/public-config/dotfiles/starship.toml ~/.config/starship.toml
# `jj config path` autopopulates an empty file.
jj_path="$(jj config path --user)"
if [[ !(-h ~/"$jj_path") ]]; then
if [[ $(du -k "${jj_path}" | cut -f1) -ne 0 ]]; then
# Keep at most one copy of existing non-symlink files
mv -f "$jj_path" "${jj_path}.old"
else
rm "$jj_path"
fi
fi
link_s ~/public-config/dotfiles/jj.toml "$jj_path"
echo "Installing common options for git"
# I assume `git` is installed, because that's the easiest way to get a copy of
# this config directory.
git config --global include.path "$(pathgitconf ~/public-config/includefile_gitconfig public)"
# Use .gitignore globally
git config --global core.excludesfile "$(pathgitconf ~/.gitignore)"
# I always use the same name...
git config --global user.name "Kyle J Strand"
# ...but not always the same email. TODO add this to the interactive component
# at the beginning of the script
mkdir -p ~/bin
cd ~/bin
for prog in ~/public-config/bin/*; do
basename="$(basename "${prog}")"
if [[ ! -e "${basename}" ]]; then
echo "Installing '~/bin/${basename}'"
link_s "${prog}"
else
echo "'${basename}' already installed"
fi
done
if ${LINUX_ANY}; then
# Linux-specific
linux_specific=~/public-config/OS_specific/Linux
if $LINUX_NATIVE; then
# Install Xmodmap
if [[ ! -e ~/.Xmodmap ]]; then
echo "Installing Xmodmap"
link_s "${linux_specific}"/Xmodmap ~/.Xmodmap
else
echo "Xmodmap already exists; not overwriting"
fi
# Install .i3 config
mkdir -p ~/.i3
cd ~/.i3
if [[ ! -e config ]]; then
echo Installing i3 config
link_s "${linux_specific}/i3_config"
mv i3_config config
else
echo i3 config already installed
fi
fi
if $WSL; then
host_git="$(where.exe git.exe)"
if [[ $? -ne 0 ]]; then
echo "can't set up Git credential manager!" >&2
else
if ! hash wslpath 2>/dev/null; then
echo "wslpath not found; not configuring Git credential manager"
else
host_git="$(wslpath -u "$host_git")"
# The `grep` is to ensure we get a nonzero status if we can't find the manager
cred_mgr="$(find "$(dirname "$(dirname "$host_git")")" -maxdepth 3 -name git-credential-manager.exe | grep .)"
if [[ $? -ne 0 ]]; then
echo "couldn't find Windows git credential manager." >&2
else
# Escape spaces
cred_mgr=$(printf %q "$cred_mgr")
git config --global credential.helper "$cred_mgr"
fi
fi
fi
# TODO: automate this
cat << EOF
NOTE: you may set the WSL hostname in /etc/wsl.conf:
[network]
hostname = <name>
EOF
fi
elif ${MAC_OSX}; then
# Currently nothing to do.
:
# TODO:
# Bash completions dir? (Apparently no standard for this...)
# Set up login shell appropriately? https://stackoverflow.com/a/7780055/1858225
fi
##############################################################################
##############################################################################
# CREATE SANDBOX DIRECTORY
##############################################################################
##############################################################################
# XXX TODO
# * Sandbox setup with makefile, inspired by http://stackoverflow.com/a/32485029/1858225
# * To check whether c++14, etc is supported:
# g++ -std=c++14 2>&1 | grep -q 'unrecognized command line'
##############################################################################
##############################################################################
# INSTALL 3RD-PARTY TOOLS
##############################################################################
##############################################################################
# XXX it would be great to be able to grab bits and pieces of this, piecemeal.
if ! ${install_tools}; then
exit
fi
##############################################################################
# Misc TODO
##############################################################################
# XXX TODO automatically generate SSH ID and send to G:
# https://gist.github.com/zentralwerkstatt/9e6c83e757cdfe430d6710585b2275c7
##############################################################################
# TODO: how can we determine if the installed vim feature-set is sufficient for
# the plugins I'm using? (`vim --version | grep <something>`?)
vim_plug=autoload/plug.vim
vim_plugin_mgr=~/.vim/${vim_plug}
# XXX this... doesn't work at all on Windows...?
# For some reason `hash` doesn't always work on Windows in Git Bash, so try
# `where` as well.
if hash vim 2>/dev/null || where vim &>/dev/null; then
if [[ ! -a "${vim_plugin_mgr}" ]]; then
if hash curl 2>/dev/null; then
echo Installing Vim plugins
curl -fLo "${vim_plugin_mgr}" --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
vim "+PlugInstall"
else
echo "'curl' not installed; not installing Vim-Plug."
fi
fi
else
# TODO `vim-gtk` seems pretty good, generally; just install that?
echo "WARNING: vim not installed"
fi
# TODO Somehow automatically perform no-extension file-association?
# https://superuser.com/a/13947/199803
# TODO ultimately this should *NOT* depend on Vim.
if [[ -e "$vim_plugin_mgr" && ! -e "${NVIM_PATH}/${vim_plug}" ]]; then
mkdir -p "${NVIM_PATH}/$(dirname "${vim_plug}")"
link_s "$vim_plugin_mgr" "${NVIM_PATH}/${vim_plug}"
fi
# Install dev tools (Debian-based only)
# TODO: other package managers
# TODO: `brew` for Mac?
installusingapt=false
if hash apt-get 2>/dev/null; then
installusingapt=true
fi
if ${WINDOWS}; then
echo "To install Windows tools, run install.ps1."
fi
# TODO we should be able to unify our package-manager logic.
# * Install commands are always (?) of the form `<pkg-mgr-install> <pkg-name>`
# * We would need to set up a pkg-mgr-install-command function/alias/variable,
# then have a lookup table for known packages. Then something like:
# for pkg in $known_pkgs; do
# # TODO check syntax for assoc-array!!
# pkg_name="${pkg_names[$mgr][$pkg]}"
# if [[ -z "$pkg_name" ]]; then continue; fi
# $pkgmgr_install $pkg_name
# done
havetoolchain=false
if hash g++ 2>/dev/null; then
havetoolchain=true;
else
if hash clang++ 2>/dev/null; then
havetoolchain=true;
else
if $installusingapt; then
echo Installing build-essential using apt
sudo apt-get install build-essential
if [[ $? -eq 0 ]]; then
havetoolchain=true
fi
fi
fi
fi
havecmake=false
if hash cmake 2>/dev/null; then
havecmake=true;
else
if $installusingapt; then
echo Installing cmake using apt
sudo apt-get install cmake
if [[ $? -eq 0 ]]; then
havecmake=true
fi
fi
fi
if $installusingapt; then
echo Installing xclip and fzf using apt
sudo apt-get install xclip fzf
elif ! $WINDOWS; then
# On windows, assume fzf will be installed with choco; otherwise, try to install from source
if [[ ! -d ~/.fzf ]]; then
echo Installing fzf
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
fi
fi
# TODO: install FiraCode font: https://github.com/tonsky/FiraCode
# On Windows, with Scoop:
# ```
# scoop bucket add nerd-fonts
# scoop install FiraCode
# ```
# ...actually, Consolas, the default Alacritty font on Windows, seems to
# include most or all of the characters used by Starship.
# Related: install Scoop and/or WinGet?
# TODO: consider installing `zk` (which requires `sqlite3` as well): https://github.com/sirupsen/zk
# Create installers directory
mkdir -p ~/Installers
# Install rust
if ! hash rustc 2>/dev/null; then
if hash sh 2>/dev/null; then
if hash wget 2>/dev/null; then
echo Installing Rust
wget -P ~/Installers https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init
chmod a+x ~/Installers/rustup-init
~/Installers/rustup-init
elif hash curl 2>/dev/null; then
echo Installing Rust
curl https://sh.rustup.rs -sSf | sh
else
echo "Neither 'curl' nor 'wget' is installed; not installing Rust" >&2
fi
else
echo "*NIX shell not available; not installing Rust" >&2
# TODO: on Windows, download and run the `rustup` executable
fi
else
echo Checking for Rust updates
rustup update
fi
# TODO: consider using cargo-binstall instead of building everything from
# scratch. This would be *especially* helpful on systems where I don't actually
# have any reason to install Rust itself.
# https://github.com/cargo-bins/cargo-binstall#installation
# Just in case the above didn't work
if ! hash cargo 2>/dev/null; then
echo "Can't install rust tools; cargo not installed!" >&2
else
rustup default stable
if ! hash rg 2>/dev/null; then
echo Installing ripgrep
cargo install ripgrep
fi
if ! hash fastmod 2>/dev/null; then
echo Installing fastmod
cargo install fastmod
fi
if ! hash fd 2>/dev/null; then
echo Installing fd
cargo install fd-find
fi
if ! hash tokei 2>/dev/null; then
echo Installing tokei
cargo install tokei
fi
if ! hash bat 2>/dev/null; then
echo Installing bat
cargo install bat
fi
# TODO install `broot`? Needs a script, `br`, to be sourced. Just symlink
# as `.bash.d/br`?
# TODO install a powerline-compatible font and starship?
# (Starship is just `cargo install`, but it needs libssl-dev and
# pkg-config, as well as a Powerline compatible font such as FiraCode.)
# Other tools:
# * https://github.com/lotabout/skim (replace fzf, or do they work together?)
# * https://github.com/mookid/diffr
# TODO restore default toolchain?
fi
# The original sshrc repo apparently no longer exists. I have found forks, but
# they are pretty old.
# I should reconsider whether I actually want this functionality, and/or if
# there's a better way to accomplish something similar.
# TODO: install how2? (Not sure how useful it is yet; requires nodejs and some
# fiddling to make it work; specifically, how2 assumes nodejs executable is
# called `node`)
# TODO: other possibly useful command-line tools:
# * eg (easygit) - Simply wget and chmod
# * Stuff from here: http://zeroturnaround.com/rebellabs/5-unexpectedly-useful-command-line-tools-you-might-overlook/
# * z - remembers common dirs (work with `cd` alias?)
# * shellcheck - static analysis of Bash for common errors
# * multitail - better than `tail -F`?
# * tree - nice recursive dir printing (already installed at work)
# Windows tools are not installed; those should be installed using `install.ps1`.
if $WSL; then
if ! hash wsl-open 2>/dev/null; then
echo "installing wsl-open"
# Install wsl-open
git clone https://github.com/4U6U57/wsl-open/ ~/ToolsBld/wsl-open
cd ~/ToolsBld/wsl-open
# TODO keep this updated? tool hasn't changed in a year and a half, as of Oct 2022
git checkout v2.2.1
chmod a+x ./wsl-open.sh
cd ~/bin
link_s ~/ToolsBld/wsl-open/wsl-open.sh
fi
fi