component

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 7, 2024 License: Apache-2.0 Imports: 19 Imported by: 6

README

CLI UX Component library

Usage

To use the component package, import it into your Go program as follows:

import "github.com/vmware-tanzu/tanzu-plugin-runtime/component"

AskForConfirmation Component

AskForConfirmation is a function that prompts the user to confirm or deny a choice with a message and returns an error if the response is not affirmative.

Usage
package main

import (
    "github.com/pkg/errors"
    "github.com/vmware-tanzu/tanzu-plugin-runtime/component"
)

func main() {
    err := AskForConfirmation("Are you sure you want to delete this file?")
    if err != nil {
        return errors.Wrap(err, "failed to delete file")
    }

    // continue with file deletion
}

The function takes a message string as its argument and returns an error if the user's response is not affirmative (i.e., "y" or "Y"). If the response is affirmative, AskForConfirmation returns nil, and the program can continue executing.

If an error occurs during the function's execution, it will return a new error wrapped with the github.com/pkg/errors package.

Colorable-TTY

Colorable-TTY is a Golang package that provides utilities for creating colorized and formatted console output. This package uses the logrusorgru/aurora package to generate the colorized output. It also includes several functions for formatting strings such as Rpad, Underline, Bold, TrimRightSpace, and BeginsWith.

Then, you can use the functions provided by this package. For example:

package main

import (
    "fmt"
    "github.com/vmware-tanzu/tanzu-plugin-runtime/component"
)

func main() {
    fmt.Println(component.Underline("This text is underlined!"))
    fmt.Println(component.Bold("This text is bold!"))
    fmt.Println(component.Rpad("Right padded text", 20))
    fmt.Println(component.TrimRightSpace("Trim the whitespace at the end   "))
    fmt.Println(component.BeginsWith("This is a test", "This"))
}

Output Writer Component

This package provides a way to write output to different formats. It defines the OutputWriter interface which consists of SetKeys, AddRow, and Render methods.

How to use
Initialization
func NewOutputWriterWithOptions(output io.Writer, outputFormat string, opts []OutputWriterOption, headers ...string) OutputWriter
func NewObjectWriter(output io.Writer, outputFormat string, data interface{}) OutputWriter
  • NewOutputWriterWithOptions returns a new instance of OutputWriter and it accepts an io.Writer, an outputFormat (one of TableOutputType, YAMLOutputType, JSONOutputType, ListTableOutputType), and a variadic list of headers for the table.

  • NewObjectWriter is the same as NewOutputWriterWithOptions but it is used for writing objects instead of tables. It accepts an io.Writer, an outputFormat (one of YAMLOutputType, JSONOutputType), and an object that should be written.

  • It also accepts a list of OutputWriterOption's that can be used to further customize its output.

Note that NewOutputWriter has been deprecated in favor of NewOutputWriterWithOptions One difference in the default rendering behavior for YAML/JSON output between the writer created with NewOutputWriter vs that created with NewOutputWriterWithOptions is that row fields no longer gets auto stringified in the latter.

To retain the stringify behavior (unlikely what if needed except for backward compatibility reasons), create the output writer like so:

    writer := output.NewOutputWriter(os.Stdout, output.TableOutputType, []OutputWriterOption{WithAutoStringify()}, "Name", "Age")
Usage
func (ow *outputwriter) SetKeys(headerKeys ...string)
func (obw *objectwriter) SetKeys(headerKeys ...string)

SetKeys sets the values to use as the keys for the output values. It accepts a variadic list of strings.

func (ow *outputwriter) AddRow(items ...interface{})
func (obw *objectwriter) AddRow(items ...interface{})

AddRow appends a new row to our table. It accepts a variadic list of items. It is required to add items in the same order as the headers were provided.

func (ow *outputwriter) Render()
func (obw *objectwriter) Render()

Render emits the generated output to the output stream.

If NewOutputWriterWithOptions was used for initialization, Render will generate output in the format specified by the outputFormat parameter.

If NewObjectWriter was used for initialization, Render will generate output in the format specified by the outputFormat parameter, and it will use the provided object for output.

Constants
const (
    TableOutputType OutputType = "table"
    YAMLOutputType OutputType = "yaml"
    JSONOutputType OutputType = "json"
    ListTableOutputType OutputType = "listtable"
)
  • TableOutputType specifies that the output should be in table format.
  • YAMLOutputType specifies that the output should be in yaml format.
  • JSONOutputType specifies that the output should be in json format.
  • ListTableOutputType specifies that the output should be in a list table format.
