disgo

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2019 License: MIT Imports: 7 Imported by: 0

README

Disgo

Simple console output library for Go command-line interfaces.

Disgo provides four essential features for most user-friendly CLI applications:

  1. Simple output levels
  2. Output formatting
  3. Step-by-step outputs
  4. Simple user prompting

Table of content

  1. Console
    1. Console options
    2. Writing to the Console
    3. Output Formatting
    4. Step-by-step processes
    5. Symbols
  2. Prompter
    1. Confirmation prompt
    2. String input prompt
  3. Examples
  4. License

Console

The disgo Console provides an idiomatic way to build user-friendly command-line interfaces.

You can use it globally within your application, or you can instantiate your own Console.

Console options

When creating a Console instance or when using the global Console that this package provides, you might want to give it some options, such as:

  • WithDebug, which lets you enable or disable the debug output (it is disabled by default)
  • WithDefaultWriter, which lets you specify an io.Writer on which Debug and Info-level outputs should be written (it is set to os.Stdout by default)
  • WithErrorWriter, which lets you specify an io.Writer on which Error-level outputs should be written (it is set to os.Stderr by default)
  • WithColors, which lets you explicitely enable or disable colors in your output (it is enabled by default)

You can either pass those options to disgo.NewConsole() when creating a Console instance, like so:

    myConsole := disgo.New(disgo.WithDebug(true))

Or, if you are using the global console, you will simply need to call the SetupGlobalConsole function:

    disgo.SetupGlobalConsole(disgo.WithDebug(true))
Writing to the Console

Now that your console is set up, you can start writing on it. Printing functions behave idiomatically, like you would expect.

Here is how to use them on a local console:

    // All of those give the same output:
    // "Number of days in a year: 365" followed by a newline.
    myConsole.Infoln("Number of days in a year:", 365)
    myConsole.Infof("Number of days in a year: %d\n", 365)
    myConsole.Info("Number of days in a year: 365\n")

    // Debug methods are similar to info, except that they are not printed
    // if debug outputs are not enabled on the console.
    myConsole.Debugln("Number of days in a year:", 365)
    myConsole.Debugf("Number of days in a year: %d\n", 365)
    myConsole.Debug("Number of days in a year: 365\n")


    // Error methods are similar to info, except that they are written on
    // the error writer (os.Stderr by default).
    myConsole.Errorln("Number of days in a year:", 365)
    myConsole.Errorf("Number of days in a year: %d\n", 365)
    myConsole.Error("Number of days in a year: 365\n")

When using the global console, call the console printing functions directly:

    // All of those give the same output:
    // "Number of days in a year: 365" followed by a newline.
    disgo.Infoln("Number of days in a year:", 365)
    disgo.Infof("Number of days in a year: %d\n", 365)
    disgo.Info("Number of days in a year: 365\n")

    // Debug methods are similar to info, except that they are not printed
    // if debug outputs are not enabled on the console.
    disgo.Debugln("Number of days in a year:", 365)
    disgo.Debugf("Number of days in a year: %d\n", 365)
    disgo.Debug("Number of days in a year: 365\n")


    // Error methods are similar to info, except that they are written on
    // the error writer (os.Stderr by default).
    disgo.Errorln("Number of days in a year:", 365)
    disgo.Errorf("Number of days in a year: %d\n", 365)
    disgo.Error("Number of days in a year: 365\n")
Output Formatting

Another feature provided by this package is output formatting. It exposes six different output formats, which will print an output with a specific color, font-weight and font-style depending on what the output's content should convey to the user. For example, if you want to attract a user's attention to an error, you might use the disgo.Failure() formatting function, like so:

    if err := validateConfiguration; err != nil {
        disgo.Errorln("Invalid configuration detected:", disgo.Failure(err))
        return err
    }

Other output formats include Success, Trace, Important and Link.

You can of course combine those formats in elegant ways, like shown in the examples section.

Step-by-step processes

A lot of command-line interfaces describe step-by-step processes to the user, but it's difficult to combine clean code, clear output and elegant user interfaces. Disgo attempts to solve that problem by associating steps to its console.

For example, when beginning a task, you can use StartStep and specify the description of that step. Then, until that task is over, all calls to Disgo's printing functions will be queued. Once the task is complete (by calling EndStep, FailStep or by starting another step with StartStep), the task status is printed and all of the outputs that were queued during the task are printed with an indent, under the task, like so:

