1![cobra logo](https://cloud.githubusercontent.com/assets/173412/10886352/ad566232-814f-11e5-9cd0-aa101788c117.png) 2 3Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files. 4 5Cobra is used in many Go projects such as [Kubernetes](http://kubernetes.io/), 6[Hugo](https://gohugo.io), and [Github CLI](https://github.com/cli/cli) to 7name a few. [This list](./projects_using_cobra.md) contains a more extensive list of projects using Cobra. 8 9[![](https://img.shields.io/github/workflow/status/spf13/cobra/Test?longCache=tru&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest) 10[![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra) 11[![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra) 12[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra) 13[![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199) 14 15# Table of Contents 16 17- [Overview](#overview) 18- [Concepts](#concepts) 19 * [Commands](#commands) 20 * [Flags](#flags) 21- [Installing](#installing) 22- [Getting Started](#getting-started) 23 * [Using the Cobra Generator](#using-the-cobra-generator) 24 * [Using the Cobra Library](#using-the-cobra-library) 25 * [Working with Flags](#working-with-flags) 26 * [Positional and Custom Arguments](#positional-and-custom-arguments) 27 * [Example](#example) 28 * [Help Command](#help-command) 29 * [Usage Message](#usage-message) 30 * [PreRun and PostRun Hooks](#prerun-and-postrun-hooks) 31 * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens) 32 * [Generating documentation for your command](#generating-documentation-for-your-command) 33 * [Generating shell completions](#generating-shell-completions) 34- [Contributing](CONTRIBUTING.md) 35- [License](#license) 36 37# Overview 38 39Cobra is a library providing a simple interface to create powerful modern CLI 40interfaces similar to git & go tools. 41 42Cobra is also an application that will generate your application scaffolding to rapidly 43develop a Cobra-based application. 44 45Cobra provides: 46* Easy subcommand-based CLIs: `app server`, `app fetch`, etc. 47* Fully POSIX-compliant flags (including short & long versions) 48* Nested subcommands 49* Global, local and cascading flags 50* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname` 51* Intelligent suggestions (`app srver`... did you mean `app server`?) 52* Automatic help generation for commands and flags 53* Automatic help flag recognition of `-h`, `--help`, etc. 54* Automatically generated shell autocomplete for your application (bash, zsh, fish, powershell) 55* Automatically generated man pages for your application 56* Command aliases so you can change things without breaking them 57* The flexibility to define your own help, usage, etc. 58* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps 59 60# Concepts 61 62Cobra is built on a structure of commands, arguments & flags. 63 64**Commands** represent actions, **Args** are things and **Flags** are modifiers for those actions. 65 66The best applications read like sentences when used, and as a result, users 67intuitively know how to interact with them. 68 69The pattern to follow is 70`APPNAME VERB NOUN --ADJECTIVE.` 71 or 72`APPNAME COMMAND ARG --FLAG` 73 74A few good real world examples may better illustrate this point. 75 76In the following example, 'server' is a command, and 'port' is a flag: 77 78 hugo server --port=1313 79 80In this command we are telling Git to clone the url bare. 81 82 git clone URL --bare 83 84## Commands 85 86Command is the central point of the application. Each interaction that 87the application supports will be contained in a Command. A command can 88have children commands and optionally run an action. 89 90In the example above, 'server' is the command. 91 92[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command) 93 94## Flags 95 96A flag is a way to modify the behavior of a command. Cobra supports 97fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/). 98A Cobra command can define flags that persist through to children commands 99and flags that are only available to that command. 100 101In the example above, 'port' is the flag. 102 103Flag functionality is provided by the [pflag 104library](https://github.com/spf13/pflag), a fork of the flag standard library 105which maintains the same interface while adding POSIX compliance. 106 107# Installing 108Using Cobra is easy. First, use `go get` to install the latest version 109of the library. This command will install the `cobra` generator executable 110along with the library and its dependencies: 111 112 go get -u github.com/spf13/cobra 113 114Next, include Cobra in your application: 115 116```go 117import "github.com/spf13/cobra" 118``` 119 120# Getting Started 121 122While you are welcome to provide your own organization, typically a Cobra-based 123application will follow the following organizational structure: 124 125``` 126 ▾ appName/ 127 ▾ cmd/ 128 add.go 129 your.go 130 commands.go 131 here.go 132 main.go 133``` 134 135In a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra. 136 137```go 138package main 139 140import ( 141 "{pathToYourApp}/cmd" 142) 143 144func main() { 145 cmd.Execute() 146} 147``` 148 149## Using the Cobra Generator 150 151Cobra provides its own program that will create your application and add any 152commands you want. It's the easiest way to incorporate Cobra into your application. 153 154[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it. 155 156## Using the Cobra Library 157 158To manually implement Cobra you need to create a bare main.go file and a rootCmd file. 159You will optionally provide additional commands as you see fit. 160 161### Create rootCmd 162 163Cobra doesn't require any special constructors. Simply create your commands. 164 165Ideally you place this in app/cmd/root.go: 166 167```go 168var rootCmd = &cobra.Command{ 169 Use: "hugo", 170 Short: "Hugo is a very fast static site generator", 171 Long: `A Fast and Flexible Static Site Generator built with 172 love by spf13 and friends in Go. 173 Complete documentation is available at http://hugo.spf13.com`, 174 Run: func(cmd *cobra.Command, args []string) { 175 // Do Stuff Here 176 }, 177} 178 179func Execute() { 180 if err := rootCmd.Execute(); err != nil { 181 fmt.Fprintln(os.Stderr, err) 182 os.Exit(1) 183 } 184} 185``` 186 187You will additionally define flags and handle configuration in your init() function. 188 189For example cmd/root.go: 190 191```go 192package cmd 193 194import ( 195 "fmt" 196 "os" 197 198 homedir "github.com/mitchellh/go-homedir" 199 "github.com/spf13/cobra" 200 "github.com/spf13/viper" 201) 202 203var ( 204 // Used for flags. 205 cfgFile string 206 userLicense string 207 208 rootCmd = &cobra.Command{ 209 Use: "cobra", 210 Short: "A generator for Cobra based Applications", 211 Long: `Cobra is a CLI library for Go that empowers applications. 212This application is a tool to generate the needed files 213to quickly create a Cobra application.`, 214 } 215) 216 217// Execute executes the root command. 218func Execute() error { 219 return rootCmd.Execute() 220} 221 222func init() { 223 cobra.OnInitialize(initConfig) 224 225 rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)") 226 rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution") 227 rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "name of license for the project") 228 rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration") 229 viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author")) 230 viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper")) 231 viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>") 232 viper.SetDefault("license", "apache") 233 234 rootCmd.AddCommand(addCmd) 235 rootCmd.AddCommand(initCmd) 236} 237 238func initConfig() { 239 if cfgFile != "" { 240 // Use config file from the flag. 241 viper.SetConfigFile(cfgFile) 242 } else { 243 // Find home directory. 244 home, err := homedir.Dir() 245 cobra.CheckErr(err) 246 247 // Search config in home directory with name ".cobra" (without extension). 248 viper.AddConfigPath(home) 249 viper.SetConfigName(".cobra") 250 } 251 252 viper.AutomaticEnv() 253 254 if err := viper.ReadInConfig(); err == nil { 255 fmt.Println("Using config file:", viper.ConfigFileUsed()) 256 } 257} 258``` 259 260### Create your main.go 261 262With the root command you need to have your main function execute it. 263Execute should be run on the root for clarity, though it can be called on any command. 264 265In a Cobra app, typically the main.go file is very bare. It serves one purpose: to initialize Cobra. 266 267```go 268package main 269 270import ( 271 "{pathToYourApp}/cmd" 272) 273 274func main() { 275 cmd.Execute() 276} 277``` 278 279### Create additional commands 280 281Additional commands can be defined and typically are each given their own file 282inside of the cmd/ directory. 283 284If you wanted to create a version command you would create cmd/version.go and 285populate it with the following: 286 287```go 288package cmd 289 290import ( 291 "fmt" 292 293 "github.com/spf13/cobra" 294) 295 296func init() { 297 rootCmd.AddCommand(versionCmd) 298} 299 300var versionCmd = &cobra.Command{ 301 Use: "version", 302 Short: "Print the version number of Hugo", 303 Long: `All software has versions. This is Hugo's`, 304 Run: func(cmd *cobra.Command, args []string) { 305 fmt.Println("Hugo Static Site Generator v0.9 -- HEAD") 306 }, 307} 308``` 309 310### Returning and handling errors 311 312If you wish to return an error to the caller of a command, `RunE` can be used. 313 314```go 315package cmd 316 317import ( 318 "fmt" 319 320 "github.com/spf13/cobra" 321) 322 323func init() { 324 rootCmd.AddCommand(tryCmd) 325} 326 327var tryCmd = &cobra.Command{ 328 Use: "try", 329 Short: "Try and possibly fail at something", 330 RunE: func(cmd *cobra.Command, args []string) error { 331 if err := someFunc(); err != nil { 332 return err 333 } 334 return nil 335 }, 336} 337``` 338 339The error can then be caught at the execute function call. 340 341## Working with Flags 342 343Flags provide modifiers to control how the action command operates. 344 345### Assign flags to a command 346 347Since the flags are defined and used in different locations, we need to 348define a variable outside with the correct scope to assign the flag to 349work with. 350 351```go 352var Verbose bool 353var Source string 354``` 355 356There are two different approaches to assign a flag. 357 358### Persistent Flags 359 360A flag can be 'persistent', meaning that this flag will be available to the 361command it's assigned to as well as every command under that command. For 362global flags, assign a flag as a persistent flag on the root. 363 364```go 365rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") 366``` 367 368### Local Flags 369 370A flag can also be assigned locally, which will only apply to that specific command. 371 372```go 373localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") 374``` 375 376### Local Flag on Parent Commands 377 378By default, Cobra only parses local flags on the target command, and any local flags on 379parent commands are ignored. By enabling `Command.TraverseChildren`, Cobra will 380parse local flags on each command before executing the target command. 381 382```go 383command := cobra.Command{ 384 Use: "print [OPTIONS] [COMMANDS]", 385 TraverseChildren: true, 386} 387``` 388 389### Bind Flags with Config 390 391You can also bind your flags with [viper](https://github.com/spf13/viper): 392```go 393var author string 394 395func init() { 396 rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution") 397 viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author")) 398} 399``` 400 401In this example, the persistent flag `author` is bound with `viper`. 402**Note**: the variable `author` will not be set to the value from config, 403when the `--author` flag is not provided by user. 404 405More in [viper documentation](https://github.com/spf13/viper#working-with-flags). 406 407### Required flags 408 409Flags are optional by default. If instead you wish your command to report an error 410when a flag has not been set, mark it as required: 411```go 412rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)") 413rootCmd.MarkFlagRequired("region") 414``` 415 416Or, for persistent flags: 417```go 418rootCmd.PersistentFlags().StringVarP(&Region, "region", "r", "", "AWS region (required)") 419rootCmd.MarkPersistentFlagRequired("region") 420``` 421 422## Positional and Custom Arguments 423 424Validation of positional arguments can be specified using the `Args` field 425of `Command`. 426 427The following validators are built in: 428 429- `NoArgs` - the command will report an error if there are any positional args. 430- `ArbitraryArgs` - the command will accept any args. 431- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`. 432- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args. 433- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args. 434- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args. 435- `ExactValidArgs(int)` - the command will report an error if there are not exactly N positional args OR if there are any positional args that are not in the `ValidArgs` field of `Command` 436- `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args. 437 438An example of setting the custom validator: 439 440```go 441var cmd = &cobra.Command{ 442 Short: "hello", 443 Args: func(cmd *cobra.Command, args []string) error { 444 if len(args) < 1 { 445 return errors.New("requires a color argument") 446 } 447 if myapp.IsValidColor(args[0]) { 448 return nil 449 } 450 return fmt.Errorf("invalid color specified: %s", args[0]) 451 }, 452 Run: func(cmd *cobra.Command, args []string) { 453 fmt.Println("Hello, World!") 454 }, 455} 456``` 457 458## Example 459 460In the example below, we have defined three commands. Two are at the top level 461and one (cmdTimes) is a child of one of the top commands. In this case the root 462is not executable, meaning that a subcommand is required. This is accomplished 463by not providing a 'Run' for the 'rootCmd'. 464 465We have only defined one flag for a single command. 466 467More documentation about flags is available at https://github.com/spf13/pflag 468 469```go 470package main 471 472import ( 473 "fmt" 474 "strings" 475 476 "github.com/spf13/cobra" 477) 478 479func main() { 480 var echoTimes int 481 482 var cmdPrint = &cobra.Command{ 483 Use: "print [string to print]", 484 Short: "Print anything to the screen", 485 Long: `print is for printing anything back to the screen. 486For many years people have printed back to the screen.`, 487 Args: cobra.MinimumNArgs(1), 488 Run: func(cmd *cobra.Command, args []string) { 489 fmt.Println("Print: " + strings.Join(args, " ")) 490 }, 491 } 492 493 var cmdEcho = &cobra.Command{ 494 Use: "echo [string to echo]", 495 Short: "Echo anything to the screen", 496 Long: `echo is for echoing anything back. 497Echo works a lot like print, except it has a child command.`, 498 Args: cobra.MinimumNArgs(1), 499 Run: func(cmd *cobra.Command, args []string) { 500 fmt.Println("Echo: " + strings.Join(args, " ")) 501 }, 502 } 503 504 var cmdTimes = &cobra.Command{ 505 Use: "times [string to echo]", 506 Short: "Echo anything to the screen more times", 507 Long: `echo things multiple times back to the user by providing 508a count and a string.`, 509 Args: cobra.MinimumNArgs(1), 510 Run: func(cmd *cobra.Command, args []string) { 511 for i := 0; i < echoTimes; i++ { 512 fmt.Println("Echo: " + strings.Join(args, " ")) 513 } 514 }, 515 } 516 517 cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input") 518 519 var rootCmd = &cobra.Command{Use: "app"} 520 rootCmd.AddCommand(cmdPrint, cmdEcho) 521 cmdEcho.AddCommand(cmdTimes) 522 rootCmd.Execute() 523} 524``` 525 526For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/). 527 528## Help Command 529 530Cobra automatically adds a help command to your application when you have subcommands. 531This will be called when a user runs 'app help'. Additionally, help will also 532support all other commands as input. Say, for instance, you have a command called 533'create' without any additional configuration; Cobra will work when 'app help 534create' is called. Every command will automatically have the '--help' flag added. 535 536### Example 537 538The following output is automatically generated by Cobra. Nothing beyond the 539command and flag definitions are needed. 540 541 $ cobra help 542 543 Cobra is a CLI library for Go that empowers applications. 544 This application is a tool to generate the needed files 545 to quickly create a Cobra application. 546 547 Usage: 548 cobra [command] 549 550 Available Commands: 551 add Add a command to a Cobra Application 552 help Help about any command 553 init Initialize a Cobra Application 554 555 Flags: 556 -a, --author string author name for copyright attribution (default "YOUR NAME") 557 --config string config file (default is $HOME/.cobra.yaml) 558 -h, --help help for cobra 559 -l, --license string name of license for the project 560 --viper use Viper for configuration (default true) 561 562 Use "cobra [command] --help" for more information about a command. 563 564 565Help is just a command like any other. There is no special logic or behavior 566around it. In fact, you can provide your own if you want. 567 568### Defining your own help 569 570You can provide your own Help command or your own template for the default command to use 571with following functions: 572 573```go 574cmd.SetHelpCommand(cmd *Command) 575cmd.SetHelpFunc(f func(*Command, []string)) 576cmd.SetHelpTemplate(s string) 577``` 578 579The latter two will also apply to any children commands. 580 581## Usage Message 582 583When the user provides an invalid flag or invalid command, Cobra responds by 584showing the user the 'usage'. 585 586### Example 587You may recognize this from the help above. That's because the default help 588embeds the usage as part of its output. 589 590 $ cobra --invalid 591 Error: unknown flag: --invalid 592 Usage: 593 cobra [command] 594 595 Available Commands: 596 add Add a command to a Cobra Application 597 help Help about any command 598 init Initialize a Cobra Application 599 600 Flags: 601 -a, --author string author name for copyright attribution (default "YOUR NAME") 602 --config string config file (default is $HOME/.cobra.yaml) 603 -h, --help help for cobra 604 -l, --license string name of license for the project 605 --viper use Viper for configuration (default true) 606 607 Use "cobra [command] --help" for more information about a command. 608 609### Defining your own usage 610You can provide your own usage function or template for Cobra to use. 611Like help, the function and template are overridable through public methods: 612 613```go 614cmd.SetUsageFunc(f func(*Command) error) 615cmd.SetUsageTemplate(s string) 616``` 617 618## Version Flag 619 620Cobra adds a top-level '--version' flag if the Version field is set on the root command. 621Running an application with the '--version' flag will print the version to stdout using 622the version template. The template can be customized using the 623`cmd.SetVersionTemplate(s string)` function. 624 625## PreRun and PostRun Hooks 626 627It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherited by children if they do not declare their own. These functions are run in the following order: 628 629- `PersistentPreRun` 630- `PreRun` 631- `Run` 632- `PostRun` 633- `PersistentPostRun` 634 635An example of two commands which use all of these features is below. When the subcommand is executed, it will run the root command's `PersistentPreRun` but not the root command's `PersistentPostRun`: 636 637```go 638package main 639 640import ( 641 "fmt" 642 643 "github.com/spf13/cobra" 644) 645 646func main() { 647 648 var rootCmd = &cobra.Command{ 649 Use: "root [sub]", 650 Short: "My root command", 651 PersistentPreRun: func(cmd *cobra.Command, args []string) { 652 fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args) 653 }, 654 PreRun: func(cmd *cobra.Command, args []string) { 655 fmt.Printf("Inside rootCmd PreRun with args: %v\n", args) 656 }, 657 Run: func(cmd *cobra.Command, args []string) { 658 fmt.Printf("Inside rootCmd Run with args: %v\n", args) 659 }, 660 PostRun: func(cmd *cobra.Command, args []string) { 661 fmt.Printf("Inside rootCmd PostRun with args: %v\n", args) 662 }, 663 PersistentPostRun: func(cmd *cobra.Command, args []string) { 664 fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args) 665 }, 666 } 667 668 var subCmd = &cobra.Command{ 669 Use: "sub [no options!]", 670 Short: "My subcommand", 671 PreRun: func(cmd *cobra.Command, args []string) { 672 fmt.Printf("Inside subCmd PreRun with args: %v\n", args) 673 }, 674 Run: func(cmd *cobra.Command, args []string) { 675 fmt.Printf("Inside subCmd Run with args: %v\n", args) 676 }, 677 PostRun: func(cmd *cobra.Command, args []string) { 678 fmt.Printf("Inside subCmd PostRun with args: %v\n", args) 679 }, 680 PersistentPostRun: func(cmd *cobra.Command, args []string) { 681 fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args) 682 }, 683 } 684 685 rootCmd.AddCommand(subCmd) 686 687 rootCmd.SetArgs([]string{""}) 688 rootCmd.Execute() 689 fmt.Println() 690 rootCmd.SetArgs([]string{"sub", "arg1", "arg2"}) 691 rootCmd.Execute() 692} 693``` 694 695Output: 696``` 697Inside rootCmd PersistentPreRun with args: [] 698Inside rootCmd PreRun with args: [] 699Inside rootCmd Run with args: [] 700Inside rootCmd PostRun with args: [] 701Inside rootCmd PersistentPostRun with args: [] 702 703Inside rootCmd PersistentPreRun with args: [arg1 arg2] 704Inside subCmd PreRun with args: [arg1 arg2] 705Inside subCmd Run with args: [arg1 arg2] 706Inside subCmd PostRun with args: [arg1 arg2] 707Inside subCmd PersistentPostRun with args: [arg1 arg2] 708``` 709 710## Suggestions when "unknown command" happens 711 712Cobra will print automatic suggestions when "unknown command" errors happen. This allows Cobra to behave similarly to the `git` command when a typo happens. For example: 713 714``` 715$ hugo srever 716Error: unknown command "srever" for "hugo" 717 718Did you mean this? 719 server 720 721Run 'hugo --help' for usage. 722``` 723 724Suggestions are automatic based on every subcommand registered and use an implementation of [Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion. 725 726If you need to disable suggestions or tweak the string distance in your command, use: 727 728```go 729command.DisableSuggestions = true 730``` 731 732or 733 734```go 735command.SuggestionsMinimumDistance = 1 736``` 737 738You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but makes sense in your set of commands and for some which you don't want aliases. Example: 739 740``` 741$ kubectl remove 742Error: unknown command "remove" for "kubectl" 743 744Did you mean this? 745 delete 746 747Run 'kubectl help' for usage. 748``` 749 750## Generating documentation for your command 751 752Cobra can generate documentation based on subcommands, flags, etc. Read more about it in the [docs generation documentation](doc/README.md). 753 754## Generating shell completions 755 756Cobra can generate a shell-completion file for the following shells: bash, zsh, fish, PowerShell. If you add more information to your commands, these completions can be amazingly powerful and flexible. Read more about it in [Shell Completions](shell_completions.md). 757 758# License 759 760Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt) 761