progress: tweak how os.Stderr is mocked

This commit changes the way `os.Stderr` is mocked so that higher
level consumes of the libary can use helpers can replace os.Stderr
(like `testutil.CaptureStdio()` is doing). The existing approach
assigns the "real" os.Stderr to osStderr so early that it cannot
be changed later.
This commit is contained in:
Michael Vogt 2025-02-04 12:16:46 +01:00 committed by Simon de Vlieger
parent 3e7ebe81c4
commit 75407ea511
2 changed files with 11 additions and 6 deletions

View file

@ -12,7 +12,7 @@ type (
func MockOsStderr(w io.Writer) (restore func()) { func MockOsStderr(w io.Writer) (restore func()) {
saved := osStderr saved := osStderr
osStderr = w osStderr = func() io.Writer { return w }
return func() { return func() {
osStderr = saved osStderr = saved
} }

View file

@ -18,8 +18,6 @@ import (
) )
var ( var (
osStderr io.Writer = os.Stderr
// This is only needed because pb.Pool require a real terminal. // This is only needed because pb.Pool require a real terminal.
// It sets it into "raw-mode" but there is really no need for // It sets it into "raw-mode" but there is really no need for
// this (see "func render()" below) so once this is fixed // this (see "func render()" below) so once this is fixed
@ -30,6 +28,13 @@ var (
CURSOR_SHOW = ESC + "[?25h" CURSOR_SHOW = ESC + "[?25h"
) )
// Used for testing, this must be a function (instead of the usual
// "var osStderr = os.Stderr" so that higher level libraries can test
// this code by replacing "os.Stderr", e.g. testutil.CaptureStdio()
var osStderr = func() io.Writer {
return os.Stderr
}
func cursorUp(i int) string { func cursorUp(i int) string {
return fmt.Sprintf("%s[%dA", ESC, i) return fmt.Sprintf("%s[%dA", ESC, i)
} }
@ -104,7 +109,7 @@ type terminalProgressBar struct {
// most terminals. // most terminals.
func NewTerminalProgressBar() (ProgressBar, error) { func NewTerminalProgressBar() (ProgressBar, error) {
b := &terminalProgressBar{ b := &terminalProgressBar{
out: osStderr, out: osStderr(),
} }
b.spinnerPb = pb.New(0) b.spinnerPb = pb.New(0)
b.spinnerPb.SetTemplate(`[{{ (cycle . "|" "/" "-" "\\") }}] {{ string . "spinnerMsg" }}`) b.spinnerPb.SetTemplate(`[{{ (cycle . "|" "/" "-" "\\") }}] {{ string . "spinnerMsg" }}`)
@ -248,7 +253,7 @@ type verboseProgressBar struct {
// NewVerboseProgressBar starts a new "verbose" progressbar that will just // NewVerboseProgressBar starts a new "verbose" progressbar that will just
// prints message but does not show any progress. // prints message but does not show any progress.
func NewVerboseProgressBar() (ProgressBar, error) { func NewVerboseProgressBar() (ProgressBar, error) {
b := &verboseProgressBar{w: osStderr} b := &verboseProgressBar{w: osStderr()}
return b, nil return b, nil
} }
@ -281,7 +286,7 @@ type debugProgressBar struct {
// so "glitches/weird" messages from the lower-layers can be inspected // so "glitches/weird" messages from the lower-layers can be inspected
// easier. // easier.
func NewDebugProgressBar() (ProgressBar, error) { func NewDebugProgressBar() (ProgressBar, error) {
b := &debugProgressBar{w: osStderr} b := &debugProgressBar{w: osStderr()}
return b, nil return b, nil
} }