BOA¶
Declarative Go CLI Framework built on Cobra
BOA adds a declarative layer on top of cobra, making CLI creation as simple as defining a struct.
Quick Example¶
package main
import (
"fmt"
"github.com/GiGurra/boa/pkg/boa"
"github.com/spf13/cobra"
)
type Params struct {
Name string `descr:"User name"`
Port int `descr:"Port number" default:"8080" optional:"true"`
Verbose bool `short:"v" optional:"true"`
}
func main() {
boa.CmdT[Params]{
Use: "myapp",
Short: "A simple CLI application",
RunFunc: func(params *Params, cmd *cobra.Command, args []string) {
fmt.Printf("Hello %s on port %d\n", params.Name, params.Port)
},
}.Run()
}
This generates:
A simple CLI application
Usage:
myapp [flags]
Flags:
-n, --name string User name (required)
-p, --port int Port number (default 8080)
-v, --verbose
-h, --help help for myapp
With Config File¶
Add a configfile tag and boa loads it automatically — CLI flags and env vars still take priority:
type Params struct {
ConfigFile string `configfile:"true" optional:"true" default:"config.json"`
Host string `descr:"Server host" default:"localhost"`
Port int `descr:"Port number" default:"8080"`
Labels map[string]string `descr:"Key-value labels" optional:"true"`
Matrix [][]int `boa:"configonly"` // config-file only, no CLI flag
}
myapp # uses config.json values
myapp --host override.local # CLI wins over config file
myapp --config-file staging.json # different config file
HOST=ci.local myapp # env var wins over config file
Installation¶
Features¶
- Declarative parameters - Define CLI flags as struct fields with tags
- Plain Go types - No wrapper types; use
string,int,*string,map[string]string, etc. - Automatic flag generation - Field names become kebab-case flags (acronym-aware:
DBHost→--db-host) - Struct composition - Named struct fields auto-prefix children (
DB.Host→--db-host), embedded fields stay flat - Environment variable binding - Via struct tags or auto-generated with enrichers
- Built-in validation - Required fields, alternatives, custom validators
- Config file support - Automatic loading via
configfiletag with value priority, substruct config files, and pluggable format registry - JSON fallback - Complex types (nested slices, maps) parsed as JSON on CLI
- Pointer fields -
*string,*intetc. for truly optional params (nil = not set) - Validation tags -
min/maxfor range checks,patternfor regex matching - Custom types -
RegisterType[T]for user-defined CLI parameter types - Viper-like config discovery - Optional
boavipersubpackage for auto-locating config files - Cobra compatible - Access underlying Cobra commands when needed
Next Steps¶
- Getting Started - Installation, basic usage, and all parameter types
- Struct Tags - Complete reference for all struct tags
- Validation - Required/optional, alternatives, conditional requirements
- Lifecycle Hooks - Customize behavior at different stages
- Enrichers - Auto-derivation of flag names, env vars, and short flags
- Error Handling - Run() vs RunE() and error propagation
- Advanced - Config files, JSON fallback, ParamT, testing
- Global Config - Init() and WithDefaultOptional()
- Cobra Interoperability - Access Cobra primitives and migrate incrementally
- Migration - Migrating from old BOA or Cobra