Documentation
¶
Overview ¶
Package cli provides a framework-agnostic way to define command-line interfaces in Go.
The core philosophy of this package is to decouple your application's command-line interface logic from specific CLI frameworks like spf13/cobra or urfave/cli. This approach offers several benefits:
Testability: Commands and their logic can be easily tested in isolation, without framework dependencies
Flexibility: You can switch between underlying CLI frameworks without significant code changes
Simplicity: The package focuses on core CLI functionality, avoiding unnecessary complexity
Extensibility: Support for custom hooks, flags, and configuration sources
At its core, the package uses a simple Command interface that all CLI commands implement:
type Command interface {
Execute(ctx context.Context, args, dashedArgs []string) error
}
Additional interfaces like CommandFlags, CommandDescription, CommandHook, etc., can be implemented to add functionality as needed.
The package also includes a robust configuration system through the cfg subpackage, allowing commands to load configuration from multiple sources (environment variables, files, command-line flags) with a clear precedence order.
Basic usage:
cmd := cli.New(rootCommand{}).
AddCommand("sub", subCommand{})
err := spf13cobra.Execute(context.Background(), os.Args, cmd)
cli.Exit(context.Background(), err)
For detailed examples, see the README and the example package.
Index ¶
- func Exit(ctx context.Context, err error, options ...ExitOption)
- func GetInitializedFlagsFromContext(ctx context.Context) ([]Flag, []Flag)
- func GetMetadataFromContext(ctx context.Context, key any) any
- func NewCommandContext(ctx context.Context) context.Context
- func NewContextCancelableBySignal(sig os.Signal, sigs ...os.Signal) (context.Context, func())
- func NewContextWithMetadata(ctx context.Context) context.Context
- func NewErrorWithExitStatus(err error, status uint8) error
- func NewErrorWithHelp(err error) error
- func SetExitLoggerInMetadata(ctx context.Context, writer io.WriteCloser)
- func SetInitializedFlagsInContext(ctx context.Context, localFlags, persistentFlags []Flag)
- func SetMetadataInContext(ctx context.Context, key, value any)
- type CLI
- type Command
- type CommandContext
- type CommandDescription
- type CommandExamples
- type CommandFlags
- type CommandHook
- type CommandPersistentFlags
- type CommandPersistentHook
- type CommandUsage
- type ExitOption
- type ExitStatusError
- type Flag
- func NewBuiltinFlag[T builtins](longName, shortName string, destination *T, description string) Flag
- func NewBuiltinPointerFlag[T builtins](longName, shortName string, destination **T, description string) Flag
- func NewBuiltinSliceFlag[T builtins](longName, shortName string, destination *[]T, description string) Flag
- func NewFlag(longName, shortName string, valuer FlagValuer, description string) Flag
- type FlagValuer
- type Hook
- type HookFunc
- type PersistentHook
- type ShowHelpError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Exit ¶
func Exit(ctx context.Context, err error, options ...ExitOption)
Exit terminates the CLI application, handling errors and setting the appropriate exit status code.
func GetInitializedFlagsFromContext ¶ added in v1.2.0
GetInitializedFlagsFromContext retrieves the initialized local and persistent flags for a command from the context. Returns nil slices if no flags are found. Warning: This function is exposed for sourcing flag values in configuration loader, you should not use it directly.
func GetMetadataFromContext ¶
GetMetadataFromContext retrieves a value from the global CLI metadata store based on the provided key. Returns nil if the key is not found.
func NewCommandContext ¶ added in v1.2.0
NewCommandContext is called for each command to create a dedicated context. Warning: This does not make sens to use outside of cli mapper.
func NewContextCancelableBySignal ¶
NewContextCancelableBySignal creates a new context that is automatically canceled when any of the provided signals are received. This is useful for gracefully shutting down the CLI application on interrupt signals (e.g., Ctrl+C).
func NewContextWithMetadata ¶
NewContextWithMetadata creates a new context that includes a metadata store. This store can be used to pass arbitrary data between different parts of the CLI application. This function should be called at the beginning of the CLI application's execution.
func NewErrorWithExitStatus ¶
NewErrorWithExitStatus creates a new error that implements the ExitStatusError interface, allowing a custom exit status to be set.
func NewErrorWithHelp ¶
NewErrorWithHelp creates a new error that implements the ShowHelpError interface, indicating that the help message should be shown.
func SetExitLoggerInMetadata ¶
func SetExitLoggerInMetadata(ctx context.Context, writer io.WriteCloser)
SetExitLoggerInMetadata sets the logger used by the CLI to write the exit message if any, inside the metadata. By default, the Exit func tries to find the logger in the metadata.
func SetInitializedFlagsInContext ¶ added in v1.2.0
SetInitializedFlagsInContext stores the initialized local and persistent flags for a command in the context. This allows the flags to be accessed later, for example, by configuration sources. Warning: This function is exposed for cli mappers, you should not use it directly.
func SetMetadataInContext ¶
SetMetadataInContext associates a key-value pair in the global CLI metadata store. This allows for storing and retrieving data that needs to be accessible across the entire CLI application.
Types ¶
type CLI ¶
type CLI struct {
// Name is the name of the command as it appears on the command line.
// For the root command, this is typically empty as it represents the application itself.
// For subcommands, it's the command name that will be used to invoke it.
Name string
// Command is the command to execute for this CLI.
// It must implement at least the Command interface, and may optionally
// implement additional interfaces like CommandFlags, CommandHook, etc.
Command Command
// SubCommands is a list of subcommands for this CLI.
// These are commands that can be invoked under the parent command.
SubCommands []*CLI
}
CLI represents a command-line interface with a root command and optional subcommands. It provides the structure for building hierarchical CLI applications.
func New ¶ added in v1.3.0
New creates a new CLI with the given command as its root. This is the entry point for building a CLI application.
Example:
rootCmd := New(myRootCommand{})
func (*CLI) AddCommand ¶
AddCommand adds a subcommand to the CLI with the given name. The name will be used to invoke the command on the command line. Returns the CLI instance for chaining method calls.
Example:
rootCmd := New(myRootCommand{}).
AddCommand("serve", &serveCommand{}).
AddCommand("version", &versionCommand{})
func (*CLI) Mount ¶ added in v1.1.0
Mount adds a pre-configured CLI hierarchy as a subcommand to the current CLI. This allows for composing complex CLI structures from simpler ones. Unlike AddCommand which adds a single command, Mount adds an entire command tree with its own subcommands.
The name parameter sets the name of the mounted CLI's root command. Returns the current CLI instance for chaining method calls.
Example:
// Create a sub-CLI
userCLI := New(userRootCommand{}).
AddCommand("list", &listUsersCommand{}).
AddCommand("create", &createUserCommand{})
// Mount it to the main CLI
mainCLI := New(mainRootCommand{}).
Mount("user", userCLI)
type CommandContext ¶
CommandContext allows commands to customize the context passed to their subcommands. This is useful for propagating configuration, dependencies, or other context-specific data down the command tree.
type CommandDescription ¶
type CommandDescription interface{ Description() string }
CommandDescription allows a command to provide a human-readable description of its purpose. This is used for generating help text. A short description is created from the first description line.
type CommandExamples ¶
type CommandExamples interface{ Examples() []string }
CommandExamples allows a command to provide usage examples. These examples are displayed in the help text to guide users on how to use the command.
type CommandFlags ¶
type CommandFlags interface{ Flags() []Flag }
CommandFlags allows a command to define command-line flags.
type CommandHook ¶
type CommandHook interface{ Hook() *Hook }
CommandHook allows a command to define callbacks (hooks) that are executed at specific points in the command's lifecycle. This enables custom behavior before or after command execution.
type CommandPersistentFlags ¶
type CommandPersistentFlags interface{ PersistentFlags() []Flag }
CommandPersistentFlags allows a command to define flags that` are inherited by all of its subcommands.
type CommandPersistentHook ¶
type CommandPersistentHook interface{ PersistentHook() *PersistentHook }
CommandPersistentHook allows a command to define persistent hooks that are executed for the command and all of its subcommands.
type CommandUsage ¶
type CommandUsage interface{ Usage() string }
CommandUsage allows a command to specify its argument usage pattern. This helps define how arguments should be passed to the command.
type ExitOption ¶
type ExitOption func(*exitOptions)
ExitOption defines the function signature for options that can be passed to the Exit function.
func WithExitFunc ¶
func WithExitFunc(exitFunc func(status int)) ExitOption
WithExitFunc allows overriding the default exit function (os.Exit) with a custom function. This is primarily useful for testing.
func WithExitLoggerFunc ¶
func WithExitLoggerFunc(getLoggerFunc func(context.Context) io.WriteCloser) ExitOption
WithExitLoggerFunc defines a way to customize logger used in messages.
type ExitStatusError ¶
ExitStatusError allows commands to specify a custom exit status code for the CLI application.
type Flag ¶
type Flag interface {
// FlagValuer defines methods to get and set flag's value.
FlagValuer
// LongName returns the long name of the flag (e.g., "--verbose").
LongName() string
// ShortName returns the short name of the flag (e.g., "-v"). May be empty.
ShortName() string
// Description returns a description of the flag's purpose.
Description() string
}
Flag represents a command-line flag. It combines the FlagValuer interface with methods to access flag metadata (long name, short name, description).
func NewBuiltinFlag ¶ added in v1.2.0
func NewBuiltinFlag[T builtins](longName, shortName string, destination *T, description string) Flag
NewBuiltinFlag creates a Flag for built-in types (int, string, bool, etc.). It handles the conversion between string representations and the underlying Go type. See NewFlag for more details.
func NewBuiltinPointerFlag ¶ added in v1.2.0
func NewBuiltinPointerFlag[T builtins](longName, shortName string, destination **T, description string) Flag
NewBuiltinPointerFlag creates a Flag for pointers to built-in types. See NewBuiltinFlag for more details.
func NewBuiltinSliceFlag ¶ added in v1.2.0
func NewBuiltinSliceFlag[T builtins](longName, shortName string, destination *[]T, description string) Flag
NewBuiltinSliceFlag creates a Flag for slices of built-in types. The flag value is expected to be a comma-separated list of values. See NewBuiltinFlag for more details.
func NewFlag ¶
func NewFlag(longName, shortName string, valuer FlagValuer, description string) Flag
NewFlag creates a new Flag instance.
longName is the long flag name, like --longname ; cannot be empty. shortName is the short flag name ; usually 1 character, like -s ; can be empty. valuer provide the way to set value to the destination. description is a short text explaining the flag ; can be empty.
It panics if invalid inputs are provided.
type FlagValuer ¶
type FlagValuer interface {
// Destination returns a pointer to the variable that stores the flag's value.
// This allows CLI frameworks to access the underlying value directly.
Destination() any
// FromString parses a string and sets the flag's value.
// This is called when a flag is specified on the command line.
// It should convert the string representation to the appropriate type
// and store it in the destination.
FromString(str string) error
// IsSet returns true if the flag has been set (i.e., its value has been
// modified from the default). This allows commands to determine if a
// flag was explicitly provided by the user.
IsSet() bool
// String returns a string representation of the flag's current value.
// This is used for displaying the flag's value in help text and error messages.
String() string
// TypeRepr returns a string representing the underlying type of the
// flag's value (e.g., "int", "string", "bool"). This is used in help text
// to indicate the expected type of the flag's value.
TypeRepr() string
}
FlagValuer defines the interface for getting and setting the value of a flag. It abstracts the underlying type of the flag, allowing for type-safe flag handling while providing a common interface for CLI frameworks to interact with.
By implementing this interface, you can create custom flag types that work seamlessly with the CLI framework.
func NewFlagValuer ¶ added in v1.2.0
func NewFlagValuer[T any](destination *T, parse func(string) (T, error), toString func(T) string) FlagValuer
NewFlagValuer creates a new FlagValuer instance for any type. It provides a generic implementation of the FlagValuer interface that can work with any Go type.
Parameters:
- destination: Pointer to where the flag value will be stored
- parse: Function to parse a string into the destination type
- toString: Function to convert the destination type to a string
Returns a FlagValuer that manages the value at destination.
It panics if any of the parameters is nil.
Example:
var count int
valuer := NewFlagValuer(
&count,
func(s string) (int, error) { return strconv.Atoi(s) },
func(i int) string { return strconv.Itoa(i) },
)
func NewStringerFlagValuer ¶ added in v1.2.0
func NewStringerFlagValuer[T fmt.Stringer](destination *T, parse func(string) (T, error)) FlagValuer
NewStringerFlagValuer creates a FlagValuer for types that implement the fmt.Stringer interface. It simplifies the creation of FlagValuers for types that already have a String() method.
Parameters:
- destination: Pointer to where the flag value will be stored
- parse: Function to parse a string into the destination type
Returns a FlagValuer that manages the value at destination, using the type's String() method for string representation.
Example:
var duration time.Duration
valuer := NewStringerFlagValuer(
&duration,
func(s string) (time.Duration, error) { return time.ParseDuration(s) },
)
type Hook ¶
type Hook struct {
// BeforeCommandExecution is called before the command's Execute method is invoked.
BeforeCommandExecution HookFunc
// AfterCommandExecution is called after the command's Execute
// method has completed (regardless of whether it returned an error).
AfterCommandExecution HookFunc
}
Hook defines callbacks that are executed during the command lifecycle.
type PersistentHook ¶
type PersistentHook struct {
// BeforeFlagsDefinition is called before the command's flags are
// processed. This is a good place to set up dependencies or
// perform initialization that affects flag parsing.
BeforeFlagsDefinition HookFunc
// BeforeCommandExecution is called before the command's Execute
// method is invoked (but after flag parsing).
BeforeCommandExecution HookFunc
// AfterCommandExecution is called after the command's Execute
// method has completed (regardless of whether it returned an error).
AfterCommandExecution HookFunc
}
PersistentHook defines callbacks that are executed for a command and all of its subcommands.
type ShowHelpError ¶
ShowHelpError is an interface that allows commands to signal whether the help message should be displayed along with the error.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package clicfg provides a flexible configuration system for CLI applications.
|
Package clicfg provides a flexible configuration system for CLI applications. |
|
internal/generator
command
|
|
|
internal
|
|
|
example/spf13_cobra
command
|
|