go-cli
Golang CLI application development. Covers command structure (Cobra), configuration layering (Viper), exit codes, and I/O patterns.
SKILL.mdskills/go/go-cli/SKILL.md
GitHubCore Stack
- Cobra: Command and subcommand structure.
- Viper: Configuration management (flags, env vars, config files).
- pflag: POSIX-compliant flags (integrated with Cobra).
Project Structure
myapp/
├── cmd/
│ └── myapp/
│ ├── main.go # Entry point
│ ├── root.go # Root command
│ └── serve.go # Subcommand
Best Practices
- Silence Usage on Error — Set
SilenceUsage: truein your root command to avoid printing help text on every runtime error. - Bind Flags to Viper — Ensure flags can be overridden by environment variables or config files.
- Stderr for Logs, Stdout for Data — Diagnostic info should never go to stdout, as it breaks unix pipes.
- Graceful Shutdown — Use
signal.NotifyContextto handle SIGINT/SIGTERM. - Unix Exit Codes — Return
0for success,1for general failure,2for usage errors. - Machine-Readable Output — Provide an
--outputflag (json, table, plain) for automation. - Embed Version Info — Use
ldflagsto inject version and git commit hash at build time.
Code Snippets
Root Command Setup
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "My awesome CLI",
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return initializeConfig(cmd)
},
}
Binding Flags to Viper
func init() {
rootCmd.PersistentFlags().String("config", "", "config file")
viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config"))
}
Argument Validation
var cmd = &cobra.Command{
Use: "greet [name]",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Hello %s\n", args[0])
},
}
Anti-patterns
- ❌ Calling
os.Exit()inside commands — Prevents cleanup and tests from running. Return an error fromRunEinstead. - ❌ Hardcoded config paths — Allow users to specify a config file via flag or env var.
- ❌ Logging to Stdout — Corrupts the data stream when users pipe your program to another.
- ❌ Missing help descriptions — Makes the CLI hard to discover for new users.
- ❌ Ignoring signals — Hard-stopping services can leave data in an inconsistent state.