tapioca

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2024 License: MIT Imports: 4 Imported by: 2

README

tapioca

Add dynamic bubbbletea elements to existing Go applications. tapioca makes dynamic bubbbletea models stay at the bottom of the terminal, unaffected by log messages, the same way that tapioca pearls stay at the bottom of bubble tea.

Why should you use tapioca?

  • You have a useful application with a pragmatic command line interface. It doesn't matter if it is complex and uses cobra or if it is simple and uses flag.

  • You already have set in place some logging mechanism. It doesn't matter if you are using log, zerolog or any other logging mechanism as long as it supports specifying it's output as an io.Writer.

  • You want to add some dynamic elements. A simple progress bar or something way more complex.

Add some tapioca to your application! With all the flexibility of bubbbletea but without its complexity. As simple as two lines of code:

program := tapioca.NewProgram(spinner.New()).GoRun()
defer program.QuitAndWait()

Examples

Cobra & Spinner

Long running commands often require logging some intermediate information to let users know that the program is running as expected. However, printing a bunch of debug logs does not look nice in an application. Spinners can make your application more user friendly and tapioca integrates them painlessly with your cobra application.

./examples/cobra/cmd/connect.go

var connectCmd = &cobra.Command{
	[...]
	Run: func(cmd *cobra.Command, args []string) {
        // Create and run a spinner in the background
		program := tapioca.NewProgram(spinner.New()).GoRun()
		defer program.QuitAndWait() // Quit when command ends

		// Set the command output to the program
		defer func(w io.Writer) { cmd.SetOut(w) }(cmd.OutOrStdout())
		cmd.SetOut(program)
        [...]
    }
}

cobra

Log & Progress

./examples/log/main.go

var logger *log.Logger = log.Default()

func main() {
	// Create and start the progress bar
	program := tapioca.NewProgram(progress.New()).GoRun()
	defer program.QuitAndWait()

	// Use a logger that works together with bubbletea
	defer func(l *log.Logger) { logger = l }(logger)
	logger = log.New(program, "", log.LstdFlags)

	// Do work, log and increase progress bar
	for i := 0; i <= 100; i++ {
		time.Sleep(10 * time.Millisecond)
		logger.Println("Started", i)
		time.Sleep(10 * time.Millisecond)
		logger.Println("Finished", i)
		program.Send(float64(i) / 100)
	}
	logger.Println("Finished everything!")
}

log-progress

Without tapioca

log-progress_no-tapioca

Charm's Log

./examples/charmlog/main.go charmlog

Without tapioca

charmlog_no-tapioca

Pre-defined models

tapioca extends bubbles with some pre-defined models for fast prototyping:

  • Progress: TODO:
    • Title
    • Spinner
    • ETA
  • Spinner with title (similar to charmbracelet/huh's)

These models are usable out of the box and quit after pressing usual quit key combinations (ctrl+C/cmd+C). They are intended to cover basic dynamic elements that one would like to add to an existing application.

However they are just the tip of the iceberg of what can be done with Bubbletea and you might want a custom element. We also provide a WrapModel function that will wrap your custom model to make it behave better with an existing application (e.g. quitting with ctrl+C/cmd+C).

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func HandleMessage

func HandleMessage(msg tea.Msg) tea.Cmd

Handles common CLI signals like Ctrl+C for quitting.

Types

type ModelWrapper

type ModelWrapper struct {
	tea.Model
}

func WrapModel

func WrapModel(model tea.Model) *ModelWrapper

func (*ModelWrapper) Init

func (m *ModelWrapper) Init() tea.Cmd

func (*ModelWrapper) Update

func (m *ModelWrapper) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*ModelWrapper) View

func (m *ModelWrapper) View() string

type Program

type Program struct {
	*tea.Program
	// contains filtered or unexported fields
}

Adds an io.Writer interface to tea.Program

Example
package main

import (
	"fmt"
	"time"

	"github.com/esdandreu/tapioca"
	"github.com/esdandreu/tapioca/spinner"
)

func main() {
	program := tapioca.NewProgram(spinner.New()).GoRun()
	defer program.QuitAndWait()

	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Millisecond)
		fmt.Fprintln(program, i, "milliseconds")
	}
}

func NewProgram

func NewProgram(model tea.Model, opts ...tea.ProgramOption) *Program

func (*Program) GoRun

func (program *Program) GoRun(afterRun ...func(tea.Model, error)) *Program

func (*Program) QuitAndWait

func (program *Program) QuitAndWait()

func (*Program) Write

func (program *Program) Write(p []byte) (int, error)

Directories

Path Synopsis
progress module
spinner module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL