README

Go CLI Library GoDoc

cli is a library for implementing powerful command-line interfaces in Go. cli is the library that powers the CLI for Packer, Serf, Consul, Vault, Terraform, and Nomad.

Features

  • Easy sub-command based CLIs: cli foo, cli bar, etc.

  • Support for nested subcommands such as cli foo bar.

  • Optional support for default subcommands so cli does something other than error.

  • Support for shell autocompletion of subcommands, flags, and arguments with callbacks in Go. You don't need to write any shell code.

  • Automatic help generation for listing subcommands

  • Automatic help flag recognition of -h, --help, etc.

  • Automatic version flag recognition of -v, --version.

  • Helpers for interacting with the terminal, such as outputting information, asking for input, etc. These are optional, you can always interact with the terminal however you choose.

  • Use of Go interfaces/types makes augmenting various parts of the library a piece of cake.

Example

Below is a simple example of creating and running a CLI

package main

import (
	"log"
	"os"

	"github.com/mitchellh/cli"
)

func main() {
	c := cli.NewCLI("app", "1.0.0")
	c.Args = os.Args[1:]
	c.Commands = map[string]cli.CommandFactory{
		"foo": fooCommandFactory,
		"bar": barCommandFactory,
	}

	exitStatus, err := c.Run()
	if err != nil {
		log.Println(err)
	}

	os.Exit(exitStatus)
}
Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const (
	// RunResultHelp is a value that can be returned from Run to signal
	// to the CLI to render the help output.
	RunResultHelp = -18511
)

Variables

