Getting Started with goopt
Quick Start
1. Installation
go get github.com/napalu/goopt
2. Choose Your Style
Struct-First Approach
Names are optional, but if you want to use them, you can use the name
tag to override the default name. If the name is not provided, goopt will use the default FlagNameConverter
to convert the field name to a valid flag name in lowerCamelCase.
// Define your CLI structure using struct tags
type Options struct {
// Global flags
Verbose bool `goopt:"short:v;desc:Enable verbose output"`
Output string `goopt:"short:o;desc:Output file;required:true"`
// Commands and their flags
Create struct {
User struct {
Name string `goopt:"short:n;desc:Username to create;required:true"`
Password string `goopt:"short:p;desc:User password;secure:true"`
} `goopt:"kind:command;desc:Create a new user"`
} `goopt:"kind:command;desc:Create resources"`
}
func main() {
opts := &Options{}
parser, _ := goopt.NewParserFromStruct(opts)
if ok := parser.Parse(os.Args); !ok {
fmt.Fprintln(os.Stderr, "Invalid command-line arguments:")
for _, err := range parser.Errors() {
fmt.Fprintf(os.Stderr, " - %s\n", err)
}
parser.PrintUsageWithGroups(os.Stdout)
os.Exit(1)
}
// Access values directly through the struct
if opts.Verbose {
fmt.Println("Verbose mode enabled")
}
}
Builder Approach
func main() {
parser := goopt.NewParser()
// Add global flags
parser.AddFlag("verbose", goopt.NewArg(
goopt.WithDescription("Enable verbose output"),
goopt.WithShort("v"),
))
// Add commands and their flags
create := parser.AddCommand(goopt.NewCommand(
goopt.WithName("create"),
goopt.WithDescription("Create resources"),
))
user := create.AddCommand(goopt.NewCommand(
goopt.WithName("user"),
goopt.WithDescription("Create a new user"),
))
user.AddFlag(goopt.NewArg(
goopt.WithShortFlag("n"),
goopt.WithDescription("Username to create"),
goopt.WithRequired(true),
))
if !parser.Parse(os.Args) {
parser.PrintUsageWithGroups(os.Stdout)
return
}
// Access values through the parser
if verbose, _ := parser.Get("verbose"); verbose == "true" {
fmt.Println("Verbose mode enabled")
}
// Or access it as a boolean
if v, _ := parser.GetBool("verbose"); v {
fmt.Println("Verbose mode enabled")
}
// Or check if the flag is present and provide a default value
if vd := parser.GetOrDefault("verbose", "false"); vd == "false" {
fmt.Println("Verbose mode is disabled")
}
}
Programmatic Definition with Commands
package main
import (
"os"
"fmt"
"github.com/napalu/goopt"
"github.com/napalu/goopt/types"
)
func main() {
parser := goopt.NewParser()
// Define flags
parser.AddFlag("output", goopt.NewArg(
goopt.WithDescription("Output file"),
goopt.WithType(types.Single),
goopt.WithRequired(true),
))
// Define commands and subcommands
createCmd := &goopt.Command{
Name: "create",
Subcommands: []goopt.Command{
{Name: "user"},
{Name: "group"},
},
}
parser.AddCommand(createCmd)
// Parse the command-line arguments
if !parser.Parse(os.Args) {
parser.PrintUsage(os.Stdout)
return
}
// Access parsed flags
output, _ := parser.Get("output")
fmt.Println("Output:", output)
// Access parsed commands
cmdValue, _ := parser.GetCommandValue("create user")
fmt.Println("Command value:", cmdValue)
}
Initialization using option functions
The library provides an interface for defining flags and commands.
package main
import (
"os"
"github.com/napalu/goopt"
"github.com/napalu/goopt/types"
)
func main() {
parser, _ := goopt.NewParser(
goopt.WithFlag("testFlag", goopt.NewArg(goopt.WithType(types.Single))),
goopt.WithCommand(
goopt.NewCommand(goopt.WithName("testCommand")),
),
)
parser.Parse(os.Args)
}
This interface allows for dynamic and flexible construction of command-line parsers.
3. Add Shell Completion (Optional)
import (
"os"
"log"
"github.com/napalu/goopt"
c "github.com/napalu/goopt/completion"
)
func main() {
// ... parser setup as above ...
// Add completion support
exec, err := os.Executable()
if err != nil {
log.Fatal(err)
}
manager, err := c.NewManager("fish", exec)
if err != nil {
log.Fatal(err)
}
manager.Accept(parser.GetCompletionData())
err = manager.Save()
if err != nil {
log.Fatal(err)
}
// depending on the shell, you may need to source the completion file
// ... rest of your code ...
}
4. Environment Variables (Optional)
func main() {
// ... parser setup as above ...
// Enable environment variable support
parser.SetEnvNameConverter(func(s string) string {
// default flag name converter is lowerCamelCase
return parser.DefaultFlagNameConverter(s)
})
// ... rest of your code ...
}
Version Compatibility
goopt supports all Go versions from 1.18 onward. See our compatibility policy for details.
Next Steps
- Command structure patterns - Have a look at different ways to structure your CLI
- Flag structure patterns - Have a look at different ways to structure your flags
- Positional Arguments - Explore positional arguments
- Struct Tags - Explore struct tags
- Configuration Guide - Environment variables and external config
- Shell Completion - Set up shell completions
- Advanced Features - Explore dependencies, validation, and more