Skilllibrary cobra-go
install
source · Clone the upstream repo
git clone https://github.com/merceralex397-collab/skilllibrary
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/merceralex397-collab/skilllibrary "$T" && mkdir -p ~/.claude/skills && cp -r "$T/10-cli-systems-and-ops/cobra-go" ~/.claude/skills/merceralex397-collab-skilllibrary-cobra-go && rm -rf "$T"
manifest:
10-cli-systems-and-ops/cobra-go/SKILL.mdsource content
Purpose
Write correct Cobra command definitions with proper flag binding, argument validation, and shell completions.
When to use this skill
- adding a new subcommand to an existing Cobra CLI
- fixing flag binding,
chains, or arg validatorsPersistentPreRunE - implementing dynamic shell completion (
)ValidArgsFunction - restructuring a command hierarchy (grouping, aliases, hidden commands)
Do not use this skill when
- scaffolding a full CLI project with config/output layers — prefer
cli-development-go - building interactive TUI — prefer
bubbletea-go - the project uses a different CLI framework (urfave/cli, kong)
Procedure
- Create command file — one file per command in
. Definecmd/
.var fooCmd = &cobra.Command{...} - Set
correctly — format:Use
. Cobra parses this for help text."verb [flags] <required> [optional]" - Choose
overRunE
— always returnRun
so Cobra can exit non-zero on failure.error - Add args validation — use
orArgs: cobra.ExactArgs(1)
. Custom validators:cobra.MinimumNArgs(1)
.Args: func(cmd, args) error - Register flags in
— useinit()
for local,Flags()
for inherited. Bind to Viper if present.PersistentFlags() - Chain PreRunE — use
on parent for shared setup. Call parent's PreRunE from child if overriding.PersistentPreRunE - Add completions — implement
returningValidArgsFunction
.([]string, cobra.ShellCompDirective) - Register in parent — call
inparentCmd.AddCommand(fooCmd)
.init()
Key patterns
var deployCmd = &cobra.Command{ Use: "deploy <environment>", Short: "Deploy to target environment", Args: cobra.ExactArgs(1), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return []string{"staging", "production"}, cobra.ShellCompDirectiveNoFileComp }, RunE: func(cmd *cobra.Command, args []string) error { env := args[0] dryRun, _ := cmd.Flags().GetBool("dry-run") return runDeploy(cmd.Context(), env, dryRun) }, } func init() { deployCmd.Flags().Bool("dry-run", false, "Preview without applying") rootCmd.AddCommand(deployCmd) }
PersistentPreRunE chain (child calling parent):
child.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { if parent.PersistentPreRunE != nil { if err := parent.PersistentPreRunE(cmd, args); err != nil { return err } } return childSetup(cmd) }
Decision rules
- One command per file — keeps
navigable.cmd/ - Always use
— bareRunE
swallows errors.Run - Never call
inside a command — return errors and letos.Exit()
handle exit codes.Execute() - Use
to pass cancellation and deadlines.cmd.Context() - Mark internal commands with
rather than removing them.Hidden: true
References
Related skills
— full CLI project setupcli-development-go
— interactive TUI after CLI parsingbubbletea-go
— building and distributing the binaryrelease-binaries