Assorted shell and Python scripts
1#!/usr/bin/env bash
2
3# LICENSE
4# Copyright 2022 Jeffrey Serio <hyperreal@moonshadow.dev>
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19set -eu
20set -o pipefail
21set -o posix
22
23# Check for dependencies: curl and gum.
24if ! test -x "$(command -v curl)"; then
25 echo "Missing dependencies: curl"
26 exit 1
27fi
28
29if ! test -x "$(command -v gum)"; then
30 echo "Missing dependencies: gum"
31 echo "See https://github.com/charmbracelet/gum"
32 exit 1
33fi
34
35if ! test -x "$(command -v unzip)"; then
36 echo "Missing dependencies: unzip"
37 exit 1
38fi
39
40# Directory on the local filesystem where the fonts will be installed.
41LOCAL_FONT_DIR="${HOME}/.local/share/fonts"
42
43# Fancy error output message.
44gum_error() {
45 gum style \
46 --foreground 3 \
47 --border-foreground 203 \
48 --border rounded \
49 --align center \
50 --width 50 \
51 --margin "1 2" \
52 "ERROR" \
53 "" \
54 "$1"
55 exit 1
56}
57
58# Print the startup message.
59message=$(echo "Nerd font installer :nerd_face:" | gum format -t emoji)
60gum style \
61 --foreground 212 \
62 --border-foreground 57 \
63 --border rounded \
64 --align center \
65 --width 50 \
66 --margin "1 2" \
67 "$message"
68
69# Read the nerd-font download URLs into an array
70readarray -t nf_url_array < <(curl --silent "https://api.github.com/repos/ryanoasis/nerd-fonts/releases/latest" | grep "browser_download_url" | grep "\.zip" | cut -d : -f 2,3 | tr -d '" ')
71
72# Add the nerd-font basenames without file extension suffix into an associative
73# array, using these as the keys and the download URLs as the values.
74declare -A nf_array
75for nf in "${nf_url_array[@]}"; do
76 name="$(basename -s .zip "$nf")"
77 nf_array[$name]="$nf"
78done
79
80# Sort the keys of the array.
81IFS=$'\n'
82readarray -t sorted_keys < <(sort <<<"${!nf_array[*]}")
83unset IFS
84
85# Display nerd-font selection menu with the keys of the associative array.
86selection=$(gum choose --height=10 --limit=1 "${sorted_keys[@]}")
87
88# Prompt for user confirmation and proceed with installation of nerd fonts.
89#
90# For each nerd font selected, print a status message while downloading and
91# installing the nerd font. Else print an error message if any of it fails.
92#
93# If user declines to proceed with installation, print a cancel message.
94if gum confirm "Proceed with installation?"; then
95 if ! gum spin --spinner dot --title "Downloading $selection..." \
96 -- curl --create-dirs -f -sL -o "${LOCAL_FONT_DIR}/${selection}.zip" "${nf_array["$selection"]}"; then
97 gum_error "Failed to download nerdfont archive $selection"
98 fi
99 if ! gum spin --spinner dot --title "Installing $selection..." \
100 -- unzip -uo "${LOCAL_FONT_DIR}/$selection.zip" -d "${LOCAL_FONT_DIR}"; then
101 gum_error "Failed to install nerdfont archive $selection"
102 fi
103else
104 gum style \
105 --foreground 212 \
106 --border-foreground 57 \
107 --border rounded \
108 --align center \
109 --width 50 \
110 --margin "1 2" \
111 "Nerd font installation cancelled"
112fi
113
114# Clean up local font directory. Removes everything besides fonts.
115if ! gum spin --spinner dot --title "Cleaning up local font directory..." \
116 -- find "${LOCAL_FONT_DIR}" -mindepth 1 \
117 -not -name "*.otf" \
118 -not -name "*.ttf" \
119 -not -name "static" \
120 -exec rm -rf {} \;; then
121 gum_error "Failed to clean up local font directory. Try doing it manually."
122fi
123
124# Update font cache
125if ! gum spin --spinner dot --title "Updating font cache..." \
126 -- fc-cache -f; then
127 gum_error "Failed to update font cache."
128fi
129
130# Print a message stating which nerd fonts were installed.
131gum format -t markdown -- \
132 "# Successfully installed" \
133 "$(printf "* %s\n" "${selection[@]}")"