Flags and CLI structure
Simple command-line tools can rely on `flag` directly, but growing CLIs need structure that keeps parsing, validation, and command execution readable.
Canonical guidance
- keep simple CLIs simple
- parse and validate flags near
main - introduce more command structure only when the command surface actually grows
Use when
- writing build or admin tools
- reviewing
mainpackages - deciding whether a CLI has outgrown ad hoc parsing
Avoid
- spreading flag state across unrelated packages
- turning every tiny tool into a framework
- leaving invalid combinations to fail deep in execution
Preferred pattern
func main() {
flag.Parse()
if err := run(flag.Args()); err != nil {
log.Fatal(err)
}
}
Anti-pattern
- using package globals and deep helper calls to discover what the command-line actually configured
Explanation: This is tempting because it feels convenient, but it makes CLI behavior harder to validate and test.
Why
- the Google docs add practical guidance for the common gap between tiny one-flag tools and fully structured CLIs
Related pages
Sources
- Google Go Style Decisions - Google
- Google Go Best Practices - Google