#!/usr/bin/env bash # Bootstrap for installing scripts from Klick3R-1/.bin (root-level files) # Usage: # curl -fsSL https://scripts.klick3r.com | bash # curl -fsSL https://scripts.klick3r.com | bash -s -- list # curl -fsSL https://scripts.klick3r.com | bash -s -- NAME # BRANCH=master curl -fsSL https://scripts.klick3r.com | bash -s -- list set -Eeuo pipefail # If we're piped (curl | bash), restore stdin to TTY so `read` works. if [ ! -t 0 ] && [ -r /dev/tty ]; then exec /dev/null 2>&1; } abort() { echo "Error: $*" >&2; exit 1; } curl_api() { if [ -n "${GH_TOKEN:-}" ]; then curl "${CURL_OPTS[@]}" "${API_ACCEPT[@]}" -H "Authorization: Bearer ${GH_TOKEN}" "$@" else curl "${CURL_OPTS[@]}" "${API_ACCEPT[@]}" "$@" fi } curl_file() { if [ -n "${GH_TOKEN:-}" ]; then curl "${CURL_OPTS[@]}" -H "Authorization: Bearer ${GH_TOKEN}" "$@" else curl "${CURL_OPTS[@]}" "$@" fi } download_to() { local url="$1" dest="$2" curl_file "$url" -o "$dest" } _branch_candidates() { printf '%s\n' "$BRANCH" "main" "master" | awk '!seen[$0]++'; } # Fast + dependency-free: GitHub Trees API (root only) fetch_root_files() { local b resp names for b in $(_branch_candidates); do resp="$(curl_api "https://api.github.com/repos/${REPO_USER}/${REPO_NAME}/git/trees/${b}" 2>/dev/null || true)" # Basic sanity: must contain a "tree" array if ! printf '%s' "$resp" | grep -q '"tree"'; then continue; fi # Split objects and print path for type=blob names="$( printf '%s' "$resp" \ | tr -d '\n' | sed 's/},{/}\n{/g' \ | awk -F'"' '/"type":"blob"/ { for (i=1;i<=NF;i++) if ($i=="path") { print $(i+2) } }' \ | grep -Ev "$SKIP_REGEX" \ | grep -v '/' \ | sort -u )" if [ -n "$names" ]; then __EFFECTIVE_BRANCH="$b" printf '%s\n' "$names" return 0 fi done abort "Could not list files from ${REPO_USER}/${REPO_NAME} (branches tried: $(_branch_candidates | paste -sd, -))." } effective_branch() { echo "${__EFFECTIVE_BRANCH:-$BRANCH}"; } raw_url_for() { local name="$1" b; b="$(effective_branch)" echo "https://raw.githubusercontent.com/${REPO_USER}/${REPO_NAME}/${b}/${name}" } ensure_path() { if ! echo ":$PATH:" | grep -q ":$HOME/.bin:"; then echo "ℹ️ ~/.bin is not in PATH. Add to your shell rc:" echo ' export PATH="$HOME/.bin:$PATH"' echo fi } select_file() { mapfile -t FILES < <(fetch_root_files) ((${#FILES[@]})) || abort "No files found in repo root." echo "Available scripts (${#FILES[@]}):" for ((i=0;i<${#FILES[@]};i++)); do printf " %2d) %s\n" "$((i+1))" "${FILES[$i]}"; done echo while true; do read -rp "Enter number [1]: " choice || true [[ -z "${choice:-}" ]] && choice=1 if [[ "$choice" =~ ^[0-9]+$ ]] && (( choice>=1 && choice<=${#FILES[@]} )); then echo "${FILES[choice-1]}" return 0 fi echo "Invalid choice. Try again." done } install_file() { local name="$1" mkdir -p "$HOME/.bin" download_to "$(raw_url_for "$name")" "$HOME/.bin/${name}" chmod +x "$HOME/.bin/${name}" echo "✅ Installed: $HOME/.bin/${name}" } maybe_run() { local name="$1" read -rp "Run '${name}' now? [y/N]: " ans || true case "${ans:-}" in y|Y) exec "$HOME/.bin/${name}";; *) echo "Done. Run later with: ${name}";; esac } usage() { cat <<'EOF' Usage: curl -fsSL https://scripts.klick3r.com | bash # interactive picker curl -fsSL https://scripts.klick3r.com | bash -s -- list # list available (repo root) curl -fsSL https://scripts.klick3r.com | bash -s -- NAME # install NAME directly Env: BRANCH=... # override branch (default: main; tries main→master automatically) GH_TOKEN=... # optional to lift GitHub API rate limits EOF } main() { ensure_path case "${1:-}" in "" ) name="$(select_file)"; install_file "$name"; maybe_run "$name" ;; list ) fetch_root_files ;; -h|--help|help ) usage ;; * ) # Verify existence before install if fetch_root_files | grep -Fxq -- "$1"; then install_file "$1"; maybe_run "$1" else echo "Unknown script: $1" echo; usage echo "Available:"; fetch_root_files exit 1 fi ;; esac } main "$@"