Skip to content

Commit

Permalink
Start work on making this a nushell module
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Feb 3, 2025
1 parent 72bd1db commit 66e342e
Show file tree
Hide file tree
Showing 2 changed files with 405 additions and 76 deletions.
310 changes: 310 additions & 0 deletions modules/dnf/dnf.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
#!/usr/bin/evn nu

def add_repos [$repos: list]: nothing -> nothing {
if ($repos | is-not-empty) {
print $'(ansi green)Adding repositories(ansi reset)'

for $repo in $repos {
# Substitute %OS_VERSION% & remove newlines/whitespaces from all repo entries
let repo = $repo | str replace '%OS_VERSION%' $env.OS_VERSION | str trim

let repo = if ($repo | str starts-with 'https://') or ($repo | str starts-with 'http://') {
print $"Adding repository URL: (ansi cyan)'${repo}'(ansi reset)"
$repo
} else if ($repo | str ends-with '.repo') and ($'($env.CONFIG_DIRECTORY)/dnf/($repo)' | path exists) {
print $"Adding repository file: (ansi cyan)'($repo)'(ansi reset)"
$env.CONFIG_DIRECTORY | path join dnf $repo
} else {
return (error make {
msg: $"(ansi red)Urecognized repo (ansi cyan)'($repo)'(ansi reset)"
label: {
span: (metadata $repo).span
text: 'Found in config'
}
})
}

try {
^dnf -y config-manager addrepo --from-repofile $repo
}
}
}
}

def add_coprs [$copr_repos: list]: nothing -> nothing {
if ($copr_repos | is-not-empty) {
print $'(ansi green)Adding COPR repositories(ansi reset)'

for $copr in $copr_repos {
let is_copr = ($copr | split row / | length) == 2

if not $is_copr {
return (error make {
msg: $"(ansi red)The string '(ansi cyan)($copr)(ansi red)' is not recognized as a COPR repo(ansi reset)"
label: {
span: (metadata $is_copr).span
text: 'Checks if string is a COPR repo'
}
})
}

print $"Adding COPR repository: (ansi cyan)'($copr)'(ansi reset)"
try {
^dnf -y copr enable $copr
}
}
}
}

def add_keys [$keys: list]: nothing -> nothing {
if ($keys | is-not-empty) {
print $'(ansi green)Adding keys(ansi reset)'

for $key in $keys {
let key = $key | str replace '%OS_VERSION%' $env.OS_VERSION | str trim

try {
^rpm --import $key
}
}
}
}

def run_optfix [$optfix_pkgs: list]: nothing -> nothing {
const LIB_EXEC_DIR = '/usr/libexec/bluebuild'
const SYSTEMD_DIR = '/etc/systemd/system'
const MODULE_DIR = '/tmp/modules/dnf'
const LIB_OPT_DIR = '/usr/lib/opt'
const VAR_OPT_DIR = '/var/opt'
const OPTFIX_SCRIPT = 'optfix.sh'
const SERV_UNIT = 'bluebuild-optfix.service'

if ($optfix_pkgs | is-not-empty) {
if not ($LIB_EXEC_DIR | path join $OPTFIX_SCRIPT | path exists) {
mkdir $LIB_EXEC_DIR
cp ($MODULE_DIR | path join $OPTFIX_SCRIPT) $'($LIB_EXEC_DIR)/'

try {
chmod +x $'($LIB_EXEC_DIR | path join $OPTFIX_SCRIPT)'
}
}

if not ($SYSTEMD_DIR | path join $SERV_UNIT | path exists) {
cp ($MODULE_DIR | path join $SERV_UNIT) $'($SYSTEMD_DIR)/'

try {
^systemctl enable $SERV_UNIT
}
}

print $"(ansi green)Creating symlinks to fix packages that install to /opt(ansi reset)"
mkdir $VAR_OPT_DIR

try {
^ln -snf $VAR_OPT_DIR /opt
}

for $opt in $optfix_pkgs {
let lib_dir = $LIB_OPT_DIR | path join $opt
mkdir $lib_dir

try {
^ln -sf $lib_dir ($VAR_OPT_DIR | path join $opt)
}

print $"Created symlinks for '(ansi cyan)($opt)(ansi reset)'"
}
}
}