Example
package main

import (
    "fmt"
    "os"

    "github.com/vmware-tanzu/tanzu-plugin-runtime/component"
)

func main() {
    // Example usage of NewOutputWriterWithOptions

    // Create a OutputWriter with default options
    writer := output.NewOutputWriterWithOptions(os.Stdout, output.TableOutputType, []OutputWriterOption{}, "Name", "Age")

    writer.AddRow("John", 30)
    writer.AddRow("Bob", 45)
    writer.Render()

    // Example usage of NewObjectWriter
    data := map[string]interface{}{
        "Name": "John",
        "Age": 30,
    }
    writer = output.NewObjectWriter(os.Stdout, output.JSONOutputType, data)
    writer.Render()
}

This will output:

+------+-----+
| Name | Age |
+------+-----+
| John | 30  |
| Bob  | 45  |
+------+-----+

{"Age":30,"Name":"John"}

OutputWriterSpinner Component

OutputWriterSpinner provides an interface to OutputWriter augmented with a spinner. It allows for displaying output of multiple types (Text, Table, Yaml, Json) with a spinner while also providing the ability to stop the spinner, display the final text and render the output.

Usage

To use OutputWriterSpinner, you can import the package in your Go code and create an instance of the OutputWriterSpinner interface using the NewOutputWriterSpinner function.

Note that NewOutputWriterWithSpinner and NewOutputWriterSpinnerWithOptions has been deprecated in favor of NewOutputWriterSpinner. The main difference is how the parameters are provided when creating a OutputWriterSpinner component.

Using Spinner to display Table/JSON/YAML output
import "github.com/vmware-tanzu/tanzu-plugin-runtime/component"

// Create new OutputWriterSpinner component. If `WithOutputStream` option is not provided, it will use os.Stdout as default output stream
owSpinner := component.NewOutputWriterSpinner(
        component.WithOutputFormat(component.TableOutputType), // For JSON use JSONOutputType and for YAML use YAMLOutputType
        component.WithSpinnerText("Fetching data..."),
        component.WithSpinnerStarted(),
        component.WithHeaders("Namespace", "Name", "Ready"))

// Do some processing to fetch the data from server and fill rows for table
owSpinner.AddRow("default", "pod1", "False")
owSpinner.AddRow("default", "pod2", "True")

// Stop the running spinner instance, displays FinalText if set, then renders the tabular output
owSpinner.Render()

Using Spinner to display plain text
import "github.com/vmware-tanzu/tanzu-plugin-runtime/component"

// Create new OutputWriterSpinner component
spinner := component.NewOutputWriterSpinner(component.WithOutputStream(os.Stderr))

spinner.SetText("Installing plugin 'apps'")
spinner.StartSpinner()

// Do some processing to fetch and install the required plugin
err := InstallPlugin("apps")

if err != nil {
    spinner.SetFinalText("Error while installing the plugin 'apps'", log.LogTypeERROR)
} else {
    spinner.SetFinalText("Successfully installed the plugin 'apps'", log.LogTypeSuccess)
}

// Stop the spinner and displays FinalText
spinner.StopSpinner()

The NewOutputWriterSpinner function takes in the following optional options:

  • WithOutputStream(writer io.Writer): sets the output stream for the OutputWriterSpinner component.
  • WithOutputFormat(outputFormat OutputType): sets output format for the OutputWriterSpinner component.
  • WithOutputWriterOptions(opts ...OutputWriterOption): configures OutputWriterOptions to the OutputWriterSpinner component.
  • WithSpinnerText(text string): sets the spinner text
  • WithSpinnerFinalText(finalText string, prefix log.LogType): sets the spinner final text and prefix log indicator
  • WithSpinnerStarted(): starts the spinner when the OutputWriterSpinner component gets created
  • WithHeaders(headers ...string): Sets the headers for the OutputWriterOptions component

The created OutputWriterSpinner instance provides following methods:

  • SetKeys(headerKeys ...string): sets the headers for the OutputWriter component
  • AddRow(items ...interface{}): adds rows to the OutputWriter component
  • SetText(text string): sets the spinner text
  • SetFinalText(finalText string, prefix log.LogType): sets the spinner final text and prefix log indicator
  • StartSpinner(): starts the spinner instance, showing the spinnerText
  • StopSpinner(): stops the running spinner instance, displays FinalText if set
  • Render(): stops the running spinner instance, displays FinalText if set, then renders the output

