Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml → .github/workflows/install.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test
name: Install

permissions:
contents: read
Expand Down Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Setup dotfiles
run: |
chmod +x setup.sh
DOTFILES_DIR="$GITHUB_WORKSPACE" ./setup.sh
printf 'y\n1\n' | DOTFILES_DIR="$GITHUB_WORKSPACE" ./setup.sh

- name: Smoke test zsh
shell: zsh {0}
Expand Down
160 changes: 123 additions & 37 deletions scripts/install-nerd-font.sh
Original file line number Diff line number Diff line change
@@ -1,56 +1,142 @@
#!/usr/bin/env bash

##################################################################################
##### Fetch the canonical list of Nerd Font names (= release asset names)
##################################################################################
get_font_list() {
local json
json=$(curl -fsSL "$FONTS_JSON_URL") || {
printf "Failed to fetch font list from %s\n" "$FONTS_JSON_URL" | tee -a "$LOG_FILE" >&2
exit 0
}

if command -v python3 >/dev/null 2>&1; then
printf '%s' "$json" | python3 -c '
import json, sys
data = json.load(sys.stdin)
names = sorted(f["folderName"] for f in data["fonts"])
print("\n".join(names))
'
elif command -v jq >/dev/null 2>&1; then
printf '%s' "$json" | jq -r '.fonts[].folderName' | sort
else
printf "Need python3 or jq installed to parse the font list\n" | tee -a "$LOG_FILE" >&2
exit 0
fi
}

##################################################################################
##### Function to install Nerd font
##################################################################################
install_nerd_font() {

print_step "Install Nerd font"

print_step "Install Nerd font"
start_spinner "Installing..."
# Ask for Nerd font at all
local need_nerd_font
while true; do
read -rp "Do you want Nerd font [Y/n] " need_nerd_font
case "$need_nerd_font" in
[Yy]*) break ;;
[Nn]*)
printf "Skipping font installation.\n" | tee -a "$LOG_FILE"
echo
return 0
;;
*) ehco "Please answer y or n." ;;
esac
done

# Menu is interactive, so it happens before the spinner starts.
mapfile -t fonts < <(get_font_list)

# Check if fonts list is populated
if [ "${#fonts[@]}" -eq 0 ]; then
printf "No fonts available - continuing without font installation.\n" | tee -a "$LOG_FILE"
return 0
fi

