diff --git a/shellkit.sh b/shellkit.sh index bcfd538..52b3db8 100644 --- a/shellkit.sh +++ b/shellkit.sh @@ -117,4 +117,109 @@ running() { done } -echo "shellkit loaded. Available: check, ensure, spinner, backup, confirm, bench, random_string, jsonval, dedup, coln, sum, running" +# ── countdown — visual countdown timer ───────────────── +# Usage: countdown 10 "Liftoff!" +countdown() { + local secs="${1:-5}" + local msg="${2:-Done}" + while [ "$secs" -gt 0 ]; do + printf "\r${YELLOW}⏳${NC} %2d seconds... " "$secs" + sleep 1 + secs=$((secs - 1)) + done + printf "\r${GREEN}✓${NC} %s \n" "$msg" +} + +# ── progress — draw a progress bar ──────────────────── +# Usage: for i in $(seq 1 100); do progress $i 100 "Processing"; sleep 0.05; done; echo +progress() { + local current="${1:-0}" + local total="${2:-100}" + local label="${3:-}" + local width=40 + local pct=$((current * 100 / total)) + local filled=$((pct * width / 100)) + local empty=$((width - filled)) + printf "\r${label:+$label }[" + printf "%${filled}s" | tr ' ' '█' + printf "%${empty}s" | tr ' ' '░' + printf "] %3d%%" "$pct" +} + +# ── http_status — quick HTTP status check ───────────── +# Usage: http_status https://example.com +http_status() { + local url="$1" + local code + code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$url" 2>/dev/null) + if [ -z "$code" ]; then + echo -e "${RED}✗${NC} $url — unreachable" + return 1 + elif [ "${code:0:1}" = "2" ] || [ "${code:0:1}" = "3" ]; then + echo -e "${GREEN}✓${NC} $url — $code" + return 0 + else + echo -e "${RED}✗${NC} $url — $code" + return 1 + fi +} + +# ── envfile — load .env files safely ────────────────── +# Usage: envfile .env +envfile() { + local file="${1:-.env}" + if [ ! -f "$file" ]; then + echo -e "${RED}✗${NC} $file not found" + return 1 + fi + while IFS='=' read -r key value; do + # Skip comments and empty lines + case "$key" in + ""|\#*) continue ;; + esac + # Strip quotes and whitespace + value="${value#\"}"; value="${value%\"}" + value="${value#\'}"; value="${value%\'}" + export "$key"="$value" + done < "$file" + local count + count=$(grep -c '=' "$file" 2>/dev/null || echo 0) + echo -e "${GREEN}✓${NC} Loaded $count vars from $file" +} + +# ── healthcheck — TCP port check with timeout ───────── +# Usage: healthcheck localhost 5432 5 +healthcheck() { + local host="${1:-localhost}" + local port="${2:-80}" + local timeout="${3:-3}" + if timeout "$timeout" bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null; then + echo -e "${GREEN}✓${NC} $host:$port — healthy" + return 0 + else + echo -e "${RED}✗${NC} $host:$port — not responding" + return 1 + fi +} + +# ── retry — retry a command N times with backoff ────── +# Usage: retry 3 2 curl https://flakey-api.example.com +retry() { + local max="${1:-3}" + local delay="${2:-1}" + shift 2 + local attempt=0 + until "$@"; do + attempt=$((attempt + 1)) + if [ "$attempt" -ge "$max" ]; then + echo -e "${RED}✗${NC} Failed after $max attempts" + return 1 + fi + echo -e "${YELLOW}→${NC} Attempt $attempt/$max failed, retrying in ${delay}s..." + sleep "$delay" + delay=$((delay * 2)) + done + return 0 +} + +echo "shellkit loaded. Available: check, ensure, spinner, backup, confirm, bench, random_string, jsonval, dedup, coln, sum, running, countdown, progress, http_status, envfile, healthcheck, retry"