Prompt Component

This is a Go package that provides a way to prompt the user for input in a CLI application. It utilizes the AlecAivazis/survey/v2 package to display a prompt to the user and capture their response.

Create a PromptConfig object to specify the prompt's message, options, default value, and help text. Then call the Run method with a pointer to a variable of the desired type to store the user's response.

var response string
p := &PromptConfig{
    Message: "Enter a value:",
    Default: "default value",
    Help: "Enter the value you would like to use.",
}
err := p.Run(&response)
if err != nil {
    // Handle error
}
fmt.Println("You entered:", response)

The PromptConfig struct also provides the Sensitive option to hide user input, and the Options field to provide a list of choices for the user to select from.

var response string
p := &PromptConfig{
    Message: "Enter your password:",
    Sensitive: true,
}
err := p.Run(&response)
if err != nil {
    // Handle error
}
fmt.Println("Your password is:", response)

p = &PromptConfig{
    Message: "Select an option:",
    Options: []string{"Option 1", "Option 2", "Option 3"},
}
err = p.Run(&response)
if err != nil {
    // Handle error
}
fmt.Println("You selected:", response)
Example
package main

import (
    "fmt"
    "github.com/vmware-tanzu/tanzu-plugin-runtime/component"
)

func main() {
    var response string
    p := &prompt.PromptConfig{
        Message: "Enter your name:",
        Default: "John Doe",
        Help: "Enter your full name.",
    }
    err := p.Run(&response)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Hello,", response)
}

Question Component

The question.go file provides a Go package component that implements prompting a CLI question and reading user response.

Usage
Asking a Question

To prompt the user with a question, you can create a QuestionConfig object with the message to display and then call Run() method with a response object. For example:

package main

import (
    "fmt"

    "github.com/vmware-tanzu/tanzu-plugin-runtime/component"
)

func main() {
    q := component.QuestionConfig{
        Message: "What is your name?",
    }
    var name string
    err := q.Run(&name)
    if err != nil {
        // handle error
    }
    fmt.Printf("Hello, %s!\n", name)
}

The response object should be a pointer to a variable where the user's response will be stored.

This will display a prompt asking the user for their favorite color, with a default value of "blue" and a help message indicating the purpose of the question.

Reader Component

The reader.go file provides a Go package component that implements reading input from a file or standard input (stdin).

To read input from a file, call ReadInput and pass the file path:

import "github.com/vmware-tanzu/tanzu-plugin-runtime/component"

func main() {
    filePath := "/path/to/file.txt"
    data, err := component.ReadInput(filePath)
    if err != nil {
        // Handle error
    }
    // Do something with the input data
    fmt.Println(string(data))
}

To read input from stdin, pass the - character as the file path to ReadInput:

import "github.com/vmware-tanzu/tanzu-plugin-runtime/component"

func main() {
    data, err := component.ReadInput("-")
    if err != nil {
        // Handle error
    }
    // Do something with the input data
    fmt.Println(string(data))
}

Select Component

The select.go file provides a Go package component that implements a prompt for selecting an option. The package uses the survey library for prompting.

To prompt the user to select an option, create a SelectConfig object and pass it to the Select function:

import "github.com/vmware-tanzu/tanzu-plugin-runtime/component"

func main() {
    options := []string{"Option A", "Option B", "Option C"}
    config := &component.SelectConfig{
        Message: "Please select an option:",
        Default: "Option A",
        Options: options,
        Help: "Use arrow keys to move up and down, press Enter to select",
    }
    var response string
    err := component.Select(config, &response)
    if err != nil {
        // Handle error
    }
    // Do something with the selected option
    fmt.Println(response)
}

Documentation

Overview

Package component defines components that can be made use of in plugins.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Ask

func Ask(q *QuestionConfig, response interface{}) error

Ask asks a questions and lets the user select an option.

func AskForConfirmation

func AskForConfirmation(message string) error

AskForConfirmation is used to prompt the user to confirm or deny a choice

func BeginsWith

func BeginsWith(s, prefix string) bool

func Bold

func Bold(s string) string

