From 0c9235d59c5ffd98c661fb4f17cae9fbdde14364 Mon Sep 17 00:00:00 2001 From: Billy Lynch Date: Tue, 18 Apr 2023 11:05:28 -0400 Subject: [PATCH] Ensure that io writers are properly closed. Because the writers were being defered closed in New, this means that some files could be closed before we had the opportunity to write to them. This moves the close to their own func that can be ran in the correct place. Signed-off-by: Billy Lynch --- internal/commands/root/root.go | 1 + internal/io/streams.go | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/internal/commands/root/root.go b/internal/commands/root/root.go index c59be2d0..660b7695 100644 --- a/internal/commands/root/root.go +++ b/internal/commands/root/root.go @@ -65,6 +65,7 @@ func New(cfg *config.Config) *cobra.Command { DisableAutoGenTag: true, RunE: func(cmd *cobra.Command, args []string) error { s := io.New(o.Config.LogPath) + defer s.Close() return s.Wrap(func() error { switch { case o.FlagVersion: diff --git a/internal/io/streams.go b/internal/io/streams.go index 5ef731da..c4a6eae8 100644 --- a/internal/io/streams.go +++ b/internal/io/streams.go @@ -31,6 +31,8 @@ type Streams struct { TTYIn io.Reader TTYOut io.Writer + + close []func() error } func New(logPath string) *Streams { @@ -46,7 +48,7 @@ func New(logPath string) *Streams { // As a janky way to preserve error message, tee stderr to // a temp file. if f, err := os.Create(logPath); err == nil { - defer f.Close() + s.close = append(s.close, f.Close) s.Err = io.MultiWriter(s.Err, f) } } @@ -55,7 +57,7 @@ func New(logPath string) *Streams { // set the input/output if we can actually open it. tty, err := tty.Open() if err == nil { - defer tty.Close() + s.close = append(s.close, tty.Close) s.TTYIn = tty.Input() s.TTYOut = tty.Output() } else { @@ -80,3 +82,12 @@ func (s *Streams) Wrap(fn func() error) error { } return nil } + +func (s *Streams) Close() error { + for _, fn := range s.close { + if err := fn(); err != nil { + return err + } + } + return nil +}