linuxbox/update/lib/packages.sh

406 lines
11 KiB
Bash

#!/bin/bash
# CMtec Update System - Package Management Abstraction Layer
# Provides unified interface for different package managers
# Package manager detection and initialization
init_package_managers() {
log INFO "Initializing package managers for ${SYSTEM_INFO[DISTRO]}..."
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
PACKAGE_MANAGER="pacman"
AUR_HELPER=""
detect_aur_helper
FLATPAK_AVAILABLE=$(command_exists flatpak && echo "yes" || echo "no")
;;
"ubuntu"|"debian")
PACKAGE_MANAGER="apt"
SNAP_AVAILABLE=$(command_exists snap && echo "yes" || echo "no")
FLATPAK_AVAILABLE=$(command_exists flatpak && echo "yes" || echo "no")
;;
*)
log ERROR "Unsupported distribution: ${SYSTEM_INFO[DISTRO]}"
return 1
;;
esac
log SUCCESS "Package managers initialized"
log INFO "Primary: $PACKAGE_MANAGER"
[ -n "$AUR_HELPER" ] && log INFO "AUR helper: $AUR_HELPER"
[ "$FLATPAK_AVAILABLE" == "yes" ] && log INFO "Flatpak: available"
[ "$SNAP_AVAILABLE" == "yes" ] && log INFO "Snap: available"
}
# Detect AUR helper for Arch systems
detect_aur_helper() {
local helpers=("yay" "paru" "pikaur" "trizen")
for helper in "${helpers[@]}"; do
if command_exists "$helper"; then
AUR_HELPER="$helper"
log INFO "Found AUR helper: $helper"
return 0
fi
done
log WARNING "No AUR helper found - will install yay if needed"
AUR_HELPER=""
}
# Install AUR helper (yay) if not present
install_aur_helper() {
if [ -n "$AUR_HELPER" ]; then
return 0
fi
log INFO "Installing yay AUR helper..."
local section_start=$(date +%s)
# Clean up any existing build directory
[ -d ~/yay-bin ] && rm -rf ~/yay-bin
cd ~
(
git clone https://aur.archlinux.org/yay-bin.git 2>&1 | tee -a "$LOG_FILE"
cd yay-bin
makepkg --noconfirm -si 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing yay AUR helper..."
wait
# Clean up build directory
[ -d ~/yay-bin ] && rm -rf ~/yay-bin
AUR_HELPER="yay"
log SUCCESS "Yay AUR helper installed $(show_timer $section_start)"
}
# Update package databases
update_package_databases() {
local section_start=$(date +%s)
log SECTION "Updating package databases"
case "$PACKAGE_MANAGER" in
"pacman")
if confirm "Refresh pacman package databases?"; then
(
sudo pacman -Syy --noconfirm 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Refreshing pacman databases..."
wait
log SUCCESS "Pacman databases updated $(show_timer $section_start)"
else
log WARNING "Package database refresh skipped"
fi
;;
"apt")
if confirm "Update APT package databases?"; then
(
sudo apt update 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating APT databases..."
wait
log SUCCESS "APT databases updated $(show_timer $section_start)"
else
log WARNING "Package database update skipped"
fi
;;
esac
}
# System upgrade
system_upgrade() {
local section_start=$(date +%s)
log SECTION "Upgrading system packages"
case "$PACKAGE_MANAGER" in
"pacman")
if confirm "Upgrade all system packages?"; then
(
sudo pacman -Su --noconfirm 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Upgrading system packages (may take a while)..."
wait
log SUCCESS "System packages upgraded $(show_timer $section_start)"
else
log WARNING "System upgrade skipped"
fi
;;
"apt")
if confirm "Upgrade all system packages?"; then
(
sudo apt upgrade -y 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Upgrading system packages (may take a while)..."
wait
log SUCCESS "System packages upgraded $(show_timer $section_start)"
else
log WARNING "System upgrade skipped"
fi
;;
esac
}
# Install packages using primary package manager
install_packages() {
local packages=("$@")
if [ ${#packages[@]} -eq 0 ]; then
return 0
fi
log INFO "Installing packages: ${packages[*]}"
case "$PACKAGE_MANAGER" in
"pacman")
(
sudo pacman --noconfirm --needed -S "${packages[@]}" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing ${#packages[@]} packages..."
wait
;;
"apt")
(
sudo apt install -y "${packages[@]}" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing ${#packages[@]} packages..."
wait
;;
esac
}
# Install AUR packages (Arch only)
install_aur_packages() {
local packages=("$@")
if [ ${#packages[@]} -eq 0 ] || [ "$PACKAGE_MANAGER" != "pacman" ]; then
return 0
fi
# Ensure AUR helper is available
if [ -z "$AUR_HELPER" ]; then
install_aur_helper
fi
log INFO "Installing AUR packages: ${packages[*]}"
(
"$AUR_HELPER" --noconfirm -S --needed --aur "${packages[@]}" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing ${#packages[@]} AUR packages..."
wait
}
# Update AUR packages
update_aur_packages() {
if [ "$PACKAGE_MANAGER" != "pacman" ] || [ -z "$AUR_HELPER" ]; then
return 0
fi
local section_start=$(date +%s)
log SECTION "Updating AUR packages"
if confirm "Update AUR packages?"; then
(
"$AUR_HELPER" --noconfirm --aur 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating AUR packages..."
wait
log SUCCESS "AUR packages updated $(show_timer $section_start)"
else
log WARNING "AUR update skipped"
fi
}
# Install Flatpak applications
install_flatpak_apps() {
local apps=("$@")
if [ ${#apps[@]} -eq 0 ] || [ "$FLATPAK_AVAILABLE" != "yes" ]; then
return 0
fi
log INFO "Installing Flatpak apps: ${apps[*]}"
for app in "${apps[@]}"; do
(
flatpak install -y flathub "$app" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing Flatpak app: $app..."
wait
done
}
# Update Flatpak applications
update_flatpak_apps() {
if [ "$FLATPAK_AVAILABLE" != "yes" ]; then
return 0
fi
local section_start=$(date +%s)
log SECTION "Updating Flatpak applications"
if confirm "Update Flatpak applications?"; then
(
flatpak update -y 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating Flatpak applications..."
wait
log SUCCESS "Flatpak applications updated $(show_timer $section_start)"
else
log WARNING "Flatpak update skipped"
fi
}
# Install Snap packages (Ubuntu/Debian)
install_snap_packages() {
local packages=("$@")
if [ ${#packages[@]} -eq 0 ] || [ "$SNAP_AVAILABLE" != "yes" ]; then
return 0
fi
log INFO "Installing Snap packages: ${packages[*]}"
for package in "${packages[@]}"; do
local snap_args=""
# Handle special snap flags
case "$package" in
*"--classic")
snap_args="--classic"
package=${package//" --classic"/}
;;
esac
(
sudo snap install $snap_args "$package" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing Snap package: $package..."
wait
done
}
# Update Snap packages
update_snap_packages() {
if [ "$SNAP_AVAILABLE" != "yes" ]; then
return 0
fi
local section_start=$(date +%s)
log SECTION "Updating Snap packages"
if confirm "Update Snap packages?"; then
(
sudo snap refresh 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating Snap packages..."
wait
log SUCCESS "Snap packages updated $(show_timer $section_start)"
else
log WARNING "Snap update skipped"
fi
}
# Install packages from various sources (unified interface)
install_package_set() {
local pkg_type="$1"
shift
local packages=("$@")
if [ ${#packages[@]} -eq 0 ]; then
return 0
fi
case "$pkg_type" in
"system"|"main")
install_packages "${packages[@]}"
;;
"aur")
install_aur_packages "${packages[@]}"
;;
"flatpak")
install_flatpak_apps "${packages[@]}"
;;
"snap")
install_snap_packages "${packages[@]}"
;;
*)
log ERROR "Unknown package type: $pkg_type"
return 1
;;
esac
}
# Setup package managers (install if needed)
setup_package_managers() {
log SECTION "Setting up package managers"
# Setup Flatpak if not available but potentially useful
if [ "$FLATPAK_AVAILABLE" != "yes" ] && [ "${SYSTEM_INFO[WSL]}" != "yes" ]; then
setup_flatpak
fi
# Setup Snap for Ubuntu systems if not available
if [ "$PACKAGE_MANAGER" == "apt" ] && [ "$SNAP_AVAILABLE" != "yes" ]; then
setup_snap
fi
# Install AUR helper for Arch if needed
if [ "$PACKAGE_MANAGER" == "pacman" ] && [ -z "$AUR_HELPER" ]; then
install_aur_helper
fi
}
# Setup Flatpak
setup_flatpak() {
log INFO "Setting up Flatpak..."
local section_start=$(date +%s)
(
case "$PACKAGE_MANAGER" in
"pacman")
sudo pacman --noconfirm --needed -S flatpak
;;
"apt")
sudo apt install -y flatpak
;;
esac
# Add Flathub repository
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# Install Flatseal for permission management
flatpak install -y flathub com.github.tchx84.Flatseal
) 2>&1 | tee -a "$LOG_FILE" &
spinner $! "Setting up Flatpak and Flathub repository..."
wait
FLATPAK_AVAILABLE="yes"
log SUCCESS "Flatpak setup completed $(show_timer $section_start)"
}
# Setup Snap
setup_snap() {
log INFO "Setting up Snap..."
local section_start=$(date +%s)
(
sudo apt install -y snap 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing Snap package manager..."
wait
SNAP_AVAILABLE="yes"
log SUCCESS "Snap setup completed $(show_timer $section_start)"
}
# Get package manager status
get_package_manager_status() {
echo "Primary: $PACKAGE_MANAGER"
[ -n "$AUR_HELPER" ] && echo "AUR: $AUR_HELPER"
[ "$FLATPAK_AVAILABLE" == "yes" ] && echo "Flatpak: available"
[ "$SNAP_AVAILABLE" == "yes" ] && echo "Snap: available"
}
# Source guard to prevent double-sourcing
if [ -z "$PACKAGES_LIB_LOADED" ]; then
PACKAGES_LIB_LOADED=true
fi