OSDN Git Service

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