From fc81a0b6add6ebc15fdea39769f61542bee2e3ec Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Fri, 5 Jun 2026 14:20:50 +0200 Subject: [PATCH] ui/terminal: unexport Terminal type --- internal/ui/terminal.go | 2 +- internal/ui/termstatus/status.go | 68 +++++++++++++-------------- internal/ui/termstatus/status_test.go | 28 +++++------ 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/internal/ui/terminal.go b/internal/ui/terminal.go index d4d5a10de..b100a27e2 100644 --- a/internal/ui/terminal.go +++ b/internal/ui/terminal.go @@ -6,7 +6,7 @@ import ( ) // Terminal is used to write messages and display status lines which can be -// updated. See termstatus.Terminal for a concrete implementation. +// updated. See termstatus.Setup for a concrete implementation. type Terminal interface { // Print writes a line to the terminal. Appends a newline if not present. Print(line string) diff --git a/internal/ui/termstatus/status.go b/internal/ui/termstatus/status.go index 63f168472..892e4c712 100644 --- a/internal/ui/termstatus/status.go +++ b/internal/ui/termstatus/status.go @@ -9,16 +9,16 @@ import ( "strings" "sync" - "github.com/restic/restic/internal/terminal" + tty "github.com/restic/restic/internal/terminal" "github.com/restic/restic/internal/ui" ) -var _ ui.Terminal = &Terminal{} +var _ ui.Terminal = &terminal{} -// Terminal is used to write messages and display status lines which can be +// 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. -type Terminal struct { +type terminal struct { rd io.ReadCloser inFd uintptr wr io.Writer @@ -97,8 +97,8 @@ func Setup(stdin io.ReadCloser, stdout, stderr io.Writer, quiet bool) (ui.Termin } } -func new(rd io.ReadCloser, wr io.Writer, errWriter io.Writer, disableStatus bool) *Terminal { - t := &Terminal{ +func new(rd io.ReadCloser, wr io.Writer, errWriter io.Writer, disableStatus bool) *terminal { + t := &terminal{ rd: rd, wr: wr, errWriter: errWriter, @@ -112,22 +112,22 @@ func new(rd io.ReadCloser, wr io.Writer, errWriter io.Writer, disableStatus bool } if d, ok := rd.(fder); ok { - if terminal.InputIsTerminal(d.Fd()) { + if tty.InputIsTerminal(d.Fd()) { t.inFd = d.Fd() t.inputIsTerminal = true } } if d, ok := wr.(fder); ok { - if terminal.CanUpdateStatus(d.Fd()) { + if tty.CanUpdateStatus(d.Fd()) { // only use the fancy status code when we're running on a real terminal. t.canUpdateStatus = true t.fd = d.Fd() - t.clearCurrentLine = terminal.ClearCurrentLine(t.fd) - t.moveCursorUp = terminal.MoveCursorUp(t.fd) - t.moveCursorDown = terminal.MoveCursorDown(t.fd) + t.clearCurrentLine = tty.ClearCurrentLine(t.fd) + t.moveCursorUp = tty.MoveCursorUp(t.fd) + t.moveCursorDown = tty.MoveCursorDown(t.fd) } - if terminal.OutputIsTerminal(d.Fd()) { + if tty.OutputIsTerminal(d.Fd()) { t.outputIsTerminal = true } } @@ -136,19 +136,19 @@ func new(rd io.ReadCloser, wr io.Writer, errWriter io.Writer, disableStatus bool } // InputIsTerminal returns whether the input is a terminal. -func (t *Terminal) InputIsTerminal() bool { +func (t *terminal) InputIsTerminal() bool { return t.inputIsTerminal } // InputRaw returns the input reader. -func (t *Terminal) InputRaw() io.ReadCloser { +func (t *terminal) InputRaw() io.ReadCloser { return t.rd } -func (t *Terminal) ReadPassword(ctx context.Context, prompt string) (string, error) { +func (t *terminal) ReadPassword(ctx context.Context, prompt string) (string, error) { if t.InputIsTerminal() { t.Flush() - return terminal.ReadPassword(ctx, int(t.inFd), t.errWriter, prompt) + return tty.ReadPassword(ctx, int(t.inFd), t.errWriter, prompt) } if t.OutputIsTerminal() { t.Print("reading repository password from stdin") @@ -167,13 +167,13 @@ func readPassword(in io.Reader) (password string, err error) { } // CanUpdateStatus return whether the status output is updated in place. -func (t *Terminal) CanUpdateStatus() bool { +func (t *terminal) CanUpdateStatus() bool { return t.canUpdateStatus } // OutputWriter returns a output writer that is safe for concurrent use with // other output methods. Output is only shown after a line break. -func (t *Terminal) OutputWriter() io.Writer { +func (t *terminal) OutputWriter() io.Writer { t.outputWriterOnce.Do(func() { t.outputWriter = newLineWriter(t.Print) }) @@ -183,19 +183,19 @@ func (t *Terminal) OutputWriter() io.Writer { // OutputRaw returns the raw 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 { +func (t *terminal) OutputRaw() io.Writer { t.Flush() return t.wr } // OutputIsTerminal returns whether the output is a terminal. -func (t *Terminal) OutputIsTerminal() bool { +func (t *terminal) OutputIsTerminal() bool { return t.outputIsTerminal } // 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) { +func (t *terminal) Run(ctx context.Context) { defer close(t.closed) if t.canUpdateStatus { t.run(ctx) @@ -206,12 +206,12 @@ func (t *Terminal) Run(ctx context.Context) { } // run listens on the channels and updates the terminal screen. -func (t *Terminal) run(ctx context.Context) { +func (t *terminal) run(ctx context.Context) { var status []string for { select { case <-ctx.Done(): - if !terminal.IsProcessBackground(t.fd) { + if !tty.IsProcessBackground(t.fd) { t.writeStatus([]string{}, false) } @@ -222,7 +222,7 @@ func (t *Terminal) run(ctx context.Context) { msg.barrier <- struct{}{} continue } - if terminal.IsProcessBackground(t.fd) { + if tty.IsProcessBackground(t.fd) { // ignore all messages, do nothing, we are in the background process group continue } @@ -247,7 +247,7 @@ func (t *Terminal) run(ctx context.Context) { case stat := <-t.status: status = append(status[:0], stat.lines...) - if terminal.IsProcessBackground(t.fd) { + if tty.IsProcessBackground(t.fd) { // ignore all messages, do nothing, we are in the background process group continue } @@ -257,13 +257,13 @@ func (t *Terminal) run(ctx context.Context) { } } -func (t *Terminal) logWriteErr(err error) { +func (t *terminal) logWriteErr(err error) { if err != nil { _, _ = fmt.Fprintf(t.errWriter, "write failed: %v\n", err) } } -func (t *Terminal) writeStatus(status []string, skipUnchanged bool) { +func (t *terminal) writeStatus(status []string, skipUnchanged bool) { var unchanged []bool if skipUnchanged { if slices.Equal(status, t.lastStatus) { @@ -322,7 +322,7 @@ func findUnchangedLines(curr, last []string) []bool { // runWithoutStatus listens on the channels and just prints out the messages, // without status lines. -func (t *Terminal) runWithoutStatus(ctx context.Context) { +func (t *terminal) runWithoutStatus(ctx context.Context) { var lastStatus []string for { select { @@ -359,7 +359,7 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) { } // Flush waits for all pending messages to be printed. -func (t *Terminal) Flush() { +func (t *terminal) Flush() { ch := make(chan struct{}) defer close(ch) select { @@ -372,7 +372,7 @@ func (t *Terminal) Flush() { } } -func (t *Terminal) print(line string, isErr bool) { +func (t *terminal) print(line string, isErr bool) { // make sure the line ends with a line break if len(line) == 0 || line[len(line)-1] != '\n' { line += "\n" @@ -385,12 +385,12 @@ func (t *Terminal) print(line string, isErr bool) { } // Print writes a line to the terminal. -func (t *Terminal) Print(line string) { +func (t *terminal) Print(line string) { t.print(line, false) } // Error writes an error to the terminal. -func (t *Terminal) Error(line string) { +func (t *terminal) Error(line string) { t.print(line, true) } @@ -410,11 +410,11 @@ func sanitizeLines(lines []string, width int) []string { // SetStatus updates the status lines. // The lines should not contain newlines; this method adds them. // Pass nil or an empty array to remove the status lines. -func (t *Terminal) SetStatus(lines []string) { +func (t *terminal) SetStatus(lines []string) { // only truncate interactive status output var width int if t.canUpdateStatus { - width = terminal.Width(t.fd) + width = tty.Width(t.fd) if width <= 0 { // use 80 columns by default width = 80 diff --git a/internal/ui/termstatus/status_test.go b/internal/ui/termstatus/status_test.go index 78bc5ec6a..f8a7c4f5b 100644 --- a/internal/ui/termstatus/status_test.go +++ b/internal/ui/termstatus/status_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "github.com/restic/restic/internal/terminal" + tty "github.com/restic/restic/internal/terminal" rtest "github.com/restic/restic/internal/test" ) @@ -17,9 +17,9 @@ func TestSetStatus(t *testing.T) { buf, term, cancel := setupStatusTest() const ( - cl = terminal.PosixControlClearLine - home = terminal.PosixControlMoveCursorHome - up = terminal.PosixControlMoveCursorUp + cl = tty.PosixControlClearLine + home = tty.PosixControlMoveCursorHome + up = tty.PosixControlMoveCursorUp clearLn = home + cl ) @@ -55,10 +55,10 @@ func TestSetStatusUnchangedLines(t *testing.T) { buf, term, cancel := setupStatusTest() const ( - cl = terminal.PosixControlClearLine - home = terminal.PosixControlMoveCursorHome - up = terminal.PosixControlMoveCursorUp - down = terminal.PosixControlMoveCursorDown + cl = tty.PosixControlClearLine + home = tty.PosixControlMoveCursorHome + up = tty.PosixControlMoveCursorUp + down = tty.PosixControlMoveCursorDown clearLn = home + cl stepDown = home + down @@ -82,15 +82,15 @@ func TestSetStatusUnchangedLines(t *testing.T) { rtest.Equals(t, exp, buf.String()) } -func setupStatusTest() (*bytes.Buffer, *Terminal, context.CancelFunc) { +func setupStatusTest() (*bytes.Buffer, *terminal, context.CancelFunc) { buf := &bytes.Buffer{} term := new(nil, buf, buf, false) term.canUpdateStatus = true term.fd = ^uintptr(0) - term.clearCurrentLine = terminal.PosixClearCurrentLine - term.moveCursorUp = terminal.PosixMoveCursorUp - term.moveCursorDown = terminal.PosixMoveCursorDown + term.clearCurrentLine = tty.PosixClearCurrentLine + term.moveCursorUp = tty.PosixMoveCursorUp + term.moveCursorDown = tty.PosixMoveCursorDown ctx, cancel := context.WithCancel(context.Background()) go term.Run(ctx) @@ -101,8 +101,8 @@ func TestPrint(t *testing.T) { buf, term, cancel := setupStatusTest() const ( - cl = terminal.PosixControlClearLine - home = terminal.PosixControlMoveCursorHome + cl = tty.PosixControlClearLine + home = tty.PosixControlMoveCursorHome ) term.Print("test")