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