provisioning/scripts/libs/os/pkg.nu

236 lines
6.1 KiB
Text
Raw Normal View History

#!/usr/bin/env nu
# Package management abstraction
# Provides OS-agnostic package operations
use std
use ./detect.nu as os_detect
# Helper: Result type
def ok [value: any] { {ok: $value, err: null} }
def err [message: string] { {ok: null, err: $message} }
def is-ok [result: record] { $result.err == null }
# Install package(s)
export def install [
packages: string # Package name or space-separated list
--assume-yes: bool = true # Skip confirmation prompts
] {
# GUARD: Validate input
if ($packages | is-empty) {
return (err "packages cannot be empty")
}
# PRECONDITION: Check OS support
let current_os = (os_detect detect)
if not (os_detect is-supported $current_os) {
return (err $"OS not supported for package management: ($current_os)")
}
# MAIN LOGIC: OS-specific commands
let result = match $current_os {
"debian" | "ubuntu" => {
let cmd = if $assume_yes { "apt-get install -y" } else { "apt-get install" }
(^sh -c $"$cmd $packages" 2>&1 | complete)
}
"nixos" => {
err "Use NixOS modules for package management, not imperative install"
}
"alpine" => {
let cmd = if $assume_yes { "apk add -y" } else { "apk add" }
(^sh -c $"$cmd $packages" 2>&1 | complete)
}
"macos" => {
let cmd = if $assume_yes { "brew install" } else { "brew install" }
(^sh -c $"$cmd $packages" 2>&1 | complete)
}
_ => {
return (err $"Package installation not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok "Packages installed successfully"
} else {
err $"Package installation failed: ($result.stderr)"
}
}
# Remove package(s)
export def remove [
packages: string
--assume-yes: bool = true
] {
# GUARD: Validate input
if ($packages | is-empty) {
return (err "packages cannot be empty")
}
let current_os = (os_detect detect)
# MAIN LOGIC
let result = match $current_os {
"debian" | "ubuntu" => {
let cmd = if $assume_yes { "apt-get remove -y" } else { "apt-get remove" }
(^sh -c $"$cmd $packages" 2>&1 | complete)
}
"nixos" => {
err "Use NixOS modules, not imperative remove"
}
"alpine" => {
let cmd = if $assume_yes { "apk del -y" } else { "apk del" }
(^sh -c $"$cmd $packages" 2>&1 | complete)
}
"macos" => {
let cmd = if $assume_yes { "brew uninstall" } else { "brew uninstall" }
(^sh -c $"$cmd $packages" 2>&1 | complete)
}
_ => {
return (err $"Package removal not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok "Packages removed successfully"
} else {
err $"Package removal failed: ($result.stderr)"
}
}
# Update package cache/index
export def update [] {
let current_os = (os_detect detect)
let result = match $current_os {
"debian" | "ubuntu" => {
(^apt-get update 2>&1 | complete)
}
"nixos" => {
err "Use 'nix flake update' or nixpkgs channel management"
}
"alpine" => {
(^apk update 2>&1 | complete)
}
"macos" => {
(^brew update 2>&1 | complete)
}
_ => {
return (err $"Package update not supported on ($current_os)")
}
}
if $result.exit_code == 0 {
ok "Package cache updated"
} else {
err $"Package update failed: ($result.stderr)"
}
}
# Check if package is installed
export def is-installed [package: string] {
# GUARD: Validate input
if ($package | is-empty) {
return (err "package name cannot be empty")
}
let current_os = (os_detect detect)
let cmd_result = match $current_os {
"debian" | "ubuntu" => {
(^sh -c $"dpkg -l | grep -q '^ii.*$package'" 2>&1 | complete)
}
"nixos" => {
(^sh -c $"nix eval --raw -f '<nixpkgs>' 'lib.attrsets.hasAttr \"$package\" self'" 2>&1 | complete)
}
"alpine" => {
(^apk info $package 2>&1 | complete)
}
"macos" => {
(^brew list $package 2>&1 | complete)
}
_ => {
return (err $"Package check not supported on ($current_os)")
}
}
ok ($cmd_result.exit_code == 0)
}
# Get package version
export def version [package: string] {
# GUARD: Validate input
if ($package | is-empty) {
return (err "package name cannot be empty")
}
let current_os = (os_detect detect)
let version_info = match $current_os {
"debian" | "ubuntu" => {
let dpkg_result = (^sh -c $"dpkg -l | grep '^ii.*$package' | awk '{{print $3}}'" 2>&1 | complete)
if $dpkg_result.exit_code == 0 {
$dpkg_result.stdout | str trim
} else {
"not installed"
}
}
"nixos" => {
"use nix version checking"
}
"alpine" => {
let apk_result = (^apk info $package 2>&1 | complete)
if $apk_result.exit_code == 0 {
$apk_result.stdout | str trim
} else {
"not installed"
}
}
"macos" => {
let brew_result = (^brew list --versions $package 2>&1 | complete)
if $brew_result.exit_code == 0 {
$brew_result.stdout | str trim
} else {
"not installed"
}
}
_ => {
return (err $"Version check not supported on ($current_os)")
}
}
ok $version_info
}
# Main: Show usage
export def main [] {
print "Package management abstraction library"
print ""
print "Usage:"
print " pkg install <package-list> [--assume-yes]"
print " pkg remove <package-list> [--assume-yes]"
print " pkg update"
print " pkg is-installed <package>"
print " pkg version <package>"
print ""
print "Supported OS: debian, ubuntu, alpine, nixos, macos"
}