#!/usr/bin/env bash # ================================================== # KoolDots (2026) # Project URL: https://github.com/LinuxBeginnings # License: GNU GPLv3 # SPDX-License-Identifier: GPL-3.0-or-later # ================================================== # Script to manage Java runtimes # Based on script from https://github.com/jmhorcas # Submitted to KoolDots >https://github.com/LinuxBeginnings/Hyprland-Dots/issues/49 # --- 1. Icons (Nerd Fonts) --- ICON_JAVA="" ICON_ACTIVE="󰄬" ICON_INSTALLED="" ICON_REMOTE=" " # --- 2. Distro detection --- if [ -r /etc/os-release ]; then . /etc/os-release fi DISTRO="unknown" case "${ID:-}" in arch) DISTRO="arch" ;; debian | ubuntu | linuxmint) DISTRO="debian" ;; fedora) DISTRO="fedora" ;; opensuse* | sles) DISTRO="opensuse" ;; esac if [ "$DISTRO" = "unknown" ] && [ -n "${ID_LIKE:-}" ]; then case "$ID_LIKE" in *arch*) DISTRO="arch" ;; *debian* | *ubuntu*) DISTRO="debian" ;; *fedora*) DISTRO="fedora" ;; *suse*) DISTRO="opensuse" ;; esac fi if [ "$DISTRO" = "unknown" ]; then notify-send "Error" "Unsupported distro for now." exit 1 fi # --- 3. Package helpers --- list_installed_pkgs() { case "$DISTRO" in arch) pacman -Qq | grep -E '^jdk.*-openjdk$' ;; debian) dpkg -l 'openjdk-*-jdk' 2>/dev/null | awk '/^ii/ {print $2}' ;; fedora | opensuse) rpm -qa | grep -E '^java-[0-9]+-openjdk' ;; esac } list_available_pkgs() { case "$DISTRO" in arch) pacman -Ssq '^jdk.*-openjdk$' | sort -u ;; debian) apt-cache search openjdk- | awk '{print $1}' | grep -E '^openjdk-[0-9]+-jdk$' | sort -u ;; fedora) dnf -q repoquery --qf '%{name}' 'java-*-openjdk' 2>/dev/null | grep -E '^java-[0-9]+-openjdk' | sort -u ;; opensuse) zypper -n search -s 'java-*-openjdk' 2>/dev/null | awk -F'|' '{print $2}' | xargs -n1 | grep -E '^java-[0-9]+-openjdk' | sort -u ;; esac } pkg_description() { local pkg="$1" case "$DISTRO" in arch) pacman -Si "$pkg" | grep "Description" | cut -d ':' -f2- | head -n 1 | xargs ;; debian) apt-cache show "$pkg" 2>/dev/null | awk -F': ' '/^Description/ {print $2; exit}' ;; fedora) dnf info -q "$pkg" 2>/dev/null | awk -F': ' '/^Summary/ {print $2; exit}' ;; opensuse) zypper -n info "$pkg" 2>/dev/null | awk -F': ' '/^Summary/ {print $2; exit}' ;; esac } get_active_version_raw() { case "$DISTRO" in arch) archlinux-java get ;; *) java -version 2>&1 | awk -F\" '/version/ {print $2; exit}' ;; esac } get_active_version_num() { local raw="$1" echo "$raw" | grep -oE '[0-9]+' | head -n1 } list_java_alternatives() { case "$DISTRO" in debian) update-alternatives --list java 2>/dev/null ;; fedora | opensuse) alternatives --list java 2>/dev/null ;; *) echo "" ;; esac } set_default_java() { local sel_num="$1" case "$DISTRO" in arch) local java_env java_env=$(archlinux-java status | grep "java-$sel_num" | awk '{print $1}' | head -n 1) if [ -n "$java_env" ]; then notify-send "Java" "Setting $java_env as default..." pkexec archlinux-java set "$java_env" else notify-send "Error" "Version $sel_num is not installed. Install it first." fi ;; debian | fedora | opensuse) local alt_path alt_path=$(list_java_alternatives | grep -E "java-$sel_num|jdk-$sel_num|openjdk-$sel_num" | head -n1) if [ -n "$alt_path" ]; then notify-send "Java" "Setting Java $sel_num as default..." if [ "$DISTRO" = "debian" ]; then pkexec update-alternatives --set java "$alt_path" else pkexec alternatives --set java "$alt_path" fi else notify-send "Error" "Version $sel_num is not installed. Install it first." fi ;; esac } install_pkg() { local pkg="$1" case "$DISTRO" in arch) kitty -e sudo pacman -S "$pkg" ;; debian) kitty -e sudo apt install "$pkg" ;; fedora) kitty -e sudo dnf install "$pkg" ;; opensuse) kitty -e sudo zypper install "$pkg" ;; esac } remove_pkg() { local pkg="$1" case "$DISTRO" in arch) kitty -e sudo pacman -Rs "$pkg" ;; debian) kitty -e sudo apt remove "$pkg" ;; fedora) kitty -e sudo dnf remove "$pkg" ;; opensuse) kitty -e sudo zypper remove "$pkg" ;; esac } # --- 4. Initial data --- INSTALLED_PKGS=$(list_installed_pkgs) TEMP_ALL=$(list_available_pkgs) ACTIVE_VERSION_RAW=$(get_active_version_raw) ACTIVE_VERSION_NUM=$(get_active_version_num "$ACTIVE_VERSION_RAW") if [ "$DISTRO" = "arch" ]; then TEMP_ALL_SYSTEM=$(archlinux-java status) LATEST_VERSION=$(echo "$TEMP_ALL" "$TEMP_ALL_SYSTEM" | grep -oE '[0-9]+' | sort -nr | head -n1) else LATEST_VERSION=$(echo "$TEMP_ALL" | grep -oE '[0-9]+' | sort -nr | head -n1) fi ALL_AVAILABLE=$(echo "$TEMP_ALL" | awk -v lv="$LATEST_VERSION" '{ v=$0; gsub(/[^0-9]/,"",v); if(v=="") v=lv+1; print v " " $0 }' | sort -nr | cut -d' ' -f2-) # --- 5. Functions --- get_version_num() { local pkg="$1" local v=$(echo "$pkg" | grep -oE '[0-9]+') # If there is not a number, it is the "latest" if [ -z "$v" ]; then echo "$LATEST_VERSION" else echo "$v" fi } generate_list() { for pkg in $ALL_AVAILABLE; do DESC=$(pkg_description "$pkg") VERSION=$(get_version_num "$pkg") ICON="$ICON_REMOTE" # We use a temporary variable for the icon to avoid overwriting ICON_REMOTE DISPLAY_ICON="$ICON_REMOTE" # 1. Is it installed? if echo "$INSTALLED_PKGS" | grep -q "^$pkg$"; then DISPLAY_ICON="$ICON_INSTALLED" fi # 2. Is it the active one? # We compare if the number matches OR if the raw name matches if [[ "$VERSION" == "$ACTIVE_VERSION_NUM" ]] || [[ "$pkg" == "$ACTIVE_VERSION_RAW" ]]; then DISPLAY_ICON="$ICON_ACTIVE" fi # Ensure that if the icon is empty (remote) it maintains the space [ -z "$DISPLAY_ICON" ] && DISPLAY_ICON=" " printf "%s %s %s │ %s\n" "$ICON_JAVA" "$DISPLAY_ICON" "$DESC" "$pkg" done } # --- 6. rofi --- THEME="$HOME/.config/rofi/config.rasi" SELECTION=$(generate_list | rofi -dmenu -i \ -p "󰒓 Java" \ -config "$THEME" \ -theme-str ' window { width: 1400px; } listview { scrollbar: true; } inputbar { children: [ "prompt", "textbox-prompt-colon", "entry" ]; } prompt { background-color: @selected; text-color: @background; padding: 4px 8px; border-radius: 4px; } ' \ -kb-custom-1 "Alt+i" \ -kb-custom-2 "Alt+r" \ -mesg "$ICON_ACTIVE Default | $ICON_INSTALLED Installed | Enter: Set default | Alt+I: Install | Alt+R: Remove") EXIT_CODE=$? [ -z "$SELECTION" ] && exit 0 # --- 7. Clean selection --- # 1. Extract the package name from the right side of the │ separator PKG_NAME=$(echo "$SELECTION" | awk -F'│' '{print $2}' | xargs | awk '{print $1}') # 2. Get the real number contained in the name (if it exists) SEL_RAW_NUM=$(echo "$PKG_NAME" | grep -oE '[0-9]+') # If it doesn't have a value (it's the latest package), assign LATEST_VERSION if [ -z "$SEL_RAW_NUM" ]; then SEL_RAW_NUM="$LATEST_VERSION" fi # --- 8. Actions --- case $EXIT_CODE in 0) # SET DEFAULT set_default_java "$SEL_RAW_NUM" ;; 10) # INSTALL install_pkg "$PKG_NAME" ;; 11) # REMOVE remove_pkg "$PKG_NAME" ;; esac