$npx -y skills add samber/cc-skills-golang --skill golang-spf13-cobraGolang CLI command tree library using spf13/cobra — cobra.Command, RunE vs Run, PersistentPreRunE hook chain, Args validators (NoArgs, ExactArgs, MatchAll, custom), persistent vs local flags, command groups, ValidArgsFunction, RegisterFlagCompletionFunc, ShellCompDirective, usage
| 1 | **Persona:** You are a Go CLI engineer building command trees that feel native to the Unix shell. You design the user-facing surface first, then wire behavior into the right hook. |
| 2 | |
| 3 | **Modes:** |
| 4 | |
| 5 | - **Build** — creating a new CLI from scratch: follow command tree setup, hook wiring, and flag sections sequentially. |
| 6 | - **Extend** — adding subcommands, flags, or completions to an existing CLI: read the current command tree first, then apply changes consistent with the existing structure. |
| 7 | - **Review** — auditing an existing CLI: check the Common Mistakes table, verify `RunE` usage, `OutOrStdout()`, hook chain ordering, and args validation. |
| 8 | |
| 9 | # Using spf13/cobra for CLI command trees in Go |
| 10 | |
| 11 | Cobra is the de facto standard for Go CLI applications. It provides the command/subcommand tree, flag parsing (via `pflag`), args validation, shell completion generation, and documentation generation. It does **not** handle configuration layering — that's viper's job. |
| 12 | |
| 13 | **Official Resources:** |
| 14 | |
| 15 | - [pkg.go.dev/github.com/spf13/cobra](https://pkg.go.dev/github.com/spf13/cobra) |
| 16 | - [github.com/spf13/cobra](https://github.com/spf13/cobra) |
| 17 | - [cobra.dev](https://cobra.dev) |
| 18 | |
| 19 | This skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber/cc-skills-golang@golang-pkg-go-dev` skill (`godig`) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber/cc-skills-golang@golang-gopls` skill (`gopls`). Context7 remains a fallback for docs not indexed on pkg.go.dev. |
| 20 | |
| 21 | ```bash |
| 22 | go get github.com/spf13/cobra@latest |
| 23 | ``` |
| 24 | |
| 25 | ## Cobra vs. viper |
| 26 | |
| 27 | These libraries do fundamentally different things and can be used independently. |
| 28 | |
| 29 | | Concern | cobra | viper | |
| 30 | | --- | --- | --- | |
| 31 | | Owns | Command tree, flags, arg validation, completions | Configuration value resolution | |
| 32 | | User-facing? | Yes — subcommands, flags, help text | No — purely a key-value resolver | |
| 33 | | Without the other? | Yes — a CLI with flags only needs cobra | Yes — a daemon reading YAML + env needs only viper | |
| 34 | | Integration seam | Hands `pflag.Flag` to viper via `BindPFlag` | Treats the cobra flag as the highest-precedence layer | |
| 35 | |
| 36 | **Use cobra alone** when your binary takes flags and args but needs no config file or env resolution. **Use viper alone** when you have a long-running service reading config from YAML + env with no CLI subcommands. Use both when you need both — bind at `PersistentPreRunE` on the root command. |
| 37 | |
| 38 | → See `samber/cc-skills-golang@golang-spf13-viper` for the viper side of this integration. |
| 39 | |
| 40 | ## Command tree |
| 41 | |
| 42 | Every cobra CLI has a root command plus zero or more subcommands registered with `AddCommand`. The root command name is the binary name. |
| 43 | |
| 44 | ```go |
| 45 | var rootCmd = &cobra.Command{ |
| 46 | Use: "myapp", |
| 47 | Short: "One-line summary", |
| 48 | SilenceUsage: true, // ✓ prevents usage wall on every error |
| 49 | SilenceErrors: true, // ✓ lets you control error output format |
| 50 | } |
| 51 | ``` |
| 52 | |
| 53 | Use `AddGroup` to label subcommands in help output — register groups **before** the `AddCommand` calls that reference them; cobra does not retroactively assign groups. |
| 54 | |
| 55 | ## The Run\* family |
| 56 | |
| 57 | Cobra commands have five run hooks executed in order: |
| 58 | |
| 59 | ``` |
| 60 | PersistentPreRunE → PreRunE → RunE → PostRunE → PersistentPostRunE |
| 61 | ``` |
| 62 | |
| 63 | Always use `*E` variants — the non-`E` forms cannot return errors. Key rules: |
| 64 | |
| 65 | - `PersistentPreRunE` on the root runs before **every** subcommand — use it for config init and auth checks. |
| 66 | - A child `PersistentPreRunE` **replaces** the parent's entirely — call the |