It is also important to note that FailStep and FailStepf can be used to return errors at the same time as they report a step as having failed. This allows you to write:

    disgo.StartStep("Doing something")
    if err := doSomething(); err != nil {
        return disgo.FailStepf("unable to do something: %v", err)
    }

Instead of having to call FailStep in your error handling before returning. You are still free to do so if you prefer, though.

Using the global console for step management is not thread-safe though, as it was built with simplicity in mind and can only handle one step at a time.

Prompter

The Prompter is not yet complete, as it only handles confirmation prompts for now. Its goal is to provide simple functions to prompt users for information.

Confirmation prompt

The confirmation prompt lets you prompt users for a yes or no answer.

    result, err := disgo.Confirm(disgo.Confirmation{
        Label:              "Install with current database?",
    })

Will produce the following output:

Install with current database? [y/n]

To which the user can answer by y, n, Y, N, yes, no, YES, NO, 0, 1, true, false, etc.

The confirmation prompt supports default values, like so:

    result, err := disgo.Confirm(disgo.Confirmation{
        EnableDefaultValue: true,
        DefaultValue:       false,
        Label:              "Install with current database?",
    })

This will set the default value to false, so that when the user does not have access to a TTY or that he simply presses enter to skip the prompt, a value of your choosing is used.

It's also possible to add your own confirmation parsers, if you don't want the user to answer to a yes/no question for example. This also means that you can customize the choices that will be presented to the user:

    result, err := disgo.Confirm(disgo.Confirmation{
        Label:              "Install with current database?",
        Choices:            []string{"yes", "no"},
        Parser:             func(input string) (bool, error) {
            switch input {
            case "yes":
                return true, nil
            case "no":
                return false, nil
            default:
                return false, fmt.Errorf("invalid input %q", input)
            }
        },
    })

This will output:

Install with current database? [yes/no]

And will use a custom parser for parsing the user's answer.

String input prompt

Not implemented yet.

Symbols

Disgo provides aliases to UTF-8 characters that could be useful to build your command-line interfaces.

    disgo.Infoln(disgo.Check) // ✔
    disgo.Infoln(disgo.Cross) // ✖
    disgo.Infoln(disgo.LeftArrow) // ❮
    disgo.Infoln(disgo.RightArrow) // ❯
    disgo.Infoln(disgo.LeftTriangle) // ◀
    disgo.Infoln(disgo.RightTriangle) // ▶

Examples

Here are a few examples of Disgo's output, using this repository's example program:



License

MIT License

Copyright (c) 2019

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Documentation

Overview

Package disgo is a console output and prompting library for modern command line interfaces.

It does not provide structured logging and is not built with performance in mind, since it is aimed at building user-friendly command line interfaces, and not applications.

The packages that compose disgo can be used independently.

The console package (github.com/ullaakut/disgo/console) is a simplified console output library which only handles two basic output levels (standard and debug), and can also manage outputs for step-by-step processes as well as formatting outputs.

The prompter package (github.com/ullaakut/disgo/prompter) is a simple user prompter that asks users for input data or confirmations.

The symbol package (github.com/ullaakut/disgo/symbol) provides access to cherry-picked UTF-8 symbols that are useful for making user-friendly command line interfaces.

Index

Constants

View Source
const (
	// Check displays ✔
	SymbolCheck = "\xe2\x9c\x94"

	// Cross displays ✖
	SymbolCross = "\xe2\x9c\x96"

	// LeftArrow displays ❮
	SymbolLeftArrow = "\xe2\x9d\xae"

	// RightArrow displays ❯
	SymbolRightArrow = "\xe2\x9d\xaf"

	// LeftTriangle displays ◀
	SymbolLeftTriangle = "\xe2\x97\x80"

	// RightTriangle displays ▶
	SymbolRightTriangle = "\xe2\x96\xb6"
)

This file contains a few cherry-picked UTF-8 symbols to be used to build user-friendly command-line interfaces. They are all colorless so that they can be used along with disgo's formatting helpers.

Variables

