Nyx-Tools/nyx/bash/nyx-tui.sh
2025-08-13 13:52:50 +02:00

341 lines
9 KiB
Bash

#!/usr/bin/env bash
# nyx-tui: interactive TUI for Nyx tasks
if [ -z "${BASH_VERSION:-}" ]; then
echo "This script must be run with bash, not $SHELL" >&2
exit 1
fi
set -euo pipefail
########################################################################
# CONFIGURATION (injected by Nix)
########################################################################
log_dir="@LOG_DIR@"
nix_dir="@NIX_DIR@"
version="@VERSION@"
dialog_bin="${DIALOG_BIN:-@DIALOG_BIN@}"
PAGER="${PAGER:=less}"
# Fallbacks if Nix didn't substitute
if [[ -z "${dialog_bin//@DIALOG_BIN@/}" ]]; then
# If placeholder remained, try common defaults
if command -v dialog >/dev/null 2>&1; then
dialog_bin="$(command -v dialog)"
elif command -v whiptail >/dev/null 2>&1; then
dialog_bin="$(command -v whiptail)"
else
echo "Error: neither 'dialog' nor 'whiptail' found. Please install one." >&2
exit 1
fi
fi
if ! command -v "$dialog_bin" >/dev/null 2>&1; then
echo "Error: dialog binary '$dialog_bin' is not executable." >&2
exit 1
fi
mkdir -p "$log_dir"
########################################################################
# CLI args
########################################################################
do_startup=false
print_help() {
cat <<'EOF'
nyx-tui [--pretty] [--help]
--pretty Show a simple artificial startup screen (optional).
--help Show this help.
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--pretty) do_startup=true; shift;;
-h|--help) print_help; exit 0;;
*) echo "Unknown argument: $1" >&2; exit 2;;
esac
done
########################################################################
# Colors (TTY only)
########################################################################
if [[ -t 1 ]]; then
RED=$'\e[31m'; GREEN=$'\e[32m'; YELLOW=$'\e[33m'
BLUE=$'\e[34m'; MAGENTA=$'\e[35m'; CYAN=$'\e[36m'
BOLD=$'\e[1m'; RESET=$'\e[0m'
else
RED=""; GREEN=""; YELLOW=""; BLUE=""; MAGENTA=""; CYAN=""; BOLD=""; RESET=""
fi
pause() { read -r -p "Press Enter to continue..." _; }
########################################################################
# Dialog wrappers
########################################################################
d_msg() {
local msg="${1:-}"
"$dialog_bin" --title "Nyx TUI" --msgbox "$msg" 8 60
clear
}
d_textbox() {
local title="${1:-}"; local file="${2:-}"
"$dialog_bin" --title "$title" --textbox "$file" 20 100
clear
}
d_menu() {
local title="$1"; shift
local prompt="$1"; shift
local choice
choice=$("$dialog_bin" --title "$title" --menu "$prompt" 20 70 10 "$@" 3>&1 1>&2 2>&3) || return 1
echo "$choice"
}
########################################################################
# Helpers
########################################################################
run_with_spinner() {
local label="$1"; shift
echo "${CYAN}${BOLD}${label}${RESET}"
( "$@" ) &
local pid=$!
local spin='|/-\'; local i=0
while kill -0 "$pid" 2>/dev/null; do
i=$(( (i+1) % 4 ))
printf "\r%s" "${spin:$i:1}"
sleep 0.1
done
wait "$pid"; local status=$?; printf "\r"
return $status
}
########################################################################
# Actions
########################################################################
action_rebuild() {
clear
if command -v nyx-rebuild >/dev/null 2>&1; then
run_with_spinner "Rebuilding (nyx-rebuild)..." nyx-rebuild || true
if ! check_last_log_for_error; then
return
fi
d_msg "Rebuild finished."
elif command -v nixos-rebuild >/dev/null 2>&1; then
run_with_spinner "nixos-rebuild switch --flake ${nix_dir} ..." \
sudo nixos-rebuild switch --flake "$nix_dir" || true
sleep 1
d_msg "nixos-rebuild finished."
else
d_msg "No rebuild tool found (nyx-rebuild / nixos-rebuild). Skipping."
fi
}
action_update() {
clear
if command -v nyx-rebuild >/dev/null 2>&1; then
run_with_spinner "Updating (nyx-rebuild --update)..." nyx-rebuild --update || true
if ! check_last_log_for_error; then
return
fi
d_msg "Update finished."
elif command -v nixos-rebuild >/dev/null 2>&1; then
(
cd "$nix_dir"
run_with_spinner "nix flake update..." nix flake update || true
)
run_with_spinner "nixos-rebuild switch --flake ${nix_dir} ..." \
sudo nixos-rebuild switch --flake "$nix_dir" || true
sleep 1
d_msg "nixos-rebuild finished."
else
d_msg "No update tool found. Skipping."
fi
}
action_repair() {
clear
if command -v nyx-rebuild >/dev/null 2>&1; then
run_with_spinner "Repairing (nyx-rebuild --repair)..." nyx-rebuild --repair || true
if ! check_last_log_for_error; then
return
fi
d_msg "Repair finished."
else
d_msg "No repair tool found. Skipping."
fi
}
action_cleanup() {
clear
if command -v nyx-cleanup >/dev/null 2>&1; then
run_with_spinner "Cleaning up..." nyx-cleanup || true
sleep 1
d_msg "Cleanup finished."
else
d_msg "nyx-cleanup not found; nothing to do."
fi
}
action_update_flake() {
clear
if command -v nix >/dev/null 2>&1 && [[ -d "$nix_dir" ]]; then
( cd "$nix_dir" && run_with_spinner "nix flake update..." nix flake update ) || true
d_msg "Flake update finished."
else
d_msg "nix not installed or flake dir missing: ${nix_dir}"
fi
}
action_git_pull() {
clear
if [[ -d "$nix_dir/.git" ]]; then
( cd "$nix_dir" && run_with_spinner "git pull --rebase..." git pull --rebase ) || true
d_msg "Git pull completed."
else
d_msg "No git repo at: ${nix_dir}"
fi
}
action_system_info() {
local tmp; tmp="$(mktemp)"
{
echo "Host: $(hostname)"
echo "Kernel: $(uname -srmo)"
echo "Uptime: $(uptime -p)"
echo
echo "Disk (root):"
df -h /
echo
if command -v nix >/dev/null 2>&1; then
echo "Nix profiles:"
nix profile list || true
else
echo "Nix not installed."
fi
} > "$tmp"
d_textbox "System Info" "$tmp"
rm -f "$tmp"
}
action_view_logs() {
if [[ -d "$log_dir" ]]; then
local lastlog tmp
tmp="$(mktemp)"
lastlog="$(find "$log_dir" -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null | sort -nr | awk 'NR==1{print $2}')"
if [[ -n "${lastlog:-}" && -f "$lastlog" ]]; then
$PAGER <"$lastlog"
else
d_msg "No logs found in ${log_dir}"
fi
rm -f "$tmp"
else
d_msg "Log directory not found: ${log_dir}"
fi
}
check_last_log_for_error() {
local lastlog
lastlog="$(find "$log_dir" -type f -name '*.log' -printf '%T@ %p\n' 2>/dev/null |
sort -nr | awk 'NR==1{print $2}')"
if [[ -n "${lastlog:-}" && -f "$lastlog" ]]; then
if grep -qi "error" "$lastlog"; then
local tmp
tmp="$(mktemp)"
echo "Error detected in: $(basename "$lastlog")" > "$tmp"
echo >> "$tmp"
grep -A99999 -i "error" "$lastlog" >> "$tmp"
d_textbox "Last Build Error" "$tmp"
rm -f "$tmp"
return 1
elif grep -qi "failed" "$lastlog"; then
local tmp
tmp="$(mktemp)"
echo "Error detected in: $(basename "$lastlog")" > "$tmp"
echo >> "$tmp"
grep -A99999 -i "error" "$lastlog" >> "$tmp"
d_textbox "Last Build Error" "$tmp"
rm -f "$tmp"
return 1
fi
fi
return 0
}
startup() {
clear
if "$do_startup"; then
echo
nyx-tool "Nyx" "nyx-tui" "$version" \
"A better way to nyx" \
"by Peritia-System" \
"https://github.com/Peritia-System/Nyx-Tools" \
"https://github.com/Peritia-System/Nyx-Tools/issues" \
"Because who doesn't love a good TUI"
echo "Loading Nyx TUI..."
echo
local bar_length=25
for ((i=0; i<=bar_length; i++)); do
local filled empty percent
filled=$(printf "%${i}s" | tr ' ' '#')
empty=$(printf "%$((bar_length - i))s" | tr ' ' ' ')
percent=$(( i * 100 / bar_length ))
printf "\r[%s%s] %d%%" "$filled" "$empty" "$percent"
sleep 0.2
# Slow down after 70% (i > 17 when bar_length = 25)
if [[ $i -gt 17 ]]; then
sleep 0.1
fi
done
echo -e "\nAll Loaded!\n"
read -r -p "Press Enter to continue..."
clear
else
echo
nyx-tool "Nyx" "nyx-tui" "$version" \
"A better way to nyx" \
"by Peritia-System" \
"https://github.com/Peritia-System/Nyx-Tools" \
"https://github.com/Peritia-System/Nyx-Tools/issues" \
"Because who doesn't love a good TUI"
read -r -p "Press Enter to continue..."
clear
fi
}
########################################################################
# Menu Loop
########################################################################
startup
while true; do
choice=$(d_menu "Nyx TUI ${version}" "Select an action:" \
1 "Update" \
2 "Rebuild" \
3 "Repair" \
4 "Cleanup (nyx-cleanup)" \
5 "Flake: nix flake update" \
6 "Git pull (in nix dir)" \
7 "System info" \
8 "View latest rebuild log" \
X "Exit") || { clear; exit 0; }
case "$choice" in
1) action_update ;;
2) action_rebuild ;;
3) action_repair ;;
4) action_cleanup ;;
5) action_update_flake ;;
6) action_git_pull ;;
7) action_system_info ;;
8) action_view_logs ;;
X) clear; exit 0 ;;
esac
done