235 lines
6.1 KiB
Text
235 lines
6.1 KiB
Text
#!/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"
|
|
}
|