# Print menu
echo
local cols=3
local col_width=26
local total=${#fonts[@]}
local total_items=$((total + 1))
for ((i = 0; i < total_items; i++)); do
if (( i == 0 )); then
local skip_label="Skip installation"
local skip_pad=$(( col_width - ${#skip_label} ))
(( skip_pad < 0 )) && skip_pad=0
printf "%3d) %s%s%s%*s" 0 "${BOLD}${GREEN}" "$skip_label" "${RC}" "$skip_pad" ""
else
printf "%3d) %-*s" "$i" "$col_width" "${fonts[$((i - 1))]}"
fi
if (( (i + 1) % cols == 0 )); then
echo
fi
done
if (( total_items % cols != 0 )); then
echo
fi
echo

local choice
while true; do
read -rp "Select font: " choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 0 ] && [ "$choice" -le "$total" ]; then
break
fi
printf "Invalid choice, try again."
done

if [ "$choice" -eq 0 ]; then
printf "Skipping font installation.\n" | tee -a "$LOG_FILE"
echo
return 0
fi

local NERD_FONT_FAMILY="${fonts[$((choice - 1))]}"

start_spinner "Installing..."

{
printf "\n##### Function to install Nerd font #####\n"

local message

if fc-list 2>/dev/null | grep -qi "$NERD_FONT_FAMILY"; then
local font_dir="$FONT_INSTALL_ROOT/${NERD_FONT_FAMILY}NerdFont"

# already installed? (checked by presence of font files, not by
# fc-list name, since the internal family name doesn't always
# match the download name)
if [ -d "$font_dir" ] && find "$font_dir" -maxdepth 1 \( -iname '*.ttf' -o -iname '*.otf' \) 2>/dev/null | grep -q .; then
message="$(msg_skip "$NERD_FONT_FAMILY")"
printf "Installation skipped - %s is already present!\n" "$NERD_FONT_FAMILY"
else
font_temp_dir=$(mktemp -d)
font_archive="$font_temp_dir/JetBrainsMono.tar.xz"
font_unpack_dir="$font_temp_dir/unpacked"
NERD_FONT_URL="https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.zip"
font_dir="$HOME/.local/share/fonts/JetBrainsMonoNerdFont"
mkdir -p "$font_unpack_dir" "$font_dir"

if ! curl -fsSL "$NERD_FONT_URL" -o "$font_archive"; then
rm -rf "$font_temp_dir"
local tmp_dir archive url
tmp_dir=$(mktemp -d)
archive="$tmp_dir/${NERD_FONT_FAMILY}.zip"
url="https://github.com/ryanoasis/nerd-fonts/releases/latest/download/${NERD_FONT_FAMILY}.zip"

if ! curl -fsSL "$url" -o "$archive"; then
message="$(msg_err "Failed to download ${BOLD}$NERD_FONT_FAMILY${RC}! Check ${BOLD}${LOG_FILE}${RC} for details.")"
fi
if ! tar -xJf "$font_archive" -C "$font_unpack_dir"; then
rm -rf "$font_temp_dir"
message="$(msg_err "Failed to extract ${BOLD}$NERD_FONT_FAMILY${RC}! Check ${BOLD}${LOG_FILE}${RC} for details.")"
fi

find "$font_unpack_dir" -type f -name 'JetBrainsMonoNerdFont-*.ttf' -exec cp {} "$font_dir"/ \;
font_found=
for font_file in "$font_dir"/*.ttf; do
if [ -f "$font_file" ]; then
font_found=1
break
else
mkdir -p "$tmp_dir/unpacked" "$font_dir"
if ! unzip -qq -o "$archive" -d "$tmp_dir/unpacked"; then
message="$(msg_err "Failed to extract ${BOLD}$NERD_FONT_FAMILY${RC}! Check ${BOLD}${LOG_FILE}${RC} for details.")"
else
find "$tmp_dir/unpacked" -type f \( -iname '*.ttf' -o -iname '*.otf' \) -exec cp {} "$font_dir/" \;

if ! find "$font_dir" -maxdepth 1 \( -iname '*.ttf' -o -iname '*.otf' \) | grep -q .; then
message="$(msg_err "No font files found for ${BOLD}$NERD_FONT_FAMILY${RC}!")"
else
fc-cache -f "$font_dir" >/dev/null 2>&1
message="$(msg_ok "Font ${BOLD}$NERD_FONT_FAMILY${RC} installed.")"
fi
fi
done
rm -rf "$font_temp_dir"

if [ -z "$font_found" ]; then
message="$(msg_err "No standard JetBrainsMono Nerd Font files were found in the archive.")"
fi

fc-cache -f >/dev/null 2>&1
message="$(msg_ok "$NERD_FONT_FAMILY installed.")"

rm -rf "$tmp_dir"
fi
} >> "$LOG_FILE" 2>&1

stop_spinner "$message"
stop_spinner "$message" | tee -a "$LOG_FILE"
}
3 changes: 2 additions & 1 deletion scripts/variables
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ DEPENDENCIES=""
DOTFILES_DIR="${DOTFILES_DIR:-$HOME/dotfiles}"
LOG_DIR="${DOTFILES_DIR}/log"
LOG_FILE="${LOG_DIR}/installation.log"
NERD_FONT_FAMILY="JetBrainsMono Nerd Font"
FONTS_JSON_URL="https://raw.githubusercontent.com/ryanoasis/nerd-fonts/master/bin/scripts/lib/fonts.json"
FONT_INSTALL_ROOT="${FONT_INSTALL_ROOT:-$HOME/.local/share/fonts}"
2 changes: 1 addition & 1 deletion setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ done
##################################################################################
head
start_log
install_nerd_font
install_nerd_font "$@"
check_env
auth_sudo
update_system
Expand Down