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