
Golang Cli
Scaffold and harden Go command-line tools with Cobra flags, argument validation, and testable command execution.
Overview
golang-cli is an agent skill for the Build phase that teaches solo builders how to design, validate, and test Go CLIs with Cobra commands and captured output in unit tests.
Install
npx skills add https://github.com/samber/cc-skills-golang --skill golang-cliWhat is this skill?
- Cobra command patterns with Short/Long help, Args validators (ExactArgs, MinimumNArgs, etc.), and RunE for returning err
- Built-in positional argument validators plus custom Args funcs for enums like dev, staging, and prod
- Test harness that sets SetOut, SetErr, and SetArgs on the root command to capture stdout/stderr without hitting the real
- Guidance to wire commands with OutOrStdout() and ErrOrStderr() so production and tests share the same I/O paths
- Deploy-style subcommand examples you can adapt for migrations, releases, and ops workflows
- Examples cover built-in Cobra positional Args validators (see SKILL.md table) plus custom enum validation for deploy tar
- Testing pattern uses SetOut, SetErr, and SetArgs on the command root to capture combined output in tests
Adoption & trust: 3.7k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need a maintainable Go CLI with correct argument validation and tests, but cobra’s Args options and I/O wiring are easy to get wrong under time pressure.
Who is it for?
Indie builders adding or refactoring cobra-based CLIs in a Go module who want errors, help text, and tests in one pass.
Skip if: Teams that only need a one-off script with the standard library flag package or a generated CLI scaffold they will not customize.
When should I use this skill?
You are implementing or refactoring a Go CLI with Cobra, need argument validation or deploy-style subcommands, or want unit tests that execute commands without a real TTY.
What do I get? / Deliverables
You leave with production-style cobra commands, explicit validation for positional args, and a repeatable executeCommand test pattern ready to extend with more subcommands.
- Cobra command and subcommand definitions with Args validation and RunE handlers
- Custom validation for constrained inputs such as environment names
- Go tests that programmatically execute commands and assert on captured output and errors
Recommended Skills
Journey fit
CLI binaries are authored during the Build phase when you turn libraries and APIs into shippable developer-facing tools. Go services and tooling usually live in backend repos; Cobra command trees, RunE error handling, and validation belong next to other server and binary code.
How it compares
Use instead of copying random cobra snippets—this skill packages opinionated validation and testing patterns for agent-driven implementation.
Common Questions / FAQ
Who is golang-cli for?
Solo and indie developers shipping Go command-line tools with Cobra who want their coding agent to follow consistent Args, RunE, and testing conventions.
When should I use golang-cli?
During Build when you create deploy or ops subcommands, tighten environment validation, or add unit tests that execute the root command with buffered I/O—especially before your first public CLI release.
Is golang-cli safe to install?
It is procedural documentation for your agent, not a running service; review the Security Audits panel on this Prism page before trusting any third-party skill repo in your environment.
SKILL.md
READMESKILL.md - Golang Cli
package main import ( "fmt" "github.com/spf13/cobra" ) // Cobra provides built-in validators for positional arguments. // See the table in SKILL.md for all available validators. var deployCmd = &cobra.Command{ Use: "deploy [environment]", Short: "Deploy to an environment", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { env := args[0] _ = env // deploy... return nil }, } // Custom validation example: var deployWithValidationCmd = &cobra.Command{ Use: "deploy [environment]", Short: "Deploy to an environment", Args: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("expected exactly 1 argument, got %d", len(args)) } valid := map[string]bool{"dev": true, "staging": true, "prod": true} if !valid[args[0]] { return fmt.Errorf("invalid environment %q, must be one of: dev, staging, prod", args[0]) } return nil }, RunE: func(cmd *cobra.Command, args []string) error { // deploy... return nil }, } package main import ( "bytes" "testing" "github.com/spf13/cobra" ) // Test commands by executing them programmatically and capturing output. // Use cmd.OutOrStdout() and cmd.ErrOrStderr() in commands (instead of // os.Stdout / os.Stderr) so output can be captured in tests. func executeCommand(root *cobra.Command, args ...string) (string, error) { buf := new(bytes.Buffer) root.SetOut(buf) root.SetErr(buf) root.SetArgs(args) err := root.Execute() return buf.String(), err } func TestServeCommand(t *testing.T) { tests := []struct { name string args []string want string wantErr bool }{ { name: "default port", args: []string{"serve"}, want: "listening on :8080\n", }, { name: "custom port", args: []string{"serve", "--port", "9090"}, want: "listening on :9090\n", }, { name: "missing required flag", args: []string{"serve", "--host", ""}, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := executeCommand(rootCmd, tt.args...) if (err != nil) != tt.wantErr { t.Errorf("error = %v, wantErr %v", err, tt.wantErr) } if !tt.wantErr && got != tt.want { t.Errorf("output = %q, want %q", got, tt.want) } }) } } package main import ( "os" "github.com/spf13/cobra" ) // === Shell Completion Command === // Cobra generates completions for bash, zsh, fish, and PowerShell automatically. func init() { rootCmd.AddCommand(&cobra.Command{ Use: "completion [bash|zsh|fish|powershell]", Short: "Generate shell completion script", Args: cobra.ExactValidArgs(1), ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, RunE: func(cmd *cobra.Command, args []string) error { switch args[0] { case "bash": return rootCmd.GenBashCompletionV2(os.Stdout, true) case "zsh": return rootCmd.GenZshCompletion(os.Stdout) case "fish": return rootCmd.GenFishCompletion(os.Stdout, true) case "powershell": return rootCmd.GenPowerShellCompletionWithDesc(os.Stdout) } return nil }, }) } // === Custom Completions === // Add custom completions for flags and arguments. func customCompletionExamples() { deployCmd.RegisterFlagCompletionFunc("env", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return []string{ "dev\tDevelopment environment", "staging\tStaging environment", "prod\tProduction environment", }, cobra.ShellCompDirectiveNoFileComp }) // Dynamic argument completion deployCmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } return getAvailableServices(), cobra.ShellCompDirectiveNoFileComp } } func getAvailableServices() []string { // fetch available services dynamically return nil } package main import ( "fmt" "log/slog" "os" "strings"