or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-features.mdflag-access.mdflag-definition.mdflag-types.mdflagset-methods.mdgo-integration.mdindex.mdusage-help.md
tile.json

flagset-methods.mddocs/

FlagSet Methods

This document covers FlagSet operations for creating and managing independent sets of flags, useful for implementing subcommands in CLI applications.

Import

import "github.com/spf13/pflag"

Creating a FlagSet

func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet

Create a new FlagSet with specified name and error handling behavior.

Error Handling Options:

type ErrorHandling int

const (
	ContinueOnError ErrorHandling = iota  // Return error from Parse()
	ExitOnError                            // Call os.Exit(2) on error
	PanicOnError                           // panic() on error
)

Usage:

// FlagSet that returns errors for manual handling
configFlags := pflag.NewFlagSet("config", pflag.ContinueOnError)

// FlagSet that exits on error (like CommandLine)
serverFlags := pflag.NewFlagSet("server", pflag.ExitOnError)

// FlagSet that panics on error
debugFlags := pflag.NewFlagSet("debug", pflag.PanicOnError)

FlagSet Configuration

Name

func (f *FlagSet) Name() string

Return the name of the flag set.

Init

func (f *FlagSet) Init(name string, errorHandling ErrorHandling)

Initialize or re-initialize a FlagSet with new name and error handling.

Usage:

fs := &pflag.FlagSet{}
fs.Init("myapp", pflag.ExitOnError)

SetOutput

func (f *FlagSet) SetOutput(output io.Writer)

Set the destination for usage and error messages. If nil, os.Stderr is used.

Usage:

import "bytes"

var buf bytes.Buffer
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
fs.SetOutput(&buf)  // Capture output for testing

Output

func (f *FlagSet) Output() io.Writer

Return the destination for usage and error messages. Returns os.Stderr if output was not set or set to nil.

Defining Flags on FlagSet

All type-specific flag definers have FlagSet method equivalents. The pattern is identical to package-level functions but called on the FlagSet instance.

Usage:

fs := pflag.NewFlagSet("mycommand", pflag.ExitOnError)

// Define flags on the FlagSet
port := fs.IntP("port", "p", 8080, "server port")
verbose := fs.BoolP("verbose", "v", false, "verbose output")
config := fs.String("config", "default.conf", "config file")

fs.Parse(os.Args[1:])

Adding Pre-Made Flags

AddFlag

func (f *FlagSet) AddFlag(flag *Flag)

Add a Flag struct directly to the FlagSet.

Usage:

flag := &pflag.Flag{
	Name:      "custom",
	Shorthand: "c",
	Usage:     "custom flag",
	Value:     myCustomValue,
	DefValue:  "default",
}

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.AddFlag(flag)

AddFlagSet

func (f *FlagSet) AddFlagSet(newSet *FlagSet)

Add all flags from another FlagSet.

Usage:

// Common flags shared across subcommands
commonFlags := pflag.NewFlagSet("common", pflag.ContinueOnError)
commonFlags.Bool("verbose", false, "verbose output")
commonFlags.String("config", "default.conf", "config file")

// Subcommand-specific flags
serverFlags := pflag.NewFlagSet("server", pflag.ExitOnError)
serverFlags.Int("port", 8080, "server port")
serverFlags.AddFlagSet(commonFlags)  // Include common flags

clientFlags := pflag.NewFlagSet("client", pflag.ExitOnError)
clientFlags.String("server", "localhost", "server address")
clientFlags.AddFlagSet(commonFlags)  // Include common flags

Parsing

Parse

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

Parse flag definitions from the argument list. Flags can be interspersed with arguments before the "--" terminator.

Usage:

fs := pflag.NewFlagSet("myapp", pflag.ContinueOnError)
fs.String("config", "default.conf", "config file")
fs.Bool("verbose", false, "verbose output")

