194 lines
6.1 KiB
Bash
Executable File
194 lines
6.1 KiB
Bash
Executable File
#!/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 "$@"
|