View Source
var (
	// Success colors a message in bold green to represent success.
	Success = color.New(color.FgGreen, color.Bold).SprintFunc()

	// Failure colors a message in bold red to represent failure.
	Failure = color.New(color.FgRed, color.Bold).SprintFunc()

	// Trace colors a message in faint white (usually rendered in gray)
	// to represent an output of low importance for the user.
	Trace = color.New(color.FgHiWhite, color.Faint).SprintFunc()

	// Important colors a message in bold to represent an important
	// information.
	Important = color.New(color.Bold).SprintFunc()

	// Link colors a message in underlined blue to represent a clickable link.
	Link = color.New(color.FgBlue, color.Underline).SprintFunc()
)
View Source
var (
	// DefaultConfirmationChoices is the default value
	// for the choices that are given to
	// the users in a confirmation prompt.
	DefaultConfirmationChoices = []string{"y", "n"}
)

Functions

func Confirm

func Confirm(config Confirmation) (bool, error)

Confirm prompts the user to confirm something using the global prompt.

func Debug

func Debug(a ...interface{})

Debug writes a debug output on the global console's default writer if the debug outputs are enabled.

func Debugf

func Debugf(format string, a ...interface{})

Debugf formats according to a format specifier and writes to the global console's default writer if the debug outputs are enabled.

func Debugln

func Debugln(a ...interface{})

Debugln writes a debug output on the global console's default writer if the debug outputs are enabled and appends a newline to its input.

func DefaultConfirmation

func DefaultConfirmation(input string) (bool, error)

DefaultConfirmation is a confirmation parser that covers most cases for confirmation. It converts y/Y/yes/YES/t/T/true/True/1 to true. It converts n/N/no/NO/f/F/false/FALSE/0 to false.

func EndStep

func EndStep()

EndStep ends a step with a success state on the global. console. It then prints all of the outputs that were queued while the step was in progress. Warning: This is not thread-safe.

func Error

func Error(a ...interface{})

Error writes an error output on the global console's error writer.

func Errorf

func Errorf(format string, a ...interface{})

Errorf formats according to a format specifier and writes to the global console's error writer.

func Errorln

func Errorln(a ...interface{})

Errorln writes an error output on the global console's error writer. It appends a newline to its input.

func FailStep

func FailStep(err error) error

FailStep ends a step with a failure state. It then prints all of the outputs that were queued while the step was in progress, and returns the given error for error handling. Warning: This is not thread-safe.

func FailStepf

func FailStepf(format string, a ...interface{}) error

FailStepf ends a step with a failure state on the global. console. It then prints all of the outputs that were queued while the step was in progress, and returns an error created from the given format and arguments. Warning: This is not thread-safe.

func Info

func Info(a ...interface{})

Info writes an info output on the global console's default writer.

func Infof

func Infof(format string, a ...interface{})

Infof formats according to a format specifier and writes to the global console's default writer.

func Infoln

func Infoln(a ...interface{})

Infoln writes an info output on the global console's default writer and appends a newline to its input.

func SetupGlobalConsole

func SetupGlobalConsole(options ...func(*Console))

SetupGlobalConsole applies options to the global console.

func SetupGlobalPrompter

func SetupGlobalPrompter(options ...func(*Prompter))

SetupGlobalPrompter applies options to the global prompter.

func StartStep

func StartStep(label string)

StartStep sets a step in the global console, which prints the step's label and makes the console queue outputs until the step is ended or failed. If a step was already in progress, it is considered to have been ended successfully. Warning: This is not thread-safe.

func StartStepf

func StartStepf(format string, a ...interface{})

StartStepf sets a step in the console, which prints the step's label and makes the console queue outputs until the step is ended or failed. If a step was already in progress, it is considered to have been ended successfully. Warning: This is not thread-safe.

func WithColors

func WithColors(enabled bool) func(*Console)

WithColors sets the use of colors in the console. By default, whether or not colors are enabled depends on the user's TTY, but this option can be used to force colors to be enabled or disabled.

func WithDebug

func WithDebug(enabled bool) func(*Console)

WithDebug enables or disables the console debug mode.

func WithDefaultOutput

func WithDefaultOutput(writer io.Writer) func(*Console)

WithDefaultOutput sets the default writer on the console.

func WithErrorOutput

func WithErrorOutput(writer io.Writer) func(*Console)

WithErrorOutput sets the error writer on the console.

func WithInteractive

func WithInteractive(enabled bool) func(*Prompter)

WithInteractive enables or disables the prompter interactive mode.

func WithReader

func WithReader(reader io.Reader) func(*Prompter)

WithReader sets the reader on the prompter. By default, if this option is not used, the default reader will be os.Stdin.

func WithWriter

func WithWriter(writer io.Writer) func(*Prompter)

