Skip to content

FlagSet for subcommand isolation

In Go's flag package, a FlagSet represents a distinct set of command-line flags. Using flag.NewFlagSet allows developers to define separate, isolated sets of flags and subcommands within a single command-line application^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md]. This is essential for building CLIs that support distinct operations (e.g., get vs add) which may require different parameters or share parameter names without conflict^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

Isolation Mechanism

When a standard flag package is used without a FlagSet, flags are defined in the global command-line namespace. By using flag.NewFlagSet, developers create a dedicated scope for a specific subcommand^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

For example, an application might define a "get" subcommand:

getCmd := flag.NewFlagSet("get", flag.ExitOnError)

This creates a new flag set named "get". Subsequent flags defined on getCmd are distinct from those defined on other FlagSet instances or the global namespace^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

Defining Subcommand Flags

Once a FlagSet is created, it possesses the same methods as the top-level flag package to define arguments, such as String, Bool, or Int. These methods bind the input to the specific FlagSet^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

For the "get" command, one might define:

getAll := getCmd.Bool("all", false, "Get all videos")
getID := getCmd.String("id", "", "YouTube video ID")

Similarly, a separate "add" command would use its own FlagSet instance to define its specific required fields (e.g., title, URL)^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

Parsing Arguments

To process the arguments, the application must inspect the raw arguments provided by the user (available in os.Args) and direct them to the correct FlagSet^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

Typically, a switch statement handles the routing based on the subcommand argument (e.g., os.Args[1])[^400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md]. Inside the specific case handler, the FlagSet.Parse method is called, passing the slice of arguments specific to that subcommand^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

For example, to parse arguments for the "get" subcommand:

// Parse everything after the subcommand name
getCmd.Parse(os.Args[2:])

This ensures that the "get" logic only attempts to parse flags relevant to it, preventing errors from flags intended for other commands^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

Usage and Help

Each FlagSet maintains its own usage and help messages. Calling the PrintDefaults() method on a FlagSet instance (e.g., getCmd.PrintDefaults()) will print the usage information for only that specific subcommand's flags^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md].

Sources

^[400-devops__09-Scripting-Language__golang__introduction__part-4.commandline__readme.md]