Add cleanup stack

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leon Mika 2026-05-02 10:11:29 +10:00
parent 1acf07af16
commit 0d12173ff9
2 changed files with 66 additions and 0 deletions

View file

@ -0,0 +1,24 @@
package cleanup
// Stack holds deferred cleanup functions and runs them in LIFO order.
// Errors are collected; one cleanup failure does not stop later ones.
type Stack struct {
fns []func() error
}
// Add registers fn to run on Run().
func (s *Stack) Add(fn func() error) {
s.fns = append(s.fns, fn)
}
// Run executes all registered functions in reverse order and returns
// every error produced.
func (s *Stack) Run() []error {
var errs []error
for i := len(s.fns) - 1; i >= 0; i-- {
if err := s.fns[i](); err != nil {
errs = append(errs, err)
}
}
return errs
}

View file

@ -0,0 +1,42 @@
package cleanup_test
import (
"errors"
"strings"
"testing"
"github.com/leonmika/wails-release/internal/cleanup"
)
func TestStack_RunsInReverseOrder(t *testing.T) {
var s cleanup.Stack
calls := []string{}
s.Add(func() error { calls = append(calls, "first"); return nil })
s.Add(func() error { calls = append(calls, "second"); return nil })
s.Run()
want := []string{"second", "first"}
for i := range want {
if calls[i] != want[i] {
t.Fatalf("call %d: got %q want %q (full: %v)", i, calls[i], want[i], calls)
}
}
}
func TestStack_ContinuesAfterError(t *testing.T) {
var s cleanup.Stack
called := []string{}
s.Add(func() error { called = append(called, "a"); return nil })
s.Add(func() error { called = append(called, "b"); return errors.New("boom") })
s.Add(func() error { called = append(called, "c"); return nil })
errs := s.Run()
if len(errs) != 1 || !strings.Contains(errs[0].Error(), "boom") {
t.Fatalf("expected one boom error, got %v", errs)
}
if len(called) != 3 {
t.Fatalf("expected all three to run, got %v", called)
}
}