xiaohongshu
xiaohongshu
cobra-patterns
Production-ready Cobra CLI patterns including command structure, flags (local and persistent), nested commands, PreRun/PostRun hooks, argument validation, and initialization patterns used by kubectl and hugo. Use when building Go CLIs, implementing Cobra commands, creating nested command structur...
Full skill instructions
Production-ready patterns for building powerful CLI applications with Cobra, following best practices from kubectl, hugo, and other production CLIs.
Select the appropriate CLI structure based on your use case:
Use the setup script to scaffold a new Cobra CLI:
cd /home/gotime2022/.claude/plugins/repos/cli-builder/skills/cobra-patterns
./scripts/setup-cobra-cli.sh <cli-name> <structure-type>
Structure types: simple, flat, nested, plugin, hybrid
Example:
./scripts/setup-cobra-cli.sh myctl nested
What This Creates:
var exampleCmd = &cobra.Command{
Use: "example [flags]",
Short: "Brief description",
Long: `Detailed description with examples`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
// Command logic
},
}
var advancedCmd = &cobra.Command{
Use: "advanced",
Short: "Advanced command with hooks",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// Runs before command execution (inherited by children)
},
PreRun: func(cmd *cobra.Command, args []string) {
// Runs before command execution (local only)
},
Run: func(cmd *cobra.Command, args []string) {
// Main command logic
},
PostRun: func(cmd *cobra.Command, args []string) {
// Runs after command execution (local only)
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
// Runs after command execution (inherited by children)
},
}
var robustCmd = &cobra.Command{
Use: "robust",
Short: "Command with proper error handling",
RunE: func(cmd *cobra.Command, args []string) error {
// Return errors instead of os.Exit
if err := validateInput(args); err != nil {
return fmt.Errorf("validation failed: %w", err)
}
if err := executeOperation(); err != nil {
return fmt.Errorf("operation failed: %w", err)
}
return nil
},
}
func init() {
// Available to this command and all subcommands
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "log level")
}
func init() {
// Only available to this specific command
createCmd.Flags().StringVarP(&name, "name", "n", "", "resource name")
createCmd.Flags().IntVar(&replicas, "replicas", 1, "number of replicas")
createCmd.Flags().BoolVar(&dryRun, "dry-run", false, "simulate operation")
// Mark required flags
createCmd.MarkFlagRequired("name")
}
func init() {
// Mutually exclusive flags (only one allowed)
createCmd.MarkFlagsMutuallyExclusive("json", "yaml", "text")
// Required together (all or none)
createCmd.MarkFlagsRequiredTogether("username", "password")
// At least one required
createCmd.MarkFlagsOneRequired("file", "stdin", "url")
// Custom flag completion
createCmd.RegisterFlagCompletionFunc("format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"json", "yaml", "text"}, cobra.ShellCompDirectiveNoFileComp
})
}
// cmd/root.go
var rootCmd = &cobra.Command{
Use: "myctl",
Short: "A production-grade CLI tool",
Long: `A complete CLI application built with Cobra.
This application demonstrates production patterns including
nested commands, flag management, and proper error handling.`,
}
func Execute() error {
return rootCmd.Execute()
}
func init() {
cobra.OnInitialize(initConfig)
// Global flags
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
// Add subcommands
rootCmd.AddCommand(getCmd)
rootCmd.AddCommand(createCmd)
rootCmd.AddCommand(deleteCmd)
}
func initConfig() {
// Initialize configuration, logging, etc.
}
// cmd/create/create.go
var createCmd = &cobra.Command{
Use: "create",
Short: "Create resources",
Long: `Create various types of resources`,
}
func init() {
// Add nested subcommands
createCmd.AddCommand(createDeploymentCmd)
createCmd.AddCommand(createServiceCmd)
createCmd.AddCommand(createConfigMapCmd)
}
// cmd/create/deployment.go
var createDeploymentCmd = &cobra.Command{
Use: "deployment [name]",
Short: "Create a deployment",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return createDeployment(args[0])
},
}
func init() {
// Define command groups
rootCmd.AddGroup(&cobra.Group{
ID: "basic",
Title: "Basic Commands:",
})
rootCmd.AddGroup(&cobra.Group{
ID: "management",
Title: "Management Commands:",
})
// Assign commands to groups
getCmd.GroupID = "basic"
createCmd.GroupID = "management"
}
// No arguments allowed
var noArgsCmd = &cobra.Command{
Use: "list",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return listResources()
},
}
// Exactly n arguments
var exactArgsCmd = &cobra.Command{
Use: "get <name>",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return getResource(args[0])
},
}
// Range of arguments
var rangeArgsCmd = &cobra.Command{
Use: "delete <name> [names...]",
Args: cobra.RangeArgs(1, 5),
RunE: func(cmd *cobra.Command, args []string) error {
return deleteResources(args)
},
}
// Custom validation
var customValidationCmd = &cobra.Command{
Use: "custom",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("requires at least 1 argument")
}
for _, arg := range args {
if !isValid(arg) {
return fmt.Errorf("invalid argument: %s", arg)
}
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return processArgs(args)
},
}
// Valid args with completion
var validArgsCmd = &cobra.Command{
Use: "select <resource>",
ValidArgs: []string{"pod", "service", "deployment", "configmap"},
Args: cobra.OnlyValidArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return selectResource(args[0])
},
}
var (
cfgFile string
config Config
)
func init() {
// Register initialization functions
cobra.OnInitialize(initConfig, initLogging, initClient)
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
}
func initConfig() {
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
home, err := os.UserHomeDir()
cobra.CheckErr(err)
viper.AddConfigPath(home)
viper.SetConfigType("yaml")
viper.SetConfigName(".myctl")
}
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err == nil {
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
}
}
func initLogging() {
// Setup logging based on flags
}
func initClient() {
// Initialize API clients, connections, etc.
}
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func init() {
// Bind flags to viper
rootCmd.PersistentFlags().String("output", "json", "output format")
viper.BindPFlag("output", rootCmd.PersistentFlags().Lookup("output"))
// Set defaults
viper.SetDefault("output", "json")
viper.SetDefault("timeout", 30)
}
func Execute() error {
// Access config via viper
output := viper.GetString("output")
timeout := viper.GetInt("timeout")
return rootCmd.Execute()
}
// Organize commands by resource type
// myctl get pods
// myctl create deployment
// myctl delete service
var getCmd = &cobra.Command{
Use: "get",
Short: "Display resources",
}
var createCmd = &cobra.Command{
Use: "create",
Short: "Create resources",
}
func init() {
// Resource-specific subcommands
getCmd.AddCommand(getPodsCmd)
getCmd.AddCommand(getServicesCmd)
createCmd.AddCommand(createDeploymentCmd)
createCmd.AddCommand(createServiceCmd)
}
// Support external commands (hugo server, hugo new, etc.)
func init() {
rootCmd.AddCommand(serverCmd)
rootCmd.AddCommand(newCmd)
// Auto-discover plugin commands
discoverPluginCommands(rootCmd)
}
func discoverPluginCommands(root *cobra.Command) {
// Look for executables like "myctl-plugin-*"
// Add them as dynamic commands
}
var longRunningCmd = &cobra.Command{
Use: "process",
Short: "Long-running operation",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
// Respect context cancellation (Ctrl+C)
return processWithContext(ctx)
},
}
func processWithContext(ctx context.Context) error {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
// Do work
}
}
}
Use validation scripts to ensure CLI compliance:
# Validate command structure
./scripts/validate-cobra-cli.sh <cli-directory>
# Test command execution
./scripts/test-cobra-commands.sh <cli-binary>
# Generate shell completions
./scripts/generate-completions.sh <cli-binary>
Validation Checks:
var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate completion script",
Long: `Generate shell completion script.
Example usage:
# Bash
source <(myctl completion bash)
# Zsh
source <(myctl completion zsh)
# Fish
myctl completion fish | source
# PowerShell
myctl completion powershell | Out-String | Invoke-Expression
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
return cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
return cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
return cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
default:
return fmt.Errorf("unsupported shell: %s", args[0])
}
},
}
See examples/ directory for production patterns:
kubectl-style/: Kubectl command organization patternhugo-style/: Hugo plugin architecture patternsimple-cli/: Basic single-level CLInested-cli/: Multi-level command hierarchyproduction-cli/: Full production CLI with all featuresEach example includes:
# 1. Generate CLI structure
./scripts/setup-cobra-cli.sh myctl nested
# 2. Add commands
cd myctl
../scripts/add-command.sh get
../scripts/add-command.sh create --parent get
# 3. Validate structure
../scripts/validate-cobra-cli.sh .
# 4. Build and test
go build -o myctl
./myctl --help
# Use authentication template
cp templates/auth-command.go cmd/login.go
# Add persistent auth flags
cp templates/auth-flags.go cmd/root.go
# Implement token management
# Edit cmd/root.go to add initAuth() to cobra.OnInitialize
# Generate resource-based structure
./scripts/setup-cobra-cli.sh myctl nested
# Add resource commands (get, create, delete, update)
./scripts/add-command.sh get --style kubectl
./scripts/add-command.sh create --style kubectl
# Add resource types as subcommands
./scripts/add-command.sh pods --parent get
./scripts/add-command.sh services --parent get
Commands not showing in help: Ensure AddCommand() is called in init()
Flags not recognized: Check if flag is registered before command execution
PersistentFlags not inherited: Verify parent command has PersistentFlags defined
Completion not working: Run completion command and source output, check ValidArgs
Context cancellation ignored: Ensure you're checking ctx.Done() in long-running operations
This skill is used by:
Plugin: cli-builder Version: 1.0.0 Category: Go CLI Development Skill Type: Patterns & Templates
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience