#!/usr/bin/env bash # ============================================================================= # install-cli-apps.sh # Detects the system package manager, then installs each app in APPS[]. # Reports whether each app was already installed or freshly installed. # ============================================================================= set -euo pipefail # ----------------------------------------------------------------------------- # πŸ”§ CONFIGURATION β€” edit this list to suit your needs # ----------------------------------------------------------------------------- APPS=( git curl wget htop tree jq unzip ripgrep fzf bat neofetch tmux vim ) # ----------------------------------------------------------------------------- # Colour 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}[SKIP]${RESET} $*"; } error() { echo -e "${RED}${BOLD}[ERROR]${RESET} $*" >&2; } # ----------------------------------------------------------------------------- # Detect package manager # ----------------------------------------------------------------------------- detect_package_manager() { if command -v apt-get &>/dev/null; then PM="apt-get"; INSTALL_CMD="apt-get install -y" elif command -v apt &>/dev/null; then PM="apt"; INSTALL_CMD="apt install -y" elif command -v dnf &>/dev/null; then PM="dnf"; INSTALL_CMD="dnf install -y" elif command -v yum &>/dev/null; then PM="yum"; INSTALL_CMD="yum install -y" elif command -v pacman &>/dev/null; then PM="pacman"; INSTALL_CMD="pacman -S --noconfirm" elif command -v zypper &>/dev/null; then PM="zypper"; INSTALL_CMD="zypper install -y" elif command -v brew &>/dev/null; then PM="brew"; INSTALL_CMD="brew install" elif command -v apk &>/dev/null; then PM="apk"; INSTALL_CMD="apk add" elif command -v xbps-install &>/dev/null; then PM="xbps"; INSTALL_CMD="xbps-install -y" elif command -v emerge &>/dev/null; then PM="emerge"; INSTALL_CMD="emerge" else error "No supported package manager found. Aborting." exit 1 fi } # ----------------------------------------------------------------------------- # Check if a binary is already available on PATH # ----------------------------------------------------------------------------- is_installed() { command -v "$1" &>/dev/null } # ----------------------------------------------------------------------------- # Privilege escalation β€” skip sudo for root or brew # ----------------------------------------------------------------------------- maybe_sudo() { if [[ "$PM" == "brew" ]] || [[ "$(id -u)" -eq 0 ]]; then "$@" else sudo "$@" fi } # ----------------------------------------------------------------------------- # Update package index (once, where applicable) # ----------------------------------------------------------------------------- update_index() { case "$PM" in apt-get|apt) info "Updating package index (apt)…" maybe_sudo apt-get update -qq ;; dnf|yum) info "Refreshing metadata (${PM})…" maybe_sudo "$PM" makecache -q ;; pacman) info "Syncing package database (pacman)…" maybe_sudo pacman -Sy --noconfirm ;; zypper) info "Refreshing repos (zypper)…" maybe_sudo zypper refresh -q ;; apk) info "Updating index (apk)…" maybe_sudo apk update -q ;; brew) info "Running brew update…" brew update --quiet ;; *) : # xbps, emerge β€” no pre-update needed here ;; esac } # ----------------------------------------------------------------------------- # Install a single package # ----------------------------------------------------------------------------- install_package() { local pkg="$1" # shellcheck disable=SC2086 maybe_sudo $INSTALL_CMD "$pkg" } # ----------------------------------------------------------------------------- # Main # ----------------------------------------------------------------------------- main() { echo "" echo -e "${BOLD}======================================${RESET}" echo -e "${BOLD} CLI App Installer ${RESET}" echo -e "${BOLD}======================================${RESET}" echo "" detect_package_manager info "Detected package manager: ${BOLD}${PM}${RESET}" echo "" update_index echo "" local already_installed=() local newly_installed=() local failed=() for app in "${APPS[@]}"; do if is_installed "$app"; then warn "${app} is already installed β€” skipping." already_installed+=("$app") else info "Installing ${app}…" if install_package "$app" &>/dev/null; then success "${app} installed successfully." newly_installed+=("$app") else error "Failed to install ${app}." failed+=("$app") fi fi done # ── Summary ──────────────────────────────────────────────────────────────── echo "" echo -e "${BOLD}======================================${RESET}" echo -e "${BOLD} Summary ${RESET}" echo -e "${BOLD}======================================${RESET}" echo -e "\n${GREEN}${BOLD}Newly installed (${#newly_installed[@]}):${RESET}" if [[ ${#newly_installed[@]} -eq 0 ]]; then echo " (none)" else for app in "${newly_installed[@]}"; do echo " βœ” $app"; done fi echo -e "\n${YELLOW}${BOLD}Already installed (${#already_installed[@]}):${RESET}" if [[ ${#already_installed[@]} -eq 0 ]]; then echo " (none)" else for app in "${already_installed[@]}"; do echo " ● $app"; done fi if [[ ${#failed[@]} -gt 0 ]]; then echo -e "\n${RED}${BOLD}Failed (${#failed[@]}):${RESET}" for app in "${failed[@]}"; do echo " ✘ $app"; done echo "" exit 1 fi echo "" } main "$@"