#!/usr/bin/env bash # Install rip.sh dependencies — supports apt, dnf, pacman, zypper, brew set -euo pipefail die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; } log() { printf '==> %s\n' "$*"; } info() { printf ' %s\n' "$*"; } usage() { cat <<'EOF' Usage: install-deps.sh [--help] Install dependencies required by rip.sh. Required tools (cdparanoia ffmpeg lame curl jq flock) are installed unconditionally; optional tools (discid id3v2) are installed after prompting. The package manager is detected automatically (pacman, apt, dnf, zypper, brew). EOF } # --------------------------------------------------------------------------- # Package map: tool -> (apt dnf pacman zypper brew) # --------------------------------------------------------------------------- # Format per manager: "pkg" or "" if not available / handled separately declare -A APT PACMAN DNF ZYPPER BREW # required APT[cdparanoia]=cdparanoia APT[ffmpeg]=ffmpeg APT[lame]=lame APT[curl]=curl APT[jq]=jq APT[flock]=util-linux # almost always pre-installed # optional APT[discid]=discid APT[id3v2]=id3v2 PACMAN[cdparanoia]=cdparanoia PACMAN[ffmpeg]=ffmpeg PACMAN[lame]=lame PACMAN[curl]=curl PACMAN[jq]=jq PACMAN[flock]=util-linux # almost always pre-installed PACMAN[discid]=libdiscid # provides the `discid` binary PACMAN[id3v2]=id3v2 DNF[cdparanoia]=cdparanoia DNF[ffmpeg]=ffmpeg # needs RPM Fusion enabled DNF[lame]=lame # needs RPM Fusion enabled DNF[curl]=curl DNF[jq]=jq DNF[flock]=util-linux DNF[discid]=libdiscid DNF[id3v2]=id3v2 ZYPPER[cdparanoia]=cdparanoia ZYPPER[ffmpeg]=ffmpeg ZYPPER[lame]=lame ZYPPER[curl]=curl ZYPPER[jq]=jq ZYPPER[flock]=util-linux ZYPPER[discid]=libdiscid-tools ZYPPER[id3v2]=id3v2 BREW[cdparanoia]=cdparanoia BREW[ffmpeg]=ffmpeg BREW[lame]=lame BREW[curl]=curl BREW[jq]=jq BREW[flock]=flock # standalone formula on macOS BREW[discid]=libdiscid BREW[id3v2]=id3v2 REQUIRED=(cdparanoia ffmpeg lame curl jq flock) OPTIONAL=(discid id3v2) # --------------------------------------------------------------------------- # Detect package manager # --------------------------------------------------------------------------- detect_pm() { if command -v pacman &>/dev/null; then echo pacman; return; fi if command -v apt-get &>/dev/null; then echo apt; return; fi if command -v dnf &>/dev/null; then echo dnf; return; fi if command -v zypper &>/dev/null; then echo zypper; return; fi if command -v brew &>/dev/null; then echo brew; return; fi echo "" } # --------------------------------------------------------------------------- # Check which tools are already installed # --------------------------------------------------------------------------- missing_tools() { local -n _list="$1" local missing=() for tool in "${_list[@]}"; do # discid ships the binary as `discid`; cd-discid is an alternative if [[ "$tool" == "discid" ]]; then command -v discid &>/dev/null && continue command -v cd-discid &>/dev/null && continue missing+=("$tool") else command -v "$tool" &>/dev/null || missing+=("$tool") fi done echo "${missing[@]:-}" } # --------------------------------------------------------------------------- # Install # --------------------------------------------------------------------------- install_packages() { local pm="$1" shift local -a pkgs=("$@") [[ ${#pkgs[@]} -eq 0 ]] && return 0 case "$pm" in pacman) sudo pacman -S --needed --noconfirm "${pkgs[@]}" ;; apt) sudo apt-get update -qq sudo apt-get install -y "${pkgs[@]}" ;; dnf) sudo dnf install -y "${pkgs[@]}" ;; zypper) sudo zypper install -y "${pkgs[@]}" ;; brew) brew install "${pkgs[@]}" ;; esac } pkg_name() { local pm="$1" tool="$2" case "$pm" in pacman) echo "${PACMAN[$tool]:-}" ;; apt) echo "${APT[$tool]:-}" ;; dnf) echo "${DNF[$tool]:-}" ;; zypper) echo "${ZYPPER[$tool]:-}" ;; brew) echo "${BREW[$tool]:-}" ;; esac } # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- main() { [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { usage; exit 0; } local pm pm=$(detect_pm) if [[ -z "$pm" ]]; then die "No supported package manager found (apt, dnf, pacman, zypper, brew)" fi log "Package manager: $pm" # Warn about RPM Fusion for dnf (ffmpeg/lame are in restricted repos) if [[ "$pm" == "dnf" ]]; then info "Note: ffmpeg and lame require RPM Fusion (https://rpmfusion.org)." info " Enable with: sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-\$(rpm -E %fedora).noarch.rpm" echo "" fi # --- Required --- local -a req_missing read -ra req_missing <<< "$(missing_tools REQUIRED)" if [[ ${#req_missing[@]} -gt 0 ]]; then log "Installing required packages: ${req_missing[*]}" local -a req_pkgs=() for tool in "${req_missing[@]}"; do local pkg pkg=$(pkg_name "$pm" "$tool") [[ -n "$pkg" ]] && req_pkgs+=("$pkg") done install_packages "$pm" "${req_pkgs[@]}" else log "All required tools already installed" fi # --- Optional --- local -a opt_missing read -ra opt_missing <<< "$(missing_tools OPTIONAL)" if [[ ${#opt_missing[@]} -gt 0 ]]; then echo "" log "Optional tools missing: ${opt_missing[*]}" info " discid — MusicBrainz disc ID lookup (enables automatic metadata)" info " id3v2 — writes ID3 tags to MP3 files" echo "" read -rp "Install optional tools? [Y/n] " ans if [[ "${ans,,}" != "n" ]]; then local -a opt_pkgs=() for tool in "${opt_missing[@]}"; do local pkg pkg=$(pkg_name "$pm" "$tool") [[ -n "$pkg" ]] && opt_pkgs+=("$pkg") done install_packages "$pm" "${opt_pkgs[@]}" fi else log "All optional tools already installed" fi # --- Final check --- echo "" log "Verification:" local all_ok=true for tool in "${REQUIRED[@]}" "${OPTIONAL[@]}"; do local status if [[ "$tool" == "discid" ]]; then (command -v discid &>/dev/null || command -v cd-discid &>/dev/null) \ && status="ok" || status="MISSING" else command -v "$tool" &>/dev/null && status="ok" || status="MISSING" fi printf ' %-15s %s\n' "$tool" "$status" [[ "$status" == "ok" ]] || all_ok=false done echo "" if [[ "$all_ok" == true ]]; then log "All tools ready. Run: ./rip.sh" else log "Some required tools are still missing — check the output above." exit 1 fi } main "$@"