From 24c4bde14aa3a4fd39ea7fa0478bcdd8f74e6bec Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Wed, 28 Feb 2024 00:53:57 +0100 Subject: feat(packages): finished implementing packages install promises --- gonf/packages.go | 16 ++++++++++++---- gonf/utils.go | 11 +++++++++++ stdlib/os/debian/apt.go | 19 +++++++++---------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/gonf/packages.go b/gonf/packages.go index 7ff512d..114a227 100644 --- a/gonf/packages.go +++ b/gonf/packages.go @@ -1,10 +1,12 @@ package gonf +import "log/slog" + // ----- Globals --------------------------------------------------------------- var packages []*PackagePromise // packages management functions -var packages_install_function func([]string) Status +var packages_install_function func([]string) (Status, []string) var packages_list_function func() var packages_update_function *CommandPromise @@ -14,7 +16,7 @@ func init() { } // ----- Public ---------------------------------------------------------------- -func SetPackagesConfiguration(install func([]string) Status, list func(), update *CommandPromise) { +func SetPackagesConfiguration(install func([]string) (Status, []string), list func(), update *CommandPromise) { packages_install_function = install packages_list_function = list packages_update_function = update @@ -47,8 +49,14 @@ func (p *PackagePromise) Promise() Promise { } func (p *PackagePromise) Resolve() { - status := packages_install_function(p.names) - if status == REPAIRED { + status, affected := packages_install_function(p.names) + switch status { + case BROKEN: + slog.Error("package", "names", p.names, "status", status, "broke", affected) + case KEPT: + slog.Debug("package", "names", p.names, "status", status) + case REPAIRED: + slog.Info("package", "names", p.names, "status", status, "repaired", affected) for _, pp := range p.chain { pp.Resolve() } diff --git a/gonf/utils.go b/gonf/utils.go index 109dbe8..f62d1c3 100644 --- a/gonf/utils.go +++ b/gonf/utils.go @@ -9,6 +9,17 @@ var builtinTemplateFunctions = map[string]any{ "var": getVariable, } +func FilterSlice[T any](slice *[]T, predicate func(T) bool) { + i := 0 + for _, element := range *slice { + if predicate(element) { // if the element matches the predicate function + (*slice)[i] = element // then we keep it in the slice + i++ + } // otherwise the element will get overwritten + } + *slice = (*slice)[:i] // or truncated out of the slice +} + func sha256sum(contents []byte) []byte { h := sha256.New() h.Write(contents) diff --git a/stdlib/os/debian/apt.go b/stdlib/os/debian/apt.go index 63ce497..2eb58fa 100644 --- a/stdlib/os/debian/apt.go +++ b/stdlib/os/debian/apt.go @@ -7,6 +7,7 @@ import ( "log/slog" "os" "os/exec" + "strings" "git.adyxax.org/adyxax/gonf/v2/gonf" "git.adyxax.org/adyxax/gonf/v2/stdlib/os/systemd" @@ -32,21 +33,19 @@ func Promise() { systemd.Promise() } -func packages_install(names []string) gonf.Status { - allKept := true - for _, n := range names { - if _, ok := packages[n]; !ok { - allKept = false - } - } - if allKept { - return gonf.KEPT +func packages_install(names []string) (gonf.Status, []string) { + gonf.FilterSlice(&names, func(n string) bool { + _, ok := packages[n] + return !ok + }) + if len(names) == 0 { + return gonf.KEPT, nil } args := append([]string{"install", "-y", "--no-install-recommends"}, names...) cmd := gonf.CommandWithEnv([]string{"DEBIAN_FRONTEND=noninteractive", "LC_ALL=C"}, "apt-get", args...) cmd.Resolve() packages_list() - return cmd.Status + return cmd.Status, names } func packages_list() { -- cgit v1.2.3