To create nested and hierarchical flags for complex CLI structures in Go, you can utilize the flag
package from the standard library along with some custom code. Here's a step-by-step guide:
import (
"flag"
"fmt"
"os"
"strings"
)
FlagSet
struct that embeds the standard flag.FlagSet
struct:type FlagSet struct {
*flag.FlagSet
parent *FlagSet // reference to the parent FlagSet
}
FlagSet
:func NewFlagSet(name string, parent *FlagSet) *FlagSet {
fs := flag.NewFlagSet(name, flag.ExitOnError)
return &FlagSet{
FlagSet: fs,
parent: parent,
}
}
Var
method on FlagSet
to add nested flags:func (fs *FlagSet) Var(p flag.Value, name string, usage string) {
fs.FlagSet.Var(p, name, usage)
}
Lookup
method on FlagSet
to support nested flag lookup:func (fs *FlagSet) Lookup(name string) *flag.Flag {
f := fs.FlagSet.Lookup(name)
if f != nil {
return f
}
if fs.parent != nil {
return fs.parent.Lookup(name)
}
return nil
}
Parse
method on FlagSet
to parse the defined flags:func (fs *FlagSet) Parse(args []string) {
fs.FlagSet.Parse(args)
// Handle additional logic specific to the nested flag structure if needed
}
FlagSet
and set up nested flags:func main() {
root := NewFlagSet("cli", nil)
sub := NewFlagSet("sub", root)
// Add flags to each FlagSet
root.StringVar(&globalFlag, "global", "", "Global flag")
sub.StringVar(&subFlag, "subflag", "", "Sub command flag")
// Parse the command-line arguments
root.Parse(os.Args[1:])
// Access flags
fmt.Printf("Global flag: %s\n", globalFlag)
fmt.Printf("Sub command flag: %s\n", subFlag)
}
By following these steps, you can create a nested and hierarchical flag structure for your complex CLI application in Go. You can extend this approach further by adding more methods to the FlagSet
struct as per your requirements.