fix(cli): add explicit output setters

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 13:24:23 +00:00
parent 821f7d191d
commit b1afac56bb
4 changed files with 40 additions and 2 deletions

View file

@ -70,6 +70,15 @@ func NewFrame(variant string) *Frame {
} }
} }
// WithOutput sets the destination writer for rendered output.
// Pass nil to keep the current writer unchanged.
func (f *Frame) WithOutput(out io.Writer) *Frame {
if out != nil {
f.out = out
}
return f
}
// Header sets the Header region model. // Header sets the Header region model.
func (f *Frame) Header(m Model) *Frame { f.setModel(RegionHeader, m); return f } func (f *Frame) Header(m Model) *Frame { f.setModel(RegionHeader, m); return f }

View file

@ -142,6 +142,16 @@ func TestFrame_Good(t *testing.T) {
f := NewFrame("C") f := NewFrame("C")
assert.Same(t, os.Stderr, f.out) assert.Same(t, os.Stderr, f.out)
}) })
t.Run("WithOutput sets output writer", func(t *testing.T) {
var buf bytes.Buffer
f := NewFrame("C").WithOutput(&buf)
f.Content(StaticModel("timed"))
f.Run()
assert.Contains(t, buf.String(), "timed")
})
} }
func TestFrame_Bad(t *testing.T) { func TestFrame_Bad(t *testing.T) {

View file

@ -123,6 +123,15 @@ func NewTaskTracker() *TaskTracker {
return &TaskTracker{out: os.Stderr} return &TaskTracker{out: os.Stderr}
} }
// WithOutput sets the destination writer for tracker output.
// Pass nil to keep the current writer unchanged.
func (tr *TaskTracker) WithOutput(out io.Writer) *TaskTracker {
if out != nil {
tr.out = out
}
return tr
}
// Add registers a task and returns it for goroutine use. // Add registers a task and returns it for goroutine use.
func (tr *TaskTracker) Add(name string) *TrackedTask { func (tr *TaskTracker) Add(name string) *TrackedTask {
t := &TrackedTask{ t := &TrackedTask{

View file

@ -121,8 +121,7 @@ func TestTaskTracker_Good(t *testing.T) {
t.Run("wait completes for non-TTY", func(t *testing.T) { t.Run("wait completes for non-TTY", func(t *testing.T) {
var buf bytes.Buffer var buf bytes.Buffer
tr := NewTaskTracker() tr := NewTaskTracker().WithOutput(&buf)
tr.out = &buf
task := tr.Add("quick") task := tr.Add("quick")
go func() { go func() {
@ -135,6 +134,17 @@ func TestTaskTracker_Good(t *testing.T) {
assert.Contains(t, buf.String(), "done") assert.Contains(t, buf.String(), "done")
}) })
t.Run("WithOutput sets output writer", func(t *testing.T) {
var buf bytes.Buffer
tr := NewTaskTracker().WithOutput(&buf)
tr.Add("quick").Done("done")
tr.Wait()
assert.Contains(t, buf.String(), "quick")
assert.Contains(t, buf.String(), "done")
})
t.Run("name width alignment", func(t *testing.T) { t.Run("name width alignment", func(t *testing.T) {
tr := NewTaskTracker() tr := NewTaskTracker()
tr.out = &bytes.Buffer{} tr.out = &bytes.Buffer{}