-
Notifications
You must be signed in to change notification settings - Fork 0
/
bootstrap
executable file
·293 lines (250 loc) · 9.14 KB
/
bootstrap
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
#!/usr/bin/env bash
# yadm bootstrap script
# Installs all my packages/sets up my environment.
#
# Checks for the presence of the $ON_OS variable,
# which is set in ~/.profile by checking `uname`
# on linux. Since the ~/.profile is sourced at the
# beginning of the Xsession and not when opening
# a shell, it can be assumed that its always set
# once `yadm clone` has been run and the computer
# has been restarted.
print_error() {
havecmd notify 2>/dev/null && notify -u critical "bootstrap error" "$1"
printf '%s%s%s\n' "$(tput setaf 1)" "$1" "$(tput sgr0)" 1>&2
} && export -f print_error
abort() {
print_error "$1"
exit 1
} && export -f abort
# install my package list parser/machine detection code
install_go_cmds() {
havecmd go || return $?
if ! havecmd spkglist; then
go install -v 'github.com/purarue/spkglist/cmd/spkglist@latest' || return $?
fi
if ! havecmd on_machine; then
go install -v 'github.com/purarue/on_machine/cmd/on_machine@latest' || return $?
fi
} && export -f install_go_cmds
declare -rx YADM_DIR="${HOME}/.config/yadm"
declare -rx PACKAGE_DIR="${YADM_DIR}/package_lists"
# report errors if user doesn't have a command
export HAVECMD_REPORT=1
# make sure my $PATH is setup properly
havecmd havecmd || {
# optionally let me continue - this may be the first time I'm running this
# on android and I need to install zsh/setup defaults
printf 'No havecmd; continue anyways? [Ctrl+C to Cancel] '
read -r || exit $?
}
ON_OS="${ON_OS:=$(on_machine)}"
declare -rx ON_OS
# match files in ~/.config/yadm, run based on OS
# https://github.com/purarue/on_machine
# e.g. run the android_bootstrap, linux_bootstrap, mac_bootstrap files
while read -r -d $'\0' bootstrap_script; do
printf 'Executing %s\n' "$bootstrap_script"
bash "$bootstrap_script" || exit $?
done < <(on_machine -cmd match -print0 -filter file -base "${YADM_DIR}" '%o_bootstrap')
declare -rx PYTHON_PACKAGE_LIST="${PACKAGE_DIR}/python3_packages.txt"
declare -rx PIPX_PACKAGE_LIST="${PACKAGE_DIR}/pipx_packages.txt"
declare -rx NODE_PACKAGE_LIST="${PACKAGE_DIR}/node_packages.txt"
declare -rx COMPUTER_NODE_PACKAGE_LIST="${PACKAGE_DIR}/computer_node_packages.txt"
declare -rx BASH_PACKAGE_LIST="${PACKAGE_DIR}/bash_packages.txt"
# data directory for https://github.com/purarue/HPI
[[ -n "${HPIDATA}" && ! -d "${HPIDATA}" ]] && mkdir -p "${HPIDATA}"
havecmd git || exit $?
echo 'Checking git config...'
# check for global name config
if [[ -z $(git config --global user.name) ]]; then
printf "No global name set. Enter name: "
read -r githubusername
git config --global user.name "${githubusername}"
fi
# check for global email config
if [[ -z $(git config --global user.email) ]]; then
if [[ -n "$GITHUB_EMAIL" ]]; then
git config --global user.email "$GITHUB_EMAIL"
else
printf "No global email set. Enter email connected to your GitHub account: "
read -r githubemail
git config --global user.email "${githubemail}"
fi
fi
# set editor to use as nvim
git config --global core.editor nvim
# specify how to handle divergent branches
git config --global pull.rebase false
git config --global core.pager 'less -i'
# set similar configuration for yadm itself
yadm gitconfig core.editor nvim
yadm gitconfig pull.rebase false
yadm gitconfig core.pager 'less -i'
case "$ON_OS" in
linux_arch*)
git config --global core.pager 'delta'
yadm gitconfig core.pager 'delta'
;;
esac
# set the hooks directory
yadm gitconfig core.hooksPath "${HOME}/.config/yadm/hooks"
havecmd python3 || exit $?
# Install python packages -- even when on android, I use this enough/do
# enough scripting here that its worth it
echo "Installing global python site-packages..."
INSTALLED_PYTHON_PACKAGES="$(python3 -m pip list --format=json | jq '.[] | select(.editable_project_location | not) | .name' -r)"
python_install_missing() {
local -r pkg="$1"
if ! grep -qx "${pkg}" <<<"${INSTALLED_PYTHON_PACKAGES}"; then
printf "Installing %s\n" "$pkg"
python3 -m pip install --user --break-system-packages "${pkg}"
fi
} && export -f python_install_missing
python_install_missing wheel
python_install_missing virtualenv
python3 -m pip install --user -q --break-system-packages -r "${PYTHON_PACKAGE_LIST}"
# Install personal python packages
# If command "$1" doesn't exist, install from $2
function install_python_personal() {
havecmd "${1}" || python3 -m pip install --user --break-system-packages "git+${2}"
} && export -f install_python_personal
install_python_personal "clone-repos" "https://github.com/purarue/clone-repos"
install_python_personal "mlength" "https://github.com/purarue/mlength"
# clone-repos ~/.config/clone-repos.yaml
PIPX_INSTALLED="$(pipx list --json 2>/dev/null | jq '.venvs | keys[]' -r)"
while read -r pipx_pkg; do
if ! grep -qix "${pipx_pkg}" <<<"${PIPX_INSTALLED}"; then
printf "Installing %s\n" "$pipx_pkg"
pipx install "${pipx_pkg}"
fi
done < <(spkglist "${PIPX_PACKAGE_LIST}")
# stuff to install on computers (linux/mac/windows), but not on android
[[ "$ON_OS" =~ ^android.* ]] || {
printf 'Executing %s\n' "${YADM_DIR}/computer_bootstrap"
bash "${YADM_DIR}/computer_bootstrap" || exit $?
}
yarn_install_from_pkglist() {
local node_installed="$1"
local package_list="$2"
while read -r npkg; do
if ! grep -qx "${npkg}" <<<"${node_installed}"; then
printf "Installing %s\n" "$npkg"
# install to ~/.local/bin
yarn global add --prefix "${HOME}/.local" "${npkg}"
fi
done < <(spkglist "${package_list}")
}
yarn_installed() {
local yarn_package_json="${HOME}/.local/share/yarn/global/package.json"
if [[ -e "${yarn_package_json}" ]]; then
jq '.dependencies | keys[]' -r <"${yarn_package_json}"
fi
}
install_yarn_packages() {
# get a list of installed packages
YARN_INSTALLED="$(yarn_installed)"
yarn_install_from_pkglist "$YARN_INSTALLED" "$NODE_PACKAGE_LIST"
# computer-only node packages
case "$ON_OS" in
android*) ;;
*)
yarn_install_from_pkglist "$YARN_INSTALLED" "$COMPUTER_NODE_PACKAGE_LIST"
;;
esac
}
havecmd yarn || exit $?
# install yarn packages
install_yarn_packages
command rm -f "${HOME}/.local/bin/yarn.lock"
# install pistol manually
#
havecmd pistol || go install github.com/doronbehar/pistol/cmd/pistol@latest
havecmd go || exit $?
GO_PACKAGE_LIST="${PACKAGE_DIR}/go_packages.txt"
# takes a line from "$GO_PACKAGE_LIST"
# binary -> package source
# and installs it if the binary isn't already on your path
function install_go_package() {
local -a packageinfo
read -ra packageinfo <<<"${1}"
havecmd "${packageinfo[0]}" || {
# fails to build fsnotify on wsl
[[ "${packageinfo[0]}" == 'twitchlive' && "${ON_OS}" =~ ^windows.* ]] && return
go install -v "${packageinfo[1]}@latest"
}
}
if [[ ! -e "${HOME}/.local/share/go/src/github.com/purarue" ]]; then
mkdir -p "${HOME}/.local/share/go/src/github.com/purarue"
fi
echo "Installing global go packages..."
while IFS= read -r go_line; do
install_go_package "${go_line}"
done < <(spkglist "${GO_PACKAGE_LIST}")
echo "Installing personal tools/scripts..."
# use bpkg to automate make installs
havecmd bpkg || curl -Lo- "https://raw.githubusercontent.com/bpkg/bpkg/master/setup.sh" | bash
havecmd bpkg || exit $?
set -e
havecmd tttlog || bpkg install -g purarue/ttt
havecmd exists || bpkg install -g purarue/exists
havecmd genpasswd || bpkg install -g purarue/genpasswd
set +e
havecmd m3u-shuf || cargo install --git 'https://github.com/purarue/m3u-shuf'
echo 'Installing basher/shell scripts...'
BASHER_ROOT="${XDG_DATA_HOME}/basher"
[[ ! -d "${BASHER_ROOT}" ]] && git clone --depth=1 'https://github.com/basherpm/basher.git' "${BASHER_ROOT}"
# symlink the single script in the basher bin into .local
havecmd basher || ln -s "${BASHER_ROOT}/bin/basher" "${HOME}/.local/bin"
# install shell scripts using basher
havecmd basher && {
BASHER_INSTALLED="$(basher list)"
while read -r bash_pkg; do
if ! grep -xq "${bash_pkg}" <<<"${BASHER_INSTALLED}"; then
echo "Installing ${bash_pkg}" 1>&2
basher install "${bash_pkg}"
fi
done < <(spkglist "${BASH_PACKAGE_LIST}")
}
if havecmd reshortcuts; then
reshortcuts # shortcuts create and format all the created files
else
printf "Created %d shortcuts\n" "$(python3 -m shortcuts create --debug | wc -l)"
fi
if [[ -n "$NVIM_SPELLFILE" ]]; then
mkdir -p "$(dirname "$NVIM_SPELLFILE")"
fi
# setup directory for ranger
dir-aliases-ranger
# setup image previews for ranger
TARGET="${XDG_CONFIG_HOME}/ranger/preview.rc"
case "$ON_OS" in
android*)
# dont think there's any way to do this right now
echo 'set preview_images false' >"${TARGET}"
;;
linux_arch*)
echo 'set preview_images true' >"${TARGET}"
if [[ "$TERM" == xterm-kitty ]]; then
# use kitty to preview images
echo 'set preview_images_method kitty' >>"${TARGET}"
else
# use ueberzug to preview images
echo 'set preview_images_method ueberzug' >>"${TARGET}"
fi
;;
*)
# fallback to w3m?
echo -e 'set preview_images true\nset preview_images_method w3m' >"${TARGET}"
;;
esac
# setup plugins
mkdir -p "${HOME}/.config/ranger/plugins"
clone-repos "$HOME/.config/clone-repos/ranger-plugins.yaml"
mkdir -p "$HOME/.local/share/todotxt-addons/"
clone-repos "$HOME/.config/clone-repos/todotxt-actions.yaml"
# sync my personal todo actions
(cd ~/.local/scripts/todo-actions/ && make)
echo "Generating completions..."
zsh "$ZDOTDIR/generate_completion"
echo "Finished bootstrapping!"