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