diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/resource/pkg/dnf.go | 20 | ||||
| -rw-r--r-- | internal/resource/pkg/dnf_test.go | 52 | ||||
| -rw-r--r-- | internal/resource/pkg/pkg.go | 54 |
3 files changed, 99 insertions, 27 deletions
diff --git a/internal/resource/pkg/dnf.go b/internal/resource/pkg/dnf.go index ad03da2..e970b10 100644 --- a/internal/resource/pkg/dnf.go +++ b/internal/resource/pkg/dnf.go @@ -2,23 +2,21 @@ package pkg import ( "fmt" - "log" "codeberg.org/snonux/gonf/internal/exec" ) -func applyDNF(name string, ensure Ensure) error { +func applyDNF(p *Package) error { var args []string - switch ensure { - case PkgPresent: - args = []string{"install", "-y", name} - case PkgAbsent: - args = []string{"remove", "-y", name} - case PkgLatest: - args = []string{"install", "-y", name} - default: - log.Fatalf("unsupported ensure state: %v", ensure) + if p.absent { + args = []string{"remove", "-y", p.name} + } else if p.latest { + // update ensures the package is installed and updated to the latest version. + args = []string{"update", "-y", p.name} + } else { + // install ensures the package is installed, but does not update it if already present. + args = []string{"install", "-y", p.name} } stdout, stderr, exitCode, err := exec.Run("dnf", args...) diff --git a/internal/resource/pkg/dnf_test.go b/internal/resource/pkg/dnf_test.go new file mode 100644 index 0000000..e9778dd --- /dev/null +++ b/internal/resource/pkg/dnf_test.go @@ -0,0 +1,52 @@ +package pkg + +import ( + "os" + "testing" +) + +func TestApplyDNF(t *testing.T) { + // Only run this test if explicitly enabled via environment variable. + if os.Getenv("GONF_RUN_DNF_TESTS") != "1" { + t.Skip("Skipping DNF test: GONF_RUN_DNF_TESTS=1 not set") + } + + // Skip if not running as root, as dnf requires superuser privileges. + if os.Getuid() != 0 { + t.Skip("Skipping DNF test: root privileges required") + } + + p := &Package{ + name: "tig", + } + + t.Run("Present", func(t *testing.T) { + p.absent = false + p.latest = false + if err := applyDNF(p); err != nil { + t.Errorf("applyDNF Present failed: %v", err) + } + }) + + t.Run("Latest", func(t *testing.T) { + p.absent = false + p.latest = true + if err := applyDNF(p); err != nil { + t.Errorf("applyDNF Latest failed: %v", err) + } + }) + + t.Run("Absent", func(t *testing.T) { + p.absent = true + p.latest = false + if err := applyDNF(p); err != nil { + t.Errorf("applyDNF Absent failed: %v", err) + } + + // // Restore the package so we don't leave the system in a changed state + // p.absent = false + // if err := applyDNF(p); err != nil { + // t.Errorf("failed to restore package tig after Absent test: %v", err) + // } + }) +} diff --git a/internal/resource/pkg/pkg.go b/internal/resource/pkg/pkg.go index 72f098c..b010c7a 100644 --- a/internal/resource/pkg/pkg.go +++ b/internal/resource/pkg/pkg.go @@ -3,38 +3,60 @@ package pkg import ( "errors" "os" -) - -type Ensure int -const ( - PkgPresent Ensure = iota - PkgAbsent - PkgLatest + opt "codeberg.org/snonux/gonf/api/options" + "codeberg.org/snonux/gonf/internal/resource" ) -type applyFunc func(name string, ensure Ensure) error +type Package struct { + name string + absent bool + latest bool +} + +func (p *Package) SetAbsent() { p.absent = true } +func (p *Package) SetLatest() { p.latest = true } -func Present(name string, ensure Ensure) error { - bin, err := detect() +func (p *Package) apply() error { + pkgMan, err := detectPackageManager() if err != nil { return err } - var applyFunc applyFunc - - switch bin { + switch pkgMan { case "dnf": - applyFunc = applyDNF + return applyDNF(p) } - return applyFunc(name, ensure) + return errors.New("unsupported package manager") } -func detect() (string, error) { +func Present(name string, opts ...opt.Option) resource.Resource { + p := &Package{ + name: name, + } + + for _, o := range opts { + o(p) + } + + return resource.Register("Package", p.name, + resource.ApplierFunc(func() error { return p.apply() })) +} + +func Absent(name string, opts ...opt.Option) resource.Resource { + opts = append(opts, opt.IsAbsent) + return Present(name, opts...) +} + +func detectPackageManager() (string, error) { switch { case exists("/etc/fedora-release"): fallthrough + case exists("/etc/centos-release"): + fallthrough + case exists("/etc/redhat-release"): + fallthrough case exists("/etc/rocky-release"): return "dnf", nil } |
