cli

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2026 License: MIT Imports: 8 Imported by: 25

README

cli - A minimal CLI command package using pflag

Go Reference

Package cli is a small, opinionated command and flag framework built on spf13/pflag. It provides command dispatch, command-scoped flags, environment-backed flag values, usage text, and a signal-aware context.Context without the larger API surface of Cobra.

Usage

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/titpetric/cli"
)

func main() {
	app := cli.NewApp("greet")
	app.DefaultCommand = "hello"

	app.AddCommand("hello", "Print a greeting", func() *cli.Command {
		var name string

		return &cli.Command{
			Default: true,
			Usage: func() string {
				return "Print a greeting for NAME."
			},
			Bind: func(fs *cli.FlagSet) {
				fs.StringVarP(&name, "name", "n", "world", "name to greet")
			},
			Run: func(ctx context.Context, args []string) error {
				fmt.Printf("Hello, %s!\n", name)
				return nil
			},
		}
	})

	if err := app.Run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

The command can then be invoked explicitly or as the default:

$ greet hello --name Ada
Hello, Ada!
$ greet -n Ada
Hello, Ada!

AddCommand supplies Command.Name and Command.Title when the constructor leaves them empty. Set Command.Default when its help usage should omit the command name.

Flags and environment variables

Bind receives a command-scoped *cli.FlagSet, which is an alias for *pflag.FlagSet. Flags may appear before or after positional arguments, and -- stops flag parsing. Run receives the remaining positional arguments with an explicitly selected command name removed.

Before parsing arguments, ParseWithFlagSet applies matching environment variables to flags that were not already changed. Environment names are lowercased and underscores become hyphens, so DB_DSN supplies the value for --db-dsn. Environment variables without an underscore are ignored. Invalid environment values are returned as errors.

Help and errors

  • -h and --help print application or command help and return nil.
  • An unknown or missing command prints application usage and returns an error.
  • Invalid flags print command usage and return the parsing error.
  • Errors returned by Command.Run, including cancellation, are returned without printing usage.

Run creates a context canceled by SIGINT or SIGTERM and passes it to the selected command. Applications remain responsible for printing returned errors and selecting an exit status.

Projects using this package

Documentation

Overview

Package cli implements a minimal, opinionated command and flag framework built on spf13/pflag.

An App registers command constructors with App.AddCommand. The selected constructor creates a Command, whose Bind callback defines scoped flags and whose Run callback executes with a signal-aware context.

A minimal application looks like this:

app := cli.NewApp("mig")
app.AddCommand("version", "Print version information", func() *cli.Command {
	return &cli.Command{
		Run: func(ctx context.Context, args []string) error {
			fmt.Println("mig version 1.2.3")
			return nil
		},
	}
})
if err := app.Run(); err != nil {
	return err
}

App.DefaultCommand selects a command when no explicit command is present. Flags are defined in Command.Bind. Before argument parsing, matching environment variables are applied to unchanged flags: names are lowercased and underscores become hyphens, so DB_DSN maps to --db-dsn.

The -h and --help flags print help and return nil. Command lookup and flag parsing errors print relevant usage before being returned. Errors produced by Command.Run are returned without printing usage.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseWithFlagSet

func ParseWithFlagSet(fs *FlagSet, args []string) error

ParseWithFlagSet applies environment variables and parses args for a scoped FlagSet. Environment names are lowercased and underscores become hyphens; variables without an underscore or a matching flag are ignored. Argument values take precedence over environment values.

Types

type App

type App struct {
	// Name is the executable name shown in usage output.
	Name string
	// DefaultCommand is selected when no explicit command is provided.
	DefaultCommand string
	// contains filtered or unexported fields
}

App is the cli entrypoint.

Example
package main

import (
	"context"
	"fmt"

	"github.com/titpetric/cli"
)

func main() {
	app := cli.NewApp("mig")

	app.AddCommand("version", "Print version information", func() *cli.Command {
		var verbose bool

		return &cli.Command{
			Name:  "version",
			Title: "Print version information",
			Bind: func(fs *cli.FlagSet) {
				fs.BoolVarP(&verbose, "verbose", "v", false, "enable verbose output")
			},
			Run: func(ctx context.Context, args []string) error {
				if verbose {
					fmt.Println("mig version 1.2.3 (commit abcdef)")
				} else {
					fmt.Println("mig version 1.2.3")
				}
				return nil
			},
		}
	})

	// In a real program you would call:
	//     _ = app.Run()
	//
	// For examples/tests, invoke RunWithArgs directly.
	_ = app.RunWithArgs([]string{"version"})

}
Output:
mig version 1.2.3

func NewApp

func NewApp(name string) *App

NewApp creates a new App instance.

func (*App) AddCommand

func (app *App) AddCommand(name, title string, constructor func() *Command)

AddCommand adds a command to the app.

func (*App) FindCommand

func (app *App) FindCommand(commands []string, fallback string) (*Command, error)

FindCommand finds a command for the app.

func (*App) HasCommand added in v0.2.1

func (app *App) HasCommand(name string) bool

HasCommand checks if a command exists in the app.

func (*App) Help

func (app *App) Help()

Help prints out registered commands for app.

func (*App) HelpCommand

func (app *App) HelpCommand(fs *FlagSet, command *Command)

HelpCommand prints out help for a specific command.

func (*App) ParseCommands added in v0.2.2

func (app *App) ParseCommands(args []string) []string

ParseCommands cleans up args[], returning only commands. If no commands are detected, DefaultCommand is returned.

func (*App) Run

func (app *App) Run() error

Run passes os.Args without the command name to RunWithArgs().

func (*App) RunWithArgs

func (app *App) RunWithArgs(args []string) error

RunWithArgs selects and executes a command with a context canceled by SIGINT or SIGTERM. Help requests return nil; lookup and flag parsing errors print usage, while errors returned by Command.Run do not.

type Command

type Command struct {
	// Name defaults to the name registered with App.AddCommand.
	Name string
	// Title defaults to the title registered with App.AddCommand.
	Title string
	// Default omits the command name from this command's usage line.
	Default bool
	// Usage returns optional descriptive text printed before flag defaults.
	Usage func() string
	// Bind defines this command's flags.
	Bind func(*FlagSet)
	// Run executes the command with its remaining positional arguments.
	Run func(context.Context, []string) error

	// Flags is populated by App.RunWithArgs with the flags defined by Bind.
	// HelpCommand uses it to print command flag defaults.
	Flags *FlagSet
}

Command is an individual command.

type CommandInfo

type CommandInfo struct {
	Name  string
	Title string
	New   func() *Command
}

CommandInfo is the constructor info for a command

type FlagSet added in v0.2.0

type FlagSet = pflag.FlagSet

FlagSet is here to prevent pflag leaking to imports.

Jump to

Keyboard shortcuts

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