if err := fs.Parse(os.Args[1:]); err != nil {
	fmt.Fprintf(os.Stderr, "Error: %v\n", err)
	os.Exit(1)
}

ParseAll

func (f *FlagSet) ParseAll(arguments []string, fn func(*Flag, string) error) error

Parse flags from arguments and call fn for each flag with the flag and its value.

Usage:

fs := pflag.NewFlagSet("myapp", pflag.ContinueOnError)
fs.String("config", "default.conf", "config file")

err := fs.ParseAll(os.Args[1:], func(flag *pflag.Flag, value string) error {
	fmt.Printf("Flag %s set to: %s\n", flag.Name, value)
	// Can perform validation here
	if flag.Name == "config" && value == "" {
		return fmt.Errorf("config cannot be empty")
	}
	return nil
})

Parsed

func (f *FlagSet) Parsed() bool

Return true if the command-line flags have been parsed.

Usage:

if !fs.Parsed() {
	fs.Parse(os.Args[1:])
}

Flag Lookup

Lookup

func (f *FlagSet) Lookup(name string) *Flag

Return the Flag structure of the named flag, or nil if none exists.

Usage:

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.Int("port", 8080, "server port")
fs.Parse(os.Args[1:])

flag := fs.Lookup("port")
if flag != nil {
	fmt.Printf("Port flag value: %s\n", flag.Value.String())
	fmt.Printf("Port was changed: %v\n", flag.Changed)
}

ShorthandLookup

func (f *FlagSet) ShorthandLookup(name string) *Flag

Return the Flag structure of the short-handed flag, or nil if none exists. Panics if len(name) > 1.

Usage:

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.IntP("port", "p", 8080, "server port")

flag := fs.ShorthandLookup("p")
if flag != nil {
	fmt.Printf("Found flag: %s\n", flag.Name)  // Prints: Found flag: port
}

Changed

func (f *FlagSet) Changed(name string) bool

Return true if the flag was set on the command line (vs using default value).

Usage:

fs.String("config", "default.conf", "config file")
fs.Parse(os.Args[1:])

if fs.Changed("config") {
	fmt.Println("Config explicitly set")
} else {
	fmt.Println("Using default config")
}

Setting Flag Values

Set

func (f *FlagSet) Set(name, value string) error

Set the value of the named flag programmatically.

Usage:

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.Int("port", 8080, "server port")

// Set flag before parsing
fs.Set("port", "9090")

fs.Parse(os.Args[1:])

Retrieving Flag Values

FlagSet provides type-safe getter methods for retrieving flag values. These methods return an error if the flag doesn't exist or has the wrong type.

Type-Safe Getters

func (f *FlagSet) GetBool(name string) (bool, error)
func (f *FlagSet) GetInt(name string) (int, error)
func (f *FlagSet) GetInt8(name string) (int8, error)
func (f *FlagSet) GetInt16(name string) (int16, error)
func (f *FlagSet) GetInt32(name string) (int32, error)
func (f *FlagSet) GetInt64(name string) (int64, error)
func (f *FlagSet) GetUint(name string) (uint, error)
func (f *FlagSet) GetUint8(name string) (uint8, error)
func (f *FlagSet) GetUint16(name string) (uint16, error)
func (f *FlagSet) GetUint32(name string) (uint32, error)
func (f *FlagSet) GetUint64(name string) (uint64, error)
func (f *FlagSet) GetFloat32(name string) (float32, error)
func (f *FlagSet) GetFloat64(name string) (float64, error)
func (f *FlagSet) GetString(name string) (string, error)
func (f *FlagSet) GetDuration(name string) (time.Duration, error)
func (f *FlagSet) GetTime(name string) (time.Time, error)
func (f *FlagSet) GetIP(name string) (net.IP, error)
func (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error)
func (f *FlagSet) GetIPNet(name string) (net.IPNet, error)
func (f *FlagSet) GetBytesHex(name string) ([]byte, error)
func (f *FlagSet) GetBytesBase64(name string) ([]byte, error)
func (f *FlagSet) GetCount(name string) (int, error)
func (f *FlagSet) GetStringSlice(name string) ([]string, error)
func (f *FlagSet) GetStringArray(name string) ([]string, error)
func (f *FlagSet) GetBoolSlice(name string) ([]bool, error)
func (f *FlagSet) GetIntSlice(name string) ([]int, error)
func (f *FlagSet) GetInt32Slice(name string) ([]int32, error)
func (f *FlagSet) GetInt64Slice(name string) ([]int64, error)
func (f *FlagSet) GetUintSlice(name string) ([]uint, error)
func (f *FlagSet) GetFloat32Slice(name string) ([]float32, error)
func (f *FlagSet) GetFloat64Slice(name string) ([]float64, error)
func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error)
func (f *FlagSet) GetIPSlice(name string) ([]net.IP, error)
func (f *FlagSet) GetIPNetSlice(name string) ([]net.IPNet, error)
func (f *FlagSet) GetStringToString(name string) (map[string]string, error)
func (f *FlagSet) GetStringToInt(name string) (map[string]int, error)
func (f *FlagSet) GetStringToInt64(name string) (map[string]int64, error)
func (f *FlagSet) GetText(name string, out encoding.TextUnmarshaler) error

