cli

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2023 License: Apache-2.0 Imports: 19 Imported by: 54

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

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

type ArgPredictor interface {
	PredictArgs() complete.Predictor
}

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

func (c *BaseCommand) Prompt(ctx context.Context, msg string, args ...any) (string, error)

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) Stdin

func (c *BaseCommand) Stdin() io.Reader

Stdin returns the stdin 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 BoolVar

type BoolVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default bool
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *bool
}

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 DurationVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default time.Duration
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *time.Duration
}

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 NewFlagSet

func NewFlagSet(opts ...Option) *FlagSet

NewFlagSet creates a new root flag set.

func (*FlagSet) Args

func (f *FlagSet) Args() []string

Args implements flag.FlagSet#Args.

func (*FlagSet) Help

func (f *FlagSet) Help() string

Help returns formatted help output.

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.

func (*FlagSet) Parse

func (f *FlagSet) Parse(args []string) error

Args implements flag.FlagSet#Parse.

func (*FlagSet) Parsed

func (f *FlagSet) Parsed() bool

Args implements flag.FlagSet#Parsed.

func (*FlagSet) Visit

func (f *FlagSet) Visit(fn func(*flag.Flag))

Args implements flag.FlagSet#Visit.

func (*FlagSet) VisitAll

func (f *FlagSet) VisitAll(fn func(*flag.Flag))

Args implements flag.FlagSet#VisitAll.

type Float64Var

type Float64Var struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default float64
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *float64
}

type Int64Var

type Int64Var struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default int64
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *int64
}

type IntVar

type IntVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default int
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *int
}

type LookupEnvFunc

type LookupEnvFunc = func(string) (string, bool)

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

type Option func(fs *FlagSet) *FlagSet

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

type ParserFunc[T any] func(val string) (T, error)

ParserFunc is a function that parses a value into T, or returns an error.

type PrinterFunc

type PrinterFunc[T any] func(cur T) string

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.

func (*RootCommand) Run

func (r *RootCommand) Run(ctx context.Context, args []string) error

Run executes the command and prints help output or delegates to a subcommand.

type SetterFunc

type SetterFunc[T any] func(cur *T, val T)

SetterFunc is a function that sets *T to T.

type StringMapVar

type StringMapVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default map[string]string
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *map[string]string
}

type StringSliceVar

type StringSliceVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default []string
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *[]string
}

type StringVar

type StringVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default string
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *string
}

type TimeVar added in v0.4.0

type TimeVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default time.Time
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *time.Time
}

type Uint64Var

type Uint64Var struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default uint64
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *uint64
}

type UintVar

type UintVar struct {
	Name    string
	Aliases []string
	Usage   string
	Example string
	Default uint
	Hidden  bool
	EnvVar  string
	Predict complete.Predictor
	Target  *uint
}

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]
}

Jump to

Keyboard shortcuts

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