cli

package module
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 17 Imported by: 2

README

cli

GoDoc CI Docs

An intentionally minimal Go package for building CLI applications. It extends the standard library's flag package with nested subcommands and flags anywhere, then gets out of the way.

Docs: https://pressly.github.io/cli

Packages

  • flagtype adds common flag.Value types for slices, enums, maps, URLs, and regular expressions. Useful when the standard library's built-in flag types are not enough.
  • graceful runs servers, workers, and batch jobs with signal-aware cancellation and bounded shutdown.
  • xflag parses flags anywhere in the argument list. It is useful with the standard library's flag package when cmd arg --flag should work like cmd --flag arg.

Installation

go get github.com/pressly/cli@latest

Requires Go 1.27 or higher.

Quick Start

root := &cli.Command{
	Name:  "echo",
	Usage: "echo [flags] <text>...",
	Flags: cli.FlagsFunc(func(f *flag.FlagSet) {
		f.Bool("capitalize", false, "capitalize the input")
	}),
	Exec: func(ctx context.Context, s *cli.State) error {
		text := strings.Join(s.Args, " ")
		// GetFlag uses generic methods, available in Go 1.27.
		if s.GetFlag[bool]("capitalize") {
			text = strings.ToUpper(text)
		}
		fmt.Fprintln(s.Stdout, text)
		return nil
	},
}
if err := cli.ParseAndRun(ctx, root, os.Args[1:], nil); err != nil {
	fmt.Fprintf(os.Stderr, "error: %v\n", err)
	os.Exit(1)
}

ParseAndRun parses the command hierarchy, handles --help, and runs the selected command.

The command above gets usable help without extra setup:

Usage:
  echo [flags] <text>...

Flags:
  --capitalize    capitalize the input

For subcommands, inherited, local, and required flags, custom help, usage errors, and subpackages, see the documentation. More complete programs live in examples.

Acknowledgements

There are many great CLI libraries out there, but I always felt they were too heavy for my needs.

Inspired by Peter Bourgon's ff library, especially its v3 branch, which was close to what I wanted. v4 took a different direction, but I wanted to keep the simplicity of v3. This library carries that idea forward.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package cli builds command-line programs on top of the standard library flag package. It adds nested subcommands, flags anywhere, inherited flags, generated help, and type-safe flag access.