WithWriter sets the writer on the prompter. By default, if this option is not used, the default writer will be os.Stdout.

Types

type Confirmation

type Confirmation struct {
	// The label that will be prompted to the user.
	// Example: `Are you sure?`
	Label string

	// The choices that will be presented to the user.
	// Example: `Y/n`. (A good practice is to uppercase
	// the default value, if there is one).
	Choices []string

	// EnableDefaultValue tells the prompter whether or not
	// there is a default value that will be used when the
	// user doesn't input any data.
	EnableDefaultValue bool

	// DefaultValue is the default value that will be used when
	// the user doesn't input any data, if EnableDefaultValue
	// is set to true OR that the prompter is set to not
	// interactive.
	DefaultValue bool

	// The parser that will be used to convert the user's input
	// into a true/false value.
	Parser ConfirmationParser
}

Confirmation represents a confirmation prompt's configuration.

type ConfirmationParser

type ConfirmationParser func(string) (bool, error)

ConfirmationParser is a function that parses an input and returns a confirmation value as well as an error, if the input can't be parsed.

type Console

type Console struct {
	// contains filtered or unexported fields
}

Console represents a disgo Console. It writes the output on a given io.Writer and can toggle debug outputs and have an error writer.

func NewConsole

func NewConsole(options ...func(*Console)) *Console

NewConsole creates a new Console and binds the given writer to its outputs.

func (Console) Debug

func (c Console) Debug(a ...interface{})

Debug writes a debug output on the console's default writer if the debug outputs are enabled.

func (Console) Debugf

func (c Console) Debugf(format string, a ...interface{})

Debugf formats according to a format specifier and writes to the console's default writer if the debug outputs are enabled.

func (Console) Debugln

func (c Console) Debugln(a ...interface{})

Debugln writes a debug output on the console's default writer if the debug outputs are enabled and appends a newline to its input.

func (*Console) EndStep

func (c *Console) EndStep()

EndStep ends a step with a success state. It then prints all of the outputs that were queued while the step was in progress.

func (Console) Error

func (c Console) Error(a ...interface{})

Error writes an error output on the console's error writer.

func (Console) Errorf

func (c Console) Errorf(format string, a ...interface{})

Errorf formats according to a format specifier and writes to the console's error writer.

func (Console) Errorln

func (c Console) Errorln(a ...interface{})

Errorln writes an error output on the console's error writer. It appends a newline to its input.

func (*Console) FailStep

func (c *Console) FailStep(err error) error

FailStep ends a step with a failure state. It then prints all of the outputs that were queued while the step was in progress, and returns the given error for error handling.

func (*Console) FailStepf

func (c *Console) FailStepf(format string, a ...interface{}) error

FailStepf ends a step with a failure state. It then prints all of the outputs that were queued while the step was in progress, and returns an error created from the given format and arguments.

func (Console) Info

func (c Console) Info(a ...interface{})

Info writes an info output on the console's default writer.

func (Console) Infof

func (c Console) Infof(format string, a ...interface{})

Infof formats according to a format specifier and writes to the console's default writer.

func (Console) Infoln

func (c Console) Infoln(a ...interface{})

Infoln writes an info output on the console's default writer and appends a newline to its input.

func (*Console) StartStep

func (c *Console) StartStep(label string)

StartStep sets a step in the console, which prints the step's label and makes the console queue outputs until the step is ended or failed. If a step was already in progress, it is considered to have been ended successfully.

func (*Console) StartStepf

func (c *Console) StartStepf(format string, a ...interface{})

StartStepf sets a step in the console, which prints the step's label and makes the console queue outputs until the step is ended or failed. If a step was already in progress, it is considered to have been ended successfully.

type Prompter

type Prompter struct {
	// contains filtered or unexported fields
}

Prompter prompts users to let them input data, and parses it.

func NewPrompter

func NewPrompter(options ...func(*Prompter)) *Prompter

NewPrompter instantiates a new prompter which will prompt users on the writer and read their output from the reader. The interactive boolean makes all prompts return a default value if set to false, and won't prompt them. This should be used if your users are not in a TTY and can't write to answer to the prompt.

func (Prompter) Confirm

func (p Prompter) Confirm(config Confirmation) (bool, error)

Confirm prompts the user to confirm something.

Directories

Path Synopsis
examples
advanced command
global command

Jump to

Keyboard shortcuts

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