def group_remove[remove: record]: nothing -> nothing {
let remove_list = $remove
| default [] packages
| select packages

if ($remove_list | is-not-empty) {
try {
^dnf group remove -y ...($remove_list)
}
}
}

def group_install[install: record]: nothing -> nothing {
let weak_deps = $install
| default true install-weak-dependencies
| select install-weak-dependencies
let skip_unav = $install
| default false skip-unavailable-packages
| select skip-unavailable-packages
let skip_broken = $install
| default false skip-broken-packages
| select skip-broken-packages
let allow_erase = $install
| default false allow-erasing-packages
| select allow-erasing-packages
let install_list = $install
| default [] packages
| select packages
| each { str trim }

if ($install_list | is-not-empty) {
mut args = []

let weak_arg = if $weak_deps {
'--setopt=install_weak_deps=True'
} else {
'--setopt=install_weak_deps=False'
}

if $skip_unav {
$args = $args | append '--skip-unavailable'
}

if $skip_broken {
$args = $args | append '--skip-broken'
}

if $allow_erase {
$args = $args | append '--allowerasing'
}

try {
^dnf -y $weak_arg group install --refresh ...($args) ...($install_list)
}
}
}

def remove[remove: record]: nothing -> nothing {
let remove_unused = $install
| default true remove-unused-dependencies
| select remove-unused-dependencies
let remove_list = $remove
| default [] packages
| select packages

if ($remove_list | is-not-empty) {
try {
^dnf remove -y ...($remove_list)
}
}
}

def install[install: record]: nothing -> nothing {
let weak_deps = $install
| default true install-weak-dependencies
| select install-weak-dependencies
let skip_unav = $install
| default false skip-unavailable-packages
| select skip-unavailable-packages
let skip_broken = $install
| default false skip-broken-packages
| select skip-broken-packages
let allow_erase = $install
| default false allow-erasing-packages
| select allow-erasing-packages
let install_list = $install
| default [] packages
| select packages
| each { str trim }
let http_list = $install_list
| filter {
($in | str starts-with 'https://') or ($in | str starts-with 'http://')
}
let local_list = $install_list
| filter {
($env.CONFIG_DIRECTORY | path join dnf $in | path exists)
}
let normal_list = $install_list
| filter {
(
not (
($in | str starts-with 'https://') or ($in | str starts-with 'http://')
) and not (
($env.CONFIG_DIRECTORY | path join dnf $in | path exists)
)
}

if ($install_list | is-not-empty) {
mut args = []

let weak_arg = if $weak_deps {
'--setopt=install_weak_deps=True'
} else {
'--setopt=install_weak_deps=False'
}

if $skip_unav {
$args = $args | append '--skip-unavailable'
}

if $skip_broken {
$args = $args | append '--skip-broken'
}

if $allow_erase {
$args = $args | append '--allowerasing'
}

if ($http_list | is-not-empty) {
$http_list
| each { $'(ansi cyan)($in)(ansi reset)' }
| str join ', '
| print $'Installing packages directly from URL: ($in)'
}

if ($local_list | is-not-empty) {
$local_list
| each { $'(ansi cyan)($in)(ansi reset)' }
| str join ', '
| print $'Installing local packages: ($in)'
}

if ($normal_list | is-not-empty) {
$normal_list
| each { $'(ansi cyan)($in)(ansi reset)' }
| str join ', '
| print $'Installing: ($in)'
}

try {
^dnf -y $weak_arg install --refresh ...($args) ...($install_list)
}
}
}

def main [config: string]: nothing -> nothing {
let config = $config | from json
let has_dnf5 = ^rpm -q dnf5 | complete

if has_dnf5.exit_code != 0 {
return (error make {
msg: $"(ansi red)ERROR: Main dependency '(ansi cyan)dnf5(ansi red)' is not installed. Install '(ansi cyan)dnf5(ansi red)' before using this module to solve this error.(ansi reset)"
label: {
span: (metadata $has_dnf5).span
text: 'Checks for dnf5'
}
})
}

add_repos ($config
| default [] repos
| select repos)
add_coprs ($config
| default [] copr
| select copr)
add_keys ($config
| default [] keys
| select keys)
group_remove ($config
| default {} group-remove
| select group-remove)
group_install ($config
| default {} group-install
| select group-install)
remove ($config
| default {} remove
| select remove)
install ($config
| default {} install
| select install)
}
Loading

0 comments on commit 66e342e

Please sign in to comment.