Skip to content

Commit

Permalink
Bubbletea initialization error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
cardil committed Mar 26, 2024
1 parent cf1573f commit 027bb62
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 20 deletions.
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -16,6 +16,7 @@ require (
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.13.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0
golang.org/x/term v0.18.0
gotest.tools/v3 v3.3.0
Expand Down Expand Up @@ -116,7 +117,6 @@ require (
github.com/xlab/treeprint v1.2.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/oauth2 v0.18.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion pkg/output/logging/context.go
Expand Up @@ -132,7 +132,7 @@ func createDefaultLogger(ctx context.Context) *zap.Logger {
zapcore.AddSync(errout),
lvl,
))
if !term.IsTerminal(errout) {
if !term.IsFancy(errout) {
ec = zap.NewProductionEncoderConfig()
logger = zap.New(zapcore.NewCore(
zapcore.NewJSONEncoder(ec),
Expand Down
14 changes: 10 additions & 4 deletions pkg/output/term/io.go
Expand Up @@ -30,11 +30,17 @@ func IsReaderTerminal(r io.Reader) bool {
return ok && term.IsTerminal(int(f.Fd()))
}

// IsTerminal returns true if the given writer is a real terminal.
func IsTerminal(w io.Writer) bool {
// IsWriterTerminal returns true if the given writer is a real terminal.
func IsWriterTerminal(w io.Writer) bool {
f, ok := w.(*os.File)
return ok && term.IsTerminal(int(f.Fd()))
}

// IsFancy returns true if the given writer is a real terminal, or the color
// is forced by the environment variables.
func IsFancy(w io.Writer) bool {
if environment.ColorIsForced() {
return true
}
f, ok := w.(*os.File)
return ok && environment.NonColorRequested() && term.IsTerminal(int(f.Fd()))
return !environment.NonColorRequested() && IsWriterTerminal(w)
}
15 changes: 11 additions & 4 deletions pkg/output/tui/progress.go
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/charmbracelet/bubbles/progress"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"go.uber.org/multierr"
"knative.dev/client-pkg/pkg/output"
"knative.dev/client-pkg/pkg/output/term"
)
Expand Down Expand Up @@ -79,12 +80,16 @@ type BubbleProgress struct {
prevSpeed []int
err error
quitChan chan struct{}
teaErr error
}

func (b *BubbleProgress) With(fn func(ProgressControl) error) error {
b.start()
defer b.stop()
return fn(b)
err := func() error {
defer b.stop()
return fn(b)
}()
return multierr.Combine(err, b.err, b.teaErr)
}

func (b *BubbleProgress) Error(err error) {
Expand Down Expand Up @@ -244,9 +249,11 @@ func (b *BubbleProgress) start() {
b.quitChan = make(chan struct{})
go func() {
t := b.tea
_, _ = t.Run()
if _, err := t.Run(); err != nil {
b.teaErr = err
}
close(b.quitChan)
if term.IsTerminal(out) {
if term.IsWriterTerminal(out) {
if err := t.ReleaseTerminal(); err != nil {
panic(err)
}
Expand Down
3 changes: 0 additions & 3 deletions pkg/output/tui/progress_test.go
Expand Up @@ -33,9 +33,6 @@ import (
)

func TestProgress(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext(t)
prt := output.NewTestPrinter()
ctx = output.WithContext(ctx, prt)
Expand Down
15 changes: 11 additions & 4 deletions pkg/output/tui/spinner.go
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"go.uber.org/multierr"
"knative.dev/client-pkg/pkg/output"
"knative.dev/client-pkg/pkg/output/term"
)
Expand All @@ -46,12 +47,16 @@ type BubbleSpinner struct {
spin spinner.Model
tea *tea.Program
quitChan chan struct{}
teaErr error
}

func (b *BubbleSpinner) With(fn func(Spinner) error) error {
b.start()
defer b.stop()
return fn(b)
err := func() error {
defer b.stop()
return fn(b)
}()
return multierr.Combine(err, b.teaErr)
}

func (b *BubbleSpinner) Init() tea.Cmd {
Expand Down Expand Up @@ -81,9 +86,11 @@ func (b *BubbleSpinner) start() {
b.quitChan = make(chan struct{})
go func() {
t := b.tea
_, _ = t.Run()
if _, err := t.Run(); err != nil {
b.teaErr = err
}
close(b.quitChan)
if term.IsTerminal(out) {
if term.IsWriterTerminal(out) {
_ = t.ReleaseTerminal()
}
}()
Expand Down
3 changes: 0 additions & 3 deletions pkg/output/tui/spinner_test.go
Expand Up @@ -26,9 +26,6 @@ import (
)

func TestSpinner(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
ctx := context.TestContext(t)
prt := output.NewTestPrinter()
ctx = output.WithContext(ctx, prt)
Expand Down

0 comments on commit 027bb62

Please sign in to comment.