README.md
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