-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathupgrade
executable file
·584 lines (542 loc) · 14 KB
/
upgrade
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
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
#!/bin/bash
# SPDX-FileCopyrightText: 2017 - 2024 sudorook <[email protected]>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
set -eu
ROOT="$(dirname "${0}")"
source "${ROOT}"/globals
! check_command git && exit 3
#
# Functions
#
function check_command() { # overrides check_command() in globals
local package
local missing=()
for package in "${@}"; do
if ! command -v "${package}" > /dev/null; then
missing+=("${package}")
fi
done
if [ ${#missing[@]} -eq 0 ]; then
return 0
else
show_warning "Install ${missing[*]@Q} first. Skipping."
return 1
fi
}
function rand_int() {
local min
local max
min="${1:-1}"
max="${2:-10}"
shuf -i"${min}-${max}" -n1
}
function is_git_dirty() {
if [ "${#}" -eq 0 ]; then
if [[ "$(git status --porcelain --untracked-files=no)" != "" ]]; then
return 0
else
return 1
fi
else
if [[ "$(git -C "${1}" status --porcelain --untracked-files=no)" != "" ]]; then
return 0
else
return 1
fi
fi
}
function git_update() {
local h
local u
local b
local d=false
local n=false
if [ -z "$(git -C "${1}" remote)" ]; then
show_warning "No remote is configured. Skipping."
return 1
fi
# get current branch
b="$(git -C "${1}" branch --show-current)"
# check if repository is dirty
if is_git_dirty "${1}"; then
d=true
fi
# if dirty, stash changes on current branch
if "${d}"; then
git -C "${1}" stash
fi
# if not master branch, switch to it
if [[ "${b}" != "master" ]]; then
git -C "${1}" checkout master
fi
# fetch updates
git -C "${1}" fetch --tags -f
# merge changes if local and remote HEAD differ
h=$(git -C "${1}" rev-parse HEAD)
u=$(git -C "${1}" rev-parse "@{u}")
if [ "${h}" != "${u}" ]; then
n=true
git -C "${1}" merge
fi
# restore original checked-out branch
if [[ "${b}" != "master" ]]; then
git -C "${1}" checkout "${b}"
fi
# restore stashed changes
if "${d}"; then
git -C "${1}" stash pop
fi
if "${n}"; then
return 0
else
return 1
fi
}
function print_usage() {
show_header "Usage: upgrade"
show_listitem "\
-i|--images upgrade Podman images
-j|--julia upgrade Julia packages
-r|--rust upgrade Rust via rustup
-R|--R upgrade R CRAN packages"
if [[ -v pkgbuilddir ]]; then
show_listitem " -p|--pkgbuild upgrade AUR pkgbuilds in ${pkgbuilddir}"
fi
show_listitem " -s|--system upgrade system packages (pacman or apt)"
if [[ -v gtkdir ]] && [[ -v plasmadir ]] && [[ -v icondir ]]; then
show_listitem " -t|--themes upgrade themes in ${gtkdir}, ${plasmadir}, and ${icondir}"
fi
if [[ -v vimpack ]]; then
show_listitem " -v|--vim upgrade Git-versioned Vim packages installed in ${vimpack}"
fi
if [[ -v nvimpack ]]; then
show_listitem " -n|--nvim upgrade Git-versioned Neovim packages installed in ${nvimpack}"
fi
if [[ -v weechatdir ]]; then
show_listitem " -w|--weechat upgrade wee-slack plugin for weechat in ${weechatdir}"
fi
if [[ -v zshdir ]]; then
show_listitem " -z|--zsh upgrade Zsh plugins in ${zshdir}"
fi
show_listitem " -x|--extra execute custom upgrade rules"
}
function upgrade_system() {
# Arch Linux (pacman)
if check_command pacman; then
show_header "Upgrading Arch Linux packages."
sudo -k sh -c "pacman -Syu && paccache -r && paccache -ruk0"
echo
return 0
fi
# Debian, Ubuntu (apt)
if check_command apt; then
show_header "Upgrading Debian packages."
sudo -k sh -c "apt update && apt -y full-upgrade && apt -y autoremove"
echo
return 0
fi
}
function upgrade_themes() {
show_header "Upgrading GTK, Plasma, and icon themes."
local repo_name
local dir
local branch
local dirty=false
local dirs=()
if [[ -v gtkdir ]] && [ -d "${gtkdir}" ]; then
for dir in "${gtkdir}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
dirs+=("${dir}")
fi
done
fi
if [[ -v plasmadir ]] && [ -d "${plasmadir}" ]; then
for dir in "${plasmadir}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
dirs+=("${dir}")
fi
done
fi
if [[ -v icondir ]] && [ -d "${icondir}" ]; then
for dir in "${icondir}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
dirs+=("${dir}")
fi
done
fi
for dir in "${dirs[@]}"; do
repo_name="$(basename "${dir}")"
show_info "${repo_name}"
branch="$(git -C "${dir}" branch --show-current)"
if is_git_dirty "${dir}"; then
dirty=true
else
dirty=false
fi
if git_update "${dir}"; then
case "${repo_name}" in
papirus-icon-theme)
if git -C "${dir}" show-ref --verify --quiet "refs/heads/tweak"; then
pushd "${dir}" > /dev/null
git checkout tweak
git reset HEAD~1
git reset --hard
git clean -xdf
git rebase master
tools/_restore_adapta_icons.sh
sync
git add .
git commit -m "Mirror updates to Adapta icon set."
git checkout master
popd > /dev/null
fi
;;
*)
if git -C "${dir}" show-ref --verify --quiet "refs/heads/tweak"; then
if "${dirty}"; then
git -C "${dir}" stash
fi
if [ "${branch}" != tweak ]; then
git -C "${dir}" checkout tweak
fi
git -C "${dir}" rebase master
if [ "${branch}" != tweak ]; then
git -C "${dir}" checkout "${branch}"
fi
if "${dirty}"; then
git -C "${dir}" stash pop
fi
fi
;;
esac
fi
sleep "$(rand_int 2 10)"
echo
done
if [[ -v thunderbirddir ]] && [[ -d "${thunderbirddir}/chrome" ]]; then
show_info "$(basename "${thunderbirddir}") (thunderbird)"
git -C "${thunderbirddir}/chrome" pull --ff-only origin master
sleep "$(rand_int 2 10)"
echo
fi
}
function upgrade_extra() {
show_header "Running extra upgrade script(s)."
}
function upgrade_vim_packages() {
show_header "Upgrading Vim plugins."
local vimpack=${HOME}/.vim/pack/dist/start
local dir
if check_command vim; then
if [ -d "${vimpack}" ]; then
for dir in "${vimpack}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
show_info "$(basename "${dir}")"
git_update "${dir}" || true
sleep "$(rand_int 2 10)"
echo
fi
done
else
show_warning "${vimpack@Q} does not exist. Skipping."
echo
fi
else
echo # for output text spacing
fi
}
function upgrade_nvim_packages() {
show_header "Upgrading Neovim plugins."
local nvimpack=${HOME}/.config/nvim/pack/dist/start
local dir
if check_command nvim; then
if [ -d "${nvimpack}" ]; then
for dir in "${nvimpack}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
show_info "$(basename "${dir}")"
git_update "${dir}" || true
sleep "$(rand_int 2 10)"
echo
fi
done
else
show_warning "${nvimpack@Q} does not exist. Skipping."
echo
fi
else
echo # for output text spacing
fi
}
function upgrade_zsh() {
show_header "Upgrading Zsh plugins."
local dir
if check_command zsh; then
# antigen-update may not be in the bash PATH, so check the zsh path if
# 'command -v antigen' returns false.
if zsh -ic "command -v antigen" > /dev/null 2>&1; then
zsh -ic "antigen update"
sleep "$(rand_int 2 10)"
else
if [[ -v zshdir ]] && [ -d "${zshdir}" ]; then
for dir in "${zshdir}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
show_info "$(basename "${dir}")"
git -C "${dir}" pull --ff-only origin master --tags
sleep "$(rand_int 2 10)"
echo
fi
done
else
show_warning "No Zsh plugins found in ${zshdir@Q}. Skipping."
echo
fi
fi
else
echo # for output text spacing
fi
}
function upgrade_gems() {
show_header "Upgrading user-installed gems."
local gemhome
local gem
gemhome="$(gem env user_gemhome)"
while read -r gem; do
if gem list --silent -i "${gem}"; then
gem update --conservative --minimal-deps "${gem}"
else
show_warning "Something went wrong parsing ${gem@Q}."
fi
done < <(
find "${gemhome}/gems/" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; |
sed \
-e "s/-linux$//g" \
-e "s/-\(x86\)\(_64\)\?$//g" \
-e "s/-[0-9\.]\+$//g"
)
}
function update_images() {
show_header "Upgrading Podman images."
local image
if check_command podman; then
if [[ "$(podman image list --noheading)" = "" ]]; then
show_warning "No images installed. Skipping..."
else
while read -r image; do
if [[ "${image}" =~ ^localhost/ ]]; then
continue
fi
podman image pull "${image}"
done <<< "$(podman image list --format "{{ .Repository }}")"
show_info "Pruning dangling images."
podman image prune --force
fi
fi
echo
}
function upgrade_julia_packages() {
show_header "Upgrading Julia packages."
if check_command julia; then
julia -e "using Pkg; Pkg.update()"
sleep "$(rand_int 2 10)"
fi
echo
}
function upgrade_rust() {
show_header "Upgrading Rust compiler and components."
if check_command rustup cargo; then
if ! [[ "$(rustup toolchain list)" = "no installed toolchains" ]]; then
rustup self upgrade-data
rustup update
if ! [ -d /usr/share/cargo/registry ]; then
show_info "Updating crates."
if [ -d "${projectdir}"/crate_dl ]; then
pushd "${projectdir}"/crate_dl > /dev/null
rm -f Cargo.lock
cargo fetch
popd > /dev/null
else
local tmpdir
tmpdir="$(mktemp -d)"
git clone --depth 1 https://github.com/sudorook/crate_dl.git "${tmpdir}"
pushd "${tmpdir}" > /dev/null
cargo fetch
popd > /dev/null
rm -rf "${tmpdir}"
fi
fi
else
show_warning "No rust toolchain installed. Skipping."
fi
fi
echo
}
function upgrade_R() {
show_header "Upgrading R packages."
if check_command Rscript; then
if [[ -v R_LIBS_USER ]]; then
Rscript <(
cat << EOF
update.packages(ask = FALSE,
checkBuilt = TRUE,
clean = TRUE,
lib = "${R_LIBS_USER}",
repos = 'https://cloud.r-project.org/')
EOF
)
else
show_warning "R_LIBS_USER is not set. Skipping."
fi
sleep "$(rand_int 2 10)"
fi
echo
}
function upgrade_pkgbuild() {
if check_command makepkg; then
show_header "Upgrading AUR pkgbuilds."
local dir
if [[ -v pkgbuilddir ]] && [[ -d "${pkgbuilddir}" ]]; then
for dir in "${pkgbuilddir}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
show_info "$(basename "${dir}")"
if git_update "${dir}"; then
pushd "${dir}" > /dev/null
makepkg -si --noconfirm
git clean -xdf
git reset --hard
popd > /dev/null
fi
sleep "$(rand_int 2 10)"
echo
fi
done
else
show_warning "No PKGBUILDs found. Skipping."
echo
fi
else
echo # for output text spacing
fi
}
function upgrade_weechat_plugins {
show_header "Upgrading weechat plugins."
local weechatdir=${HOME}/.weechat/plugins
local dir
if [ -d "${weechatdir}" ]; then
for dir in "${weechatdir}"/*; do
if git -C "${dir}" rev-parse 2> /dev/null; then
show_info "$(basename "${dir}")"
git -C "${dir}" pull --ff-only origin master --tags
sleep "$(rand_int 2 10)"
echo
fi
done
else
show_warning "No weechat plugin directory exists. Skipping."
echo
fi
}
#
# Main
#
OPTIONS=ahgijrRpstnvwxz
LONGOPTIONS=all,help,gems,images,julia,rust,R,pkgbuild,system,theme,nvim,vim,weechat,extra,zsh
PARSED=$(getopt -o "${OPTIONS}" --long "${LONGOPTIONS}" -n "${0}" -- "${@}")
eval set -- "${PARSED}"
while [ ${#} -ge 1 ]; do
case ${1} in
-a | --all)
upgrade_system
upgrade_gems
upgrade_julia_packages
upgrade_rust
upgrade_R
upgrade_pkgbuild
upgrade_themes
upgrade_vim_packages
upgrade_nvim_packages
upgrade_weechat_plugins
upgrade_zsh
upgrade_extra
shift
break
;;
-h | --help)
print_usage
exit
;;
-g | --gems)
upgrade_gems
shift
;;
-i | --images)
update_images
shift
;;
-j | --julia)
upgrade_julia_packages
shift
;;
-r | --rust)
upgrade_rust
shift
;;
-R | --R)
upgrade_R
shift
;;
-p | --pkgbuild)
upgrade_pkgbuild
shift
;;
-s | --system)
upgrade_system
shift
;;
-t | --theme)
upgrade_themes
shift
;;
-n | --nvim)
upgrade_nvim_packages
shift
;;
-v | --vim)
upgrade_vim_packages
shift
;;
-w | --weechat)
upgrade_weechat_plugins
shift
;;
-z | --zsh)
upgrade_zsh
shift
;;
-x | --extra)
upgrade_extra
shift
;;
--)
shift
break
;;
*)
show_error "Error: invalid flag."
exit 3
;;
esac
done