diff --git a/cmd/restic/termstatus.go b/cmd/restic/termstatus.go index cf3cd82ee..c0e9a045b 100644 --- a/cmd/restic/termstatus.go +++ b/cmd/restic/termstatus.go @@ -4,7 +4,6 @@ import ( "context" "sync" - "github.com/restic/restic/internal/ui" "github.com/restic/restic/internal/ui/termstatus" ) @@ -31,8 +30,7 @@ func setupTermstatus() (*termstatus.Terminal, func()) { // use the termstatus for stdout/stderr prevStdout, prevStderr := globalOptions.stdout, globalOptions.stderr - stdioWrapper := ui.NewStdioWrapper(term) - globalOptions.stdout, globalOptions.stderr = stdioWrapper.Stdout(), stdioWrapper.Stderr() + globalOptions.stdout, globalOptions.stderr = termstatus.WrapStdio(term) return term, func() { // shutdown termstatus diff --git a/internal/ui/stdio_wrapper.go b/internal/ui/stdio_wrapper.go deleted file mode 100644 index 42f4cc545..000000000 --- a/internal/ui/stdio_wrapper.go +++ /dev/null @@ -1,72 +0,0 @@ -package ui - -import ( - "bytes" - "io" - - "github.com/restic/restic/internal/ui/termstatus" -) - -// StdioWrapper provides stdout and stderr integration with termstatus. -type StdioWrapper struct { - stdout *lineWriter - stderr *lineWriter -} - -// NewStdioWrapper initializes a new stdio wrapper that can be used in place of -// os.Stdout or os.Stderr. -func NewStdioWrapper(term *termstatus.Terminal) *StdioWrapper { - return &StdioWrapper{ - stdout: newLineWriter(term.Print), - stderr: newLineWriter(term.Error), - } -} - -// Stdout returns a writer that is line buffered and can be used in place of -// os.Stdout. On Close(), the remaining bytes are written, followed by a line -// break. -func (w *StdioWrapper) Stdout() io.WriteCloser { - return w.stdout -} - -// Stderr returns a writer that is line buffered and can be used in place of -// os.Stderr. On Close(), the remaining bytes are written, followed by a line -// break. -func (w *StdioWrapper) Stderr() io.WriteCloser { - return w.stderr -} - -type lineWriter struct { - buf *bytes.Buffer - print func(string) -} - -var _ io.WriteCloser = &lineWriter{} - -func newLineWriter(print func(string)) *lineWriter { - return &lineWriter{buf: bytes.NewBuffer(nil), print: print} -} - -func (w *lineWriter) Write(data []byte) (n int, err error) { - n, err = w.buf.Write(data) - if err != nil { - return n, err - } - - // look for line breaks - buf := w.buf.Bytes() - i := bytes.LastIndexByte(buf, '\n') - if i != -1 { - w.print(string(buf[:i+1])) - w.buf.Next(i + 1) - } - - return n, err -} - -func (w *lineWriter) Close() error { - if w.buf.Len() > 0 { - w.print(string(append(w.buf.Bytes(), '\n'))) - } - return nil -} diff --git a/internal/ui/termstatus/stdio_wrapper.go b/internal/ui/termstatus/stdio_wrapper.go new file mode 100644 index 000000000..233610ba3 --- /dev/null +++ b/internal/ui/termstatus/stdio_wrapper.go @@ -0,0 +1,47 @@ +package termstatus + +import ( + "bytes" + "io" +) + +// WrapStdio returns line-buffering replacements for os.Stdout and os.Stderr. +// On Close, the remaining bytes are written, followed by a line break. +func WrapStdio(term *Terminal) (stdout, stderr io.WriteCloser) { + return newLineWriter(term.Print), newLineWriter(term.Error) +} + +type lineWriter struct { + buf bytes.Buffer + print func(string) +} + +var _ io.WriteCloser = &lineWriter{} + +func newLineWriter(print func(string)) *lineWriter { + return &lineWriter{print: print} +} + +func (w *lineWriter) Write(data []byte) (n int, err error) { + n, err = w.buf.Write(data) + if err != nil { + return n, err + } + + // look for line breaks + buf := w.buf.Bytes() + i := bytes.LastIndexByte(buf, '\n') + if i != -1 { + w.print(string(buf[:i+1])) + w.buf.Next(i + 1) + } + + return n, err +} + +func (w *lineWriter) Close() error { + if w.buf.Len() > 0 { + w.print(string(append(w.buf.Bytes(), '\n'))) + } + return nil +} diff --git a/internal/ui/stdio_wrapper_test.go b/internal/ui/termstatus/stdio_wrapper_test.go similarity index 98% rename from internal/ui/stdio_wrapper_test.go rename to internal/ui/termstatus/stdio_wrapper_test.go index b95d9180d..1e214f1f4 100644 --- a/internal/ui/stdio_wrapper_test.go +++ b/internal/ui/termstatus/stdio_wrapper_test.go @@ -1,4 +1,4 @@ -package ui +package termstatus import ( "strings"