Skip to content

Commit 71d4c28

Browse files
authored
[release-1.16] Backport of knative#1973 (#504)
## release-1.16 Backport of knative#1973 Required for openshift-knative/kn-plugin-event#556
1 parent 09050a3 commit 71d4c28

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

pkg/output/tui/progress_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
)
3434

3535
func TestProgress(t *testing.T) {
36+
t.Parallel()
3637
ctx := context.TestContext(t)
3738
prt := output.NewTestPrinter()
3839
ctx = output.WithContext(ctx, prt)

pkg/output/tui/spinner.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import (
3030
const spinnerColor = lipgloss.Color("205")
3131

3232
type Spinner interface {
33-
Runnable[Spinner]
33+
Runnable[SpinnerControl]
3434
}
3535

3636
func (w *widgets) NewSpinner(message string) Spinner {
@@ -44,17 +44,27 @@ type BubbleSpinner struct {
4444
output.InputOutput
4545
Message
4646

47+
*updater
4748
spin spinner.Model
4849
tea *tea.Program
4950
quitChan chan struct{}
5051
teaErr error
5152
}
5253

53-
func (b *BubbleSpinner) With(fn func(Spinner) error) error {
54+
// SpinnerControl allows one to control the spinner, for example, to change the
55+
// message.
56+
type SpinnerControl interface {
57+
UpdateMessage(message string)
58+
}
59+
60+
// With will start the spinner and perform long operation within the
61+
// provided fn. The spinner will be automatically shutdown when the provided
62+
// function exits.
63+
func (b *BubbleSpinner) With(fn func(SpinnerControl) error) error {
5464
b.start()
5565
err := func() error {
5666
defer b.stop()
57-
return fn(b)
67+
return fn(b.updater)
5868
}()
5969
return multierr.Combine(err, b.teaErr)
6070
}
@@ -70,10 +80,20 @@ func (b *BubbleSpinner) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
7080
}
7181

7282
func (b *BubbleSpinner) View() string {
83+
select {
84+
case m := <-b.updater.messages:
85+
// nil on channel close
86+
if m != nil {
87+
b.Message.Text = *m
88+
}
89+
default:
90+
// nothing
91+
}
7392
return fmt.Sprintf("%s %s", b.Message.Text, b.spin.View())
7493
}
7594

7695
func (b *BubbleSpinner) start() {
96+
b.updater = &updater{make(chan *string)}
7797
b.spin = spinner.New(
7898
spinner.WithSpinner(spinner.Meter),
7999
spinner.WithStyle(spinnerStyle()),
@@ -94,6 +114,7 @@ func (b *BubbleSpinner) stop() {
94114
return
95115
}
96116

117+
close(b.updater.messages)
97118
b.tea.Quit()
98119
<-b.quitChan
99120

@@ -111,3 +132,11 @@ func (b *BubbleSpinner) stop() {
111132
func spinnerStyle() lipgloss.Style {
112133
return lipgloss.NewStyle().Foreground(spinnerColor)
113134
}
135+
136+
type updater struct {
137+
messages chan *string
138+
}
139+
140+
func (u updater) UpdateMessage(message string) {
141+
u.messages <- &message
142+
}

pkg/output/tui/spinner_test.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
)
2727

2828
func TestSpinner(t *testing.T) {
29+
t.Parallel()
2930
ctx := context.TestContext(t)
3031
prt := output.NewTestPrinter()
3132
ctx = output.WithContext(ctx, prt)
@@ -35,14 +36,21 @@ func TestSpinner(t *testing.T) {
3536
if s == nil {
3637
t.Errorf("want spinner, got nil")
3738
}
38-
if err := s.With(func(spinner tui.Spinner) error {
39-
time.Sleep(20 * time.Millisecond)
39+
if err := s.With(func(sc tui.SpinnerControl) error {
40+
time.Sleep(3 * time.Millisecond)
41+
sc.UpdateMessage("msg-1")
42+
time.Sleep(3 * time.Millisecond)
43+
sc.UpdateMessage("msg-2")
44+
time.Sleep(3 * time.Millisecond)
4045
return nil
4146
}); err != nil {
4247
t.Errorf("want nil, got %v", err)
4348
}
4449
got := prt.Outputs().Out.String()
45-
want := "\x1b[?25lmessage ▰▱▱\x1b[0D\x1b[2K\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006lmessage Done\n"
50+
want := "\x1b[?25lmessage ▰▱▱\x1b[0D" +
51+
"\x1b[0D\x1b[2Kmsg-1 ▰▰▱\x1b[0D" +
52+
"\x1b[0D\x1b[2Kmsg-2 ▰▰▰\x1b[0D" +
53+
"\x1b[2K\x1b[?25h\x1b[?1002l\x1b[?1003l\x1b[?1006lmsg-2 Done\n"
4654
if got != want {
4755
t.Errorf("text missmatch\nwant %q,\n got %q", want, got)
4856
}

pkg/output/tui/widgets_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
)
2525

2626
func TestNewWidgets(t *testing.T) {
27+
t.Parallel()
2728
ctx := context.TestContext(t)
2829
w := tui.NewWidgets(ctx)
2930

@@ -33,6 +34,7 @@ func TestNewWidgets(t *testing.T) {
3334
}
3435

3536
func TestNewInteractiveWidgets(t *testing.T) {
37+
t.Parallel()
3638
ctx := context.TestContext(t)
3739
w, err := tui.NewInteractiveWidgets(ctx)
3840

0 commit comments

Comments
 (0)