#!/usr/bin/env bash # utils.sh — colors, prompts, helpers RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' BOLD='\033[1m' RESET='\033[0m' info() { echo -e "${CYAN}${BOLD}[info]${RESET} $*"; } success() { echo -e "${GREEN}${BOLD}[ok]${RESET} $*"; } warn() { echo -e "${YELLOW}${BOLD}[warn]${RESET} $*"; } error() { echo -e "${RED}${BOLD}[error]${RESET} $*" >&2; } die() { error "$*"; exit 1; } header() { echo -e "\n${BOLD}${CYAN}━━━ $* ━━━${RESET}\n"; } # ask VAR "prompt" "default" ask() { local var="$1" prompt="$2" default="$3" if [[ -n "$default" ]]; then echo -ne "${BOLD}${prompt}${RESET} ${CYAN}[${default}]${RESET}: " else echo -ne "${BOLD}${prompt}${RESET}: " fi read -r input if [[ -z "$input" && -n "$default" ]]; then eval "$var=\"$default\"" else eval "$var=\"$input\"" fi } # ask_yn VAR "prompt" "y|n" ask_yn() { local var="$1" prompt="$2" default="$3" local options if [[ "$default" == "y" ]]; then options="Y/n"; else options="y/N"; fi echo -ne "${BOLD}${prompt}${RESET} ${CYAN}[${options}]${RESET}: " read -r input input="${input:-$default}" if [[ "$input" =~ ^[Yy]$ ]]; then eval "$var=y" else eval "$var=n" fi } # ask_choice VAR "prompt" option1 option2 ... ask_choice() { local var="$1" prompt="$2"; shift 2 local options=("$@") echo -e "${BOLD}${prompt}${RESET}" for i in "${!options[@]}"; do echo -e " ${CYAN}$((i+1))${RESET}) ${options[$i]}" done echo -ne "Choice ${CYAN}[1]${RESET}: " read -r input input="${input:-1}" if [[ "$input" =~ ^[0-9]+$ ]] && (( input >= 1 && input <= ${#options[@]} )); then eval "$var=\"${options[$((input-1))]}\"" else eval "$var=\"${options[0]}\"" fi } require_cmd() { command -v "$1" &>/dev/null || die "Required command not found: $1" } slugify() { echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | sed 's/^-//;s/-$//' }