Usage:

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.Int("port", 8080, "server port")
fs.StringSlice("tags", []string{}, "tags")
fs.Parse(os.Args[1:])

// Get values with type checking
port, err := fs.GetInt("port")
if err != nil {
	log.Fatal(err)
}

tags, err := fs.GetStringSlice("tags")
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Port: %d, Tags: %v\n", port, tags)

Arguments (Non-Flag Arguments)

Args

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

Return the non-flag arguments remaining after parsing.

Usage:

fs.Parse([]string{"--verbose", "file1.txt", "file2.txt"})
files := fs.Args()  // []string{"file1.txt", "file2.txt"}

Arg

func (f *FlagSet) Arg(i int) string

Return the i'th argument. Arg(0) is the first remaining argument after flags have been processed.

Usage:

fs.Parse([]string{"--verbose", "input.txt", "output.txt"})
input := fs.Arg(0)   // "input.txt"
output := fs.Arg(1)  // "output.txt"

NArg

func (f *FlagSet) NArg() int

Return the number of arguments remaining after flags have been processed.

Usage:

fs.Parse(os.Args[1:])
if fs.NArg() < 2 {
	fmt.Fprintln(os.Stderr, "Error: expected at least 2 arguments")
	os.Exit(1)
}

NFlag

func (f *FlagSet) NFlag() int

Return the number of command-line flags that have been set.

Usage:

fs.Parse(os.Args[1:])
fmt.Printf("Number of flags set: %d\n", fs.NFlag())

ArgsLenAtDash

func (f *FlagSet) ArgsLenAtDash() int

Return the length of Args at the moment when a "--" was found during parsing, or -1 if no "--" was encountered. This allows distinguishing between arguments before and after the terminator.

Usage:

fs.Parse([]string{"file1.txt", "--verbose", "--", "--not-a-flag", "file2.txt"})

dashIndex := fs.ArgsLenAtDash()
allArgs := fs.Args()

if dashIndex >= 0 {
	beforeDash := allArgs[:dashIndex]  // []string{"file1.txt"}
	afterDash := allArgs[dashIndex:]    // []string{"--not-a-flag", "file2.txt"}
}

Iteration

Visit

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

Visit flags in lexicographical order (or primordial order if SortFlags is false), calling fn for each. Visits only flags that have been set.

Usage:

fs.Parse(os.Args[1:])

fmt.Println("Flags that were set:")
fs.Visit(func(flag *pflag.Flag) {
	fmt.Printf("  %s = %s\n", flag.Name, flag.Value.String())
})

VisitAll

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