func Green added in v1.2.0

func Green(s string) string

Green returns a green string.

func IsTTYEnabled

func IsTTYEnabled() bool

func NewAurora

func NewAurora() auroraPackage.Aurora

func NoOnlySpaces added in v0.90.0

func NoOnlySpaces(v interface{}) error

NoOnlySpaces checks if a given input string contains only empty spaces and returns an error if it does. This function does not panic if the input value is not a string.

func NoUpperCase added in v0.90.0

func NoUpperCase(v interface{}) error

NoUpperCase checks if a given input string contains uppercase characters and returns an error if it does. This function does not panic if the input value is not a string.

func Prompt

func Prompt(p *PromptConfig, response interface{}, opts ...PromptOpt) error

Prompt for input, reads input value, without trimming any characters (may include leading/tailing spaces)

func ReadInput

func ReadInput(filePath string) ([]byte, error)

ReadInput reads from file or std input and return a byte array.

func Rpad

func Rpad(s string, padding int) string

Rpad adds padding to the right of a string. from https://github.com/spf13/cobra/blob/993cc5372a05240dfd59e3ba952748b36b2cd117/cobra.go#L29

func Select

func Select(p *SelectConfig, response interface{}) error

Select an option.

func TrimRightSpace

func TrimRightSpace(s string) string

func Underline

func Underline(s string) string

Types

type OutputType

type OutputType string

OutputType defines the format of the output desired.

const (
	// TableOutputType specifies output should be in table format.
	TableOutputType OutputType = "table"
	// YAMLOutputType specifies output should be in yaml format.
	YAMLOutputType OutputType = "yaml"
	// JSONOutputType specifies output should be in json format.
	JSONOutputType OutputType = "json"
	// ListTableOutputType specified output should be in a list table format.
	ListTableOutputType OutputType = "listtable"
)

type OutputWriter

type OutputWriter interface {
	SetKeys(headerKeys ...string)
	AddRow(items ...interface{})
	Render()
}

OutputWriter is an interface for something that can write output.

func NewObjectWriter

func NewObjectWriter(output io.Writer, outputFormat string, data interface{}) OutputWriter

NewObjectWriter gets a new instance of our output writer.

func NewOutputWriter deprecated

func NewOutputWriter(output io.Writer, outputFormat string, headers ...string) OutputWriter

NewOutputWriter gets a new instance of our output writer.

Deprecated: NewOutputWriter is being deprecated in favor of NewOutputWriterWithOptions Until it is removed, it will retain the existing behavior of converting incoming row values to their golang string representation for backward compatibility reasons

func NewOutputWriterWithOptions added in v1.1.0

func NewOutputWriterWithOptions(output io.Writer, outputFormat string, opts []OutputWriterOption, headers ...string) OutputWriter

NewOutputWriterWithOptions gets a new instance of our output writer with some customization options.

type OutputWriterOption added in v1.1.0

type OutputWriterOption func(*outputwriter)

OutputWriterOption is an option for outputwriter

func WithAutoStringify added in v1.1.0

func WithAutoStringify() OutputWriterOption

WithAutoStringify configures the output writer to automatically convert row fields to their golang string representations. It is used to maintain backward compatibility with old rendering behavior, and should be _avoided_ if that need does not apply.

type OutputWriterSpinner

type OutputWriterSpinner interface {
	OutputWriter
	// RenderWithSpinner will stop spinner and render the output
	// Deprecated: RenderWithSpinner is being deprecated in favor of Render.
	RenderWithSpinner()
	// StartSpinner starts the spinner instance, showing the spinnerText
	StartSpinner()
	// StopSpinner stops the running spinner instance, displays FinalText if set
	StopSpinner()
	// SetText sets the spinner text
	SetText(text string)
	// SetFinalText sets the spinner final text and prefix
	// log indicator (log.LogTypeOUTPUT can be used for no prefix)
	SetFinalText(finalText string, prefix log.LogType)
}

OutputWriterSpinner is OutputWriter augmented with a spinner.

func NewOutputWriterSpinner added in v1.2.0

func NewOutputWriterSpinner(opts ...OutputWriterSpinnerOption) OutputWriterSpinner

NewOutputWriterSpinner returns implementation of OutputWriterSpinner

func NewOutputWriterSpinnerWithOptions deprecated added in v1.1.0

