diff --git a/profile.d/packages.sh b/profile.d/packages.sh index 15d7d37..41cd68f 100644 --- a/profile.d/packages.sh +++ b/profile.d/packages.sh @@ -34,9 +34,73 @@ # * OF SUCH DAMAGE. # ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ +# Detect the active package manager of the current distribution. +# Detection is based on /etc/os-release (ID / ID_LIKE), then falls back to +# checking available binaries in a fixed priority order. +# Echoes one of: apt dnf yum zypper pacman apk portage xbps nix +# Returns 1 if no known package manager could be identified. +_get_pkgmgr() +{ + local distro_id="" distro_like="" + if [[ -r /etc/os-release ]]; then + # shellcheck disable=SC1091 + distro_id=$( . /etc/os-release 2>/dev/null; printf '%s' "${ID:-}" ) + # shellcheck disable=SC1091 + distro_like=$( . /etc/os-release 2>/dev/null; printf '%s' "${ID_LIKE:-}" ) + fi + + # Map distro IDs/families to a package manager. + # ID_LIKE is space-separated and may list multiple families. + local id + for id in $distro_id $distro_like; do + case "${id,,}" in + debian|ubuntu|linuxmint|raspbian|pop|kali|elementary|zorin|neon|parrot) + echo "apt"; return 0 ;; + fedora) + echo "dnf"; return 0 ;; + rhel|centos|rocky|almalinux|ol|scientific|amzn) + command -v dnf >/dev/null 2>&1 && { echo "dnf"; return 0; } + echo "yum"; return 0 ;; + opensuse*|sles|sled) + echo "zypper"; return 0 ;; + arch|manjaro|endeavouros|garuda|artix|cachyos) + echo "pacman"; return 0 ;; + alpine) + echo "apk"; return 0 ;; + gentoo) + echo "portage"; return 0 ;; + void) + echo "xbps"; return 0 ;; + nixos) + echo "nix"; return 0 ;; + esac + done + + # Fallback: check for binaries in priority order. + local bin + for bin in apt-get dnf yum zypper pacman apk emerge xbps-install nix-env; do + command -v "$bin" >/dev/null 2>&1 && { + case "$bin" in + apt-get) echo "apt" ;; + emerge) echo "portage" ;; + xbps-install) echo "xbps" ;; + nix-env) echo "nix" ;; + *) echo "$bin" ;; + esac + return 0 + } + done + + return 1 +} +export -f _get_pkgmgr +# ------------------------------------------------------------------------------ + + # ------------------------------------------------------------------------------ # Look for a package within installed one -# Usage: dpkgs +# Usage: pkgs pkgs() { local ignore_case=${PKGS_DEFAULT_IGNORE_CASE:-0} @@ -85,13 +149,28 @@ pkgs() local grep_opt="" (( ignore_case )) && grep_opt="-i" - command -v dpkg >/dev/null 2>&1 && local cmd="dpkg -l" - command -v rpm >/dev/null 2>&1 && local cmd="rpm -qa" - if [[ -z $cmd ]]; then - disp E "No usable package manager seems avialable." + local pkgmgr + pkgmgr=$(_get_pkgmgr) || { + disp E "No usable package manager could be detected on this system." return 2 - fi - $cmd | grep "$grep_opt" "$pkg" + } + + local -a list_cmd + case "$pkgmgr" in + apt) list_cmd=(dpkg-query -l) ;; + dnf|yum|zypper) list_cmd=(rpm -qa) ;; + pacman) list_cmd=(pacman -Q) ;; + apk) list_cmd=(apk list --installed) ;; + portage) list_cmd=(qlist -I) ;; + xbps) list_cmd=(xbps-query -l) ;; + nix) list_cmd=(nix-env -q) ;; + *) + disp E "Package manager '$pkgmgr' is not supported by pkgs." + return 2 + ;; + esac + + "${list_cmd[@]}" | grep ${grep_opt:+"$grep_opt"} "$pkg" } export -f pkgs # ------------------------------------------------------------------------------