948 lines
24 KiB
Bash
948 lines
24 KiB
Bash
# NOTE:
|
||
# ──────────────────────────────────────< distros.sh >──────────────────────────────────────
|
||
# ╭──────────────────────────────╮
|
||
# │ User variables and functions │
|
||
# ╰──────────────────────────────╯
|
||
distro=""
|
||
ubuntu="false"
|
||
debian="false"
|
||
arch="false"
|
||
fedora="false"
|
||
alpine="false"
|
||
opensuse="false"
|
||
|
||
# Basic Colors
|
||
BLACK=$'\e[30m'
|
||
RED=$'\e[31m'
|
||
GREEN=$'\e[32m'
|
||
YELLOW=$'\e[33m'
|
||
BLUE=$'\e[34m'
|
||
MAGENTA=$'\e[35m'
|
||
CYAN=$'\e[36m'
|
||
WHITE=$'\e[37m'
|
||
|
||
# Bright Colors
|
||
BRIGHT_BLACK=$'\e[90m'
|
||
BRIGHT_RED=$'\e[91m'
|
||
BRIGHT_GREEN=$'\e[92m'
|
||
BRIGHT_YELLOW=$'\e[93m'
|
||
BRIGHT_BLUE=$'\e[94m'
|
||
BRIGHT_MAGENTA=$'\e[95m'
|
||
BRIGHT_CYAN=$'\e[96m'
|
||
BRIGHT_WHITE=$'\e[97m'
|
||
|
||
# Background Colors (standard)
|
||
BG_BLACK=$'\e[40m'
|
||
BG_RED=$'\e[41m'
|
||
BG_GREEN=$'\e[42m'
|
||
BG_YELLOW=$'\e[43m'
|
||
BG_BLUE=$'\e[44m'
|
||
BG_MAGENTA=$'\e[45m'
|
||
BG_CYAN=$'\e[46m'
|
||
BG_WHITE=$'\e[47m'
|
||
|
||
# Background Bright Colors
|
||
BG_BRIGHT_BLACK=$'\e[100m'
|
||
BG_BRIGHT_RED=$'\e[101m'
|
||
BG_BRIGHT_GREEN=$'\e[102m'
|
||
BG_BRIGHT_YELLOW=$'\e[103m'
|
||
BG_BRIGHT_BLUE=$'\e[104m'
|
||
BG_BRIGHT_MAGENTA=$'\e[105m'
|
||
BG_BRIGHT_CYAN=$'\e[106m'
|
||
BG_BRIGHT_WHITE=$'\e[107m'
|
||
|
||
# Styles
|
||
BOLD=$'\e[1m'
|
||
ITALIC=$'\e[3m'
|
||
UNDERLINE=$'\e[4m'
|
||
BLINK=$'\e[5m' # May not work in all terminals
|
||
INVERT=$'\e[7m' # Invert foreground/background
|
||
STRIKE=$'\e[9m' # Strikethrough
|
||
|
||
# Reset
|
||
NC=$'\e[0m' # Reset all styles/colors
|
||
|
||
# INFO:
|
||
# ↓ should get set in the install script itself
|
||
# ↓
|
||
# echo with $PACKAGE and first argument, if 2 exist
|
||
echo_pkg() {
|
||
# if arg 2 does not exist, use normal echo
|
||
if [[ -z $2 ]]; then
|
||
case "$1" in
|
||
build)
|
||
echo "${BOLD}${BRIGHT_RED}${PACKAGE:-PKG}-build:${NC}${BRIGHT_BLUE} Building $PACKAGE ${NC}"
|
||
;;
|
||
clone)
|
||
echo "${BOLD}${BRIGHT_RED}${PACKAGE:-PKG}-clone:${NC}${BRIGHT_YELLOW} Cloning $PACKAGE sources..${NC}"
|
||
;;
|
||
install)
|
||
echo "${BOLD}${BRIGHT_RED}${PACKAGE:-PKG}-install:${NC}${BRIGHT_GREEN} Installing $PACKAGE now!${NC}"
|
||
;;
|
||
*)
|
||
echo "${BOLD}${BRIGHT_RED}${PACKAGE:-PKG}:${NC}${YELLOW} $1 ${NC}"
|
||
;;
|
||
esac
|
||
else
|
||
case "$1" in
|
||
deps | dep | dependencies)
|
||
echo "${BOLD}${BRIGHT_RED}${PACKAGE:-PKG}-${pkger:-dependencies}:${BRIGHT_YELLOW} $2 ${NC}"
|
||
;;
|
||
*)
|
||
echo "${BOLD}${BRIGHT_RED}${PACKAGE:-PKG}-$1:${NC}${BRIGHT_YELLOW} $2 ${NC}"
|
||
;;
|
||
esac
|
||
fi
|
||
}
|
||
|
||
# alias for echo_pkg
|
||
echo-pkg() {
|
||
echo_pkg "$@"
|
||
}
|
||
|
||
echo-error() {
|
||
echo "${BOLD}${RED}${UNDERLINE}ERROR:${NC}${BRIGHT_RED} $1 ${NC}" >&2
|
||
}
|
||
|
||
command-exists() {
|
||
command -v "$@" >/dev/null 2>&1
|
||
}
|
||
|
||
silentexec() {
|
||
"$@" >/dev/null 2>&1
|
||
}
|
||
|
||
run-silent() {
|
||
if [[ -z $silent ]] || ! $silent; then
|
||
"$@"
|
||
else
|
||
silentexec "$@"
|
||
fi
|
||
}
|
||
|
||
# if given an array, it checks if the command is available, and if not - installs all packages in that array one by one
|
||
check-and-install() {
|
||
# local pkg=$1
|
||
# echo "DEBUG:: GOT ARRAY :: ${@}"
|
||
# INFO: if it's not a list, then just check and install the package..
|
||
#
|
||
# if [[ -z $2 ]]; then
|
||
# spin bold yellow "Installing $pkg"
|
||
# if ! command-exists "$pkg"; then
|
||
# if run --err err pkg-install "$pkg"; then
|
||
# upclear
|
||
# check bold "$(pen green bold 'Installed') $pkg"
|
||
# else
|
||
# upclear
|
||
# throw "Something went wrong! Could not install $(pen bold red $pkg)"
|
||
# echo-error "${err:-}"
|
||
# fi
|
||
# else
|
||
# upclear
|
||
# check bold "$pkg $(pen grey bold 'was already installed')"
|
||
# # echo_pkg deps "skipping $pkg - as it's ${RED}already installed.."
|
||
# fi
|
||
# else
|
||
local pkglength="${#@}"
|
||
# ─< else go though the list of items and do the same >───────────────────────────────────
|
||
pen grey "Packages to install: $(pen green bold $pkglength)"
|
||
for pkg in "$@"; do
|
||
if ! command-exists $pkg; then
|
||
spin bold "$(pen bold yellow Installing) $pkg"
|
||
if run --err err pkg-install $pkg; then
|
||
upclear
|
||
check "$(pen bold green Installed) $pkg"
|
||
else
|
||
upclear
|
||
throw "Something went wrong! Could not install $(pen bold red $pkg)"
|
||
echo-error "${err:-}"
|
||
fi
|
||
else
|
||
upclear
|
||
check bold "$pkg $(pen grey bold 'was already installed')"
|
||
fi
|
||
done
|
||
# fi
|
||
}
|
||
|
||
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
|
||
check_env() {
|
||
if [ "$(id -u)" -ne 0 ]; then
|
||
if command-exists sudo; then
|
||
_sudo="sudo -E"
|
||
pen blue "Testing your access.."
|
||
line
|
||
$_sudo echo "${GREEN}${BOLD}Aye, it works!${NC}"
|
||
else
|
||
echo-error "No sudo found and you're not root! Can't install packages."
|
||
return 69
|
||
fi
|
||
else
|
||
pen bold red "Root access confirmed."
|
||
_sudo=""
|
||
fi
|
||
|
||
checkFileAge() {
|
||
local file="$1"
|
||
[[ ! -e "$file" ]] && return 2 # File doesn't exist
|
||
|
||
if [[ $(find "$file" -mtime +7 -print) ]]; then
|
||
return 69 # File is older than 1 week
|
||
else
|
||
return 0 # File is within 1 week
|
||
fi
|
||
}
|
||
}
|
||
|
||
# CAUTION:
|
||
# ╭──────────────────────────────────────────────────────────────────────╮
|
||
# │ This can break really quickly, since the pkg-remove function removes │
|
||
# │ without confirmation! use with CAUTION!! │
|
||
# ╰──────────────────────────────────────────────────────────────────────╯
|
||
_setup() {
|
||
case "$1" in
|
||
debian | ubuntu)
|
||
pkg-install() {
|
||
# $_sudo apt-get install --assume-yes "$@"
|
||
if command-exists nala; then
|
||
pkger=nala
|
||
$_sudo nala install --assume-yes "$@"
|
||
else
|
||
pkger=apt-get
|
||
$_sudo apt-get install --assume-yes "$@"
|
||
fi
|
||
}
|
||
|
||
# CAUTION:
|
||
pkg-remove() {
|
||
if command-exists nala; then
|
||
pkger=nala
|
||
$_sudo nala remove --assume-yes "$@"
|
||
$_sudo nala autoremove --assume-yes
|
||
$_sudo nala autopurge --assume-yes
|
||
else
|
||
pkger=apt-get
|
||
$_sudo apt-get remove --assume-yes "$@"
|
||
$_sudo apt-get autoremove --assume-yes
|
||
fi
|
||
}
|
||
;;
|
||
fedora)
|
||
pkg-install() {
|
||
pkger=dnf
|
||
$_sudo dnf -y install "$@"
|
||
}
|
||
|
||
# CAUTION:
|
||
pkg-remove() {
|
||
pkger=dnf
|
||
$_sudo dnf -y remove "$@"
|
||
}
|
||
;;
|
||
arch)
|
||
pkg-install() {
|
||
if command-exists paru; then
|
||
pkger=paru
|
||
paru -S --color always --noconfirm --needed "$@"
|
||
elif command-exists yay; then
|
||
pkger=yay
|
||
yay -S --color always --noconfirm --needed "$@"
|
||
else
|
||
pkger=pacman
|
||
$_sudo pacman -S --color always --noconfirm --needed "$@"
|
||
fi
|
||
}
|
||
|
||
# CAUTION:
|
||
pkg-remove() {
|
||
if command-exists paru; then
|
||
pkger=paru
|
||
paru -R --color always --noconfirm "$@"
|
||
elif command-exists yay; then
|
||
pkger=yay
|
||
yay -R --color always --noconfirm "$@"
|
||
else
|
||
pkger=pacman
|
||
$_sudo pacman -R --color always --noconfirm "$@"
|
||
fi
|
||
}
|
||
;;
|
||
opensuse)
|
||
pkg-install() {
|
||
pkger=zypper
|
||
$_sudo zypper in "$@"
|
||
}
|
||
|
||
# CAUTION:
|
||
pkg-remove() {
|
||
pkger=zypper
|
||
$_sudo zypper rem "$@"
|
||
}
|
||
;;
|
||
alpine)
|
||
pkg-install() {
|
||
pkger=apk
|
||
apk add "$@"
|
||
}
|
||
|
||
# CAUTION:
|
||
pkg-remove() {
|
||
pkger=apk
|
||
apk remove "$@"
|
||
}
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# ─< Distribution detection and installation >────────────────────────────────────────
|
||
get_packager() {
|
||
# ─< define fallback function >───────────────────────────────────────────────────────────
|
||
fallback() {
|
||
local pkger=""
|
||
for pkg in apt-get dnf pacman apk zypper; do
|
||
if command-exists $pkg; then
|
||
printf "Using ${RED}${pkg}${NC} method.."
|
||
pkger="$pkg"
|
||
|
||
break
|
||
fi
|
||
done
|
||
|
||
case "$pkger" in
|
||
apt-get)
|
||
ubuntu="true"
|
||
debian="true"
|
||
distro="debian"
|
||
;;
|
||
dnf)
|
||
fedora="true"
|
||
distro="fedora"
|
||
;;
|
||
apk)
|
||
alpine="true"
|
||
distro="alpine"
|
||
;;
|
||
pacman)
|
||
arch="true"
|
||
distro="arch"
|
||
;;
|
||
zypper)
|
||
opensuse="true"
|
||
distro="opensuse"
|
||
;;
|
||
*)
|
||
pen red bold "Can not detect distribution correctly!"
|
||
return 69
|
||
;;
|
||
esac
|
||
}
|
||
|
||
if [ -e /etc/os-release ]; then
|
||
upclear
|
||
pen bold grey "Detecting distribution..."
|
||
. /etc/os-release
|
||
|
||
# ─< Convert $ID and $ID_LIKE to lowercase >──────────────────────────────────────────────
|
||
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
|
||
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
|
||
|
||
case "$ID" in
|
||
ubuntu | pop | zorin | kubuntu | linuxmintubuntu)
|
||
ubuntu="true"
|
||
distro="ubuntu"
|
||
;;
|
||
debian | kali | linuxmint | elementary | neon | kdeneon | deepin)
|
||
debian="true"
|
||
distro="debian"
|
||
;;
|
||
fedora | centos | rhel | rocky | almalinux)
|
||
fedora="true"
|
||
distro="fedora"
|
||
;;
|
||
alpine)
|
||
alpine="true"
|
||
distro="alpine"
|
||
;;
|
||
arch | manjaro | garuda | endeavour)
|
||
arch="true"
|
||
distro="arch"
|
||
;;
|
||
opensuse*)
|
||
opensuse="true"
|
||
distro="opensuse"
|
||
;;
|
||
*)
|
||
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
|
||
debian="true"
|
||
distro="debian"
|
||
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
|
||
ubuntu="true"
|
||
distro="ubuntu"
|
||
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
|
||
arch="true"
|
||
distro="arch"
|
||
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
|
||
fedora="true"
|
||
distro="fedora"
|
||
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
|
||
opensuse="true"
|
||
distro="opensuse"
|
||
else
|
||
pen bold red "Unsupported distribution: $ID"
|
||
|
||
spin bold "Trying other methods.."
|
||
sleep 1
|
||
|
||
run fallback && check "Got packager.." || throw "No chance helping you now buddy!"
|
||
fi
|
||
;;
|
||
esac
|
||
else
|
||
pen red bold "Unable to detect distribution - /etc/os-release not found."
|
||
spin bold "Trying other methods.."
|
||
|
||
sleep 1
|
||
|
||
if run fallback; then
|
||
upclear
|
||
check "Got packager.."
|
||
else
|
||
upclear
|
||
throw "No chance helping you now buddy!"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# INFO:
|
||
# ╭────────────────────────────────────────────────────────────────────────────────────────╮
|
||
# │ Automated setup for refreshing repositories and overall getting the variables to setup │
|
||
# ╰────────────────────────────────────────────────────────────────────────────────────────╯
|
||
|
||
dist_setup() {
|
||
case "$distro" in
|
||
debian)
|
||
repen bold "Found $(pen red bold $distro)"
|
||
_setup debian
|
||
# Codename support
|
||
if [ -n $VERSION_CODENAME ]; then
|
||
export $VERSION_CODENAME=$VERSION_CODENAME
|
||
# case "$VERSION_CODENAME" in
|
||
# trixie) trixie=true ;;
|
||
# bookworm) bookworm=true ;;
|
||
# bullseye) bullseye=true ;;
|
||
# buster) buster=true ;;
|
||
# esac
|
||
fi
|
||
;;
|
||
ubuntu)
|
||
repen bold "Found $(pen yellow bold $distro)"
|
||
_setup ubuntu
|
||
# Codename support
|
||
if [ -n $VERSION_CODENAME ]; then
|
||
export $VERSION_CODENAME=$VERSION_CODENAME
|
||
# case "$VERSION_CODENAME" in
|
||
# noble) noble=true ;;
|
||
# jammy) jammy=true ;;
|
||
# focal) focal=true ;;
|
||
# bionic) bionic=true ;;
|
||
# esac
|
||
fi
|
||
;;
|
||
fedora)
|
||
repen bold "Found $(pen blue bold $distro)"
|
||
_setup fedora
|
||
# Add version-specific var like: fedora_40=true
|
||
fedora_version="fedora_${VERSION_ID//./_}"
|
||
eval "$fedora_version=true"
|
||
;;
|
||
arch)
|
||
repen bold "Found $(pen blue bold $distro)"
|
||
_setup arch
|
||
if command-exists yay || command_exists paru; then
|
||
aur=true
|
||
else
|
||
aur=false
|
||
fi
|
||
;;
|
||
alpine)
|
||
repen bold "Found $(pen blue bold $distro)"
|
||
_setup $distro
|
||
;;
|
||
opensuse)
|
||
repen bold "Found $(pen green bold $distro)"
|
||
_setup $distro
|
||
;;
|
||
esac
|
||
}
|
||
|
||
update-package-list() {
|
||
local USER="${USER:-$(whoami)}"
|
||
|
||
repo::check() {
|
||
check "${distro}-repositories up to date" || upclear
|
||
throw "Error while updating $distro repositories.."
|
||
}
|
||
|
||
case "$distro" in
|
||
ubuntu | debian)
|
||
spin bold red "Refreshing $distro sources.."
|
||
if ! run $_sudo apt-get update; then
|
||
upclear
|
||
throw "Error while updating $distro repositories.."
|
||
fi
|
||
;;
|
||
fedora)
|
||
spin blue bold "Refreshing $distro repositories.."
|
||
if ! run $_sudo dnf update; then
|
||
upclear
|
||
throw "Error while updating $distro repositories.."
|
||
fi
|
||
;;
|
||
arch)
|
||
if command-exists pacman; then
|
||
if ! $aur; then
|
||
pen grey bold "If this is your first time after installation (or simmilarly soon) then this might take a while.."
|
||
spin bold grey "You don't have an AUR helper, gonna install one for ya!"
|
||
|
||
local paruBuildDir="/opt/builds"
|
||
silentexec $_sudo mkdir -p "$paruBuildDir"
|
||
|
||
# echo "${YELLOW}Installing paru as AUR helper...${NC}"
|
||
run $_sudo pacman -S --needed --noconfirm base-devel git || throw "Error installing dependencies.."
|
||
|
||
local url="https://aur.archlinux.org/paru-bin.git"
|
||
cd "$paruBuildDir" # && echo "${YELLOW} Cloning paru from ${NC}https://aur.archlinux.org/paru-bin.git"
|
||
run $_sudo git clone $url paru || throw "Error cloning sources from $url"
|
||
|
||
run $_sudo chown -R "$USER": "$paruBuildDir/paru"
|
||
cd "$paruBuildDir/paru"
|
||
|
||
local err
|
||
if run --err err makepkg --noconfirm -si; then
|
||
upclear
|
||
check "Successfully installed $(pen red bold paru)"
|
||
else
|
||
upclear
|
||
throw "Couldn't install paru!"
|
||
echo-error "${err:-}"
|
||
fi
|
||
|
||
if command-exists paru; then
|
||
check green bold "Paru is installed"
|
||
else
|
||
throw bold red "Something went wrong when installing paru!"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
spin blue bold "Refreshing $distro repositories.."
|
||
# sleep 0.01
|
||
|
||
if command-exists paru; then
|
||
if ! run paru -Sy; then
|
||
upclear
|
||
throw "Error while updating $distro repositories.."
|
||
fi
|
||
elif command-exists yay; then
|
||
if ! run yay -Sy; then
|
||
upclear
|
||
throw "Error while updating $distro repositories.."
|
||
fi
|
||
else
|
||
if ! run $_sudo pacman -Sy; then
|
||
upclear
|
||
throw "Error while updating $distro repositories.."
|
||
fi
|
||
fi
|
||
;;
|
||
opensuse)
|
||
spin bold green "Refreshing $distro repositories.."
|
||
if ! run $_sudo zypper ref; then
|
||
upclear
|
||
throw "Error while updating $distro repositories.."
|
||
fi
|
||
;;
|
||
alpine)
|
||
spin bold blue "Refreshing $distro repositories.."
|
||
if ! run $_sudo apk update; then
|
||
upclear
|
||
throw "Error while updating $distro repositories.."
|
||
fi
|
||
;;
|
||
*)
|
||
echo-error "Unsupported distribution: ${BRIGHT_RED}$distro"
|
||
return 69
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# NOTE:
|
||
# ────────────────────────────────────< end distros.sh >────────────────────────────────────
|
||
# ───────────────────────────────────────< beddu.sh >───────────────────────────────────────
|
||
#
|
||
# shellcheck disable=all
|
||
#
|
||
# beddu.sh - A lightweight bash framework for interactive scripts and pretty output
|
||
# Version: v1.1.0
|
||
#
|
||
# Copyright © 2025 Manuele Sarfatti
|
||
# Licensed under the MIT license
|
||
# See https://github.com/mjsarfatti/beddu
|
||
|
||
readonly _q='?'
|
||
readonly _a='❯'
|
||
readonly _o='◌'
|
||
readonly _O='●'
|
||
readonly _mark='✓'
|
||
readonly _warn='!'
|
||
readonly _cross='✗'
|
||
readonly _spinner='⣷⣯⣟⡿⢿⣻⣽⣾' # See for alternatives: https://antofthy.gitlab.io/info/ascii/Spinners.txt
|
||
readonly _spinner_frame_duration=0.15
|
||
|
||
up() {
|
||
printf "\033[A"
|
||
}
|
||
down() {
|
||
printf "\033[B"
|
||
}
|
||
bol() {
|
||
printf "\r"
|
||
}
|
||
eol() {
|
||
printf "\033[999C"
|
||
}
|
||
cl() {
|
||
printf "\033[2K"
|
||
}
|
||
upclear() {
|
||
up
|
||
bol
|
||
cl
|
||
}
|
||
line() {
|
||
printf "\n"
|
||
}
|
||
show_cursor() {
|
||
printf "\033[?25h"
|
||
}
|
||
hide_cursor() {
|
||
printf "\033[?25l"
|
||
}
|
||
|
||
pen() {
|
||
local new_line="\n"
|
||
local text="${*: -1}"
|
||
local args=("${@:1:$#-1}")
|
||
local format_code=""
|
||
local reset_code="\033[0m"
|
||
for arg in "${args[@]}"; do
|
||
arg=${arg,,}
|
||
case "$arg" in
|
||
-n) new_line="" ;;
|
||
bold) format_code+="\033[1m" ;;
|
||
italic) format_code+="\033[3m" ;;
|
||
underline) format_code+="\033[4m" ;;
|
||
black) format_code+="\033[30m" ;;
|
||
red) format_code+="\033[31m" ;;
|
||
green) format_code+="\033[32m" ;;
|
||
yellow) format_code+="\033[33m" ;;
|
||
blue) format_code+="\033[34m" ;;
|
||
purple) format_code+="\033[35m" ;;
|
||
cyan) format_code+="\033[36m" ;;
|
||
white) format_code+="\033[37m" ;;
|
||
grey | gray) format_code+="\033[90m" ;;
|
||
[0-9]*)
|
||
if [[ "$arg" =~ ^[0-9]+$ ]] && [ "$arg" -ge 0 ] && [ "$arg" -le 255 ]; then
|
||
format_code+="\033[38;5;${arg}m"
|
||
fi
|
||
;;
|
||
*) ;;
|
||
esac
|
||
done
|
||
printf "%b%s%b%b" "${format_code}" "${text}" "${reset_code}" "${new_line}"
|
||
}
|
||
|
||
run() {
|
||
local outvar_name errvar_name
|
||
local -n outvar errvar # Declare namerefs (will be assigned below if needed)
|
||
local cmd
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
--out)
|
||
outvar_name="$2"
|
||
shift 2
|
||
;;
|
||
--err)
|
||
errvar_name="$2"
|
||
shift 2
|
||
;;
|
||
*)
|
||
cmd=("$@")
|
||
break
|
||
;;
|
||
esac
|
||
done
|
||
[[ -n "${outvar_name}" ]] && local -n outvar="${outvar_name}"
|
||
[[ -n "${errvar_name}" ]] && local -n errvar="${errvar_name}"
|
||
local stdout_file stderr_file
|
||
stdout_file=$(mktemp)
|
||
stderr_file=$(mktemp)
|
||
"${cmd[@]}" >"${stdout_file}" 2>"${stderr_file}"
|
||
local exit_code=$?
|
||
[[ -n "${outvar_name}" ]] && outvar="$(<"$stdout_file")"
|
||
[[ -n "${errvar_name}" ]] && errvar="$(<"$stderr_file")"
|
||
rm -f "${stdout_file}" "${stderr_file}"
|
||
return $exit_code
|
||
}
|
||
|
||
check() {
|
||
if spinning; then
|
||
spop
|
||
upclear
|
||
fi
|
||
pen -n green "${_mark:-✓} "
|
||
pen "$@"
|
||
}
|
||
|
||
repen() {
|
||
upclear
|
||
pen "$@"
|
||
}
|
||
|
||
trap "spop; show_cursor" EXIT INT TERM
|
||
_spinner_pid=""
|
||
_frame_duration="${_spinner_frame_duration:-0.1}"
|
||
spin() {
|
||
local message=("$@")
|
||
local spinner="${_spinner:-⣷⣯⣟⡿⢿⣻⣽⣾}"
|
||
if spinning; then
|
||
spop --keep-cursor-hidden
|
||
fi
|
||
(
|
||
hide_cursor
|
||
trap "exit 0" USR1
|
||
line
|
||
pen -n cyan "${spinner:0:1} "
|
||
pen "${message[@]}"
|
||
while true; do
|
||
for ((i = 0; i < ${#spinner}; i++)); do
|
||
frame="${spinner:$i:1}"
|
||
up
|
||
bol
|
||
pen -n cyan "${frame} "
|
||
pen "${message[@]}"
|
||
sleep "$_frame_duration"
|
||
done
|
||
done
|
||
) &
|
||
_spinner_pid=$!
|
||
}
|
||
spop() {
|
||
local keep_cursor_hidden=false
|
||
[[ "$1" == "--keep-cursor-hidden" ]] && keep_cursor_hidden=true
|
||
if spinning; then
|
||
kill -USR1 "${_spinner_pid}" 2>/dev/null
|
||
sleep "$_frame_duration"
|
||
if ps -p "${_spinner_pid}" >/dev/null 2>&1; then
|
||
kill "${_spinner_pid}" 2>/dev/null
|
||
fi
|
||
if [[ "$keep_cursor_hidden" == false ]]; then
|
||
show_cursor
|
||
fi
|
||
_spinner_pid=""
|
||
fi
|
||
}
|
||
spinning() {
|
||
[[ -n "${_spinner_pid}" ]]
|
||
}
|
||
|
||
throw() {
|
||
if spinning; then
|
||
spop
|
||
upclear
|
||
fi
|
||
pen -n red "${_cross:-✗} "
|
||
pen "$@"
|
||
}
|
||
|
||
warn() {
|
||
if spinning; then
|
||
spop
|
||
upclear
|
||
fi
|
||
pen -n yellow bold italic "${_warn:-!} "
|
||
pen italic "$@"
|
||
}
|
||
|
||
choose() {
|
||
local -n outvar="$1"
|
||
local prompt
|
||
local options=("${@:3}")
|
||
local current=0
|
||
local count=${#options[@]}
|
||
prompt=$(
|
||
pen -n blue "${_q:-?} "
|
||
pen -n "${2} "
|
||
pen gray "[↑↓]"
|
||
)
|
||
hide_cursor
|
||
trap 'show_cursor; return' INT TERM
|
||
pen "$prompt"
|
||
while true; do
|
||
local index=0
|
||
for item in "${options[@]}"; do
|
||
if ((index == current)); then
|
||
pen -n blue "${_O:-●} "
|
||
pen "${item}"
|
||
else
|
||
pen gray "${_o:-◌} ${item}"
|
||
fi
|
||
((index++))
|
||
done
|
||
read -s -r -n1 key
|
||
if [[ $key == $'\e' ]]; then
|
||
read -s -r -n2 -t 0.0001 escape
|
||
key+="$escape"
|
||
fi
|
||
case "$key" in
|
||
$'\e[A' | 'k')
|
||
((current--))
|
||
[[ $current -lt 0 ]] && current=$((count - 1))
|
||
;;
|
||
$'\e[B' | 'j')
|
||
((current++))
|
||
[[ $current -ge "$count" ]] && current=0
|
||
;;
|
||
'q')
|
||
upclear
|
||
pen red bold "User exited the session with exit code 69!"
|
||
pen red "This is $(pen bold red 'NOT') an accident!"
|
||
exit 69
|
||
;;
|
||
'')
|
||
break
|
||
;;
|
||
esac
|
||
echo -en "\e[${count}A\e[J"
|
||
done
|
||
outvar="${options[$current]}"
|
||
}
|
||
|
||
confirm() {
|
||
local default="y"
|
||
local hint="[Y/n]"
|
||
local prompt
|
||
local response
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
--default-no)
|
||
default="n"
|
||
hint="[y/N]"
|
||
shift
|
||
;;
|
||
--default-yes)
|
||
shift
|
||
;;
|
||
*) break ;;
|
||
esac
|
||
done
|
||
prompt=$(
|
||
pen -n blue "${_q:-?} "
|
||
pen -n "$1"
|
||
pen gray " $hint"
|
||
pen -n blue "${_a:-❯} "
|
||
)
|
||
show_cursor
|
||
while true; do
|
||
read -r -p "$prompt" response
|
||
response="${response:-$default}"
|
||
case "$response" in
|
||
[Yy] | [Yy][Ee][Ss])
|
||
upclear
|
||
pen -n blue "${_a:-❯} "
|
||
pen "yes"
|
||
return 0
|
||
;;
|
||
[Nn] | [Nn][Oo])
|
||
upclear
|
||
pen -n blue "${_a:-❯} "
|
||
pen "no"
|
||
return 1
|
||
;;
|
||
[qQ] | quit)
|
||
upclear
|
||
pen red bold "User exited the session with exit code 69!"
|
||
pen red "This is $(pen bold red 'NOT') an accident!"
|
||
exit 69
|
||
;;
|
||
*)
|
||
echo
|
||
warn "Please answer yes or no."
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
request() {
|
||
local -n outvar="$1"
|
||
local prompt
|
||
local answer
|
||
prompt=$(
|
||
pen -n blue "${_q:-?} "
|
||
pen "${2}"
|
||
pen -n blue "${_a:-❯} "
|
||
)
|
||
show_cursor
|
||
while true; do
|
||
read -r -p "$prompt" answer
|
||
case "$answer" in
|
||
"")
|
||
echo
|
||
warn "Please type your answer."
|
||
;;
|
||
*) break ;;
|
||
esac
|
||
done
|
||
outvar="$answer"
|
||
}
|
||
|
||
seek() {
|
||
local -n outvar="$1"
|
||
local prompt
|
||
local answer
|
||
prompt=$(
|
||
pen -n blue "${_q:-?} "
|
||
pen "${2}"
|
||
pen -n blue "${_a:-❯} "
|
||
)
|
||
show_cursor
|
||
read -r -p "$prompt" answer
|
||
outvar="$answer"
|
||
}
|
||
# NOTE:
|
||
# ──────────────────────────────────────< end beddu >────────────────────────────────────
|
||
|
||
if check_env; then
|
||
# ─< gets the some variables like $aur, $debian, $ubuntu, $distro... >────────────────────
|
||
get_packager
|
||
|
||
# ─< get more indepths variables like $trixie, $bookworm, $jammy, $fedora_40.. >──────────
|
||
dist_setup
|
||
|
||
# WHY:
|
||
# ╭─────────────────────────────────────────────────────────────────────────╮
|
||
# │ check if the script has run at least once, so that the sources dont │
|
||
# │ have to get updated again.. │
|
||
# ╰─────────────────────────────────────────────────────────────────────────╯
|
||
pikaCheckFile="$HOME/.cache/pika_script_detection"
|
||
|
||
if [ ! -f "$pikaCheckFile" ]; then
|
||
pen bold grey "First time importing.."
|
||
|
||
if update-package-list; then
|
||
silentexec touch "$pikaCheckFile"
|
||
fi
|
||
else
|
||
echo_pkg "Skipping repo refresh"
|
||
fi
|
||
fi
|