#!/usr/bin/env bash # Package manager abstraction functions # Source common utilities if not already sourced if [ -z "$OS_TYPE" ]; then SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh" fi # Update package manager cache update_package_cache() { log_info "Updating package cache" case "$OS_TYPE" in macos) if command_exists brew; then brew update else log_error "Homebrew not installed" return 1 fi ;; debian) maybe_sudo apt-get update -qq ;; arch) maybe_sudo pacman -Sy --noconfirm ;; *) log_error "Unsupported OS: $OS_TYPE" return 1 ;; esac } # Install a package using the appropriate package manager install_package() { local package="$1" local package_debian="${2:-$package}" local package_arch="${3:-$package}" log_info "Installing package: $package" case "$OS_TYPE" in macos) if ! command_exists brew; then log_error "Homebrew not installed. Run system/macos-setup.sh first" return 1 fi brew install "$package" ;; debian) maybe_sudo apt-get install -y -qq "$package_debian" ;; arch) maybe_sudo pacman -S --noconfirm --needed "$package_arch" ;; *) log_error "Unsupported OS: $OS_TYPE" return 1 ;; esac } # Install a cask (macOS only) install_cask() { local cask="$1" if ! is_macos; then log_warn "Cask installation only supported on macOS" return 1 fi log_info "Installing cask: $cask" if ! command_exists brew; then log_error "Homebrew not installed. Run system/macos-setup.sh first" return 1 fi brew install --cask "$cask" } # Install from AUR (Arch only) install_aur() { local package="$1" if ! is_arch; then log_warn "AUR installation only supported on Arch Linux" return 1 fi log_info "Installing AUR package: $package" # Check for yay first, then paru if command_exists yay; then yay -S --noconfirm --needed "$package" elif command_exists paru; then paru -S --noconfirm --needed "$package" else log_error "No AUR helper found. Install yay or paru first" return 1 fi } # Install cargo package install_cargo() { local package="$1" if ! command_exists cargo; then log_info "Installing Rust toolchain" install_package rustup rustup cargo if is_debian || is_arch; then rustup default stable fi fi log_info "Installing cargo package: $package" cargo install "$package" } # Install Python package with pip install_pip() { local package="$1" if ! command_exists pip3; then log_info "Installing pip" install_package python3-pip python3-pip python-pip fi log_info "Installing pip package: $package" pip3 install --user "$package" } # Install npm package globally install_npm() { local package="$1" if ! command_exists npm; then log_error "npm not installed. Install Node.js first" return 1 fi log_info "Installing npm package: $package" npm install -g "$package" } # Check if package is installed package_installed() { local package="$1" case "$OS_TYPE" in macos) brew list "$package" >/dev/null 2>&1 ;; debian) dpkg -l "$package" 2>/dev/null | grep -q "^ii" ;; arch) pacman -Q "$package" >/dev/null 2>&1 ;; *) return 1 ;; esac } # Ensure Homebrew is installed (macOS only) ensure_homebrew() { if ! is_macos; then return 0 fi if command_exists brew; then log_success "Homebrew already installed" return 0 fi log_info "Installing Homebrew" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Add Homebrew to PATH for Apple Silicon Macs if [ -f "/opt/homebrew/bin/brew" ]; then eval "$(/opt/homebrew/bin/brew shellenv)" fi } # Ensure AUR helper is installed (Arch only) ensure_aur_helper() { if ! is_arch; then return 0 fi if command_exists yay || command_exists paru; then log_success "AUR helper already installed" return 0 fi log_info "Installing yay AUR helper" # Install dependencies maybe_sudo pacman -S --noconfirm --needed git base-devel # Clone and build yay local temp_dir=$(mktemp -d) git clone https://aur.archlinux.org/yay.git "$temp_dir/yay" cd "$temp_dir/yay" makepkg -si --noconfirm cd - rm -rf "$temp_dir" log_success "yay installed" } # Install a .deb package from a URL # Usage: install_deb_from_url install_deb_from_url() { local url="$1" if ! is_debian; then log_error "This function is only for Debian-based systems" return 1 fi log_info "Downloading and installing .deb from: $url" local temp_dir=$(mktemp -d) local deb_file="$temp_dir/package.deb" if ! wget -q "$url" -O "$deb_file"; then log_error "Failed to download .deb package from $url" rm -rf "$temp_dir" return 1 fi maybe_sudo dpkg -i "$deb_file" maybe_sudo apt-get install -f -y rm -rf "$temp_dir" log_success "Package installed successfully" } # Fetch latest GitHub release download URL for a specific pattern # Usage: get_latest_github_release_url # Example: get_latest_github_release_url "obsidianmd/obsidian-releases" "_amd64.deb$" get_latest_github_release_url() { local repo="$1" local pattern="$2" local api_url="https://api.github.com/repos/$repo/releases/latest" local download_url=$(curl -s "$api_url" | grep -o "https://.*$pattern" | head -n1) if [ -z "$download_url" ]; then log_error "Could not find release matching pattern: $pattern" return 1 fi echo "$download_url" }