summaryrefslogtreecommitdiff
path: root/lib/dslkeywords/package.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dslkeywords/package.rb')
-rw-r--r--lib/dslkeywords/package.rb39
1 files changed, 35 insertions, 4 deletions
diff --git a/lib/dslkeywords/package.rb b/lib/dslkeywords/package.rb
index 86903cf..9e4324f 100644
--- a/lib/dslkeywords/package.rb
+++ b/lib/dslkeywords/package.rb
@@ -5,10 +5,40 @@ require_relative 'resource'
module RCM
class DNFPackageManager
+ # Raised when a dnf subcommand exits with a non-zero status or when
+ # the dnf binary cannot be found.
+ class CommandFailed < StandardError; end
+
def installed?(pkg) = false
- def install(pkg) = `dnf install -y "#{pkg}"` unless installed?(pkg)
- def update(pkg) = `dnf update -y "#{pkg}"`
- def remove(pkg) = `dnf remove -y "#{pkg}"` if installed?(pkg)
+
+ def install(pkg)
+ return if installed?(pkg)
+
+ run_dnf!('install', pkg)
+ end
+
+ def update(pkg)
+ run_dnf!('update', pkg)
+ end
+
+ def remove(pkg)
+ return unless installed?(pkg)
+
+ run_dnf!('remove', pkg)
+ end
+
+ private
+
+ # Execute dnf <subcommand> -y <pkg> using separate arguments (no shell
+ # interpolation). Raises CommandFailed when dnf exits non-zero or is
+ # not found ($? is nil when the binary cannot be exec'd).
+ def run_dnf!(subcommand, pkg)
+ result = system('dnf', subcommand, '-y', pkg)
+ return if result
+
+ exit_code = $?&.exitstatus || '?'
+ raise CommandFailed, "dnf #{subcommand} #{pkg} failed (exit #{exit_code})"
+ end
end
# Managing packages
@@ -19,7 +49,8 @@ module RCM
def initialize(name)
super(name)
- raise UnsupportedOS, 'OS is not supported' unless File.file?('/etc/fedora-release')
+ # Use ::File to avoid resolving to RCM::File once file.rb is loaded.
+ raise UnsupportedOS, 'OS is not supported' unless ::File.file?('/etc/fedora-release')
@manager = DNFPackageManager.new