Visit flags in lexicographical order (or primordial order if SortFlags is false), calling fn for each. Visits all flags, even those not set.

Usage:

fmt.Println("All defined flags:")
fs.VisitAll(func(flag *pflag.Flag) {
	fmt.Printf("  %s = %s (default: %s)\n",
		flag.Name, flag.Value.String(), flag.DefValue)
})

HasFlags

func (f *FlagSet) HasFlags() bool

Return true if the FlagSet has any flags defined.

Usage:

if fs.HasFlags() {
	fmt.Println("FlagSet has flags defined")
}

HasAvailableFlags

func (f *FlagSet) HasAvailableFlags() bool

Return true if the FlagSet has any flags that are not hidden.

Usage:

if fs.HasAvailableFlags() {
	fs.PrintDefaults()
}

Configuration

SetInterspersed

func (f *FlagSet) SetInterspersed(interspersed bool)

Set whether to support interspersed option/non-option arguments. When true (default), flags can appear anywhere in the arguments. When false, flag parsing stops at the first non-flag argument.

Usage:

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.Bool("verbose", false, "verbose output")

// Allow: myapp file1.txt --verbose file2.txt
fs.SetInterspersed(true)

// Require: myapp --verbose file1.txt file2.txt
fs.SetInterspersed(false)

SortFlags Field

type FlagSet struct {
	SortFlags bool  // Sort flags in help/usage messages
	// ...
}

Control whether flags are sorted lexicographically in help output. Default is true.

Usage:

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.SortFlags = false  // Maintain definition order in help

Usage Field

type FlagSet struct {
	Usage func()  // Function called when error occurs
	// ...
}

The Usage function is called when a parsing error occurs. You can set a custom function to print custom usage messages.

Usage:

fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.Usage = func() {
	fmt.Fprintf(os.Stderr, "Custom usage message for %s\n", fs.Name())
	fs.PrintDefaults()
}

ParseErrorsAllowlist Field

type FlagSet struct {
	ParseErrorsAllowlist ParseErrorsAllowlist
	// ...
}

type ParseErrorsAllowlist struct {
	UnknownFlags bool  // Ignore unknown flags errors
}

Configure an allowlist of parsing errors to ignore.

Usage:

fs := pflag.NewFlagSet("app", pflag.ContinueOnError)
fs.ParseErrorsAllowlist.UnknownFlags = true  // Ignore unknown flags

// Now parsing won't fail on unknown flags
fs.Parse([]string{"--known-flag", "--unknown-flag"})

Subcommand Example

Here's a complete example of using FlagSets for subcommands:

package main

import (
	"fmt"
	"os"
	"github.com/spf13/pflag"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, "Expected 'server' or 'client' subcommand")
		os.Exit(1)
	}

	// Common flags
	commonFlags := pflag.NewFlagSet("common", pflag.ContinueOnError)
	verbose := commonFlags.BoolP("verbose", "v", false, "verbose output")
	config := commonFlags.String("config", "default.conf", "config file")

	switch os.Args[1] {
	case "server":
		serverFlags := pflag.NewFlagSet("server", pflag.ExitOnError)
		serverFlags.AddFlagSet(commonFlags)
		port := serverFlags.IntP("port", "p", 8080, "server port")

		serverFlags.Parse(os.Args[2:])
		fmt.Printf("Starting server on port %d (verbose=%v, config=%s)\n",
			*port, *verbose, *config)

	case "client":
		clientFlags := pflag.NewFlagSet("client", pflag.ExitOnError)
		clientFlags.AddFlagSet(commonFlags)
		server := clientFlags.StringP("server", "s", "localhost", "server address")

		clientFlags.Parse(os.Args[2:])
		fmt.Printf("Connecting to %s (verbose=%v, config=%s)\n",
			*server, *verbose, *config)

	default:
		fmt.Fprintf(os.Stderr, "Unknown subcommand: %s\n", os.Args[1])
		os.Exit(1)
	}
}