View Source
var (
	UiColorNone    UiColor = UiColor{noColor, false}
	UiColorRed             = UiColor{int(color.FgHiRed), false}
	UiColorGreen           = UiColor{int(color.FgHiGreen), false}
	UiColorYellow          = UiColor{int(color.FgHiYellow), false}
	UiColorBlue            = UiColor{int(color.FgHiBlue), false}
	UiColorMagenta         = UiColor{int(color.FgHiMagenta), false}
	UiColorCyan            = UiColor{int(color.FgHiCyan), false}
)

    A list of colors that are useful. These are all non-bolded by default.

    Functions

    This section is empty.

    Types

    type BasicUi

    type BasicUi struct {
    	Reader      io.Reader
    	Writer      io.Writer
    	ErrorWriter io.Writer
    }

      BasicUi is an implementation of Ui that just outputs to the given writer. This UI is not threadsafe by default, but you can wrap it in a ConcurrentUi to make it safe.

      func (*BasicUi) Ask

      func (u *BasicUi) Ask(query string) (string, error)

      func (*BasicUi) AskSecret

      func (u *BasicUi) AskSecret(query string) (string, error)

      func (*BasicUi) Error

      func (u *BasicUi) Error(message string)

      func (*BasicUi) Info

      func (u *BasicUi) Info(message string)

      func (*BasicUi) Output

      func (u *BasicUi) Output(message string)

      func (*BasicUi) Warn

      func (u *BasicUi) Warn(message string)

      type CLI

      type CLI struct {
      	// Args is the list of command-line arguments received excluding
      	// the name of the app. For example, if the command "./cli foo bar"
      	// was invoked, then Args should be []string{"foo", "bar"}.
      	Args []string
      
      	// Commands is a mapping of subcommand names to a factory function
      	// for creating that Command implementation. If there is a command
      	// with a blank string "", then it will be used as the default command
      	// if no subcommand is specified.
      	//
      	// If the key has a space in it, this will create a nested subcommand.
      	// For example, if the key is "foo bar", then to access it our CLI
      	// must be accessed with "./cli foo bar". See the docs for CLI for
      	// notes on how this changes some other behavior of the CLI as well.
      	//
      	// The factory should be as cheap as possible, ideally only allocating
      	// a struct. The factory may be called multiple times in the course
      	// of a command execution and certain events such as help require the
      	// instantiation of all commands. Expensive initialization should be
      	// deferred to function calls within the interface implementation.
      	Commands map[string]CommandFactory
      
      	// HiddenCommands is a list of commands that are "hidden". Hidden
      	// commands are not given to the help function callback and do not
      	// show up in autocomplete. The values in the slice should be equivalent
      	// to the keys in the command map.
      	HiddenCommands []string
      
      	// Name defines the name of the CLI.
      	Name string
      
      	// Version of the CLI.
      	Version string
      
      	// Autocomplete enables or disables subcommand auto-completion support.
      	// This is enabled by default when NewCLI is called. Otherwise, this
      	// must enabled explicitly.
      	//
      	// Autocomplete requires the "Name" option to be set on CLI. This name
      	// should be set exactly to the binary name that is autocompleted.
      	//
      	// Autocompletion is supported via the github.com/posener/complete
      	// library. This library supports bash, zsh and fish. To add support
      	// for other shells, please see that library.
      	//
      	// AutocompleteInstall and AutocompleteUninstall are the global flag
      	// names for installing and uninstalling the autocompletion handlers
      	// for the user's shell. The flag should omit the hyphen(s) in front of
      	// the value. Both single and double hyphens will automatically be supported
      	// for the flag name. These default to `autocomplete-install` and
      	// `autocomplete-uninstall` respectively.
      	//
      	// AutocompleteNoDefaultFlags is a boolean which controls if the default auto-
      	// complete flags like -help and -version are added to the output.
      	//
      	// AutocompleteGlobalFlags are a mapping of global flags for
      	// autocompletion. The help and version flags are automatically added.
      	Autocomplete               bool
      	AutocompleteInstall        string
      	AutocompleteUninstall      string
      	AutocompleteNoDefaultFlags bool
      	AutocompleteGlobalFlags    complete.Flags
      
      	// HelpFunc is the function called to generate the generic help
      	// text that is shown if help must be shown for the CLI that doesn't
      	// pertain to a specific command.
      	HelpFunc HelpFunc
      
      	// HelpWriter is used to print help text and version when requested.
      	// Defaults to os.Stderr for backwards compatibility.
      	// It is recommended that you set HelpWriter to os.Stdout, and
      	// ErrorWriter to os.Stderr.
      	HelpWriter io.Writer
      
      	// ErrorWriter used to output errors when a command can not be run.
      	// Defaults to the value of HelpWriter for backwards compatibility.
      	// It is recommended that you set HelpWriter to os.Stdout, and
      	// ErrorWriter to os.Stderr.
      	ErrorWriter io.Writer
      	// contains filtered or unexported fields
      }

        CLI contains the state necessary to run subcommands and parse the command line arguments.

        CLI also supports nested subcommands, such as "cli foo bar". To use nested subcommands, the key in the Commands mapping below contains the full subcommand. In this example, it would be "foo bar".

        If you use a CLI with nested subcommands, some semantics change due to ambiguities:

        * We use longest prefix matching to find a matching subcommand. This
          means if you register "foo bar" and the user executes "cli foo qux",
          the "foo" command will be executed with the arg "qux". It is up to
          you to handle these args. One option is to just return the special
          help return code `RunResultHelp` to display help and exit.
        
        * The help flag "-h" or "-help" will look at all args to determine
          the help function. For example: "otto apps list -h" will show the
          help for "apps list" but "otto apps -h" will show it for "apps".
          In the normal CLI, only the first subcommand is used.
        
        * The help flag will list any subcommands that a command takes
          as well as the command's help itself. If there are no subcommands,
          it will note this. If the CLI itself has no subcommands, this entire
          section is omitted.
        
        * Any parent commands that don't exist are automatically created as
          no-op commands that just show help for other subcommands. For example,
          if you only register "foo bar", then "foo" is automatically created.
        

        func NewCLI

        func NewCLI(app, version string) *CLI

          NewClI returns a new CLI instance with sensible defaults.

          func (*CLI) IsHelp

          func (c *CLI) IsHelp() bool

            IsHelp returns whether or not the help flag is present within the arguments.

            func (*CLI) IsVersion

            func (c *CLI) IsVersion() bool

              IsVersion returns whether or not the version flag is present within the arguments.

              func (*CLI) Run

              func (c *CLI) Run() (int, error)

                Run runs the actual CLI based on the arguments given.

                func (*CLI) Subcommand

                func (c *CLI) Subcommand() string

                  Subcommand returns the subcommand that the CLI would execute. For example, a CLI from "--version version --help" would return a Subcommand of "version"

                  func (*CLI) SubcommandArgs

                  func (c *CLI) SubcommandArgs() []string

                    SubcommandArgs returns the arguments that will be passed to the subcommand.

                    type ColoredUi

                    type ColoredUi struct {
                    	OutputColor UiColor
                    	InfoColor   UiColor
                    	ErrorColor  UiColor
                    	WarnColor   UiColor
                    	Ui          Ui
                    }

                      ColoredUi is a Ui implementation that colors its output according to the given color schemes for the given type of output.

                      func (*ColoredUi) Ask

                      func (u *ColoredUi) Ask(query string) (string, error)

                      func (*ColoredUi) AskSecret

                      func (u *ColoredUi) AskSecret(query string) (string, error)

                      func (*ColoredUi) Error

                      func (u *ColoredUi) Error(message string)

                      func (*ColoredUi) Info

                      func (u *ColoredUi) Info(message string)

                      func (*ColoredUi) Output

                      func (u *ColoredUi) Output(message string)

                      func (*ColoredUi) Warn

                      func (u *ColoredUi) Warn(message string)

                      type Command

                      type Command interface {
                      	// Help should return long-form help text that includes the command-line
                      	// usage, a brief few sentences explaining the function of the command,
                      	// and the complete list of flags the command accepts.
                      	Help() string
                      
                      	// Run should run the actual command with the given CLI instance and
                      	// command-line arguments. It should return the exit status when it is
                      	// finished.
                      	//
                      	// There are a handful of special exit codes this can return documented
                      	// above that change behavior.
                      	Run(args []string) int
                      
                      	// Synopsis should return a one-line, short synopsis of the command.
                      	// This should be less than 50 characters ideally.
                      	Synopsis() string
                      }

                        A command is a runnable sub-command of a CLI.

                        type CommandAutocomplete

                        type CommandAutocomplete interface {
                        	// AutocompleteArgs returns the argument predictor for this command.
                        	// If argument completion is not supported, this should return
                        	// complete.PredictNothing.
                        	AutocompleteArgs() complete.Predictor
                        
                        	// AutocompleteFlags returns a mapping of supported flags and autocomplete
                        	// options for this command. The map key for the Flags map should be the
                        	// complete flag such as "-foo" or "--foo".
                        	AutocompleteFlags() complete.Flags
                        }

                          CommandAutocomplete is an extension of Command that enables fine-grained autocompletion. Subcommand autocompletion will work even if this interface is not implemented. By implementing this interface, more advanced autocompletion is enabled.

                          type CommandFactory

                          type CommandFactory func() (Command, error)

                            CommandFactory is a type of function that is a factory for commands. We need a factory because we may need to setup some state on the struct that implements the command itself.

                            type CommandHelpTemplate

                            type CommandHelpTemplate interface {
                            	// HelpTemplate is the template in text/template format to use for
                            	// displaying the Help. The keys available are:
                            	//
                            	//   * ".Help" - The help text itself
                            	//   * ".Subcommands"
                            	//
                            	HelpTemplate() string
                            }

                              CommandHelpTemplate is an extension of Command that also has a function for returning a template for the help rather than the help itself. In this scenario, both Help and HelpTemplate should be implemented.

                              If CommandHelpTemplate isn't implemented, the Help is output as-is.

                              type ConcurrentUi

                              type ConcurrentUi struct {
                              	Ui Ui
                              	// contains filtered or unexported fields
                              }

                                ConcurrentUi is a wrapper around a Ui interface (and implements that interface) making the underlying Ui concurrency safe.

                                func (*ConcurrentUi) Ask

                                func (u *ConcurrentUi) Ask(query string) (string, error)

                                func (*ConcurrentUi) AskSecret

                                func (u *ConcurrentUi) AskSecret(query string) (string, error)

                                func (*ConcurrentUi) Error

                                func (u *ConcurrentUi) Error(message string)

                                func (*ConcurrentUi) Info

                                func (u *ConcurrentUi) Info(message string)

                                func (*ConcurrentUi) Output

                                func (u *ConcurrentUi) Output(message string)

                                func (*ConcurrentUi) Warn

                                func (u *ConcurrentUi) Warn(message string)

                                type HelpFunc

                                type HelpFunc func(map[string]CommandFactory) string

                                  HelpFunc is the type of the function that is responsible for generating the help output when the CLI must show the general help text.

                                  func BasicHelpFunc

                                  func BasicHelpFunc(app string) HelpFunc

                                    BasicHelpFunc generates some basic help output that is usually good enough for most CLI applications.

                                    func FilteredHelpFunc

                                    func FilteredHelpFunc(include []string, f HelpFunc) HelpFunc

                                      FilteredHelpFunc will filter the commands to only include the keys in the include parameter.

                                      type MockCommand

                                      type MockCommand struct {
                                      	// Settable
                                      	HelpText     string
                                      	RunResult    int
                                      	SynopsisText string
                                      
                                      	// Set by the command
                                      	RunCalled bool
                                      	RunArgs   []string
                                      }

                                        MockCommand is an implementation of Command that can be used for tests. It is publicly exported from this package in case you want to use it externally.

                                        func (*MockCommand) Help

                                        func (c *MockCommand) Help() string

                                        func (*MockCommand) Run

                                        func (c *MockCommand) Run(args []string) int

                                        func (*MockCommand) Synopsis

                                        func (c *MockCommand) Synopsis() string

                                        type MockCommandAutocomplete

                                        type MockCommandAutocomplete struct {
                                        	MockCommand
                                        
                                        	// Settable
                                        	AutocompleteArgsValue  complete.Predictor
                                        	AutocompleteFlagsValue complete.Flags
                                        }

                                          MockCommandAutocomplete is an implementation of CommandAutocomplete.

                                          func (*MockCommandAutocomplete) AutocompleteArgs

                                          func (c *MockCommandAutocomplete) AutocompleteArgs() complete.Predictor

                                          func (*MockCommandAutocomplete) AutocompleteFlags

                                          func (c *MockCommandAutocomplete) AutocompleteFlags() complete.Flags

                                          type MockCommandHelpTemplate

                                          type MockCommandHelpTemplate struct {
                                          	MockCommand
                                          
                                          	// Settable
                                          	HelpTemplateText string
                                          }

                                            MockCommandHelpTemplate is an implementation of CommandHelpTemplate.

                                            func (*MockCommandHelpTemplate) HelpTemplate

                                            func (c *MockCommandHelpTemplate) HelpTemplate() string

                                            type MockUi

                                            type MockUi struct {
                                            	InputReader  io.Reader
                                            	ErrorWriter  *syncBuffer
                                            	OutputWriter *syncBuffer
                                            	// contains filtered or unexported fields
                                            }

                                              MockUi is a mock UI that is used for tests and is exported publicly for use in external tests if needed as well. Do not instantite this directly since the buffers will be initialized on the first write. If there is no write then you will get a nil panic. Please use the NewMockUi() constructor function instead. You can fix your code with

                                              sed -i -e 's/new(cli.MockUi)/cli.NewMockUi()/g' *_test.go
                                              

                                              func NewMockUi

                                              func NewMockUi() *MockUi

                                                NewMockUi returns a fully initialized MockUi instance which is safe for concurrent use.

                                                func (*MockUi) Ask

                                                func (u *MockUi) Ask(query string) (string, error)

                                                func (*MockUi) AskSecret

                                                func (u *MockUi) AskSecret(query string) (string, error)

                                                func (*MockUi) Error

                                                func (u *MockUi) Error(message string)

                                                func (*MockUi) Info

                                                func (u *MockUi) Info(message string)

                                                func (*MockUi) Output

                                                func (u *MockUi) Output(message string)

                                                func (*MockUi) Warn

                                                func (u *MockUi) Warn(message string)

                                                type PrefixedUi

                                                type PrefixedUi struct {
                                                	AskPrefix       string
                                                	AskSecretPrefix string
                                                	OutputPrefix    string
                                                	InfoPrefix      string
                                                	ErrorPrefix     string
                                                	WarnPrefix      string
                                                	Ui              Ui
                                                }

                                                  PrefixedUi is an implementation of Ui that prefixes messages.

                                                  func (*PrefixedUi) Ask

                                                  func (u *PrefixedUi) Ask(query string) (string, error)

                                                  func (*PrefixedUi) AskSecret

                                                  func (u *PrefixedUi) AskSecret(query string) (string, error)

                                                  func (*PrefixedUi) Error

                                                  func (u *PrefixedUi) Error(message string)

                                                  func (*PrefixedUi) Info

                                                  func (u *PrefixedUi) Info(message string)

                                                  func (*PrefixedUi) Output

                                                  func (u *PrefixedUi) Output(message string)

                                                  func (*PrefixedUi) Warn

                                                  func (u *PrefixedUi) Warn(message string)

                                                  type Ui

                                                  type Ui interface {
                                                  	// Ask asks the user for input using the given query. The response is
                                                  	// returned as the given string, or an error.
                                                  	Ask(string) (string, error)
                                                  
                                                  	// AskSecret asks the user for input using the given query, but does not echo
                                                  	// the keystrokes to the terminal.
                                                  	AskSecret(string) (string, error)
                                                  
                                                  	// Output is called for normal standard output.
                                                  	Output(string)
                                                  
                                                  	// Info is called for information related to the previous output.
                                                  	// In general this may be the exact same as Output, but this gives
                                                  	// Ui implementors some flexibility with output formats.
                                                  	Info(string)
                                                  
                                                  	// Error is used for any error messages that might appear on standard
                                                  	// error.
                                                  	Error(string)
                                                  
                                                  	// Warn is used for any warning messages that might appear on standard
                                                  	// error.
                                                  	Warn(string)
                                                  }

                                                    Ui is an interface for interacting with the terminal, or "interface" of a CLI. This abstraction doesn't have to be used, but helps provide a simple, layerable way to manage user interactions.

                                                    type UiColor

                                                    type UiColor struct {
                                                    	Code int
                                                    	Bold bool
                                                    }

                                                      UiColor is a posix shell color code to use.

                                                      type UiWriter

                                                      type UiWriter struct {
                                                      	Ui Ui
                                                      }

                                                        UiWriter is an io.Writer implementation that can be used with loggers that writes every line of log output data to a Ui at the Info level.

                                                        func (*UiWriter) Write

                                                        func (w *UiWriter) Write(p []byte) (n int, err error)