Skilllibrary cli-development-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/cli-development-go" ~/.claude/skills/merceralex397-collab-skilllibrary-cli-development-go && rm -rf "$T"
manifest:
10-cli-systems-and-ops/cli-development-go/SKILL.mdsource content
Purpose
Build robust Go CLI tools using Cobra for command structure, Viper for config, and idiomatic Go patterns for I/O and error handling.
When to use this skill
- creating a new Go CLI binary with subcommands
- wiring Cobra commands with Viper config file and env var binding
- adding
formatting--output json|table|text - structuring a multi-command Go CLI project
Do not use this skill when
- building an interactive terminal UI — prefer
bubbletea-go - building a Python CLI — prefer
cli-development-python - only writing shell scripts — prefer
bash
Procedure
- Scaffold with Cobra-CLI — run
andcobra-cli init
to generate command files.cobra-cli add <cmd> - Define root command — set
on root for global setup (config loading, logger init).PersistentPreRunE - Bind flags to Viper — call
inviper.BindPFlag("key", cmd.Flags().Lookup("flag"))
.init() - Load config — use
,viper.SetConfigName(".myapp")
,viper.AddConfigPath("$HOME")
.viper.AutomaticEnv() - Structure output — accept
flag; use--output
for JSON,encoding/json
for tables.text/tabwriter - Handle errors idiomatically — return
fromerror
, let Cobra print usage on bad args. UseRunE
.fmt.Errorf("verb: %w", err) - Add completions — Cobra auto-generates
subcommand; add customcompletion
for dynamic completions.ValidArgsFunction - Build and test —
for version embedding; test withgo build -ldflags "-X main.version=$(git describe)"
.cobra.Command.ExecuteC()
Project layout
myapp/ cmd/ root.go # root command + global flags serve.go # subcommand migrate.go # subcommand internal/ config/config.go # Viper wrapper output/output.go # JSON/table formatter main.go # cmd.Execute() .myapp.yaml # default config
Key patterns
var rootCmd = &cobra.Command{ Use: "myapp", Short: "Does the thing", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { viper.SetConfigName(".myapp") viper.AddConfigPath(".") viper.AutomaticEnv() viper.SetEnvPrefix("MYAPP") _ = viper.ReadInConfig() return nil }, } func init() { rootCmd.PersistentFlags().StringP("output", "o", "text", "Output format: text|json|table") viper.BindPFlag("output", rootCmd.PersistentFlags().Lookup("output")) }
Decision rules
- Use
(notRunE
) so errors propagate toRun
via Cobra.os.Exit(1) - Bind every flag to Viper so env vars and config files work as overrides.
- Write to
instead ofcmd.OutOrStdout()
for testability.os.Stdout - Validate args in
field (e.g.,Args:
) not insidecobra.ExactArgs(1)
.RunE - Prefer
flag over multiple commands (--output
,list-json
).list-table
References
Related skills
— focused Cobra command patternscobra-go
— interactive TUI on top of CLIbubbletea-go
— cross-compiling and distributing the binaryrelease-binaries