From 94b19d64bed388b190f382939f00d4a392d1c78a Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Mon, 15 Sep 2025 21:04:31 +0200 Subject: [PATCH] termstatus: allow retrieving the underlying writer This is intended for special cases where it must be guaranteed that the output on stdout exactly matches what was written to the io.Writer. --- internal/ui/mock.go | 8 ++++++++ internal/ui/terminal.go | 3 +++ internal/ui/termstatus/status.go | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/internal/ui/mock.go b/internal/ui/mock.go index 5a4debb02..36452f4be 100644 --- a/internal/ui/mock.go +++ b/internal/ui/mock.go @@ -1,5 +1,9 @@ package ui +import "io" + +var _ Terminal = &MockTerminal{} + type MockTerminal struct { Output []string Errors []string @@ -20,3 +24,7 @@ func (m *MockTerminal) SetStatus(lines []string) { func (m *MockTerminal) CanUpdateStatus() bool { return true } + +func (m *MockTerminal) OutputRaw() io.Writer { + return nil +} diff --git a/internal/ui/terminal.go b/internal/ui/terminal.go index 2d9418a61..949bc3465 100644 --- a/internal/ui/terminal.go +++ b/internal/ui/terminal.go @@ -1,5 +1,7 @@ package ui +import "io" + // Terminal is used to write messages and display status lines which can be // updated. See termstatus.Terminal for a concrete implementation. type Terminal interface { @@ -7,4 +9,5 @@ type Terminal interface { Error(line string) SetStatus(lines []string) CanUpdateStatus() bool + OutputRaw() io.Writer } diff --git a/internal/ui/termstatus/status.go b/internal/ui/termstatus/status.go index d11c66573..a5ce24205 100644 --- a/internal/ui/termstatus/status.go +++ b/internal/ui/termstatus/status.go @@ -12,8 +12,11 @@ import ( "golang.org/x/text/width" "github.com/restic/restic/internal/terminal" + "github.com/restic/restic/internal/ui" ) +var _ ui.Terminal = &Terminal{} + // Terminal is used to write messages and display status lines which can be // updated. When the output is redirected to a file, the status lines are not // printed. @@ -83,6 +86,13 @@ func (t *Terminal) CanUpdateStatus() bool { return t.canUpdateStatus } +// OutputRaw returns the output writer. Should only be used if there is no +// other option. Must not be used in combination with Print, Error, SetStatus +// or any other method that writes to the terminal. +func (t *Terminal) OutputRaw() io.Writer { + return t.wr +} + // Run updates the screen. It should be run in a separate goroutine. When // ctx is cancelled, the status lines are cleanly removed. func (t *Terminal) Run(ctx context.Context) {