root := &cli.Command{
    Name: "echo",
    Flags: cli.FlagsFunc(func(f *flag.FlagSet) {
        f.Bool("capitalize", false, "capitalize the input")
    }),
    Exec: func(ctx context.Context, s *cli.State) error {
        text := strings.Join(s.Args, " ")
        if s.GetFlag[bool]("capitalize") {
            text = strings.ToUpper(text)
        }
        fmt.Fprintln(s.Stdout, text)
        return nil
    },
}
if err := cli.ParseAndRun(ctx, root, os.Args[1:], nil); err != nil {
    fmt.Fprintln(os.Stderr, err)
    os.Exit(1)
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FlagsFunc

func FlagsFunc(fn func(f *flag.FlagSet)) (fset *flag.FlagSet)

FlagsFunc builds a flag.FlagSet inline using flag.ContinueOnError.

Flags: cli.FlagsFunc(func(f *flag.FlagSet) {
    f.Bool("verbose", false, "enable verbose output")
}),

func Parse

func Parse(root *Command, args []string) error

Parse selects a command and parses its flags without running it. It returns flag.ErrHelp for -h or --help; ParseAndRun handles that case automatically.

func ParseAndRun

func ParseAndRun(ctx context.Context, root *Command, args []string, options *RunOptions) error

ParseAndRun parses args and runs the selected command. It prints help and returns nil for -h or --help.

if err := cli.ParseAndRun(ctx, root, os.Args[1:], nil); err != nil {
    fmt.Fprintf(os.Stderr, "error: %v\n", err)
    os.Exit(1)
}

func Run

func Run(ctx context.Context, root *Command, options *RunOptions) error

Run executes the command selected by Parse. Usage errors print help to stderr; other errors are returned as-is. A nil ctx uses context.Background.

func UsageErrorf added in v0.7.0

func UsageErrorf(format string, args ...any) error

UsageErrorf returns an error for invalid command arguments or flag combinations. Run prints the command's help before returning the underlying error.

if len(s.Args) == 0 {
    return cli.UsageErrorf("must supply a name")
}

Types

type Command

type Command struct {
	// Name identifies the command. It must start with a letter and contain only letters, digits,
	// dashes, or underscores.
	Name string

	// Usage overrides the generated usage line. Angle brackets usually mark required arguments,
	// square brackets optional arguments, and an ellipsis repeated arguments.
	//
	//	Usage: "echo [flags] <text>..."
	Usage string

	// Summary is the one-line description used in command lists and, when Description is empty, in
	// the command's help.
	Summary string

	// Description is the command's longer help text. Its first line is used in command lists when
	// Summary is empty.
	Description string

	// Help overrides the generated help for --help and [UsageErrorf] errors on this command.
	Help func(*Command) string

	// Flags holds this command's [flag.FlagSet]. Subcommands inherit these flags unless they are
	// marked [FlagConfig.Local].
	Flags *flag.FlagSet

	// FlagConfigs adds behavior to flags already defined in Flags. Each config must name a flag in
	// Flags.
	FlagConfigs []FlagConfig

	// SubCommands are the commands available below this command. A command that only groups
	// subcommands may leave Exec nil.
	SubCommands []*Command

	// Exec runs the selected command. Return [UsageErrorf] for invalid arguments or flag
	// combinations so [Run] prints the command's help.
	Exec func(ctx context.Context, s *State) error
	// contains filtered or unexported fields
}

Command describes a command in a CLI.

func (*Command) Path

func (c *Command) Path() []*Command

Path returns the parsed command path from root to this command, or nil before Parse.

type FlagConfig added in v0.7.0

type FlagConfig struct {
	// Name is the flag's registered name.
	Name string

	// Short is a one-letter alias, such as "v" for --verbose.
	Short string

	// Required makes [Parse] fail unless the user explicitly sets the flag.
	Required bool

	// Local prevents subcommands from inheriting the flag.
	Local bool
}

FlagConfig adds behavior to a flag already defined in Command.Flags.

type FlagName added in v0.8.0

type FlagName[T any] string

FlagName ties a flag name to the type returned by State.GetFlag.

type RunOptions

type RunOptions struct {
	// Nil fields default to the corresponding os stream.
	Stdin          io.Reader
	Stdout, Stderr io.Writer
}

RunOptions replaces the standard streams used by Run and ParseAndRun.

type State

type State struct {
	// Args holds positional arguments. Anything after "--" is included as-is.
	Args []string

	// Stdin, Stdout, and Stderr are the command's streams.
	Stdin          io.Reader
	Stdout, Stderr io.Writer

	// Cmd is the selected command.
	Cmd *Command
	// contains filtered or unexported fields
}

State contains the parsed inputs passed to Command.Exec.

func (*State) GetFlag added in v0.8.0

func (s *State) GetFlag[T any](name FlagName[T]) T

GetFlag returns a flag value as T, searching the selected command before its parents. Unknown names and type mismatches are programming errors: GetFlag panics, and Run returns the error.

verbose := s.GetFlag[bool]("verbose")
const count FlagName[int] = "count"
n := s.GetFlag(count)

Directories

Path Synopsis
examples
cmd/echo command
cmd/task command
Package flagtype provides common flag.Value implementations.
Package flagtype provides common flag.Value implementations.
Package graceful runs long-lived processes with signal handling and timeouts.
Package graceful runs long-lived processes with signal handling and timeouts.
internal
helpdoc
Package helpdoc builds the default command help document.
Package helpdoc builds the default command help document.
usage
Package usage builds and renders command help.
Package usage builds and renders command help.
pkg
Package xflag parses flags interspersed with positional arguments.
Package xflag parses flags interspersed with positional arguments.

Jump to

Keyboard shortcuts

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