Files
provision/lib/package.sh
2026-01-22 20:54:36 -08:00

261 lines
6.1 KiB
Bash
Executable File

#!/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 <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 <owner/repo> <pattern>
# 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"
}