Documentation
¶
Overview ¶
Package cli defines an SDK for building performant and consistent CLIs. All commands start with a RootCommand which can then accept one or more nested subcommands. Subcommands can also be RootCommand, which creates nested CLIs (e.g. "my-tool do the-thing").
The CLI provides opinionated, formatted help output including flag structure. It also provides a more integrated experience for defining CLI flags, hiding flags, and generating aliases.
To minimize startup times, things are as lazy-loaded as possible. This means commands are instantiated only when needed. Most applications will create a private global variable that returns the root command:
var rootCmd = func() cli.Command {
return &cli.RootCommand{
Name: "my-tool",
Version: "1.2.3",
Commands: map[string]cli.CommandFactory{
"eat": func() cli.Command {
return &EatCommand{}
},
"sleep": func() cli.Command {
return &SleepCommand{}
},
},
}
}
This CLI could be invoked via:
$ my-tool eat $ my-tool sleep
Deeply-nested RootCommand behave like nested CLIs:
var rootCmd = func() cli.Command {
return &cli.RootCommand{
Name: "my-tool",
Version: "1.2.3",
Commands: map[string]cli.CommandFactory{
"transport": func() cli.Command {
return &cli.RootCommand{
Name: "transport",
Description: "Subcommands for transportation",
Commands: map[string]cli.CommandFactory{
"bus": func() cli.Command {
return &BusCommand{}
},
"car": func() cli.Command {
return &CarCommand{}
},
"train": func() cli.Command {
return &TrainCommand{}
},
},
}
},
},
}
}
This CLI could be invoked via:
$ my-tool transport bus $ my-tool transport car $ my-tool transport train
Example (CommandGroup) ¶
package main
import (
"context"
"fmt"
"os"
"github.com/abcxyz/pkg/cli"
)
type EatCommand struct {
cli.BaseCommand
}
func (c *EatCommand) Desc() string {
return "Eat some food"
}
func (c *EatCommand) Help() string {
return `
Usage: {{ COMMAND }} [options]
The eat command eats food.
`
}
func (c *EatCommand) Flags() *cli.FlagSet {
return cli.NewFlagSet()
}
func (c *EatCommand) Run(ctx context.Context, args []string) error {
if err := c.Flags().Parse(args); err != nil {
return fmt.Errorf("failed to parse flags: %w", err)
}
// TODO: implement
return nil
}
type DrinkCommand struct {
cli.BaseCommand
}
func (c *DrinkCommand) Desc() string {
return "Drink some water"
}
func (c *DrinkCommand) Help() string {
return `
Usage: {{ COMMAND }} [options]
The drink command drinks water.
`
}
func (c *DrinkCommand) Flags() *cli.FlagSet {
return cli.NewFlagSet()
}
func (c *DrinkCommand) Run(ctx context.Context, args []string) error {
if err := c.Flags().Parse(args); err != nil {
return fmt.Errorf("failed to parse flags: %w", err)
}
// TODO: implement
return nil
}
func main() {
ctx := context.Background()
rootCmd := func() cli.Command {
return &cli.RootCommand{
Name: "my-tool",
Version: "1.2.3",
Commands: map[string]cli.CommandFactory{
"eat": func() cli.Command {
return &EatCommand{}
},
"drink": func() cli.Command {
return &DrinkCommand{}
},
},
}
}
cmd := rootCmd()
// Help output is written to stderr by default. Redirect to stdout so the
// "Output" assertion works.
cmd.SetStderr(os.Stdout)
cmd.Outf("\nTop-level help:")
if err := cmd.Run(ctx, []string{"-h"}); err != nil {
panic(err)
}
cmd.Outf("\nCommand-level help:")
if err := cmd.Run(ctx, []string{"eat", "-h"}); err != nil {
panic(err)
}
}
Output: Top-level help: Usage: my-tool COMMAND drink Drink some water eat Eat some food Command-level help: Usage: my-tool eat [options] The eat command eats food.
Example (CommandWithFlags) ¶
package main
import (
"context"
"fmt"
"os"
"strconv"
"github.com/abcxyz/pkg/cli"
)
type CountCommand struct {
cli.BaseCommand
flagStep int64
}
func (c *CountCommand) Desc() string {
return "Counts from 0 up to a number"
}
func (c *CountCommand) Help() string {
return `
Usage: {{ COMMAND }} [options] MAX
The count command prints out a list of numbers starting from 0 up to and
including the provided MAX.
$ {{ COMMAND }} 50
The value for MAX must be a positive integer.
`
}
func (c *CountCommand) Flags() *cli.FlagSet {
set := cli.NewFlagSet()
f := set.NewSection("Number options")
f.Int64Var(&cli.Int64Var{
Name: "step",
Aliases: []string{"s"},
Example: "1",
Default: 1,
Target: &c.flagStep,
Usage: "Numeric value by which to increment between each number.",
})
return set
}
func (c *CountCommand) Run(ctx context.Context, args []string) error {
f := c.Flags()
if err := f.Parse(args); err != nil {
return fmt.Errorf("failed to parse flags: %w", err)
}
args = f.Args()
if len(args) != 1 {
return fmt.Errorf("expected 1 argument, got %q", args)
}
maxStr := args[0]
max, err := strconv.ParseInt(maxStr, 10, 64)
if err != nil {
return fmt.Errorf("failed to parse max: %w", err)
}
for i := int64(0); i <= max; i += c.flagStep {
c.Outf("%d", i)
}
return nil
}
func main() {
ctx := context.Background()
// Create the command.
rootCmd := func() cli.Command {
return &cli.RootCommand{
Name: "my-tool",
Version: "1.2.3",
Commands: map[string]cli.CommandFactory{
"count": func() cli.Command {
return &CountCommand{}
},
},
}
}
cmd := rootCmd()
// Help output is written to stderr by default. Redirect to stdout so the
// "Output" assertion works.
cmd.SetStderr(os.Stdout)
cmd.Outf("\nUp to 3:")
if err := cmd.Run(ctx, []string{"count", "3"}); err != nil {
panic(err)
}
cmd.Outf("\nUp to 10, stepping 2")
if err := cmd.Run(ctx, []string{"count", "-step=2", "10"}); err != nil {
panic(err)
}
}
Output: Up to 3: 0 1 2 3 Up to 10, stepping 2 0 2 4 6 8 10
Example (Completions) ¶
package main
import (
"context"
"strconv"
"time"
"github.com/abcxyz/pkg/cli"
"github.com/posener/complete/v2"
"github.com/posener/complete/v2/predict"
)
type SingCommand struct {
cli.BaseCommand
flagSong string
flagFade time.Duration
flagNow int64
}
func (c *SingCommand) Desc() string {
return "Sings a song"
}
func (c *SingCommand) Help() string {
return `
Usage: {{ COMMAND }} [options] PATH
Sings the given song at the audio file.
`
}
// PredictArgs is an optional interface which will predict argument values. If
// omitted, no arguments are suggested.
func (c *SingCommand) PredictArgs() complete.Predictor {
return predict.Files("*.mp3")
}
func (c *SingCommand) Flags() *cli.FlagSet {
set := cli.NewFlagSet()
f := set.NewSection("Song options")
f.StringVar(&cli.StringVar{
Name: "song",
Aliases: []string{"s"},
Example: "Itsy Bitsy Spider",
Target: &c.flagSong,
Predict: predict.Set{"Happy Birthday", "Twinkly Twinkle Little Star"},
Usage: "Name of the song to play.",
})
f.DurationVar(&cli.DurationVar{
Name: "fade",
Example: "5s",
Default: 5 * time.Second,
Target: &c.flagFade,
Predict: predict.Set{"1s", "5s", "10s"},
Usage: "Duration to fade audio tracks.",
})
f.Int64Var(&cli.Int64Var{
Name: "now",
Example: "10404929",
Default: time.Now().Unix(),
Target: &c.flagNow,
Predict: complete.PredictFunc(func(prefix string) []string {
return []string{strconv.FormatInt(time.Now().Unix(), 10)}
}),
Usage: "Curring timestamp, in unix seconds.",
})
return set
}
func (c *SingCommand) Run(ctx context.Context, args []string) error {
return nil
}
func main() {
// The example is above, demonstrating various ways to define completions. To
// see even more ways, look at the examples at
// github.com/posener/complete/tree/master.
//
// Since completions are a shell function, users must add something to their
// shell configuration (e.g. .bashrc, .zshrc). The easiest method to install
// completions is to allow the binary to do it. It will detect the shell and
// insert the correct code into the user's shell profile. Instruct users to
// run the following command:
//
// COMP_INSTALL=1 COMP_YES=1 my-cli
//
// This will automatically install shell completions. To uninstall
// completions, instruct users to run:
//
// COMP_UNINSTALL=1 COMP_YES=1 my-cli
//
// This will automatically uninstall the completions.
//
// If users want to install the completions manually, you will need to provide
// them shell-specific instructions. The setup usually requires adding the
// following lines:
//
// autoload -U +X bashcompinit && bashcompinit
// complete -o nospace -C /full/path/to/my-cli my-cli
//
// Of note:
//
// 1. You must use the full filepath to the CLI binary
// 2. The argument to the CLI binary is itself
}
Example (PersistentFlags) ¶
package main
import (
"context"
"fmt"
"os"
"github.com/abcxyz/pkg/cli"
)
// serverFlags represent the shared flags among all server commands. Embed this
// struct into any commands that interact with a server.
type serverFlags struct {
flagAddress string
flagTLSSkipVerify bool
}
func (s *serverFlags) addServerFlags(set *cli.FlagSet) {
f := set.NewSection("Server options")
f.StringVar(&cli.StringVar{
Name: "server-address",
Example: "https://my.corp.server:8145",
Default: "http://localhost:8145",
EnvVar: "CLI_SERVER_ADDRESS",
Target: &s.flagAddress,
Usage: "Endpoint, including protocol and port, the server.",
})
f.BoolVar(&cli.BoolVar{
Name: "insecure",
Default: false,
EnvVar: "CLI_SERVER_TLS_SKIP_VERIFY",
Target: &s.flagTLSSkipVerify,
Usage: "Skip TLS verification. This is bad, please don't do it.",
})
}
type UploadCommand struct {
cli.BaseCommand
serverFlags
}
func (c *UploadCommand) Desc() string {
return "Upload a file"
}
func (c *UploadCommand) Help() string {
return `
Usage: {{ COMMAND }} [options]
Upload a file to the server.
`
}
func (c *UploadCommand) Flags() *cli.FlagSet {
set := cli.NewFlagSet()
c.serverFlags.addServerFlags(set)
return set
}
func (c *UploadCommand) Run(ctx context.Context, args []string) error {
if err := c.Flags().Parse(args); err != nil {
return fmt.Errorf("failed to parse flags: %w", err)
}
_ = c.flagAddress // or c.serverFlags.flagAddress
_ = c.flagTLSSkipVerify
// TODO: implement
return nil
}
type DownloadCommand struct {
cli.BaseCommand
serverFlags
}
func (c *DownloadCommand) Desc() string {
return "Download a file"
}
func (c *DownloadCommand) Help() string {
return `
Usage: {{ COMMAND }} [options]
Download a file from the server.
`
}
func (c *DownloadCommand) Flags() *cli.FlagSet {
set := cli.NewFlagSet()
c.serverFlags.addServerFlags(set)
return set
}
func (c *DownloadCommand) Run(ctx context.Context, args []string) error {
if err := c.Flags().Parse(args); err != nil {
return fmt.Errorf("failed to parse flags: %w", err)
}
_ = c.flagAddress // or c.serverFlags.flagAddress
_ = c.flagTLSSkipVerify
// TODO: implement
return nil
}
func main() {
ctx := context.Background()
rootCmd := func() cli.Command {
return &cli.RootCommand{
Name: "my-tool",
Version: "1.2.3",
Commands: map[string]cli.CommandFactory{
"download": func() cli.Command {
return &DownloadCommand{}
},
"upload": func() cli.Command {
return &UploadCommand{}
},
},
}
}
cmd := rootCmd()
// Help output is written to stderr by default. Redirect to stdout so the
// "Output" assertion works.
cmd.SetStderr(os.Stdout)
cmd.Outf("\nTop-level help:")
if err := cmd.Run(ctx, []string{"-h"}); err != nil {
panic(err)
}
cmd.Outf("\nCommand-level help:")
if err := cmd.Run(ctx, []string{"download", "-h"}); err != nil {
panic(err)
}
}
Output: Top-level help: Usage: my-tool COMMAND download Download a file upload Upload a file Command-level help: Usage: my-tool download [options] Download a file from the server. Server options -insecure Skip TLS verification. This is bad, please don't do it. The default value is "false". This option can also be specified with the CLI_SERVER_TLS_SKIP_VERIFY environment variable. -server-address="https://my.corp.server:8145" Endpoint, including protocol and port, the server. The default value is "http://localhost:8145". This option can also be specified with the CLI_SERVER_ADDRESS environment variable.
Index ¶
- func Flag[T any](f *FlagSection, i *Var[T])
- type ArgPredictor
- type BaseCommand
- func (c *BaseCommand) Errf(format string, a ...any)
- func (c *BaseCommand) ExecutablePath() (string, error)
- func (c *BaseCommand) Flags() *FlagSet
- func (c *BaseCommand) Hidden() bool
- func (c *BaseCommand) Outf(format string, a ...any)
- func (c *BaseCommand) Pipe() (stdin, stdout, stderr *bytes.Buffer)
- func (c *BaseCommand) Prompt(ctx context.Context, msg string, args ...any) (string, error)
- func (c *BaseCommand) SetStderr(w io.Writer)
- func (c *BaseCommand) SetStdin(r io.Reader)
- func (c *BaseCommand) SetStdout(w io.Writer)
- func (c *BaseCommand) Stderr() io.Writer
- func (c *BaseCommand) Stdin() io.Reader
- func (c *BaseCommand) Stdout() io.Writer
- func (c *BaseCommand) WorkingDir() (string, error)
- type BoolVar
- type Command
- type CommandFactory
- type DurationVar
- type FlagSection
- func (f *FlagSection) BoolVar(i *BoolVar)
- func (f *FlagSection) DurationVar(i *DurationVar)
- func (f *FlagSection) Float64Var(i *Float64Var)
- func (f *FlagSection) Int64Var(i *Int64Var)
- func (f *FlagSection) IntVar(i *IntVar)
- func (f *FlagSection) StringMapVar(i *StringMapVar)
- func (f *FlagSection) StringSliceVar(i *StringSliceVar)
- func (f *FlagSection) StringVar(i *StringVar)
- func (f *FlagSection) TimeVar(layout string, i *TimeVar)
- func (f *FlagSection) Uint64Var(i *Uint64Var)
- func (f *FlagSection) UintVar(i *UintVar)
- type FlagSet
- type Float64Var
- type Int64Var
- type IntVar
- type LookupEnvFunc
- type Option
- type ParserFunc
- type PrinterFunc
- type RootCommand
- type SetterFunc
- type StringMapVar
- type StringSliceVar
- type StringVar
- type TimeVar
- type Uint64Var
- type UintVar
- type Value
- type Var
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Flag ¶
func Flag[T any](f *FlagSection, i *Var[T])
Flag is a lower-level API for creating a flag on a flag section. Callers should use this for defining new flags as it sets defaults and provides more granular usage details.
It panics if any of the target, parser, or printer are nil.
Types ¶
type ArgPredictor ¶ added in v0.4.0
ArgPredictor is an optional interface that Command can implement to declare predictions for their arguments. By default, commands predict nothing for arguments.
type BaseCommand ¶
type BaseCommand struct {
// contains filtered or unexported fields
}
BaseCommand is the default command structure. All commands should embed this structure.
func (*BaseCommand) Errf ¶ added in v0.4.0
func (c *BaseCommand) Errf(format string, a ...any)
Errf is a shortcut to write to BaseCommand.Stderr.
func (*BaseCommand) ExecutablePath ¶ added in v0.5.0
func (c *BaseCommand) ExecutablePath() (string, error)
ExecutablePath returns the executable's path. See Command for more information.
func (*BaseCommand) Flags ¶
func (c *BaseCommand) Flags() *FlagSet
Flags returns the base command flags, which is always nil.
func (*BaseCommand) Hidden ¶
func (c *BaseCommand) Hidden() bool
Hidden indicates whether the command is hidden. The default is unhidden.
func (*BaseCommand) Outf ¶ added in v0.4.0
func (c *BaseCommand) Outf(format string, a ...any)
Outf is a shortcut to write to BaseCommand.Stdout.
func (*BaseCommand) Pipe ¶
func (c *BaseCommand) Pipe() (stdin, stdout, stderr *bytes.Buffer)
Pipe creates new unqiue stdin, stdout, and stderr buffers, sets them on the command, and returns them. This is most useful for testing where callers want to simulate inputs or assert certain command outputs.
func (*BaseCommand) Prompt ¶
Prompt prompts the user for a value. It reads from [Stdin], up to 64k bytes. If there's an input stream (e.g. a pipe), it will read the pipe. If the terminal is a TTY, it will prompt. Otherwise it will fail if there's no pipe and the terminal is not a tty. If the context is canceled, this function leaves the c.Stdin in a bad state.
func (*BaseCommand) SetStderr ¶
func (c *BaseCommand) SetStderr(w io.Writer)
SetStdout sets the standard error.
func (*BaseCommand) SetStdin ¶
func (c *BaseCommand) SetStdin(r io.Reader)
SetStdout sets the standard input.
func (*BaseCommand) SetStdout ¶
func (c *BaseCommand) SetStdout(w io.Writer)
SetStdout sets the standard out.
func (*BaseCommand) Stderr ¶
func (c *BaseCommand) Stderr() io.Writer
Stderr returns the stderr stream.
func (*BaseCommand) Stdout ¶
func (c *BaseCommand) Stdout() io.Writer
Stdout returns the stdout stream.
func (*BaseCommand) WorkingDir ¶ added in v0.5.0
func (c *BaseCommand) WorkingDir() (string, error)
WorkingDir returns the working directory. See Command for more information.
type Command ¶
type Command interface {
// Desc provides a short, one-line description of the command. It must be
// shorter than 50 characters and should not end with a period or punctuation.
Desc() string
// Help is the long-form help output. It should include usage instructions and
// flag information.
//
// Callers can insert the literal string "{{ COMMAND }}" which will be
// replaced with the actual subcommand structure.
Help() string
// Flags returns the list of flags that are defined on the command.
Flags() *FlagSet
// Hidden indicates whether the command is hidden from help output.
Hidden() bool
// Run executes the command.
Run(ctx context.Context, args []string) error
// Prompt provides a mechanism for asking for user input.
Prompt(ctx context.Context, msg string, args ...any) (string, error)
// Stdout returns the stdout stream. SetStdout sets the stdout stream.
Stdout() io.Writer
SetStdout(w io.Writer)
// Outf is a shortcut to write to [Command.Stdout]. It automatically appends a
// trailing newline if one is not present.
Outf(format string, a ...any)
// Stderr returns the stderr stream. SetStderr sets the stderr stream.
Stderr() io.Writer
SetStderr(w io.Writer)
// Errf is a shortcut to write to [Command.Stderr]. It automatically appends a
// trailing newline if one is not present.
Errf(format string, a ...any)
// Stdin returns the stdin stream. SetStdin sets the stdin stream.
Stdin() io.Reader
SetStdin(r io.Reader)
// Pipe creates new unqiue stdin, stdout, and stderr buffers, sets them on the
// command, and returns them. This is most useful for testing where callers
// want to simulate inputs or assert certain command outputs.
Pipe() (stdin, stdout, stderr *bytes.Buffer)
// WorkingDir returns the absolute path of current working directory from
// where the command was started. All symlinks are resolved to their real
// paths.
WorkingDir() (string, error)
// ExecutablePath returns the absolute path of the CLI executable binary. All
// symlinks are resolved to their real values.
ExecutablePath() (string, error)
}
Command is the interface for a command or subcommand. Most of these functions have default implementations on BaseCommand.
type CommandFactory ¶
type CommandFactory func() Command
CommandFactory returns a new instance of a command. This returns a function instead of allocations because we want the CLI to load as fast as possible, so we lazy load as much as possible.
type DurationVar ¶
type FlagSection ¶
type FlagSection struct {
// contains filtered or unexported fields
}
FlagSection represents a group section of flags. The flags are actually "flat" in memory, but maintain a structure for better help output and alias matching.
func (*FlagSection) BoolVar ¶
func (f *FlagSection) BoolVar(i *BoolVar)
BoolVar creates a new boolean variable (true/false). By convention, the default value should always be false. For example:
Bad: -enable-cookies (default: true) Good: -disable-cookies (default: false)
Consider naming your flags to match this convention.
func (*FlagSection) DurationVar ¶
func (f *FlagSection) DurationVar(i *DurationVar)
func (*FlagSection) Float64Var ¶
func (f *FlagSection) Float64Var(i *Float64Var)
func (*FlagSection) Int64Var ¶
func (f *FlagSection) Int64Var(i *Int64Var)
func (*FlagSection) IntVar ¶
func (f *FlagSection) IntVar(i *IntVar)
func (*FlagSection) StringMapVar ¶
func (f *FlagSection) StringMapVar(i *StringMapVar)
func (*FlagSection) StringSliceVar ¶
func (f *FlagSection) StringSliceVar(i *StringSliceVar)
func (*FlagSection) StringVar ¶
func (f *FlagSection) StringVar(i *StringVar)
func (*FlagSection) TimeVar ¶ added in v0.4.0
func (f *FlagSection) TimeVar(layout string, i *TimeVar)
func (*FlagSection) Uint64Var ¶
func (f *FlagSection) Uint64Var(i *Uint64Var)
func (*FlagSection) UintVar ¶
func (f *FlagSection) UintVar(i *UintVar)
type FlagSet ¶
type FlagSet struct {
// contains filtered or unexported fields
}
FlagSet is the root flag set for creating and managing flag sections.
func (*FlagSet) NewSection ¶
func (f *FlagSet) NewSection(name string) *FlagSection
NewSection creates a new flag section. By convention, section names should be all capital letters (e.g. "MY SECTION"), but this is not strictly enforced.
type Float64Var ¶
type LookupEnvFunc ¶
LookupEnvFunc is the signature of a function for looking up environment variables. It makes that of os.LookupEnv.
func MapLookuper ¶
func MapLookuper(m map[string]string) LookupEnvFunc
MapLookuper returns a LookupEnvFunc that reads from a map instead of the environment. This is mostly used for testing.
type Option ¶
Option is an option to the flagset.
func WithLookupEnv ¶
func WithLookupEnv(fn LookupEnvFunc) Option
WithLookupEnv defines a custom function for looking up environment variables. This is mostly useful for testing.
type ParserFunc ¶
ParserFunc is a function that parses a value into T, or returns an error.
type PrinterFunc ¶
PrinterFunc is a function that pretty-prints T.
type RootCommand ¶
type RootCommand struct {
BaseCommand
// Name is the name of the command or subcommand. For top-level commands, this
// should be the binary name. For subcommands, this should be the name of the
// subcommand.
Name string
// Description is the human-friendly description of the command.
Description string
// Hide marks the entire subcommand as hidden. It will not be shown in help
// output.
Hide bool
// Version defines the version information for the command. This can be
// omitted for subcommands as it will be inherited from the parent.
Version string
// Commands is the list of sub commands.
Commands map[string]CommandFactory
}
RootCommand represents a command root for a parent or collection of subcommands.
func (*RootCommand) Desc ¶
func (r *RootCommand) Desc() string
Desc is the root command description. It is used to satisfy the Command interface.
func (*RootCommand) Help ¶
func (r *RootCommand) Help() string
Help compiles structured help information. It is used to satisfy the Command interface.
func (*RootCommand) Hidden ¶
func (r *RootCommand) Hidden() bool
Hidden determines whether the command group is hidden. It is used to satisfy the Command interface.
type SetterFunc ¶
type SetterFunc[T any] func(cur *T, val T)
SetterFunc is a function that sets *T to T.
type StringMapVar ¶
type StringSliceVar ¶
type Value ¶
type Value interface {
flag.Value
// Get returns the value. Even though we know the concrete type with generics,
// this returns [any] to match the standard library.
Get() any
// Aliases returns any defined aliases of the flag.
Aliases() []string
// Example returns an example input for the flag. For example, if the flag was
// accepting a URL, this could be "https://example.com". This is largely meant
// as a hint to the CLI user and only affects help output.
//
// If there is a default value, the example value should be different from the
// default value.
Example() string
// Hidden returns true if the flag is hidden, false otherwise.
Hidden() bool
// IsBoolFlag returns true if the flag accepts no arguments, false otherwise.
IsBoolFlag() bool
// Predictor returns a completion predictor. All flags have a default
// predictor, but they can be further customized by the developer when
// instantiating the flag.
Predictor() complete.Predictor
}
Value is an extension of flag.Value which adds additional fields for setting examples and defining aliases. All flags with this package must statisfy this interface.
type Var ¶
type Var[T any] struct { Name string Aliases []string Usage string Example string Default T Hidden bool IsBool bool EnvVar string Target *T // Parser and Printer are the generic functions for converting string values // to/from the target value. These are populated by the individual flag // helpers. Parser ParserFunc[T] Printer PrinterFunc[T] // Predict is the completion predictor. If no predictor is defined, it // defaults to predicting something (waiting for a value) for all flags except // boolean flags (which have no value). Callers are encouraged to customize // the predictions. Predict complete.Predictor // Setter defines the function that sets the variable into the target. If nil, // it uses a default setter which overwrites the entire value of the Target. // Implementations that do special processing (such as appending to a slice), // may override this to customize the behavior. Setter SetterFunc[T] }