func NewOutputWriterSpinnerWithOptions(output io.Writer, outputFormat, spinnerText string, startSpinner bool, opts []OutputWriterOption, headers ...string) (OutputWriterSpinner, error)

NewOutputWriterSpinnerWithOptions returns implementation of OutputWriterSpinner.

Deprecated: NewOutputWriterSpinnerWithOptions is being deprecated in favor of NewOutputWriterSpinner.

func NewOutputWriterWithSpinner deprecated

func NewOutputWriterWithSpinner(output io.Writer, outputFormat, spinnerText string, startSpinner bool, headers ...string) (OutputWriterSpinner, error)

NewOutputWriterWithSpinner returns implementation of OutputWriterSpinner.

Deprecated: NewOutputWriterWithSpinner is being deprecated in favor of NewOutputWriterSpinner. Until it is removed, it will retain the existing behavior of converting incoming row values to their golang string representation for backward compatibility reasons

type OutputWriterSpinnerOption added in v1.2.0

type OutputWriterSpinnerOption func(*outputwriterspinner)

OutputWriterSpinnerOption is an option to configure outputwriterspinner

func WithHeaders added in v1.2.0

func WithHeaders(headers ...string) OutputWriterSpinnerOption

WithHeaders sets key headers

func WithOutputFormat added in v1.2.0

func WithOutputFormat(outputFormat OutputType) OutputWriterSpinnerOption

WithOutputFormat sets output format for the OutputWriterSpinner component

func WithOutputStream added in v1.2.0

func WithOutputStream(writer io.Writer) OutputWriterSpinnerOption

WithOutputStream sets the output stream for the OutputWriterSpinner component

func WithOutputWriterOptions added in v1.2.0

func WithOutputWriterOptions(opts ...OutputWriterOption) OutputWriterSpinnerOption

WithOutputWriterOptions configures OutputWriterOptions to the spinner

func WithSpinnerFinalText added in v1.2.0

func WithSpinnerFinalText(finalText string, prefix log.LogType) OutputWriterSpinnerOption

WithSpinnerFinalText sets the spinner final text and prefix log indicator (log.LogTypeOUTPUT can be used for no prefix)

func WithSpinnerStarted added in v1.2.0

func WithSpinnerStarted() OutputWriterSpinnerOption

WithSpinnerStarted starts the spinner

func WithSpinnerText added in v1.2.0

func WithSpinnerText(text string) OutputWriterSpinnerOption

WithSpinnerText sets the spinner text

type PromptConfig

type PromptConfig struct {
	// Message to display to user.
	Message string

	// Options for user to choose from
	Options []string

	// Default option.
	Default string

	// Sensitive information.
	Sensitive bool

	// Help for the prompt.
	Help string
}

PromptConfig is the configuration for a prompt.

func (*PromptConfig) Run

func (p *PromptConfig) Run(response interface{}, opts ...PromptOpt) error

Run the prompt.

type PromptOpt

type PromptOpt func(*PromptOptions) error

PromptOpt is an option for prompts

func WithStdio

func WithStdio(in terminal.FileReader, out terminal.FileWriter, err io.Writer) PromptOpt

WithStdio specifies the standard input, output and error. By default, these are os.Stdin, os.Stdout, and os.Stderr.

func WithValidator added in v0.90.0

func WithValidator(v survey.Validator) PromptOpt

WithValidator specifies a validator to use while prompting the user

type PromptOptions

type PromptOptions struct {
	// Standard in/out/error
	Stdio terminal.Stdio
	Icons survey.IconSet

	// Validators on user inputs
	Validators []survey.Validator
}

PromptOptions are options for prompting.

type QuestionConfig

type QuestionConfig struct {
	Message string
}

QuestionConfig stores config for prompting a CLI question.

func (*QuestionConfig) Run

func (q *QuestionConfig) Run(response interface{}) error

Run asks a question.

type SelectConfig

type SelectConfig struct {
	// Message to display to user.
	Message string

	// Default option.
	Default interface{}

	// Options to select frorm.
	Options []string

	// Sensitive information.
	Sensitive bool

	// Help for the prompt.
	Help string

	// PageSize defines how many options per page.
	PageSize int
}

SelectConfig is the configuration for a selection.

func (*SelectConfig) Run

func (p *SelectConfig) Run(response interface{}) error

Run the selection.

Jump to

Keyboard shortcuts

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