Browse code

Bump spf13/cobra to v0.0.3, pflag to v1.0.1

Use a tagged release of Cobra. All relevant PR's were merged, so the fork is
no longer needed.

Relevant changes:

- spf13/cobra#552 Add a field to disable [flags] in UseLine()
- spf13/cobra#567 Add `CalledAs` method to cobra.Command
- spf13/cobra#580 Update error message for missing required flags
- spf13/cobra#584 Add support for --version flag
- spf13/cobra#614 If user has a project in symlink, just use its destination folder and work there
- spf13/cobra#649 terminates the flags when -- is found in commandline
- spf13/cobra#662 Add support for ignoring parse errors
- spf13/cobra#686 doc: hide hidden parent flags

Also various improvements were added for generating Bash
completion scripts (currently not used by us)

Fixes usage output for dockerd;

Before this update:

dockerd --help

Usage: dockerd COMMAND

A self-sufficient runtime for containers.

After this update:

dockerd --help

Usage: dockerd [OPTIONS] [flags]

A self-sufficient runtime for containers.

Bump spf13/pflag to v1.0.1

Relevant changes:

- spf13/pflag#106 allow lookup by shorthand
- spf13/pflag#113 Add SortFlags option
- spf13/pflag#138 Generate flag error output for errors returned from the parseFunc
- spf13/pflag#141 Fixing Count flag usage string
- spf13/pflag#143 add int16 flag
- spf13/pflag#122 DurationSlice: implementation and tests
- spf13/pflag#115 Implement BytesHex type of argument
- spf13/pflag#150 Add uintSlice and boolSlice to name prettifier
- spf13/pflag#155 Add multiline wrapping support
- spf13/pflag#158 doc: clarify difference between string slice vs. array
- spf13/pflag#160 add ability to ignore unknown flags
- spf13/pflag#163 Allow Users To Show Deprecated Flags

Hide [flags] in usage output

Hides the [flags] in the usage output of commands (present in newer
versions of Cobra), using the `.DisableFlagsInUseLine` option.

Before this change:

dockerd --help

Usage: dockerd [OPTIONS] [flags]

A self-sufficient runtime for containers.

After this change:

dockerd --help

Usage: dockerd [OPTIONS]

A self-sufficient runtime for containers.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Â# modified: vendor/github.com/spf13/pflag/string_array.go
§

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2018/05/19 08:19:16
Showing 18 changed files
... ...
@@ -31,6 +31,7 @@ func newDaemonCommand() *cobra.Command {
31 31
 			opts.flags = cmd.Flags()
32 32
 			return runDaemon(opts)
33 33
 		},
34
+		DisableFlagsInUseLine: true,
34 35
 	}
35 36
 	cli.SetupRootCommand(cmd)
36 37
 
... ...
@@ -141,8 +141,8 @@ github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
141 141
 github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
142 142
 
143 143
 # cli
144
-github.com/spf13/cobra v1.5.1 https://github.com/dnephin/cobra.git
145
-github.com/spf13/pflag 9ff6c6923cfffbcd502984b8e0c80539a94968b7
144
+github.com/spf13/cobra v0.0.3
145
+github.com/spf13/pflag v1.0.1
146 146
 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
147 147
 github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.com/ijc25/Gotty
148 148
 
... ...
@@ -8,6 +8,7 @@ Many of the most widely used Go projects are built using Cobra including:
8 8
 * [Hugo](http://gohugo.io)
9 9
 * [rkt](https://github.com/coreos/rkt)
10 10
 * [etcd](https://github.com/coreos/etcd)
11
+* [Moby (former Docker)](https://github.com/moby/moby)
11 12
 * [Docker (distribution)](https://github.com/docker/distribution)
12 13
 * [OpenShift](https://www.openshift.com/)
13 14
 * [Delve](https://github.com/derekparker/delve)
... ...
@@ -15,16 +16,37 @@ Many of the most widely used Go projects are built using Cobra including:
15 15
 * [CockroachDB](http://www.cockroachlabs.com/)
16 16
 * [Bleve](http://www.blevesearch.com/)
17 17
 * [ProjectAtomic (enterprise)](http://www.projectatomic.io/)
18
-* [Parse (CLI)](https://parse.com/)
19 18
 * [GiantSwarm's swarm](https://github.com/giantswarm/cli)
20 19
 * [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
21
-
20
+* [rclone](http://rclone.org/)
21
+* [nehm](https://github.com/bogem/nehm)
22
+* [Pouch](https://github.com/alibaba/pouch)
22 23
 
23 24
 [![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra)
24 25
 [![CircleCI status](https://circleci.com/gh/spf13/cobra.png?circle-token=:circle-token "CircleCI status")](https://circleci.com/gh/spf13/cobra)
25
-[![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra) 
26
-
27
-![cobra](https://cloud.githubusercontent.com/assets/173412/10911369/84832a8e-8212-11e5-9f82-cc96660a4794.gif)
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)
28 49
 
29 50
 # Overview
30 51
 
... ...
@@ -39,27 +61,16 @@ Cobra provides:
39 39
 * Fully POSIX-compliant flags (including short & long versions)
40 40
 * Nested subcommands
41 41
 * Global, local and cascading flags
42
-* Easy generation of applications & commands with `cobra create appname` & `cobra add cmdname`
42
+* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname`
43 43
 * Intelligent suggestions (`app srver`... did you mean `app server`?)
44 44
 * Automatic help generation for commands and flags
45
-* Automatic detailed help for `app help [command]`
46 45
 * Automatic help flag recognition of `-h`, `--help`, etc.
47 46
 * Automatically generated bash autocomplete for your application
48 47
 * Automatically generated man pages for your application
49 48
 * Command aliases so you can change things without breaking them
50
-* The flexibilty to define your own help, usage, etc.
49
+* The flexibility to define your own help, usage, etc.
51 50
 * Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
52 51
 
53
-Cobra has an exceptionally clean interface and simple design without needless
54
-constructors or initialization methods.
55
-
56
-Applications built with Cobra commands are designed to be as user-friendly as
57
-possible. Flags can be placed before or after the command (as long as a
58
-confusing space isn’t provided). Both short and long flags can be used. A
59
-command need not even be fully typed.  Help is automatically generated and
60
-available for the application or for a specific command using either the help
61
-command or the `--help` flag.
62
-
63 52
 # Concepts
64 53
 
65 54
 Cobra is built on a structure of commands, arguments & flags.
... ...
@@ -78,11 +89,11 @@ A few good real world examples may better illustrate this point.
78 78
 
79 79
 In the following example, 'server' is a command, and 'port' is a flag:
80 80
 
81
-    > hugo server --port=1313
81
+    hugo server --port=1313
82 82
 
83 83
 In this command we are telling Git to clone the url bare.
84 84
 
85
-    > git clone URL --bare
85
+    git clone URL --bare
86 86
 
87 87
 ## Commands
88 88
 
... ...
@@ -92,20 +103,11 @@ have children commands and optionally run an action.
92 92
 
93 93
 In the example above, 'server' is the command.
94 94
 
95
-A Command has the following structure:
96
-
97
-```go
98
-type Command struct {
99
-    Use string // The one-line usage message.
100
-    Short string // The short description shown in the 'help' output.
101
-    Long string // The long message shown in the 'help <this-command>' output.
102
-    Run func(cmd *Command, args []string) // Run runs the command.
103
-}
104
-```
95
+[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command)
105 96
 
106 97
 ## Flags
107 98
 
108
-A Flag is a way to modify the behavior of a command. Cobra supports
99
+A flag is a way to modify the behavior of a command. Cobra supports
109 100
 fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
110 101
 A Cobra command can define flags that persist through to children commands
111 102
 and flags that are only available to that command.
... ...
@@ -113,23 +115,15 @@ and flags that are only available to that command.
113 113
 In the example above, 'port' is the flag.
114 114
 
115 115
 Flag functionality is provided by the [pflag
116
-library](https://github.com/ogier/pflag), a fork of the flag standard library
116
+library](https://github.com/spf13/pflag), a fork of the flag standard library
117 117
 which maintains the same interface while adding POSIX compliance.
118 118
 
119
-## Usage
120
-
121
-Cobra works by creating a set of commands and then organizing them into a tree.
122
-The tree defines the structure of the application.
123
-
124
-Once each command is defined with its corresponding flags, then the
125
-tree is assigned to the commander which is finally executed.
126
-
127 119
 # Installing
128 120
 Using Cobra is easy. First, use `go get` to install the latest version
129
-of the library. This command will install the `cobra` generator executible
130
-along with the library:
121
+of the library. This command will install the `cobra` generator executable
122
+along with the library and its dependencies:
131 123
 
132
-    > go get -v github.com/spf13/cobra/cobra
124
+    go get -u github.com/spf13/cobra/cobra
133 125
 
134 126
 Next, include Cobra in your application:
135 127
 
... ...
@@ -139,8 +133,8 @@ import "github.com/spf13/cobra"
139 139
 
140 140
 # Getting Started
141 141
 
142
-While you are welcome to provide your own organization, typically a Cobra based
143
-application will follow the following organizational structure.
142
+While you are welcome to provide your own organization, typically a Cobra-based
143
+application will follow the following organizational structure:
144 144
 
145 145
 ```
146 146
   ▾ appName/
... ...
@@ -152,18 +146,20 @@ application will follow the following organizational structure.
152 152
       main.go
153 153
 ```
154 154
 
155
-In a Cobra app, typically the main.go file is very bare. It serves, one purpose, to initialize Cobra.
155
+In a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra.
156 156
 
157 157
 ```go
158 158
 package main
159 159
 
160
-import "{pathToYourApp}/cmd"
160
+import (
161
+  "fmt"
162
+  "os"
163
+
164
+  "{pathToYourApp}/cmd"
165
+)
161 166
 
162 167
 func main() {
163
-	if err := cmd.RootCmd.Execute(); err != nil {
164
-		fmt.Println(err)
165
-		os.Exit(-1)
166
-	}
168
+  cmd.Execute()
167 169
 }
168 170
 ```
169 171
 
... ...
@@ -172,128 +168,89 @@ func main() {
172 172
 Cobra provides its own program that will create your application and add any
173 173
 commands you want. It's the easiest way to incorporate Cobra into your application.
174 174
 
175
-### cobra init
176
-
177
-The `cobra init [yourApp]` command will create your initial application code
178
-for you. It is a very powerful application that will populate your program with
179
-the right structure so you can immediately enjoy all the benefits of Cobra. It
180
-will also automatically apply the license you specify to your application.
181
-
182
-Cobra init is pretty smart. You can provide it a full path, or simply a path
183
-similar to what is expected in the import.
184
-
185
-```
186
-cobra init github.com/spf13/newAppName
187
-```
188
-
189
-### cobra add
190
-
191
-Once an application is initialized Cobra can create additional commands for you.
192
-Let's say you created an app and you wanted the following commands for it:
193
-
194
-* app serve
195
-* app config
196
-* app config create
197
-
198
-In your project directory (where your main.go file is) you would run the following:
199
-
200
-```
201
-cobra add serve
202
-cobra add config
203
-cobra add create -p 'configCmd'
204
-```
205
-
206
-Once you have run these three commands you would have an app structure that would look like:
207
-
208
-```
209
-  ▾ app/
210
-    ▾ cmd/
211
-        serve.go
212
-        config.go
213
-        create.go
214
-      main.go
215
-```
216
-
217
-at this point you can run `go run main.go` and it would run your app. `go run
218
-main.go serve`, `go run main.go config`, `go run main.go config create` along
219
-with `go run main.go help serve`, etc would all work.
220
-
221
-Obviously you haven't added your own code to these yet, the commands are ready
222
-for you to give them their tasks. Have fun.
223
-
224
-### Configuring the cobra generator
225
-
226
-The cobra generator will be easier to use if you provide a simple configuration
227
-file which will help you eliminate providing a bunch of repeated information in
228
-flags over and over.
229
-
230
-An example ~/.cobra.yaml file:
231
-
232
-```yaml
233
-author: Steve Francia <spf@spf13.com>
234
-license: MIT
235
-```
236
-
237
-You can specify no license by setting `license` to `none` or you can specify
238
-a custom license:
175
+[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it.
239 176
 
240
-```yaml
241
-license:
242
-  header: This file is part of {{ .appName }}.
243
-  text: |
244
-    {{ .copyright }}
177
+## Using the Cobra Library
245 178
 
246
-    This is my license. There are many like it, but this one is mine.
247
-    My license is my best friend. It is my life. I must master it as I must
248
-    master my life.  
249
-```
250
-
251
-## Manually implementing Cobra
252
-
253
-To manually implement cobra you need to create a bare main.go file and a RootCmd file.
179
+To manually implement Cobra you need to create a bare main.go file and a rootCmd file.
254 180
 You will optionally provide additional commands as you see fit.
255 181
 
256
-### Create the root command
257
-
258
-The root command represents your binary itself.
259
-
260
-
261
-#### Manually create rootCmd
182
+### Create rootCmd
262 183
 
263 184
 Cobra doesn't require any special constructors. Simply create your commands.
264 185
 
265 186
 Ideally you place this in app/cmd/root.go:
266 187
 
267 188
 ```go
268
-var RootCmd = &cobra.Command{
269
-	Use:   "hugo",
270
-	Short: "Hugo is a very fast static site generator",
271
-	Long: `A Fast and Flexible Static Site Generator built with
189
+var 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
272 193
                 love by spf13 and friends in Go.
273 194
                 Complete documentation is available at http://hugo.spf13.com`,
274
-	Run: func(cmd *cobra.Command, args []string) {
275
-		// Do Stuff Here
276
-	},
195
+  Run: func(cmd *cobra.Command, args []string) {
196
+    // Do Stuff Here
197
+  },
198
+}
199
+
200
+func Execute() {
201
+  if err := rootCmd.Execute(); err != nil {
202
+    fmt.Println(err)
203
+    os.Exit(1)
204
+  }
277 205
 }
278 206
 ```
279 207
 
280 208
 You will additionally define flags and handle configuration in your init() function.
281 209
 
282
-for example cmd/root.go:
210
+For example cmd/root.go:
283 211
 
284 212
 ```go
213
+import (
214
+  "fmt"
215
+  "os"
216
+
217
+  homedir "github.com/mitchellh/go-homedir"
218
+  "github.com/spf13/cobra"
219
+  "github.com/spf13/viper"
220
+)
221
+
285 222
 func init() {
286
-	cobra.OnInitialize(initConfig)
287
-	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
288
-	RootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
289
-	RootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
290
-	RootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
291
-	RootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
292
-	viper.BindPFlag("author", RootCmd.PersistentFlags().Lookup("author"))
293
-	viper.BindPFlag("projectbase", RootCmd.PersistentFlags().Lookup("projectbase"))
294
-	viper.BindPFlag("useViper", RootCmd.PersistentFlags().Lookup("viper"))
295
-	viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
296
-	viper.SetDefault("license", "apache")
223
+  cobra.OnInitialize(initConfig)
224
+  rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
225
+  rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
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 (can provide `licensetext` in config)")
228
+  rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
229
+  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
230
+  viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
231
+  viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
232
+  viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
233
+  viper.SetDefault("license", "apache")
234
+}
235
+
236
+func initConfig() {
237
+  // Don't forget to read config either from cfgFile or from home directory!
238
+  if cfgFile != "" {
239
+    // Use config file from the flag.
240
+    viper.SetConfigFile(cfgFile)
241
+  } else {
242
+    // Find home directory.
243
+    home, err := homedir.Dir()
244
+    if err != nil {
245
+      fmt.Println(err)
246
+      os.Exit(1)
247
+    }
248
+
249
+    // Search config in home directory with name ".cobra" (without extension).
250
+    viper.AddConfigPath(home)
251
+    viper.SetConfigName(".cobra")
252
+  }
253
+
254
+  if err := viper.ReadInConfig(); err != nil {
255
+    fmt.Println("Can't read config:", err)
256
+    os.Exit(1)
257
+  }
297 258
 }
298 259
 ```
299 260
 
... ...
@@ -307,17 +264,18 @@ In a Cobra app, typically the main.go file is very bare. It serves, one purpose,
307 307
 ```go
308 308
 package main
309 309
 
310
-import "{pathToYourApp}/cmd"
310
+import (
311
+  "fmt"
312
+  "os"
313
+
314
+  "{pathToYourApp}/cmd"
315
+)
311 316
 
312 317
 func main() {
313
-	if err := cmd.RootCmd.Execute(); err != nil {
314
-		fmt.Println(err)
315
-		os.Exit(-1)
316
-	}
318
+  cmd.Execute()
317 319
 }
318 320
 ```
319 321
 
320
-
321 322
 ### Create additional commands
322 323
 
323 324
 Additional commands can be defined and typically are each given their own file
... ...
@@ -330,47 +288,25 @@ populate it with the following:
330 330
 package cmd
331 331
 
332 332
 import (
333
-	"github.com/spf13/cobra"
333
+  "fmt"
334
+
335
+  "github.com/spf13/cobra"
334 336
 )
335 337
 
336 338
 func init() {
337
-	RootCmd.AddCommand(versionCmd)
339
+  rootCmd.AddCommand(versionCmd)
338 340
 }
339 341
 
340 342
 var versionCmd = &cobra.Command{
341
-	Use:   "version",
342
-	Short: "Print the version number of Hugo",
343
-	Long:  `All software has versions. This is Hugo's`,
344
-	Run: func(cmd *cobra.Command, args []string) {
345
-		fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
346
-	},
343
+  Use:   "version",
344
+  Short: "Print the version number of Hugo",
345
+  Long:  `All software has versions. This is Hugo's`,
346
+  Run: func(cmd *cobra.Command, args []string) {
347
+    fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
348
+  },
347 349
 }
348 350
 ```
349 351
 
350
-### Attach command to its parent
351
-
352
-
353
-If you notice in the above example we attach the command to its parent. In
354
-this case the parent is the rootCmd. In this example we are attaching it to the
355
-root, but commands can be attached at any level.
356
-
357
-```go
358
-RootCmd.AddCommand(versionCmd)
359
-```
360
-
361
-### Remove a command from its parent
362
-
363
-Removing a command is not a common action in simple programs, but it allows 3rd
364
-parties to customize an existing command tree.
365
-
366
-In this example, we remove the existing `VersionCmd` command of an existing
367
-root command, and we replace it with our own version:
368
-
369
-```go
370
-mainlib.RootCmd.RemoveCommand(mainlib.VersionCmd)
371
-mainlib.RootCmd.AddCommand(versionCmd)
372
-```
373
-
374 352
 ## Working with Flags
375 353
 
376 354
 Flags provide modifiers to control how the action command operates.
... ...
@@ -395,7 +331,7 @@ command it's assigned to as well as every command under that command. For
395 395
 global flags, assign a flag as a persistent flag on the root.
396 396
 
397 397
 ```go
398
-RootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
398
+rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
399 399
 ```
400 400
 
401 401
 ### Local Flags
... ...
@@ -403,43 +339,81 @@ RootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose out
403 403
 A flag can also be assigned locally which will only apply to that specific command.
404 404
 
405 405
 ```go
406
-RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
406
+rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
407
+```
408
+
409
+### Local Flag on Parent Commands
410
+
411
+By default Cobra only parses local flags on the target command, any local flags on
412
+parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will
413
+parse local flags on each command before executing the target command.
414
+
415
+```go
416
+command := cobra.Command{
417
+  Use: "print [OPTIONS] [COMMANDS]",
418
+  TraverseChildren: true,
419
+}
420
+```
421
+
422
+### Bind Flags with Config
423
+
424
+You can also bind your flags with [viper](https://github.com/spf13/viper):
425
+```go
426
+var author string
427
+
428
+func init() {
429
+  rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
430
+  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
431
+}
407 432
 ```
408 433
 
409
-### Positional Arguments
434
+In this example the persistent flag `author` is bound with `viper`.
435
+**Note**, that the variable `author` will not be set to the value from config,
436
+when the `--author` flag is not provided by user.
437
+
438
+More in [viper documentation](https://github.com/spf13/viper#working-with-flags).
439
+
440
+### Required flags
441
+
442
+Flags are optional by default. If instead you wish your command to report an error
443
+when a flag has not been set, mark it as required:
444
+```go
445
+rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
446
+rootCmd.MarkFlagRequired("region")
447
+```
448
+
449
+## Positional and Custom Arguments
450
+
451
+Validation of positional arguments can be specified using the `Args` field
452
+of `Command`.
410 453
 
411
-Validation of positional arguments can be specified using the `Args` field, which accepts
412
-one of the following values:
454
+The following validators are built in:
413 455
 
414 456
 - `NoArgs` - the command will report an error if there are any positional args.
415 457
 - `ArbitraryArgs` - the command will accept any args.
416
-- `OnlyValidArgs` - the command will report an error if there are any positiona 
417
-  args that are not in the `ValidArgs` list.
418
-- `MinimumNArgs(int)` - the command will report an error if there are not at 
419
-  least N positional args.
420
-- `MaximumNArgs(int)` - the command will report an error if there are more than 
421
-  N positional args.
422
-- `ExactArgs(int)` - the command will report an error if there are not 
423
-  exactly N positional args.
424
-- `RangeArgs(min, max)` - the command will report an error if the number of args 
425
-  is not between the minimum and maximum number of expected args.
426
-
427
-By default, `Args` uses the following legacy behaviour:
428
-- root commands with no subcommands can take arbitrary arguments
429
-- root commands with subcommands will do subcommand validity checking
430
-- subcommands will always accept arbitrary arguments and do no subsubcommand validity checking
458
+- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`.
459
+- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
460
+- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
461
+- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.
462
+- `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.
431 463
 
464
+An example of setting the custom validator:
432 465
 
433 466
 ```go
434
-var HugoCmd = &cobra.Command{
435
-    Use:   "hugo",
436
-    Short: "Hugo is a very fast static site generator",
437
-    ValidArgs: []string{"one", "two"}
438
-    Args: cobra.OnlyValidArgs
439
-    Run: func(cmd *cobra.Command, args []string) {
440
-        // args will only have the values one, two
441
-        // or the cmd.Execute() will fail.
442
-    },
467
+var cmd = &cobra.Command{
468
+  Short: "hello",
469
+  Args: func(cmd *cobra.Command, args []string) error {
470
+    if len(args) < 1 {
471
+      return errors.New("requires at least one arg")
472
+    }
473
+    if myapp.IsValidColor(args[0]) {
474
+      return nil
475
+    }
476
+    return fmt.Errorf("invalid color specified: %s", args[0])
477
+  },
478
+  Run: func(cmd *cobra.Command, args []string) {
479
+    fmt.Println("Hello, World!")
480
+  },
443 481
 }
444 482
 ```
445 483
 
... ...
@@ -458,62 +432,62 @@ More documentation about flags is available at https://github.com/spf13/pflag
458 458
 package main
459 459
 
460 460
 import (
461
-	"fmt"
462
-	"strings"
461
+  "fmt"
462
+  "strings"
463 463
 
464
-	"github.com/spf13/cobra"
464
+  "github.com/spf13/cobra"
465 465
 )
466 466
 
467 467
 func main() {
468
+  var echoTimes int
469
+
470
+  var cmdPrint = &cobra.Command{
471
+    Use:   "print [string to print]",
472
+    Short: "Print anything to the screen",
473
+    Long: `print is for printing anything back to the screen.
474
+For many years people have printed back to the screen.`,
475
+    Args: cobra.MinimumNArgs(1),
476
+    Run: func(cmd *cobra.Command, args []string) {
477
+      fmt.Println("Print: " + strings.Join(args, " "))
478
+    },
479
+  }
480
+
481
+  var cmdEcho = &cobra.Command{
482
+    Use:   "echo [string to echo]",
483
+    Short: "Echo anything to the screen",
484
+    Long: `echo is for echoing anything back.
485
+Echo works a lot like print, except it has a child command.`,
486
+    Args: cobra.MinimumNArgs(1),
487
+    Run: func(cmd *cobra.Command, args []string) {
488
+      fmt.Println("Print: " + strings.Join(args, " "))
489
+    },
490
+  }
491
+
492
+  var cmdTimes = &cobra.Command{
493
+    Use:   "times [# times] [string to echo]",
494
+    Short: "Echo anything to the screen more times",
495
+    Long: `echo things multiple times back to the user by providing
496
+a count and a string.`,
497
+    Args: cobra.MinimumNArgs(1),
498
+    Run: func(cmd *cobra.Command, args []string) {
499
+      for i := 0; i < echoTimes; i++ {
500
+        fmt.Println("Echo: " + strings.Join(args, " "))
501
+      }
502
+    },
503
+  }
468 504
 
469
-	var echoTimes int
470
-
471
-	var cmdPrint = &cobra.Command{
472
-		Use:   "print [string to print]",
473
-		Short: "Print anything to the screen",
474
-		Long: `print is for printing anything back to the screen.
475
-            For many years people have printed back to the screen.
476
-            `,
477
-		Run: func(cmd *cobra.Command, args []string) {
478
-			fmt.Println("Print: " + strings.Join(args, " "))
479
-		},
480
-	}
481
-
482
-	var cmdEcho = &cobra.Command{
483
-		Use:   "echo [string to echo]",
484
-		Short: "Echo anything to the screen",
485
-		Long: `echo is for echoing anything back.
486
-            Echo works a lot like print, except it has a child command.
487
-            `,
488
-		Run: func(cmd *cobra.Command, args []string) {
489
-			fmt.Println("Print: " + strings.Join(args, " "))
490
-		},
491
-	}
492
-
493
-	var cmdTimes = &cobra.Command{
494
-		Use:   "times [# times] [string to echo]",
495
-		Short: "Echo anything to the screen more times",
496
-		Long: `echo things multiple times back to the user by providing
497
-            a count and a string.`,
498
-		Run: func(cmd *cobra.Command, args []string) {
499
-			for i := 0; i < echoTimes; i++ {
500
-				fmt.Println("Echo: " + strings.Join(args, " "))
501
-			}
502
-		},
503
-	}
504
-
505
-	cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")
506
-
507
-	var rootCmd = &cobra.Command{Use: "app"}
508
-	rootCmd.AddCommand(cmdPrint, cmdEcho)
509
-	cmdEcho.AddCommand(cmdTimes)
510
-	rootCmd.Execute()
505
+  cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")
506
+
507
+  var rootCmd = &cobra.Command{Use: "app"}
508
+  rootCmd.AddCommand(cmdPrint, cmdEcho)
509
+  cmdEcho.AddCommand(cmdTimes)
510
+  rootCmd.Execute()
511 511
 }
512 512
 ```
513 513
 
514 514
 For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
515 515
 
516
-## The Help Command
516
+## Help Command
517 517
 
518 518
 Cobra automatically adds a help command to your application when you have subcommands.
519 519
 This will be called when a user runs 'app help'. Additionally, help will also
... ...
@@ -526,60 +500,28 @@ create' is called.  Every command will automatically have the '--help' flag adde
526 526
 The following output is automatically generated by Cobra. Nothing beyond the
527 527
 command and flag definitions are needed.
528 528
 
529
-    > hugo help
530
-
531
-    hugo is the main command, used to build your Hugo site.
529
+    $ cobra help
532 530
 
533
-    Hugo is a Fast and Flexible Static Site Generator
534
-    built with love by spf13 and friends in Go.
535
-
536
-    Complete documentation is available at http://gohugo.io/.
531
+    Cobra is a CLI library for Go that empowers applications.
532
+    This application is a tool to generate the needed files
533
+    to quickly create a Cobra application.
537 534
 
538 535
     Usage:
539
-      hugo [flags]
540
-      hugo [command]
536
+      cobra [command]
541 537
 
542 538
     Available Commands:
543
-      server          Hugo runs its own webserver to render the files
544
-      version         Print the version number of Hugo
545
-      config          Print the site configuration
546
-      check           Check content in the source directory
547
-      benchmark       Benchmark hugo by building a site a number of times.
548
-      convert         Convert your content to different formats
549
-      new             Create new content for your site
550
-      list            Listing out various types of content
551
-      undraft         Undraft changes the content's draft status from 'True' to 'False'
552
-      genautocomplete Generate shell autocompletion script for Hugo
553
-      gendoc          Generate Markdown documentation for the Hugo CLI.
554
-      genman          Generate man page for Hugo
555
-      import          Import your site from others.
539
+      add         Add a command to a Cobra Application
540
+      help        Help about any command
541
+      init        Initialize a Cobra Application
556 542
 
557 543
     Flags:
558
-      -b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
559
-      -D, --buildDrafts[=false]: include content marked as draft
560
-      -F, --buildFuture[=false]: include content with publishdate in the future
561
-          --cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
562
-          --canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
563
-          --config="": config file (default is path/config.yaml|json|toml)
564
-      -d, --destination="": filesystem path to write files to
565
-          --disableRSS[=false]: Do not build RSS files
566
-          --disableSitemap[=false]: Do not build Sitemap file
567
-          --editor="": edit new content with this editor, if provided
568
-          --ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
569
-          --log[=false]: Enable Logging
570
-          --logFile="": Log File path (if set, logging enabled automatically)
571
-          --noTimes[=false]: Don't sync modification time of files
572
-          --pluralizeListTitles[=true]: Pluralize titles in lists using inflect
573
-          --preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
574
-      -s, --source="": filesystem path to read files relative from
575
-          --stepAnalysis[=false]: display memory and timing of different steps of the program
576
-      -t, --theme="": theme to use (located in /themes/THEMENAME/)
577
-          --uglyURLs[=false]: if true, use /filename.html instead of /filename/
578
-      -v, --verbose[=false]: verbose output
579
-          --verboseLog[=false]: verbose logging
580
-      -w, --watch[=false]: watch filesystem for changes and recreate as needed
581
-
582
-    Use "hugo [command] --help" for more information about a command.
544
+      -a, --author string    author name for copyright attribution (default "YOUR NAME")
545
+          --config string    config file (default is $HOME/.cobra.yaml)
546
+      -h, --help             help for cobra
547
+      -l, --license string   name of license for the project
548
+          --viper            use Viper for configuration (default true)
549
+
550
+    Use "cobra [command] --help" for more information about a command.
583 551
 
584 552
 
585 553
 Help is just a command like any other. There is no special logic or behavior
... ...
@@ -587,38 +529,18 @@ around it. In fact, you can provide your own if you want.
587 587
 
588 588
 ### Defining your own help
589 589
 
590
-You can provide your own Help command or your own template for the default command to use.
591
-
592
-The default help command is
593
-
594
-```go
595
-func (c *Command) initHelp() {
596
-	if c.helpCommand == nil {
597
-		c.helpCommand = &Command{
598
-			Use:   "help [command]",
599
-			Short: "Help about any command",
600
-			Long: `Help provides help for any command in the application.
601
-        Simply type ` + c.Name() + ` help [path to command] for full details.`,
602
-			Run: c.HelpFunc(),
603
-		}
604
-	}
605
-	c.AddCommand(c.helpCommand)
606
-}
607
-```
608
-
609
-You can provide your own command, function or template through the following methods:
590
+You can provide your own Help command or your own template for the default command to use
591
+with following functions:
610 592
 
611 593
 ```go
612
-command.SetHelpCommand(cmd *Command)
613
-
614
-command.SetHelpFunc(f func(*Command, []string))
615
-
616
-command.SetHelpTemplate(s string)
594
+cmd.SetHelpCommand(cmd *Command)
595
+cmd.SetHelpFunc(f func(*Command, []string))
596
+cmd.SetHelpTemplate(s string)
617 597
 ```
618 598
 
619 599
 The latter two will also apply to any children commands.
620 600
 
621
-## Usage
601
+## Usage Message
622 602
 
623 603
 When the user provides an invalid flag or invalid command, Cobra responds by
624 604
 showing the user the 'usage'.
... ...
@@ -627,73 +549,44 @@ showing the user the 'usage'.
627 627
 You may recognize this from the help above. That's because the default help
628 628
 embeds the usage as part of its output.
629 629
 
630
+    $ cobra --invalid
631
+    Error: unknown flag: --invalid
630 632
     Usage:
631
-      hugo [flags]
632
-      hugo [command]
633
+      cobra [command]
633 634
 
634 635
     Available Commands:
635
-      server          Hugo runs its own webserver to render the files
636
-      version         Print the version number of Hugo
637
-      config          Print the site configuration
638
-      check           Check content in the source directory
639
-      benchmark       Benchmark hugo by building a site a number of times.
640
-      convert         Convert your content to different formats
641
-      new             Create new content for your site
642
-      list            Listing out various types of content
643
-      undraft         Undraft changes the content's draft status from 'True' to 'False'
644
-      genautocomplete Generate shell autocompletion script for Hugo
645
-      gendoc          Generate Markdown documentation for the Hugo CLI.
646
-      genman          Generate man page for Hugo
647
-      import          Import your site from others.
636
+      add         Add a command to a Cobra Application
637
+      help        Help about any command
638
+      init        Initialize a Cobra Application
648 639
 
649 640
     Flags:
650
-      -b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
651
-      -D, --buildDrafts[=false]: include content marked as draft
652
-      -F, --buildFuture[=false]: include content with publishdate in the future
653
-          --cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
654
-          --canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
655
-          --config="": config file (default is path/config.yaml|json|toml)
656
-      -d, --destination="": filesystem path to write files to
657
-          --disableRSS[=false]: Do not build RSS files
658
-          --disableSitemap[=false]: Do not build Sitemap file
659
-          --editor="": edit new content with this editor, if provided
660
-          --ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
661
-          --log[=false]: Enable Logging
662
-          --logFile="": Log File path (if set, logging enabled automatically)
663
-          --noTimes[=false]: Don't sync modification time of files
664
-          --pluralizeListTitles[=true]: Pluralize titles in lists using inflect
665
-          --preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
666
-      -s, --source="": filesystem path to read files relative from
667
-          --stepAnalysis[=false]: display memory and timing of different steps of the program
668
-      -t, --theme="": theme to use (located in /themes/THEMENAME/)
669
-          --uglyURLs[=false]: if true, use /filename.html instead of /filename/
670
-      -v, --verbose[=false]: verbose output
671
-          --verboseLog[=false]: verbose logging
672
-      -w, --watch[=false]: watch filesystem for changes and recreate as needed
641
+      -a, --author string    author name for copyright attribution (default "YOUR NAME")
642
+          --config string    config file (default is $HOME/.cobra.yaml)
643
+      -h, --help             help for cobra
644
+      -l, --license string   name of license for the project
645
+          --viper            use Viper for configuration (default true)
646
+
647
+    Use "cobra [command] --help" for more information about a command.
673 648
 
674 649
 ### Defining your own usage
675 650
 You can provide your own usage function or template for Cobra to use.
676
-
677
-The default usage function is:
651
+Like help, the function and template are overridable through public methods:
678 652
 
679 653
 ```go
680
-return func(c *Command) error {
681
-	err := tmpl(c.Out(), c.UsageTemplate(), c)
682
-	return err
683
-}
654
+cmd.SetUsageFunc(f func(*Command) error)
655
+cmd.SetUsageTemplate(s string)
684 656
 ```
685 657
 
686
-Like help, the function and template are overridable through public methods:
687
-
688
-```go
689
-command.SetUsageFunc(f func(*Command) error)
658
+## Version Flag
690 659
 
691
-command.SetUsageTemplate(s string)
692
-```
660
+Cobra adds a top-level '--version' flag if the Version field is set on the root command.
661
+Running an application with the '--version' flag will print the version to stdout using
662
+the version template. The template can be customized using the
663
+`cmd.SetVersionTemplate(s string)` function.
693 664
 
694
-## PreRun or PostRun Hooks
665
+## PreRun and PostRun Hooks
695 666
 
696
-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 inherrited by children if they do not declare their own.  These function are run in the following order:
667
+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:
697 668
 
698 669
 - `PersistentPreRun`
699 670
 - `PreRun`
... ...
@@ -707,105 +600,73 @@ An example of two commands which use all of these features is below.  When the s
707 707
 package main
708 708
 
709 709
 import (
710
-	"fmt"
710
+  "fmt"
711 711
 
712
-	"github.com/spf13/cobra"
712
+  "github.com/spf13/cobra"
713 713
 )
714 714
 
715 715
 func main() {
716 716
 
717
-	var rootCmd = &cobra.Command{
718
-		Use:   "root [sub]",
719
-		Short: "My root command",
720
-		PersistentPreRun: func(cmd *cobra.Command, args []string) {
721
-			fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
722
-		},
723
-		PreRun: func(cmd *cobra.Command, args []string) {
724
-			fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
725
-		},
726
-		Run: func(cmd *cobra.Command, args []string) {
727
-			fmt.Printf("Inside rootCmd Run with args: %v\n", args)
728
-		},
729
-		PostRun: func(cmd *cobra.Command, args []string) {
730
-			fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
731
-		},
732
-		PersistentPostRun: func(cmd *cobra.Command, args []string) {
733
-			fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
734
-		},
735
-	}
736
-
737
-	var subCmd = &cobra.Command{
738
-		Use:   "sub [no options!]",
739
-		Short: "My subcommand",
740
-		PreRun: func(cmd *cobra.Command, args []string) {
741
-			fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
742
-		},
743
-		Run: func(cmd *cobra.Command, args []string) {
744
-			fmt.Printf("Inside subCmd Run with args: %v\n", args)
745
-		},
746
-		PostRun: func(cmd *cobra.Command, args []string) {
747
-			fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
748
-		},
749
-		PersistentPostRun: func(cmd *cobra.Command, args []string) {
750
-			fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
751
-		},
752
-	}
753
-
754
-	rootCmd.AddCommand(subCmd)
755
-
756
-	rootCmd.SetArgs([]string{""})
757
-	_ = rootCmd.Execute()
758
-	fmt.Print("\n")
759
-	rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
760
-	_ = rootCmd.Execute()
761
-}
762
-```
763
-
764
-
765
-## Alternative Error Handling
766
-
767
-Cobra also has functions where the return signature is an error. This allows for errors to bubble up to the top,
768
-providing a way to handle the errors in one location. The current list of functions that return an error is:
769
-
770
-* PersistentPreRunE
771
-* PreRunE
772
-* RunE
773
-* PostRunE
774
-* PersistentPostRunE
775
-
776
-If you would like to silence the default `error` and `usage` output in favor of your own, you can set `SilenceUsage`
777
-and `SilenceErrors` to `false` on the command. A child command respects these flags if they are set on the parent
778
-command.
717
+  var rootCmd = &cobra.Command{
718
+    Use:   "root [sub]",
719
+    Short: "My root command",
720
+    PersistentPreRun: func(cmd *cobra.Command, args []string) {
721
+      fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
722
+    },
723
+    PreRun: func(cmd *cobra.Command, args []string) {
724
+      fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
725
+    },
726
+    Run: func(cmd *cobra.Command, args []string) {
727
+      fmt.Printf("Inside rootCmd Run with args: %v\n", args)
728
+    },
729
+    PostRun: func(cmd *cobra.Command, args []string) {
730
+      fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
731
+    },
732
+    PersistentPostRun: func(cmd *cobra.Command, args []string) {
733
+      fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
734
+    },
735
+  }
779 736
 
780
-**Example Usage using RunE:**
737
+  var subCmd = &cobra.Command{
738
+    Use:   "sub [no options!]",
739
+    Short: "My subcommand",
740
+    PreRun: func(cmd *cobra.Command, args []string) {
741
+      fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
742
+    },
743
+    Run: func(cmd *cobra.Command, args []string) {
744
+      fmt.Printf("Inside subCmd Run with args: %v\n", args)
745
+    },
746
+    PostRun: func(cmd *cobra.Command, args []string) {
747
+      fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
748
+    },
749
+    PersistentPostRun: func(cmd *cobra.Command, args []string) {
750
+      fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
751
+    },
752
+  }
781 753
 
782
-```go
783
-package main
754
+  rootCmd.AddCommand(subCmd)
784 755
 
785
-import (
786
-	"errors"
787
-	"log"
756
+  rootCmd.SetArgs([]string{""})
757
+  rootCmd.Execute()
758
+  fmt.Println()
759
+  rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
760
+  rootCmd.Execute()
761
+}
762
+```
788 763
 
789
-	"github.com/spf13/cobra"
790
-)
764
+Output:
765
+```
766
+Inside rootCmd PersistentPreRun with args: []
767
+Inside rootCmd PreRun with args: []
768
+Inside rootCmd Run with args: []
769
+Inside rootCmd PostRun with args: []
770
+Inside rootCmd PersistentPostRun with args: []
791 771
 
792
-func main() {
793
-	var rootCmd = &cobra.Command{
794
-		Use:   "hugo",
795
-		Short: "Hugo is a very fast static site generator",
796
-		Long: `A Fast and Flexible Static Site Generator built with
797
-                love by spf13 and friends in Go.
798
-                Complete documentation is available at http://hugo.spf13.com`,
799
-		RunE: func(cmd *cobra.Command, args []string) error {
800
-			// Do Stuff Here
801
-			return errors.New("some random error")
802
-		},
803
-	}
804
-
805
-	if err := rootCmd.Execute(); err != nil {
806
-		log.Fatal(err)
807
-	}
808
-}
772
+Inside rootCmd PersistentPreRun with args: [arg1 arg2]
773
+Inside subCmd PreRun with args: [arg1 arg2]
774
+Inside subCmd Run with args: [arg1 arg2]
775
+Inside subCmd PostRun with args: [arg1 arg2]
776
+Inside subCmd PersistentPostRun with args: [arg1 arg2]
809 777
 ```
810 778
 
811 779
 ## Suggestions when "unknown command" happens
... ...
@@ -848,81 +709,28 @@ Did you mean this?
848 848
 Run 'kubectl help' for usage.
849 849
 ```
850 850
 
851
-## Generating Markdown-formatted documentation for your command
852
-
853
-Cobra can generate a Markdown-formatted document based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Markdown Docs](doc/md_docs.md).
851
+## Generating documentation for your command
854 852
 
855
-## Generating man pages for your command
853
+Cobra can generate documentation based on subcommands, flags, etc. in the following formats:
856 854
 
857
-Cobra can generate a man page based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Man Docs](doc/man_docs.md).
855
+- [Markdown](doc/md_docs.md)
856
+- [ReStructured Text](doc/rest_docs.md)
857
+- [Man Page](doc/man_docs.md)
858 858
 
859
-## Generating bash completions for your command
859
+## Generating bash completions
860 860
 
861 861
 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).
862 862
 
863
-## Debugging
864
-
865
-Cobra provides a ‘DebugFlags’ method on a command which, when called, will print
866
-out everything Cobra knows about the flags for each command.
867
-
868
-### Example
869
-
870
-```go
871
-command.DebugFlags()
872
-```
873
-
874
-## Release Notes
875
-* **0.9.0** June 17, 2014
876
-  * flags can appears anywhere in the args (provided they are unambiguous)
877
-  * --help prints usage screen for app or command
878
-  * Prefix matching for commands
879
-  * Cleaner looking help and usage output
880
-  * Extensive test suite
881
-* **0.8.0** Nov 5, 2013
882
-  * Reworked interface to remove commander completely
883
-  * Command now primary structure
884
-  * No initialization needed
885
-  * Usage & Help templates & functions definable at any level
886
-  * Updated Readme
887
-* **0.7.0** Sept 24, 2013
888
-  * Needs more eyes
889
-  * Test suite
890
-  * Support for automatic error messages
891
-  * Support for help command
892
-  * Support for printing to any io.Writer instead of os.Stderr
893
-  * Support for persistent flags which cascade down tree
894
-  * Ready for integration into Hugo
895
-* **0.1.0** Sept 3, 2013
896
-  * Implement first draft
897
-
898
-## Extensions
899
-
900
-Libraries for extending Cobra:
901
-
902
-* [cmdns](https://github.com/gosuri/cmdns): Enables name spacing a command's immediate children. It provides an alternative way to structure subcommands, similar to `heroku apps:create` and `ovrclk clusters:launch`.
903
-
904
-## ToDo
905
-* Launch proper documentation site
906
-
907
-## Contributing
863
+# Contributing
908 864
 
909 865
 1. Fork it
910
-2. Create your feature branch (`git checkout -b my-new-feature`)
911
-3. Commit your changes (`git commit -am 'Add some feature'`)
912
-4. Push to the branch (`git push origin my-new-feature`)
913
-5. Create new Pull Request
866
+2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)
867
+3. Create your feature branch (`git checkout -b my-new-feature`)
868
+4. Make changes and add them (`git add .`)
869
+5. Commit your changes (`git commit -m 'Add some feature'`)
870
+6. Push to the branch (`git push origin my-new-feature`)
871
+7. Create new pull request
914 872
 
915
-## Contributors
916
-
917
-Names in no particular order:
918
-
919
-* [spf13](https://github.com/spf13),
920
-[eparis](https://github.com/eparis),
921
-[bep](https://github.com/bep), and many more!
922
-
923
-## License
873
+# License
924 874
 
925 875
 Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
926
-
927
-
928
-[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/spf13/cobra/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
... ...
@@ -16,14 +16,14 @@ func legacyArgs(cmd *Command, args []string) error {
16 16
 		return nil
17 17
 	}
18 18
 
19
-	// root command with subcommands, do subcommand checking
19
+	// root command with subcommands, do subcommand checking.
20 20
 	if !cmd.HasParent() && len(args) > 0 {
21 21
 		return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
22 22
 	}
23 23
 	return nil
24 24
 }
25 25
 
26
-// NoArgs returns an error if any args are included
26
+// NoArgs returns an error if any args are included.
27 27
 func NoArgs(cmd *Command, args []string) error {
28 28
 	if len(args) > 0 {
29 29
 		return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
... ...
@@ -31,7 +31,7 @@ func NoArgs(cmd *Command, args []string) error {
31 31
 	return nil
32 32
 }
33 33
 
34
-// OnlyValidArgs returns an error if any args are not in the list of ValidArgs
34
+// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
35 35
 func OnlyValidArgs(cmd *Command, args []string) error {
36 36
 	if len(cmd.ValidArgs) > 0 {
37 37
 		for _, v := range args {
... ...
@@ -43,21 +43,12 @@ func OnlyValidArgs(cmd *Command, args []string) error {
43 43
 	return nil
44 44
 }
45 45
 
46
-func stringInSlice(a string, list []string) bool {
47
-	for _, b := range list {
48
-		if b == a {
49
-			return true
50
-		}
51
-	}
52
-	return false
53
-}
54
-
55
-// ArbitraryArgs never returns an error
46
+// ArbitraryArgs never returns an error.
56 47
 func ArbitraryArgs(cmd *Command, args []string) error {
57 48
 	return nil
58 49
 }
59 50
 
60
-// MinimumNArgs returns an error if there is not at least N args
51
+// MinimumNArgs returns an error if there is not at least N args.
61 52
 func MinimumNArgs(n int) PositionalArgs {
62 53
 	return func(cmd *Command, args []string) error {
63 54
 		if len(args) < n {
... ...
@@ -67,7 +58,7 @@ func MinimumNArgs(n int) PositionalArgs {
67 67
 	}
68 68
 }
69 69
 
70
-// MaximumNArgs returns an error if there are more than N args
70
+// MaximumNArgs returns an error if there are more than N args.
71 71
 func MaximumNArgs(n int) PositionalArgs {
72 72
 	return func(cmd *Command, args []string) error {
73 73
 		if len(args) > n {
... ...
@@ -77,7 +68,7 @@ func MaximumNArgs(n int) PositionalArgs {
77 77
 	}
78 78
 }
79 79
 
80
-// ExactArgs returns an error if there are not exactly n args 
80
+// ExactArgs returns an error if there are not exactly n args.
81 81
 func ExactArgs(n int) PositionalArgs {
82 82
 	return func(cmd *Command, args []string) error {
83 83
 		if len(args) != n {
... ...
@@ -87,7 +78,7 @@ func ExactArgs(n int) PositionalArgs {
87 87
 	}
88 88
 }
89 89
 
90
-// RangeArgs returns an error if the number of args is not within the expected range 
90
+// RangeArgs returns an error if the number of args is not within the expected range.
91 91
 func RangeArgs(min int, max int) PositionalArgs {
92 92
 	return func(cmd *Command, args []string) error {
93 93
 		if len(args) < min || len(args) > max {
... ...
@@ -1,6 +1,7 @@
1 1
 package cobra
2 2
 
3 3
 import (
4
+	"bytes"
4 5
 	"fmt"
5 6
 	"io"
6 7
 	"os"
... ...
@@ -10,20 +11,18 @@ import (
10 10
 	"github.com/spf13/pflag"
11 11
 )
12 12
 
13
+// Annotations for Bash completion.
13 14
 const (
14
-	BashCompFilenameExt     = "cobra_annotation_bash_completion_filename_extentions"
15
+	BashCompFilenameExt     = "cobra_annotation_bash_completion_filename_extensions"
15 16
 	BashCompCustom          = "cobra_annotation_bash_completion_custom"
16 17
 	BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
17 18
 	BashCompSubdirsInDir    = "cobra_annotation_bash_completion_subdirs_in_dir"
18 19
 )
19 20
 
20
-func preamble(out io.Writer, name string) error {
21
-	_, err := fmt.Fprintf(out, "# bash completion for %-36s -*- shell-script -*-\n", name)
22
-	if err != nil {
23
-		return err
24
-	}
25
-	_, err = fmt.Fprint(out, `
26
-__debug()
21
+func writePreamble(buf *bytes.Buffer, name string) {
22
+	buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
23
+	buf.WriteString(fmt.Sprintf(`
24
+__%[1]s_debug()
27 25
 {
28 26
     if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
29 27
         echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
... ...
@@ -32,13 +31,13 @@ __debug()
32 32
 
33 33
 # Homebrew on Macs have version 1.3 of bash-completion which doesn't include
34 34
 # _init_completion. This is a very minimal version of that function.
35
-__my_init_completion()
35
+__%[1]s_init_completion()
36 36
 {
37 37
     COMPREPLY=()
38 38
     _get_comp_words_by_ref "$@" cur prev words cword
39 39
 }
40 40
 
41
-__index_of_word()
41
+__%[1]s_index_of_word()
42 42
 {
43 43
     local w word=$1
44 44
     shift
... ...
@@ -50,7 +49,7 @@ __index_of_word()
50 50
     index=-1
51 51
 }
52 52
 
53
-__contains_word()
53
+__%[1]s_contains_word()
54 54
 {
55 55
     local w word=$1; shift
56 56
     for w in "$@"; do
... ...
@@ -59,9 +58,9 @@ __contains_word()
59 59
     return 1
60 60
 }
61 61
 
62
-__handle_reply()
62
+__%[1]s_handle_reply()
63 63
 {
64
-    __debug "${FUNCNAME[0]}"
64
+    __%[1]s_debug "${FUNCNAME[0]}"
65 65
     case $cur in
66 66
         -*)
67 67
             if [[ $(type -t compopt) = "builtin" ]]; then
... ...
@@ -86,14 +85,14 @@ __handle_reply()
86 86
 
87 87
                 local index flag
88 88
                 flag="${cur%%=*}"
89
-                __index_of_word "${flag}" "${flags_with_completion[@]}"
89
+                __%[1]s_index_of_word "${flag}" "${flags_with_completion[@]}"
90
+                COMPREPLY=()
90 91
                 if [[ ${index} -ge 0 ]]; then
91
-                    COMPREPLY=()
92 92
                     PREFIX=""
93 93
                     cur="${cur#*=}"
94 94
                     ${flags_completion[${index}]}
95 95
                     if [ -n "${ZSH_VERSION}" ]; then
96
-                        # zfs completion needs --flag= prefix
96
+                        # zsh completion needs --flag= prefix
97 97
                         eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
98 98
                     fi
99 99
                 fi
... ...
@@ -104,7 +103,7 @@ __handle_reply()
104 104
 
105 105
     # check if we are handling a flag with special work handling
106 106
     local index
107
-    __index_of_word "${prev}" "${flags_with_completion[@]}"
107
+    __%[1]s_index_of_word "${prev}" "${flags_with_completion[@]}"
108 108
     if [[ ${index} -ge 0 ]]; then
109 109
         ${flags_completion[${index}]}
110 110
         return
... ...
@@ -133,25 +132,34 @@ __handle_reply()
133 133
         declare -F __custom_func >/dev/null && __custom_func
134 134
     fi
135 135
 
136
-    __ltrim_colon_completions "$cur"
136
+    # available in bash-completion >= 2, not always present on macOS
137
+    if declare -F __ltrim_colon_completions >/dev/null; then
138
+        __ltrim_colon_completions "$cur"
139
+    fi
140
+
141
+    # If there is only 1 completion and it is a flag with an = it will be completed
142
+    # but we don't want a space after the =
143
+    if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
144
+       compopt -o nospace
145
+    fi
137 146
 }
138 147
 
139 148
 # The arguments should be in the form "ext1|ext2|extn"
140
-__handle_filename_extension_flag()
149
+__%[1]s_handle_filename_extension_flag()
141 150
 {
142 151
     local ext="$1"
143 152
     _filedir "@(${ext})"
144 153
 }
145 154
 
146
-__handle_subdirs_in_dir_flag()
155
+__%[1]s_handle_subdirs_in_dir_flag()
147 156
 {
148 157
     local dir="$1"
149 158
     pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
150 159
 }
151 160
 
152
-__handle_flag()
161
+__%[1]s_handle_flag()
153 162
 {
154
-    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
163
+    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
155 164
 
156 165
     # if a command required a flag, and we found it, unset must_have_one_flag()
157 166
     local flagname=${words[c]}
... ...
@@ -162,27 +170,30 @@ __handle_flag()
162 162
         flagname=${flagname%%=*} # strip everything after the =
163 163
         flagname="${flagname}=" # but put the = back
164 164
     fi
165
-    __debug "${FUNCNAME[0]}: looking for ${flagname}"
166
-    if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then
165
+    __%[1]s_debug "${FUNCNAME[0]}: looking for ${flagname}"
166
+    if __%[1]s_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
167 167
         must_have_one_flag=()
168 168
     fi
169 169
 
170 170
     # if you set a flag which only applies to this command, don't show subcommands
171
-    if __contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
171
+    if __%[1]s_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
172 172
       commands=()
173 173
     fi
174 174
 
175 175
     # keep flag value with flagname as flaghash
176
-    if [ -n "${flagvalue}" ] ; then
177
-        flaghash[${flagname}]=${flagvalue}
178
-    elif [ -n "${words[ $((c+1)) ]}" ] ; then
179
-        flaghash[${flagname}]=${words[ $((c+1)) ]}
180
-    else
181
-        flaghash[${flagname}]="true" # pad "true" for bool flag
176
+    # flaghash variable is an associative array which is only supported in bash > 3.
177
+    if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
178
+        if [ -n "${flagvalue}" ] ; then
179
+            flaghash[${flagname}]=${flagvalue}
180
+        elif [ -n "${words[ $((c+1)) ]}" ] ; then
181
+            flaghash[${flagname}]=${words[ $((c+1)) ]}
182
+        else
183
+            flaghash[${flagname}]="true" # pad "true" for bool flag
184
+        fi
182 185
     fi
183 186
 
184 187
     # skip the argument to a two word flag
185
-    if __contains_word "${words[c]}" "${two_word_flags[@]}"; then
188
+    if __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then
186 189
         c=$((c+1))
187 190
         # if we are looking for a flags value, don't show commands
188 191
         if [[ $c -eq $cword ]]; then
... ...
@@ -194,13 +205,13 @@ __handle_flag()
194 194
 
195 195
 }
196 196
 
197
-__handle_noun()
197
+__%[1]s_handle_noun()
198 198
 {
199
-    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
199
+    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
200 200
 
201
-    if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
201
+    if __%[1]s_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
202 202
         must_have_one_noun=()
203
-    elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then
203
+    elif __%[1]s_contains_word "${words[c]}" "${noun_aliases[@]}"; then
204 204
         must_have_one_noun=()
205 205
     fi
206 206
 
... ...
@@ -208,61 +219,66 @@ __handle_noun()
208 208
     c=$((c+1))
209 209
 }
210 210
 
211
-__handle_command()
211
+__%[1]s_handle_command()
212 212
 {
213
-    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
213
+    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
214 214
 
215 215
     local next_command
216 216
     if [[ -n ${last_command} ]]; then
217 217
         next_command="_${last_command}_${words[c]//:/__}"
218 218
     else
219 219
         if [[ $c -eq 0 ]]; then
220
-            next_command="_$(basename "${words[c]//:/__}")"
220
+            next_command="_%[1]s_root_command"
221 221
         else
222 222
             next_command="_${words[c]//:/__}"
223 223
         fi
224 224
     fi
225 225
     c=$((c+1))
226
-    __debug "${FUNCNAME[0]}: looking for ${next_command}"
227
-    declare -F $next_command >/dev/null && $next_command
226
+    __%[1]s_debug "${FUNCNAME[0]}: looking for ${next_command}"
227
+    declare -F "$next_command" >/dev/null && $next_command
228 228
 }
229 229
 
230
-__handle_word()
230
+__%[1]s_handle_word()
231 231
 {
232 232
     if [[ $c -ge $cword ]]; then
233
-        __handle_reply
233
+        __%[1]s_handle_reply
234 234
         return
235 235
     fi
236
-    __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
236
+    __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
237 237
     if [[ "${words[c]}" == -* ]]; then
238
-        __handle_flag
239
-    elif __contains_word "${words[c]}" "${commands[@]}"; then
240
-        __handle_command
241
-    elif [[ $c -eq 0 ]] && __contains_word "$(basename "${words[c]}")" "${commands[@]}"; then
242
-        __handle_command
238
+        __%[1]s_handle_flag
239
+    elif __%[1]s_contains_word "${words[c]}" "${commands[@]}"; then
240
+        __%[1]s_handle_command
241
+    elif [[ $c -eq 0 ]]; then
242
+        __%[1]s_handle_command
243
+    elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then
244
+        # aliashash variable is an associative array which is only supported in bash > 3.
245
+        if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
246
+            words[c]=${aliashash[${words[c]}]}
247
+            __%[1]s_handle_command
248
+        else
249
+            __%[1]s_handle_noun
250
+        fi
243 251
     else
244
-        __handle_noun
252
+        __%[1]s_handle_noun
245 253
     fi
246
-    __handle_word
254
+    __%[1]s_handle_word
247 255
 }
248 256
 
249
-`)
250
-	return err
257
+`, name))
251 258
 }
252 259
 
253
-func postscript(w io.Writer, name string) error {
260
+func writePostscript(buf *bytes.Buffer, name string) {
254 261
 	name = strings.Replace(name, ":", "__", -1)
255
-	_, err := fmt.Fprintf(w, "__start_%s()\n", name)
256
-	if err != nil {
257
-		return err
258
-	}
259
-	_, err = fmt.Fprintf(w, `{
262
+	buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
263
+	buf.WriteString(fmt.Sprintf(`{
260 264
     local cur prev words cword
261 265
     declare -A flaghash 2>/dev/null || :
266
+    declare -A aliashash 2>/dev/null || :
262 267
     if declare -F _init_completion >/dev/null 2>&1; then
263 268
         _init_completion -s || return
264 269
     else
265
-        __my_init_completion -n "=" || return
270
+        __%[1]s_init_completion -n "=" || return
266 271
     fi
267 272
 
268 273
     local c=0
... ...
@@ -271,350 +287,288 @@ func postscript(w io.Writer, name string) error {
271 271
     local local_nonpersistent_flags=()
272 272
     local flags_with_completion=()
273 273
     local flags_completion=()
274
-    local commands=("%s")
274
+    local commands=("%[1]s")
275 275
     local must_have_one_flag=()
276 276
     local must_have_one_noun=()
277 277
     local last_command
278 278
     local nouns=()
279 279
 
280
-    __handle_word
280
+    __%[1]s_handle_word
281 281
 }
282 282
 
283
-`, name)
284
-	if err != nil {
285
-		return err
286
-	}
287
-	_, err = fmt.Fprintf(w, `if [[ $(type -t compopt) = "builtin" ]]; then
283
+`, name))
284
+	buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
288 285
     complete -o default -F __start_%s %s
289 286
 else
290 287
     complete -o default -o nospace -F __start_%s %s
291 288
 fi
292 289
 
293
-`, name, name, name, name)
294
-	if err != nil {
295
-		return err
296
-	}
297
-	_, err = fmt.Fprintf(w, "# ex: ts=4 sw=4 et filetype=sh\n")
298
-	return err
290
+`, name, name, name, name))
291
+	buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
299 292
 }
300 293
 
301
-func writeCommands(cmd *Command, w io.Writer) error {
302
-	if _, err := fmt.Fprintf(w, "    commands=()\n"); err != nil {
303
-		return err
304
-	}
294
+func writeCommands(buf *bytes.Buffer, cmd *Command) {
295
+	buf.WriteString("    commands=()\n")
305 296
 	for _, c := range cmd.Commands() {
306 297
 		if !c.IsAvailableCommand() || c == cmd.helpCommand {
307 298
 			continue
308 299
 		}
309
-		if _, err := fmt.Fprintf(w, "    commands+=(%q)\n", c.Name()); err != nil {
310
-			return err
311
-		}
300
+		buf.WriteString(fmt.Sprintf("    commands+=(%q)\n", c.Name()))
301
+		writeCmdAliases(buf, c)
312 302
 	}
313
-	_, err := fmt.Fprintf(w, "\n")
314
-	return err
303
+	buf.WriteString("\n")
315 304
 }
316 305
 
317
-func writeFlagHandler(name string, annotations map[string][]string, w io.Writer) error {
306
+func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
318 307
 	for key, value := range annotations {
319 308
 		switch key {
320 309
 		case BashCompFilenameExt:
321
-			_, err := fmt.Fprintf(w, "    flags_with_completion+=(%q)\n", name)
322
-			if err != nil {
323
-				return err
324
-			}
310
+			buf.WriteString(fmt.Sprintf("    flags_with_completion+=(%q)\n", name))
325 311
 
312
+			var ext string
326 313
 			if len(value) > 0 {
327
-				ext := "__handle_filename_extension_flag " + strings.Join(value, "|")
328
-				_, err = fmt.Fprintf(w, "    flags_completion+=(%q)\n", ext)
314
+				ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|")
329 315
 			} else {
330
-				ext := "_filedir"
331
-				_, err = fmt.Fprintf(w, "    flags_completion+=(%q)\n", ext)
332
-			}
333
-			if err != nil {
334
-				return err
316
+				ext = "_filedir"
335 317
 			}
318
+			buf.WriteString(fmt.Sprintf("    flags_completion+=(%q)\n", ext))
336 319
 		case BashCompCustom:
337
-			_, err := fmt.Fprintf(w, "    flags_with_completion+=(%q)\n", name)
338
-			if err != nil {
339
-				return err
340
-			}
320
+			buf.WriteString(fmt.Sprintf("    flags_with_completion+=(%q)\n", name))
341 321
 			if len(value) > 0 {
342 322
 				handlers := strings.Join(value, "; ")
343
-				_, err = fmt.Fprintf(w, "    flags_completion+=(%q)\n", handlers)
323
+				buf.WriteString(fmt.Sprintf("    flags_completion+=(%q)\n", handlers))
344 324
 			} else {
345
-				_, err = fmt.Fprintf(w, "    flags_completion+=(:)\n")
346
-			}
347
-			if err != nil {
348
-				return err
325
+				buf.WriteString("    flags_completion+=(:)\n")
349 326
 			}
350 327
 		case BashCompSubdirsInDir:
351
-			_, err := fmt.Fprintf(w, "    flags_with_completion+=(%q)\n", name)
328
+			buf.WriteString(fmt.Sprintf("    flags_with_completion+=(%q)\n", name))
352 329
 
330
+			var ext string
353 331
 			if len(value) == 1 {
354
-				ext := "__handle_subdirs_in_dir_flag " + value[0]
355
-				_, err = fmt.Fprintf(w, "    flags_completion+=(%q)\n", ext)
332
+				ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0]
356 333
 			} else {
357
-				ext := "_filedir -d"
358
-				_, err = fmt.Fprintf(w, "    flags_completion+=(%q)\n", ext)
359
-			}
360
-			if err != nil {
361
-				return err
334
+				ext = "_filedir -d"
362 335
 			}
336
+			buf.WriteString(fmt.Sprintf("    flags_completion+=(%q)\n", ext))
363 337
 		}
364 338
 	}
365
-	return nil
366 339
 }
367 340
 
368
-func writeShortFlag(flag *pflag.Flag, w io.Writer) error {
369
-	b := (len(flag.NoOptDefVal) > 0)
341
+func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
370 342
 	name := flag.Shorthand
371 343
 	format := "    "
372
-	if !b {
344
+	if len(flag.NoOptDefVal) == 0 {
373 345
 		format += "two_word_"
374 346
 	}
375 347
 	format += "flags+=(\"-%s\")\n"
376
-	if _, err := fmt.Fprintf(w, format, name); err != nil {
377
-		return err
378
-	}
379
-	return writeFlagHandler("-"+name, flag.Annotations, w)
348
+	buf.WriteString(fmt.Sprintf(format, name))
349
+	writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
380 350
 }
381 351
 
382
-func writeFlag(flag *pflag.Flag, w io.Writer) error {
383
-	b := (len(flag.NoOptDefVal) > 0)
352
+func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
384 353
 	name := flag.Name
385 354
 	format := "    flags+=(\"--%s"
386
-	if !b {
355
+	if len(flag.NoOptDefVal) == 0 {
387 356
 		format += "="
388 357
 	}
389 358
 	format += "\")\n"
390
-	if _, err := fmt.Fprintf(w, format, name); err != nil {
391
-		return err
392
-	}
393
-	return writeFlagHandler("--"+name, flag.Annotations, w)
359
+	buf.WriteString(fmt.Sprintf(format, name))
360
+	writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
394 361
 }
395 362
 
396
-func writeLocalNonPersistentFlag(flag *pflag.Flag, w io.Writer) error {
397
-	b := (len(flag.NoOptDefVal) > 0)
363
+func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
398 364
 	name := flag.Name
399 365
 	format := "    local_nonpersistent_flags+=(\"--%s"
400
-	if !b {
366
+	if len(flag.NoOptDefVal) == 0 {
401 367
 		format += "="
402 368
 	}
403 369
 	format += "\")\n"
404
-	if _, err := fmt.Fprintf(w, format, name); err != nil {
405
-		return err
406
-	}
407
-	return nil
370
+	buf.WriteString(fmt.Sprintf(format, name))
408 371
 }
409 372
 
410
-func writeFlags(cmd *Command, w io.Writer) error {
411
-	_, err := fmt.Fprintf(w, `    flags=()
373
+func writeFlags(buf *bytes.Buffer, cmd *Command) {
374
+	buf.WriteString(`    flags=()
412 375
     two_word_flags=()
413 376
     local_nonpersistent_flags=()
414 377
     flags_with_completion=()
415 378
     flags_completion=()
416 379
 
417 380
 `)
418
-	if err != nil {
419
-		return err
420
-	}
421 381
 	localNonPersistentFlags := cmd.LocalNonPersistentFlags()
422
-	var visitErr error
423 382
 	cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
424
-		if err := writeFlag(flag, w); err != nil {
425
-			visitErr = err
383
+		if nonCompletableFlag(flag) {
426 384
 			return
427 385
 		}
386
+		writeFlag(buf, flag, cmd)
428 387
 		if len(flag.Shorthand) > 0 {
429
-			if err := writeShortFlag(flag, w); err != nil {
430
-				visitErr = err
431
-				return
432
-			}
388
+			writeShortFlag(buf, flag, cmd)
433 389
 		}
434 390
 		if localNonPersistentFlags.Lookup(flag.Name) != nil {
435
-			if err := writeLocalNonPersistentFlag(flag, w); err != nil {
436
-				visitErr = err
437
-				return
438
-			}
391
+			writeLocalNonPersistentFlag(buf, flag)
439 392
 		}
440 393
 	})
441
-	if visitErr != nil {
442
-		return visitErr
443
-	}
444 394
 	cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
445
-		if err := writeFlag(flag, w); err != nil {
446
-			visitErr = err
395
+		if nonCompletableFlag(flag) {
447 396
 			return
448 397
 		}
398
+		writeFlag(buf, flag, cmd)
449 399
 		if len(flag.Shorthand) > 0 {
450
-			if err := writeShortFlag(flag, w); err != nil {
451
-				visitErr = err
452
-				return
453
-			}
400
+			writeShortFlag(buf, flag, cmd)
454 401
 		}
455 402
 	})
456
-	if visitErr != nil {
457
-		return visitErr
458
-	}
459 403
 
460
-	_, err = fmt.Fprintf(w, "\n")
461
-	return err
404
+	buf.WriteString("\n")
462 405
 }
463 406
 
464
-func writeRequiredFlag(cmd *Command, w io.Writer) error {
465
-	if _, err := fmt.Fprintf(w, "    must_have_one_flag=()\n"); err != nil {
466
-		return err
467
-	}
407
+func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
408
+	buf.WriteString("    must_have_one_flag=()\n")
468 409
 	flags := cmd.NonInheritedFlags()
469
-	var visitErr error
470 410
 	flags.VisitAll(func(flag *pflag.Flag) {
411
+		if nonCompletableFlag(flag) {
412
+			return
413
+		}
471 414
 		for key := range flag.Annotations {
472 415
 			switch key {
473 416
 			case BashCompOneRequiredFlag:
474 417
 				format := "    must_have_one_flag+=(\"--%s"
475
-				b := (flag.Value.Type() == "bool")
476
-				if !b {
418
+				if flag.Value.Type() != "bool" {
477 419
 					format += "="
478 420
 				}
479 421
 				format += "\")\n"
480
-				if _, err := fmt.Fprintf(w, format, flag.Name); err != nil {
481
-					visitErr = err
482
-					return
483
-				}
422
+				buf.WriteString(fmt.Sprintf(format, flag.Name))
484 423
 
485 424
 				if len(flag.Shorthand) > 0 {
486
-					if _, err := fmt.Fprintf(w, "    must_have_one_flag+=(\"-%s\")\n", flag.Shorthand); err != nil {
487
-						visitErr = err
488
-						return
489
-					}
425
+					buf.WriteString(fmt.Sprintf("    must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
490 426
 				}
491 427
 			}
492 428
 		}
493 429
 	})
494
-	return visitErr
495 430
 }
496 431
 
497
-func writeRequiredNouns(cmd *Command, w io.Writer) error {
498
-	if _, err := fmt.Fprintf(w, "    must_have_one_noun=()\n"); err != nil {
499
-		return err
500
-	}
432
+func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
433
+	buf.WriteString("    must_have_one_noun=()\n")
501 434
 	sort.Sort(sort.StringSlice(cmd.ValidArgs))
502 435
 	for _, value := range cmd.ValidArgs {
503
-		if _, err := fmt.Fprintf(w, "    must_have_one_noun+=(%q)\n", value); err != nil {
504
-			return err
505
-		}
436
+		buf.WriteString(fmt.Sprintf("    must_have_one_noun+=(%q)\n", value))
506 437
 	}
507
-	return nil
508 438
 }
509 439
 
510
-func writeArgAliases(cmd *Command, w io.Writer) error {
511
-	if _, err := fmt.Fprintf(w, "    noun_aliases=()\n"); err != nil {
512
-		return err
440
+func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
441
+	if len(cmd.Aliases) == 0 {
442
+		return
513 443
 	}
444
+
445
+	sort.Sort(sort.StringSlice(cmd.Aliases))
446
+
447
+	buf.WriteString(fmt.Sprint(`    if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
448
+	for _, value := range cmd.Aliases {
449
+		buf.WriteString(fmt.Sprintf("        command_aliases+=(%q)\n", value))
450
+		buf.WriteString(fmt.Sprintf("        aliashash[%q]=%q\n", value, cmd.Name()))
451
+	}
452
+	buf.WriteString(`    fi`)
453
+	buf.WriteString("\n")
454
+}
455
+func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
456
+	buf.WriteString("    noun_aliases=()\n")
514 457
 	sort.Sort(sort.StringSlice(cmd.ArgAliases))
515 458
 	for _, value := range cmd.ArgAliases {
516
-		if _, err := fmt.Fprintf(w, "    noun_aliases+=(%q)\n", value); err != nil {
517
-			return err
518
-		}
459
+		buf.WriteString(fmt.Sprintf("    noun_aliases+=(%q)\n", value))
519 460
 	}
520
-	return nil
521 461
 }
522 462
 
523
-func gen(cmd *Command, w io.Writer) error {
463
+func gen(buf *bytes.Buffer, cmd *Command) {
524 464
 	for _, c := range cmd.Commands() {
525 465
 		if !c.IsAvailableCommand() || c == cmd.helpCommand {
526 466
 			continue
527 467
 		}
528
-		if err := gen(c, w); err != nil {
529
-			return err
530
-		}
468
+		gen(buf, c)
531 469
 	}
532 470
 	commandName := cmd.CommandPath()
533 471
 	commandName = strings.Replace(commandName, " ", "_", -1)
534 472
 	commandName = strings.Replace(commandName, ":", "__", -1)
535
-	if _, err := fmt.Fprintf(w, "_%s()\n{\n", commandName); err != nil {
536
-		return err
537
-	}
538
-	if _, err := fmt.Fprintf(w, "    last_command=%q\n", commandName); err != nil {
539
-		return err
540
-	}
541
-	if err := writeCommands(cmd, w); err != nil {
542
-		return err
543
-	}
544
-	if err := writeFlags(cmd, w); err != nil {
545
-		return err
546
-	}
547
-	if err := writeRequiredFlag(cmd, w); err != nil {
548
-		return err
549
-	}
550
-	if err := writeRequiredNouns(cmd, w); err != nil {
551
-		return err
552
-	}
553
-	if err := writeArgAliases(cmd, w); err != nil {
554
-		return err
555
-	}
556
-	if _, err := fmt.Fprintf(w, "}\n\n"); err != nil {
557
-		return err
473
+
474
+	if cmd.Root() == cmd {
475
+		buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName))
476
+	} else {
477
+		buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
558 478
 	}
559
-	return nil
479
+
480
+	buf.WriteString(fmt.Sprintf("    last_command=%q\n", commandName))
481
+	buf.WriteString("\n")
482
+	buf.WriteString("    command_aliases=()\n")
483
+	buf.WriteString("\n")
484
+
485
+	writeCommands(buf, cmd)
486
+	writeFlags(buf, cmd)
487
+	writeRequiredFlag(buf, cmd)
488
+	writeRequiredNouns(buf, cmd)
489
+	writeArgAliases(buf, cmd)
490
+	buf.WriteString("}\n\n")
560 491
 }
561 492
 
562
-func (cmd *Command) GenBashCompletion(w io.Writer) error {
563
-	if err := preamble(w, cmd.Name()); err != nil {
564
-		return err
493
+// GenBashCompletion generates bash completion file and writes to the passed writer.
494
+func (c *Command) GenBashCompletion(w io.Writer) error {
495
+	buf := new(bytes.Buffer)
496
+	writePreamble(buf, c.Name())
497
+	if len(c.BashCompletionFunction) > 0 {
498
+		buf.WriteString(c.BashCompletionFunction + "\n")
565 499
 	}
566
-	if len(cmd.BashCompletionFunction) > 0 {
567
-		if _, err := fmt.Fprintf(w, "%s\n", cmd.BashCompletionFunction); err != nil {
568
-			return err
569
-		}
570
-	}
571
-	if err := gen(cmd, w); err != nil {
572
-		return err
573
-	}
574
-	return postscript(w, cmd.Name())
500
+	gen(buf, c)
501
+	writePostscript(buf, c.Name())
502
+
503
+	_, err := buf.WriteTo(w)
504
+	return err
505
+}
506
+
507
+func nonCompletableFlag(flag *pflag.Flag) bool {
508
+	return flag.Hidden || len(flag.Deprecated) > 0
575 509
 }
576 510
 
577
-func (cmd *Command) GenBashCompletionFile(filename string) error {
511
+// GenBashCompletionFile generates bash completion file.
512
+func (c *Command) GenBashCompletionFile(filename string) error {
578 513
 	outFile, err := os.Create(filename)
579 514
 	if err != nil {
580 515
 		return err
581 516
 	}
582 517
 	defer outFile.Close()
583 518
 
584
-	return cmd.GenBashCompletion(outFile)
519
+	return c.GenBashCompletion(outFile)
585 520
 }
586 521
 
587
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
588
-func (cmd *Command) MarkFlagRequired(name string) error {
589
-	return MarkFlagRequired(cmd.Flags(), name)
522
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
523
+// and causes your command to report an error if invoked without the flag.
524
+func (c *Command) MarkFlagRequired(name string) error {
525
+	return MarkFlagRequired(c.Flags(), name)
590 526
 }
591 527
 
592
-// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
593
-func (cmd *Command) MarkPersistentFlagRequired(name string) error {
594
-	return MarkFlagRequired(cmd.PersistentFlags(), name)
528
+// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
529
+// and causes your command to report an error if invoked without the flag.
530
+func (c *Command) MarkPersistentFlagRequired(name string) error {
531
+	return MarkFlagRequired(c.PersistentFlags(), name)
595 532
 }
596 533
 
597
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
534
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
535
+// and causes your command to report an error if invoked without the flag.
598 536
 func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
599 537
 	return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
600 538
 }
601 539
 
602 540
 // MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
603 541
 // Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
604
-func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error {
605
-	return MarkFlagFilename(cmd.Flags(), name, extensions...)
542
+func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
543
+	return MarkFlagFilename(c.Flags(), name, extensions...)
606 544
 }
607 545
 
608 546
 // MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
609 547
 // Generated bash autocompletion will call the bash function f for the flag.
610
-func (cmd *Command) MarkFlagCustom(name string, f string) error {
611
-	return MarkFlagCustom(cmd.Flags(), name, f)
548
+func (c *Command) MarkFlagCustom(name string, f string) error {
549
+	return MarkFlagCustom(c.Flags(), name, f)
612 550
 }
613 551
 
614 552
 // MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
615 553
 // Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
616
-func (cmd *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
617
-	return MarkFlagFilename(cmd.PersistentFlags(), name, extensions...)
554
+func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
555
+	return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
618 556
 }
619 557
 
620 558
 // MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
... ...
@@ -27,48 +27,60 @@ import (
27 27
 )
28 28
 
29 29
 var templateFuncs = template.FuncMap{
30
-	"trim":               strings.TrimSpace,
31
-	"trimRightSpace":     trimRightSpace,
32
-	"appendIfNotPresent": appendIfNotPresent,
33
-	"rpad":               rpad,
34
-	"gt":                 Gt,
35
-	"eq":                 Eq,
30
+	"trim":                    strings.TrimSpace,
31
+	"trimRightSpace":          trimRightSpace,
32
+	"trimTrailingWhitespaces": trimRightSpace,
33
+	"appendIfNotPresent":      appendIfNotPresent,
34
+	"rpad":                    rpad,
35
+	"gt":                      Gt,
36
+	"eq":                      Eq,
36 37
 }
37 38
 
38 39
 var initializers []func()
39 40
 
40
-// automatic prefix matching can be a dangerous thing to automatically enable in CLI tools.
41
-// Set this to true to enable it
41
+// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
42
+// to automatically enable in CLI tools.
43
+// Set this to true to enable it.
42 44
 var EnablePrefixMatching = false
43 45
 
44
-//EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
45
-//To disable sorting, set it to false.
46
+// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
47
+// To disable sorting, set it to false.
46 48
 var EnableCommandSorting = true
47 49
 
48
-//AddTemplateFunc adds a template function that's available to Usage and Help
49
-//template generation.
50
+// MousetrapHelpText enables an information splash screen on Windows
51
+// if the CLI is started from explorer.exe.
52
+// To disable the mousetrap, just set this variable to blank string ("").
53
+// Works only on Microsoft Windows.
54
+var MousetrapHelpText string = `This is a command line tool.
55
+
56
+You need to open cmd.exe and run it from there.
57
+`
58
+
59
+// AddTemplateFunc adds a template function that's available to Usage and Help
60
+// template generation.
50 61
 func AddTemplateFunc(name string, tmplFunc interface{}) {
51 62
 	templateFuncs[name] = tmplFunc
52 63
 }
53 64
 
54
-//AddTemplateFuncs adds multiple template functions availalble to Usage and
55
-//Help template generation.
65
+// AddTemplateFuncs adds multiple template functions that are available to Usage and
66
+// Help template generation.
56 67
 func AddTemplateFuncs(tmplFuncs template.FuncMap) {
57 68
 	for k, v := range tmplFuncs {
58 69
 		templateFuncs[k] = v
59 70
 	}
60 71
 }
61 72
 
62
-//OnInitialize takes a series of func() arguments and appends them to a slice of func().
73
+// OnInitialize sets the passed functions to be run when each command's
74
+// Execute method is called.
63 75
 func OnInitialize(y ...func()) {
64
-	for _, x := range y {
65
-		initializers = append(initializers, x)
66
-	}
76
+	initializers = append(initializers, y...)
67 77
 }
68 78
 
69
-//Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
70
-//Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
71
-//ints and then compared.
79
+// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
80
+
81
+// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
82
+// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
83
+// ints and then compared.
72 84
 func Gt(a interface{}, b interface{}) bool {
73 85
 	var left, right int64
74 86
 	av := reflect.ValueOf(a)
... ...
@@ -96,7 +108,9 @@ func Gt(a interface{}, b interface{}) bool {
96 96
 	return left > right
97 97
 }
98 98
 
99
-//Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
99
+// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
100
+
101
+// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
100 102
 func Eq(a interface{}, b interface{}) bool {
101 103
 	av := reflect.ValueOf(a)
102 104
 	bv := reflect.ValueOf(b)
... ...
@@ -116,7 +130,9 @@ func trimRightSpace(s string) string {
116 116
 	return strings.TrimRightFunc(s, unicode.IsSpace)
117 117
 }
118 118
 
119
-// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s
119
+// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
120
+
121
+// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
120 122
 func appendIfNotPresent(s, stringToAppend string) string {
121 123
 	if strings.Contains(s, stringToAppend) {
122 124
 		return s
... ...
@@ -124,7 +140,7 @@ func appendIfNotPresent(s, stringToAppend string) string {
124 124
 	return s + " " + stringToAppend
125 125
 }
126 126
 
127
-//rpad adds padding to the right of a string
127
+// rpad adds padding to the right of a string.
128 128
 func rpad(s string, padding int) string {
129 129
 	template := fmt.Sprintf("%%-%ds", padding)
130 130
 	return fmt.Sprintf(template, s)
... ...
@@ -138,7 +154,7 @@ func tmpl(w io.Writer, text string, data interface{}) error {
138 138
 	return t.Execute(w, data)
139 139
 }
140 140
 
141
-// ld compares two strings and returns the levenshtein distance between them
141
+// ld compares two strings and returns the levenshtein distance between them.
142 142
 func ld(s, t string, ignoreCase bool) int {
143 143
 	if ignoreCase {
144 144
 		s = strings.ToLower(s)
... ...
@@ -173,3 +189,12 @@ func ld(s, t string, ignoreCase bool) int {
173 173
 	}
174 174
 	return d[len(s)][len(t)]
175 175
 }
176
+
177
+func stringInSlice(a string, list []string) bool {
178
+	for _, b := range list {
179
+		if b == a {
180
+			return true
181
+		}
182
+	}
183
+	return false
184
+}
... ...
@@ -11,8 +11,8 @@
11 11
 // See the License for the specific language governing permissions and
12 12
 // limitations under the License.
13 13
 
14
-//Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
15
-//In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
14
+// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
15
+// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
16 16
 package cobra
17 17
 
18 18
 import (
... ...
@@ -27,177 +27,224 @@ import (
27 27
 	flag "github.com/spf13/pflag"
28 28
 )
29 29
 
30
+// FParseErrWhitelist configures Flag parse errors to be ignored
31
+type FParseErrWhitelist flag.ParseErrorsWhitelist
32
+
30 33
 // Command is just that, a command for your application.
31
-// eg.  'go run' ... 'run' is the command. Cobra requires
34
+// E.g.  'go run ...' - 'run' is the command. Cobra requires
32 35
 // you to define the usage and description as part of your command
33 36
 // definition to ensure usability.
34 37
 type Command struct {
35
-	// Name is the command name, usually the executable's name.
36
-	name string
37
-	// The one-line usage message.
38
+	// Use is the one-line usage message.
38 39
 	Use string
39
-	// An array of aliases that can be used instead of the first word in Use.
40
+
41
+	// Aliases is an array of aliases that can be used instead of the first word in Use.
40 42
 	Aliases []string
41
-	// An array of command names for which this command will be suggested - similar to aliases but only suggests.
43
+
44
+	// SuggestFor is an array of command names for which this command will be suggested -
45
+	// similar to aliases but only suggests.
42 46
 	SuggestFor []string
43
-	// The short description shown in the 'help' output.
47
+
48
+	// Short is the short description shown in the 'help' output.
44 49
 	Short string
45
-	// The long message shown in the 'help <this-command>' output.
50
+
51
+	// Long is the long message shown in the 'help <this-command>' output.
46 52
 	Long string
47
-	// Examples of how to use the command
53
+
54
+	// Example is examples of how to use the command.
48 55
 	Example string
49
-	// List of all valid non-flag arguments that are accepted in bash completions
56
+
57
+	// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
50 58
 	ValidArgs []string
51
-	// List of aliases for ValidArgs. These are not suggested to the user in the bash
52
-	// completion, but accepted if entered manually.
53
-	ArgAliases []string
59
+
54 60
 	// Expected arguments
55 61
 	Args PositionalArgs
56
-	// Custom functions used by the bash autocompletion generator
62
+
63
+	// ArgAliases is List of aliases for ValidArgs.
64
+	// These are not suggested to the user in the bash completion,
65
+	// but accepted if entered manually.
66
+	ArgAliases []string
67
+
68
+	// BashCompletionFunction is custom functions used by the bash autocompletion generator.
57 69
 	BashCompletionFunction string
58
-	// Is this command deprecated and should print this string when used?
70
+
71
+	// Deprecated defines, if this command is deprecated and should print this string when used.
59 72
 	Deprecated string
60
-	// Is this command hidden and should NOT show up in the list of available commands?
73
+
74
+	// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
61 75
 	Hidden bool
62
-	// Tags are key/value pairs that can be used by applications to identify or
63
-	// group commands
64
-	Tags map[string]string
65
-	// Full set of flags
66
-	flags *flag.FlagSet
67
-	// Set of flags childrens of this command will inherit
68
-	pflags *flag.FlagSet
69
-	// Flags that are declared specifically by this command (not inherited).
70
-	lflags *flag.FlagSet
71
-	// SilenceErrors is an option to quiet errors down stream
72
-	SilenceErrors bool
73
-	// Silence Usage is an option to silence usage when an error occurs.
74
-	SilenceUsage bool
76
+
77
+	// Annotations are key/value pairs that can be used by applications to identify or
78
+	// group commands.
79
+	Annotations map[string]string
80
+
81
+	// Version defines the version for this command. If this value is non-empty and the command does not
82
+	// define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
83
+	// will print content of the "Version" variable.
84
+	Version string
85
+
75 86
 	// The *Run functions are executed in the following order:
76 87
 	//   * PersistentPreRun()
77 88
 	//   * PreRun()
78 89
 	//   * Run()
79 90
 	//   * PostRun()
80 91
 	//   * PersistentPostRun()
81
-	// All functions get the same args, the arguments after the command name
82
-	// PersistentPreRun: children of this command will inherit and execute
92
+	// All functions get the same args, the arguments after the command name.
93
+	//
94
+	// PersistentPreRun: children of this command will inherit and execute.
83 95
 	PersistentPreRun func(cmd *Command, args []string)
84
-	// PersistentPreRunE: PersistentPreRun but returns an error
96
+	// PersistentPreRunE: PersistentPreRun but returns an error.
85 97
 	PersistentPreRunE func(cmd *Command, args []string) error
86 98
 	// PreRun: children of this command will not inherit.
87 99
 	PreRun func(cmd *Command, args []string)
88
-	// PreRunE: PreRun but returns an error
100
+	// PreRunE: PreRun but returns an error.
89 101
 	PreRunE func(cmd *Command, args []string) error
90
-	// Run: Typically the actual work function. Most commands will only implement this
102
+	// Run: Typically the actual work function. Most commands will only implement this.
91 103
 	Run func(cmd *Command, args []string)
92
-	// RunE: Run but returns an error
104
+	// RunE: Run but returns an error.
93 105
 	RunE func(cmd *Command, args []string) error
94 106
 	// PostRun: run after the Run command.
95 107
 	PostRun func(cmd *Command, args []string)
96
-	// PostRunE: PostRun but returns an error
108
+	// PostRunE: PostRun but returns an error.
97 109
 	PostRunE func(cmd *Command, args []string) error
98
-	// PersistentPostRun: children of this command will inherit and execute after PostRun
110
+	// PersistentPostRun: children of this command will inherit and execute after PostRun.
99 111
 	PersistentPostRun func(cmd *Command, args []string)
100
-	// PersistentPostRunE: PersistentPostRun but returns an error
112
+	// PersistentPostRunE: PersistentPostRun but returns an error.
101 113
 	PersistentPostRunE func(cmd *Command, args []string) error
102
-	// DisableAutoGenTag remove
114
+
115
+	// SilenceErrors is an option to quiet errors down stream.
116
+	SilenceErrors bool
117
+
118
+	// SilenceUsage is an option to silence usage when an error occurs.
119
+	SilenceUsage bool
120
+
121
+	// DisableFlagParsing disables the flag parsing.
122
+	// If this is true all flags will be passed to the command as arguments.
123
+	DisableFlagParsing bool
124
+
125
+	// DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
126
+	// will be printed by generating docs for this command.
103 127
 	DisableAutoGenTag bool
104
-	// Commands is the list of commands supported by this program.
128
+
129
+	// DisableFlagsInUseLine will disable the addition of [flags] to the usage
130
+	// line of a command when printing help or generating docs
131
+	DisableFlagsInUseLine bool
132
+
133
+	// DisableSuggestions disables the suggestions based on Levenshtein distance
134
+	// that go along with 'unknown command' messages.
135
+	DisableSuggestions bool
136
+	// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
137
+	// Must be > 0.
138
+	SuggestionsMinimumDistance int
139
+
140
+	// TraverseChildren parses flags on all parents before executing child command.
141
+	TraverseChildren bool
142
+
143
+	//FParseErrWhitelist flag parse errors to be ignored
144
+	FParseErrWhitelist FParseErrWhitelist
145
+
146
+	// commands is the list of commands supported by this program.
105 147
 	commands []*Command
106
-	// Parent Command for this command
148
+	// parent is a parent command for this command.
107 149
 	parent *Command
108
-	// max lengths of commands' string lengths for use in padding
150
+	// Max lengths of commands' string lengths for use in padding.
109 151
 	commandsMaxUseLen         int
110 152
 	commandsMaxCommandPathLen int
111 153
 	commandsMaxNameLen        int
112
-	// is commands slice are sorted or not
154
+	// commandsAreSorted defines, if command slice are sorted or not.
113 155
 	commandsAreSorted bool
156
+	// commandCalledAs is the name or alias value used to call this command.
157
+	commandCalledAs struct {
158
+		name   string
159
+		called bool
160
+	}
114 161
 
162
+	// args is actual args parsed from flags.
163
+	args []string
164
+	// flagErrorBuf contains all error messages from pflag.
115 165
 	flagErrorBuf *bytes.Buffer
116
-
117
-	args          []string             // actual args parsed from flags
118
-	output        *io.Writer           // nil means stderr; use Out() method instead
119
-	usageFunc     func(*Command) error // Usage can be defined by application
120
-	usageTemplate string               // Can be defined by Application
121
-	flagErrorFunc func(*Command, error) error
122
-	helpTemplate  string                   // Can be defined by Application
123
-	helpFunc      func(*Command, []string) // Help can be defined by application
124
-	helpCommand   *Command                 // The help command
125
-	// The global normalization function that we can use on every pFlag set and children commands
166
+	// flags is full set of flags.
167
+	flags *flag.FlagSet
168
+	// pflags contains persistent flags.
169
+	pflags *flag.FlagSet
170
+	// lflags contains local flags.
171
+	lflags *flag.FlagSet
172
+	// iflags contains inherited flags.
173
+	iflags *flag.FlagSet
174
+	// parentsPflags is all persistent flags of cmd's parents.
175
+	parentsPflags *flag.FlagSet
176
+	// globNormFunc is the global normalization function
177
+	// that we can use on every pflag set and children commands
126 178
 	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
127 179
 
128
-	// Disable the suggestions based on Levenshtein distance that go along with 'unknown command' messages
129
-	DisableSuggestions bool
130
-	// If displaying suggestions, allows to set the minimum levenshtein distance to display, must be > 0
131
-	SuggestionsMinimumDistance int
132
-
133
-	// Disable the flag parsing. If this is true all flags will be passed to the command as arguments.
134
-	DisableFlagParsing bool
135
-
136
-	// TraverseChildren parses flags on all parents before executing child command
137
-	TraverseChildren bool
138
-}
139
-
140
-// os.Args[1:] by default, if desired, can be overridden
180
+	// output is an output writer defined by user.
181
+	output io.Writer
182
+	// usageFunc is usage func defined by user.
183
+	usageFunc func(*Command) error
184
+	// usageTemplate is usage template defined by user.
185
+	usageTemplate string
186
+	// flagErrorFunc is func defined by user and it's called when the parsing of
187
+	// flags returns an error.
188
+	flagErrorFunc func(*Command, error) error
189
+	// helpTemplate is help template defined by user.
190
+	helpTemplate string
191
+	// helpFunc is help func defined by user.
192
+	helpFunc func(*Command, []string)
193
+	// helpCommand is command with usage 'help'. If it's not defined by user,
194
+	// cobra uses default help command.
195
+	helpCommand *Command
196
+	// versionTemplate is the version template defined by user.
197
+	versionTemplate string
198
+}
199
+
200
+// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
141 201
 // particularly useful when testing.
142 202
 func (c *Command) SetArgs(a []string) {
143 203
 	c.args = a
144 204
 }
145 205
 
146
-func (c *Command) getOut(def io.Writer) io.Writer {
147
-	if c.output != nil {
148
-		return *c.output
149
-	}
150
-
151
-	if c.HasParent() {
152
-		return c.parent.Out()
153
-	}
154
-	return def
155
-}
156
-
157
-func (c *Command) Out() io.Writer {
158
-	return c.getOut(os.Stderr)
159
-}
160
-
161
-func (c *Command) getOutOrStdout() io.Writer {
162
-	return c.getOut(os.Stdout)
163
-}
164
-
165 206
 // SetOutput sets the destination for usage and error messages.
166 207
 // If output is nil, os.Stderr is used.
167 208
 func (c *Command) SetOutput(output io.Writer) {
168
-	c.output = &output
209
+	c.output = output
169 210
 }
170 211
 
171
-// Usage can be defined by application
212
+// SetUsageFunc sets usage function. Usage can be defined by application.
172 213
 func (c *Command) SetUsageFunc(f func(*Command) error) {
173 214
 	c.usageFunc = f
174 215
 }
175 216
 
176
-// Can be defined by Application
217
+// SetUsageTemplate sets usage template. Can be defined by Application.
177 218
 func (c *Command) SetUsageTemplate(s string) {
178 219
 	c.usageTemplate = s
179 220
 }
180 221
 
181 222
 // SetFlagErrorFunc sets a function to generate an error when flag parsing
182
-// fails
223
+// fails.
183 224
 func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
184 225
 	c.flagErrorFunc = f
185 226
 }
186 227
 
187
-// Can be defined by Application
228
+// SetHelpFunc sets help function. Can be defined by Application.
188 229
 func (c *Command) SetHelpFunc(f func(*Command, []string)) {
189 230
 	c.helpFunc = f
190 231
 }
191 232
 
233
+// SetHelpCommand sets help command.
192 234
 func (c *Command) SetHelpCommand(cmd *Command) {
193 235
 	c.helpCommand = cmd
194 236
 }
195 237
 
196
-// Can be defined by Application
238
+// SetHelpTemplate sets help template to be used. Application can use it to set custom template.
197 239
 func (c *Command) SetHelpTemplate(s string) {
198 240
 	c.helpTemplate = s
199 241
 }
200 242
 
243
+// SetVersionTemplate sets version template to be used. Application can use it to set custom template.
244
+func (c *Command) SetVersionTemplate(s string) {
245
+	c.versionTemplate = s
246
+}
247
+
201 248
 // SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
202 249
 // The user should not have a cyclic dependency on commands.
203 250
 func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
... ...
@@ -210,41 +257,88 @@ func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string
210 210
 	}
211 211
 }
212 212
 
213
+// OutOrStdout returns output to stdout.
214
+func (c *Command) OutOrStdout() io.Writer {
215
+	return c.getOut(os.Stdout)
216
+}
217
+
218
+// OutOrStderr returns output to stderr
219
+func (c *Command) OutOrStderr() io.Writer {
220
+	return c.getOut(os.Stderr)
221
+}
222
+
223
+func (c *Command) getOut(def io.Writer) io.Writer {
224
+	if c.output != nil {
225
+		return c.output
226
+	}
227
+	if c.HasParent() {
228
+		return c.parent.getOut(def)
229
+	}
230
+	return def
231
+}
232
+
233
+// UsageFunc returns either the function set by SetUsageFunc for this command
234
+// or a parent, or it returns a default usage function.
213 235
 func (c *Command) UsageFunc() (f func(*Command) error) {
214 236
 	if c.usageFunc != nil {
215 237
 		return c.usageFunc
216 238
 	}
217
-
218 239
 	if c.HasParent() {
219
-		return c.parent.UsageFunc()
240
+		return c.Parent().UsageFunc()
220 241
 	}
221 242
 	return func(c *Command) error {
222
-		err := tmpl(c.Out(), c.UsageTemplate(), c)
243
+		c.mergePersistentFlags()
244
+		err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c)
223 245
 		if err != nil {
224
-			fmt.Print(err)
246
+			c.Println(err)
225 247
 		}
226 248
 		return err
227 249
 	}
228 250
 }
229 251
 
252
+// Usage puts out the usage for the command.
253
+// Used when a user provides invalid input.
254
+// Can be defined by user by overriding UsageFunc.
255
+func (c *Command) Usage() error {
256
+	return c.UsageFunc()(c)
257
+}
258
+
230 259
 // HelpFunc returns either the function set by SetHelpFunc for this command
231
-// or a parent, or it returns a function which calls c.Help()
260
+// or a parent, or it returns a function with default help behavior.
232 261
 func (c *Command) HelpFunc() func(*Command, []string) {
233
-	cmd := c
234
-	for cmd != nil {
235
-		if cmd.helpFunc != nil {
236
-			return cmd.helpFunc
237
-		}
238
-		cmd = cmd.parent
262
+	if c.helpFunc != nil {
263
+		return c.helpFunc
239 264
 	}
240
-	return func(*Command, []string) {
241
-		err := c.Help()
265
+	if c.HasParent() {
266
+		return c.Parent().HelpFunc()
267
+	}
268
+	return func(c *Command, a []string) {
269
+		c.mergePersistentFlags()
270
+		err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
242 271
 		if err != nil {
243 272
 			c.Println(err)
244 273
 		}
245 274
 	}
246 275
 }
247 276
 
277
+// Help puts out the help for the command.
278
+// Used when a user calls help [command].
279
+// Can be defined by user by overriding HelpFunc.
280
+func (c *Command) Help() error {
281
+	c.HelpFunc()(c, []string{})
282
+	return nil
283
+}
284
+
285
+// UsageString return usage string.
286
+func (c *Command) UsageString() string {
287
+	tmpOutput := c.output
288
+	bb := new(bytes.Buffer)
289
+	c.SetOutput(bb)
290
+	c.Usage()
291
+	c.output = tmpOutput
292
+	return bb.String()
293
+}
294
+
248 295
 // FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
249 296
 // command or a parent, or it returns a function which returns the original
250 297
 // error.
... ...
@@ -263,6 +357,7 @@ func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
263 263
 
264 264
 var minUsagePadding = 25
265 265
 
266
+// UsagePadding return padding for the usage.
266 267
 func (c *Command) UsagePadding() int {
267 268
 	if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
268 269
 		return minUsagePadding
... ...
@@ -272,7 +367,7 @@ func (c *Command) UsagePadding() int {
272 272
 
273 273
 var minCommandPathPadding = 11
274 274
 
275
-//
275
+// CommandPathPadding return padding for the command path.
276 276
 func (c *Command) CommandPathPadding() int {
277 277
 	if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
278 278
 		return minCommandPathPadding
... ...
@@ -282,6 +377,7 @@ func (c *Command) CommandPathPadding() int {
282 282
 
283 283
 var minNamePadding = 11
284 284
 
285
+// NamePadding returns padding for the name.
285 286
 func (c *Command) NamePadding() int {
286 287
 	if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
287 288
 		return minNamePadding
... ...
@@ -289,6 +385,7 @@ func (c *Command) NamePadding() int {
289 289
 	return c.parent.commandsMaxNameLen
290 290
 }
291 291
 
292
+// UsageTemplate returns usage template for the command.
292 293
 func (c *Command) UsageTemplate() string {
293 294
 	if c.usageTemplate != "" {
294 295
 		return c.usageTemplate
... ...
@@ -298,32 +395,32 @@ func (c *Command) UsageTemplate() string {
298 298
 		return c.parent.UsageTemplate()
299 299
 	}
300 300
 	return `Usage:{{if .Runnable}}
301
-  {{if .HasAvailableFlags}}{{appendIfNotPresent .UseLine "[flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
302
-  {{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}}
301
+  {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
302
+  {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
303 303
 
304 304
 Aliases:
305
-  {{.NameAndAliases}}
306
-{{end}}{{if .HasExample}}
305
+  {{.NameAndAliases}}{{end}}{{if .HasExample}}
307 306
 
308 307
 Examples:
309
-{{ .Example }}{{end}}{{ if .HasAvailableSubCommands}}
308
+{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
310 309
 
311
-Available Commands:{{range .Commands}}{{if .IsAvailableCommand}}
312
-  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasAvailableLocalFlags}}
310
+Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
311
+  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
313 312
 
314 313
 Flags:
315
-{{.LocalFlags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasAvailableInheritedFlags}}
314
+{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
316 315
 
317 316
 Global Flags:
318
-{{.InheritedFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasHelpSubCommands}}
317
+{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
319 318
 
320
-Additional help topics:{{range .Commands}}{{if .IsHelpCommand}}
321
-  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasAvailableSubCommands }}
319
+Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
320
+  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
322 321
 
323 322
 Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
324 323
 `
325 324
 }
326 325
 
326
+// HelpTemplate return help template for the command.
327 327
 func (c *Command) HelpTemplate() string {
328 328
 	if c.helpTemplate != "" {
329 329
 		return c.helpTemplate
... ...
@@ -332,72 +429,76 @@ func (c *Command) HelpTemplate() string {
332 332
 	if c.HasParent() {
333 333
 		return c.parent.HelpTemplate()
334 334
 	}
335
-	return `{{with or .Long .Short }}{{. | trim}}
335
+	return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}
336 336
 
337 337
 {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
338 338
 }
339 339
 
340
-// Really only used when casting a command to a commander
341
-func (c *Command) resetChildrensParents() {
342
-	for _, x := range c.commands {
343
-		x.parent = c
340
+// VersionTemplate return version template for the command.
341
+func (c *Command) VersionTemplate() string {
342
+	if c.versionTemplate != "" {
343
+		return c.versionTemplate
344
+	}
345
+
346
+	if c.HasParent() {
347
+		return c.parent.VersionTemplate()
344 348
 	}
349
+	return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}}
350
+`
345 351
 }
346 352
 
347
-// Test if the named flag is a boolean flag.
348
-func isBooleanFlag(name string, f *flag.FlagSet) bool {
349
-	flag := f.Lookup(name)
353
+func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
354
+	flag := fs.Lookup(name)
350 355
 	if flag == nil {
351 356
 		return false
352 357
 	}
353
-	return flag.Value.Type() == "bool"
358
+	return flag.NoOptDefVal != ""
354 359
 }
355 360
 
356
-// Test if the named flag is a boolean flag.
357
-func isBooleanShortFlag(name string, f *flag.FlagSet) bool {
358
-	result := false
359
-	f.VisitAll(func(f *flag.Flag) {
360
-		if f.Shorthand == name && f.Value.Type() == "bool" {
361
-			result = true
362
-		}
363
-	})
364
-	return result
361
+func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
362
+	if len(name) == 0 {
363
+		return false
364
+	}
365
+
366
+	flag := fs.ShorthandLookup(name[:1])
367
+	if flag == nil {
368
+		return false
369
+	}
370
+	return flag.NoOptDefVal != ""
365 371
 }
366 372
 
367 373
 func stripFlags(args []string, c *Command) []string {
368
-	if len(args) < 1 {
374
+	if len(args) == 0 {
369 375
 		return args
370 376
 	}
371 377
 	c.mergePersistentFlags()
372 378
 
373 379
 	commands := []string{}
380
+	flags := c.Flags()
374 381
 
375
-	inQuote := false
376
-	inFlag := false
377
-	for _, y := range args {
378
-		if !inQuote {
379
-			switch {
380
-			case strings.HasPrefix(y, "\""):
381
-				inQuote = true
382
-			case strings.Contains(y, "=\""):
383
-				inQuote = true
384
-			case strings.HasPrefix(y, "--") && !strings.Contains(y, "="):
385
-				// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
386
-				inFlag = !isBooleanFlag(y[2:], c.Flags())
387
-			case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !isBooleanShortFlag(y[1:], c.Flags()):
388
-				inFlag = true
389
-			case inFlag:
390
-				inFlag = false
391
-			case y == "":
392
-				// strip empty commands, as the go tests expect this to be ok....
393
-			case !strings.HasPrefix(y, "-"):
394
-				commands = append(commands, y)
395
-				inFlag = false
382
+Loop:
383
+	for len(args) > 0 {
384
+		s := args[0]
385
+		args = args[1:]
386
+		switch {
387
+		case s == "--":
388
+			// "--" terminates the flags
389
+			break Loop
390
+		case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
391
+			// If '--flag arg' then
392
+			// delete arg from args.
393
+			fallthrough // (do the same as below)
394
+		case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
395
+			// If '-f arg' then
396
+			// delete 'arg' from args or break the loop if len(args) <= 1.
397
+			if len(args) <= 1 {
398
+				break Loop
399
+			} else {
400
+				args = args[1:]
401
+				continue
396 402
 			}
397
-		}
398
-
399
-		if strings.HasSuffix(y, "\"") && !strings.HasSuffix(y, "\\\"") {
400
-			inQuote = false
403
+		case s != "" && !strings.HasPrefix(s, "-"):
404
+			commands = append(commands, s)
401 405
 		}
402 406
 	}
403 407
 
... ...
@@ -449,13 +550,31 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
449 449
 	return commandFound, a, nil
450 450
 }
451 451
 
452
+func (c *Command) findSuggestions(arg string) string {
453
+	if c.DisableSuggestions {
454
+		return ""
455
+	}
456
+	if c.SuggestionsMinimumDistance <= 0 {
457
+		c.SuggestionsMinimumDistance = 2
458
+	}
459
+	suggestionsString := ""
460
+	if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
461
+		suggestionsString += "\n\nDid you mean this?\n"
462
+		for _, s := range suggestions {
463
+			suggestionsString += fmt.Sprintf("\t%v\n", s)
464
+		}
465
+	}
466
+	return suggestionsString
467
+}
468
+
452 469
 func (c *Command) findNext(next string) *Command {
453 470
 	matches := make([]*Command, 0)
454 471
 	for _, cmd := range c.commands {
455 472
 		if cmd.Name() == next || cmd.HasAlias(next) {
473
+			cmd.commandCalledAs.name = next
456 474
 			return cmd
457 475
 		}
458
-		if EnablePrefixMatching && cmd.HasNameOrAliasPrefix(next) {
476
+		if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
459 477
 			matches = append(matches, cmd)
460 478
 		}
461 479
 	}
... ...
@@ -463,6 +582,7 @@ func (c *Command) findNext(next string) *Command {
463 463
 	if len(matches) == 1 {
464 464
 		return matches[0]
465 465
 	}
466
+
466 467
 	return nil
467 468
 }
468 469
 
... ...
@@ -477,11 +597,11 @@ func (c *Command) Traverse(args []string) (*Command, []string, error) {
477 477
 		// A long flag with a space separated value
478 478
 		case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
479 479
 			// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
480
-			inFlag = !isBooleanFlag(arg[2:], c.Flags())
480
+			inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
481 481
 			flags = append(flags, arg)
482 482
 			continue
483 483
 		// A short flag with a space separated value
484
-		case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !isBooleanShortFlag(arg[1:], c.Flags()):
484
+		case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
485 485
 			inFlag = true
486 486
 			flags = append(flags, arg)
487 487
 			continue
... ...
@@ -509,23 +629,7 @@ func (c *Command) Traverse(args []string) (*Command, []string, error) {
509 509
 	return c, args, nil
510 510
 }
511 511
 
512
-func (c *Command) findSuggestions(arg string) string {
513
-	if c.DisableSuggestions {
514
-		return ""
515
-	}
516
-	if c.SuggestionsMinimumDistance <= 0 {
517
-		c.SuggestionsMinimumDistance = 2
518
-	}
519
-	suggestionsString := ""
520
-	if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
521
-		suggestionsString += "\n\nDid you mean this?\n"
522
-		for _, s := range suggestions {
523
-			suggestionsString += fmt.Sprintf("\t%v\n", s)
524
-		}
525
-	}
526
-	return suggestionsString
527
-}
528
-
512
+// SuggestionsFor provides suggestions for the typedName.
529 513
 func (c *Command) SuggestionsFor(typedName string) []string {
530 514
 	suggestions := []string{}
531 515
 	for _, cmd := range c.commands {
... ...
@@ -546,38 +650,24 @@ func (c *Command) SuggestionsFor(typedName string) []string {
546 546
 	return suggestions
547 547
 }
548 548
 
549
+// VisitParents visits all parents of the command and invokes fn on each parent.
549 550
 func (c *Command) VisitParents(fn func(*Command)) {
550
-	var traverse func(*Command) *Command
551
-
552
-	traverse = func(x *Command) *Command {
553
-		if x != c {
554
-			fn(x)
555
-		}
556
-		if x.HasParent() {
557
-			return traverse(x.parent)
558
-		}
559
-		return x
551
+	if c.HasParent() {
552
+		fn(c.Parent())
553
+		c.Parent().VisitParents(fn)
560 554
 	}
561
-	traverse(c)
562 555
 }
563 556
 
557
+// Root finds root command.
564 558
 func (c *Command) Root() *Command {
565
-	var findRoot func(*Command) *Command
566
-
567
-	findRoot = func(x *Command) *Command {
568
-		if x.HasParent() {
569
-			return findRoot(x.parent)
570
-		}
571
-		return x
559
+	if c.HasParent() {
560
+		return c.Parent().Root()
572 561
 	}
573
-
574
-	return findRoot(c)
562
+	return c
575 563
 }
576 564
 
577
-// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
578
-// found during arg parsing. This allows your program to know which args were
579
-// before the -- and which came after. (Description from
580
-// https://godoc.org/github.com/spf13/pflag#FlagSet.ArgsLenAtDash).
565
+// ArgsLenAtDash will return the length of c.Flags().Args at the moment
566
+// when a -- was found during args parsing.
581 567
 func (c *Command) ArgsLenAtDash() int {
582 568
 	return c.Flags().ArgsLenAtDash()
583 569
 }
... ...
@@ -591,24 +681,47 @@ func (c *Command) execute(a []string) (err error) {
591 591
 		c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
592 592
 	}
593 593
 
594
-	// initialize help flag as the last point possible to allow for user
594
+	// initialize help and version flag at the last point possible to allow for user
595 595
 	// overriding
596
-	c.initHelpFlag()
596
+	c.InitDefaultHelpFlag()
597
+	c.InitDefaultVersionFlag()
597 598
 
598 599
 	err = c.ParseFlags(a)
599 600
 	if err != nil {
600 601
 		return c.FlagErrorFunc()(c, err)
601 602
 	}
602
-	// If help is called, regardless of other flags, return we want help
603
+
604
+	// If help is called, regardless of other flags, return we want help.
603 605
 	// Also say we need help if the command isn't runnable.
604 606
 	helpVal, err := c.Flags().GetBool("help")
605 607
 	if err != nil {
606 608
 		// should be impossible to get here as we always declare a help
607
-		// flag in initHelpFlag()
609
+		// flag in InitDefaultHelpFlag()
608 610
 		c.Println("\"help\" flag declared as non-bool. Please correct your code")
609 611
 		return err
610 612
 	}
611
-	if helpVal || !c.Runnable() {
613
+
614
+	if helpVal {
615
+		return flag.ErrHelp
616
+	}
617
+
618
+	// for back-compat, only add version flag behavior if version is defined
619
+	if c.Version != "" {
620
+		versionVal, err := c.Flags().GetBool("version")
621
+		if err != nil {
622
+			c.Println("\"version\" flag declared as non-bool. Please correct your code")
623
+			return err
624
+		}
625
+		if versionVal {
626
+			err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c)
627
+			if err != nil {
628
+				c.Println(err)
629
+			}
630
+			return err
631
+		}
632
+	}
633
+
634
+	if !c.Runnable() {
612 635
 		return flag.ErrHelp
613 636
 	}
614 637
 
... ...
@@ -642,6 +755,9 @@ func (c *Command) execute(a []string) (err error) {
642 642
 		c.PreRun(c, argWoFlags)
643 643
 	}
644 644
 
645
+	if err := c.validateRequiredFlags(); err != nil {
646
+		return err
647
+	}
645 648
 	if c.RunE != nil {
646 649
 		if err := c.RunE(c, argWoFlags); err != nil {
647 650
 			return err
... ...
@@ -677,18 +793,7 @@ func (c *Command) preRun() {
677 677
 	}
678 678
 }
679 679
 
680
-func (c *Command) errorMsgFromParse() string {
681
-	s := c.flagErrorBuf.String()
682
-
683
-	x := strings.Split(s, "\n")
684
-
685
-	if len(x) > 0 {
686
-		return x[0]
687
-	}
688
-	return ""
689
-}
690
-
691
-// Call execute to use the args (os.Args[1:] by default)
680
+// Execute uses the args (os.Args[1:] by default)
692 681
 // and run through the command tree finding appropriate matches
693 682
 // for commands and then corresponding flags.
694 683
 func (c *Command) Execute() error {
... ...
@@ -696,8 +801,8 @@ func (c *Command) Execute() error {
696 696
 	return err
697 697
 }
698 698
 
699
+// ExecuteC executes the command.
699 700
 func (c *Command) ExecuteC() (cmd *Command, err error) {
700
-
701 701
 	// Regardless of what command execute is called on, run on Root only
702 702
 	if c.HasParent() {
703 703
 		return c.Root().ExecuteC()
... ...
@@ -710,7 +815,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
710 710
 
711 711
 	// initialize help as the last point possible to allow for user
712 712
 	// overriding
713
-	c.initHelpCmd()
713
+	c.InitDefaultHelpCmd()
714 714
 
715 715
 	var args []string
716 716
 
... ...
@@ -739,6 +844,11 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
739 739
 		return c, err
740 740
 	}
741 741
 
742
+	cmd.commandCalledAs.called = true
743
+	if cmd.commandCalledAs.name == "" {
744
+		cmd.commandCalledAs.name = cmd.Name()
745
+	}
746
+
742 747
 	err = cmd.execute(flags)
743 748
 	if err != nil {
744 749
 		// Always show help if requested, even if SilenceErrors is in
... ...
@@ -759,9 +869,8 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
759 759
 		if !cmd.SilenceUsage && !c.SilenceUsage {
760 760
 			c.Println(cmd.UsageString())
761 761
 		}
762
-		return cmd, err
763 762
 	}
764
-	return cmd, nil
763
+	return cmd, err
765 764
 }
766 765
 
767 766
 func (c *Command) ValidateArgs(args []string) error {
... ...
@@ -771,49 +880,102 @@ func (c *Command) ValidateArgs(args []string) error {
771 771
 	return c.Args(c, args)
772 772
 }
773 773
 
774
-func (c *Command) initHelpFlag() {
774
+func (c *Command) validateRequiredFlags() error {
775
+	flags := c.Flags()
776
+	missingFlagNames := []string{}
777
+	flags.VisitAll(func(pflag *flag.Flag) {
778
+		requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
779
+		if !found {
780
+			return
781
+		}
782
+		if (requiredAnnotation[0] == "true") && !pflag.Changed {
783
+			missingFlagNames = append(missingFlagNames, pflag.Name)
784
+		}
785
+	})
786
+
787
+	if len(missingFlagNames) > 0 {
788
+		return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missingFlagNames, `", "`))
789
+	}
790
+	return nil
791
+}
792
+
793
+// InitDefaultHelpFlag adds default help flag to c.
794
+// It is called automatically by executing the c or by calling help and usage.
795
+// If c already has help flag, it will do nothing.
796
+func (c *Command) InitDefaultHelpFlag() {
775 797
 	c.mergePersistentFlags()
776 798
 	if c.Flags().Lookup("help") == nil {
777
-		c.Flags().BoolP("help", "h", false, "help for "+c.Name())
799
+		usage := "help for "
800
+		if c.Name() == "" {
801
+			usage += "this command"
802
+		} else {
803
+			usage += c.Name()
804
+		}
805
+		c.Flags().BoolP("help", "h", false, usage)
778 806
 	}
779 807
 }
780 808
 
781
-func (c *Command) initHelpCmd() {
782
-	if c.helpCommand == nil {
783
-		if !c.HasSubCommands() {
784
-			return
809
+// InitDefaultVersionFlag adds default version flag to c.
810
+// It is called automatically by executing the c.
811
+// If c already has a version flag, it will do nothing.
812
+// If c.Version is empty, it will do nothing.
813
+func (c *Command) InitDefaultVersionFlag() {
814
+	if c.Version == "" {
815
+		return
816
+	}
817
+
818
+	c.mergePersistentFlags()
819
+	if c.Flags().Lookup("version") == nil {
820
+		usage := "version for "
821
+		if c.Name() == "" {
822
+			usage += "this command"
823
+		} else {
824
+			usage += c.Name()
785 825
 		}
826
+		c.Flags().Bool("version", false, usage)
827
+	}
828
+}
786 829
 
830
+// InitDefaultHelpCmd adds default help command to c.
831
+// It is called automatically by executing the c or by calling help and usage.
832
+// If c already has help command or c has no subcommands, it will do nothing.
833
+func (c *Command) InitDefaultHelpCmd() {
834
+	if !c.HasSubCommands() {
835
+		return
836
+	}
837
+
838
+	if c.helpCommand == nil {
787 839
 		c.helpCommand = &Command{
788 840
 			Use:   "help [command]",
789 841
 			Short: "Help about any command",
790 842
 			Long: `Help provides help for any command in the application.
791
-    Simply type ` + c.Name() + ` help [path to command] for full details.`,
792
-			PersistentPreRun:  func(cmd *Command, args []string) {},
793
-			PersistentPostRun: func(cmd *Command, args []string) {},
843
+Simply type ` + c.Name() + ` help [path to command] for full details.`,
794 844
 
795 845
 			Run: func(c *Command, args []string) {
796 846
 				cmd, _, e := c.Root().Find(args)
797 847
 				if cmd == nil || e != nil {
798
-					c.Printf("Unknown help topic %#q.", args)
848
+					c.Printf("Unknown help topic %#q\n", args)
799 849
 					c.Root().Usage()
800 850
 				} else {
801
-					helpFunc := cmd.HelpFunc()
802
-					helpFunc(cmd, args)
851
+					cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
852
+					cmd.Help()
803 853
 				}
804 854
 			},
805 855
 		}
806 856
 	}
857
+	c.RemoveCommand(c.helpCommand)
807 858
 	c.AddCommand(c.helpCommand)
808 859
 }
809 860
 
810
-// Used for testing
861
+// ResetCommands delete parent, subcommand and help command from c.
811 862
 func (c *Command) ResetCommands() {
863
+	c.parent = nil
812 864
 	c.commands = nil
813 865
 	c.helpCommand = nil
866
+	c.parentsPflags = nil
814 867
 }
815 868
 
816
-// Sorts commands by their names
869
+// Sorts commands by their names.
817 870
 type commandSorterByName []*Command
818 871
 
819 872
 func (c commandSorterByName) Len() int           { return len(c) }
... ...
@@ -893,72 +1055,48 @@ main:
893 893
 	}
894 894
 }
895 895
 
896
-// Print is a convenience method to Print to the defined output
896
+// Print is a convenience method to Print to the defined output, fallback to Stderr if not set.
897 897
 func (c *Command) Print(i ...interface{}) {
898
-	fmt.Fprint(c.Out(), i...)
898
+	fmt.Fprint(c.OutOrStderr(), i...)
899 899
 }
900 900
 
901
-// Println is a convenience method to Println to the defined output
901
+// Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
902 902
 func (c *Command) Println(i ...interface{}) {
903
-	str := fmt.Sprintln(i...)
904
-	c.Print(str)
903
+	c.Print(fmt.Sprintln(i...))
905 904
 }
906 905
 
907
-// Printf is a convenience method to Printf to the defined output
906
+// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
908 907
 func (c *Command) Printf(format string, i ...interface{}) {
909
-	str := fmt.Sprintf(format, i...)
910
-	c.Print(str)
911
-}
912
-
913
-// Output the usage for the command
914
-// Used when a user provides invalid input
915
-// Can be defined by user by overriding UsageFunc
916
-func (c *Command) Usage() error {
917
-	c.mergePersistentFlags()
918
-	err := c.UsageFunc()(c)
919
-	return err
920
-}
921
-
922
-// Output the help for the command
923
-// Used when a user calls help [command]
924
-// by the default HelpFunc in the commander
925
-func (c *Command) Help() error {
926
-	c.mergePersistentFlags()
927
-	err := tmpl(c.getOutOrStdout(), c.HelpTemplate(), c)
928
-	return err
929
-}
930
-
931
-func (c *Command) UsageString() string {
932
-	tmpOutput := c.output
933
-	bb := new(bytes.Buffer)
934
-	c.SetOutput(bb)
935
-	c.Usage()
936
-	c.output = tmpOutput
937
-	return bb.String()
908
+	c.Print(fmt.Sprintf(format, i...))
938 909
 }
939 910
 
940 911
 // CommandPath returns the full path to this command.
941 912
 func (c *Command) CommandPath() string {
942
-	str := c.Name()
943
-	x := c
944
-	for x.HasParent() {
945
-		str = x.parent.Name() + " " + str
946
-		x = x.parent
913
+	if c.HasParent() {
914
+		return c.Parent().CommandPath() + " " + c.Name()
947 915
 	}
948
-	return str
916
+	return c.Name()
949 917
 }
950 918
 
951
-//The full usage for a given command (including parents)
919
+// UseLine puts out the full usage for a given command (including parents).
952 920
 func (c *Command) UseLine() string {
953
-	str := ""
921
+	var useline string
954 922
 	if c.HasParent() {
955
-		str = c.parent.CommandPath() + " "
923
+		useline = c.parent.CommandPath() + " " + c.Use
924
+	} else {
925
+		useline = c.Use
956 926
 	}
957
-	return str + c.Use
927
+	if c.DisableFlagsInUseLine {
928
+		return useline
929
+	}
930
+	if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
931
+		useline += " [flags]"
932
+	}
933
+	return useline
958 934
 }
959 935
 
960
-// For use in determining which flags have been assigned to which commands
961
-// and which persist
936
+// DebugFlags used to determine which flags have been assigned to which commands
937
+// and which persist.
962 938
 func (c *Command) DebugFlags() {
963 939
 	c.Println("DebugFlags called on", c.Name())
964 940
 	var debugflags func(*Command)
... ...
@@ -969,12 +1107,8 @@ func (c *Command) DebugFlags() {
969 969
 		}
970 970
 		if x.HasFlags() {
971 971
 			x.flags.VisitAll(func(f *flag.Flag) {
972
-				if x.HasPersistentFlags() {
973
-					if x.persistentFlag(f.Name) == nil {
974
-						c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
975
-					} else {
976
-						c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [LP]")
977
-					}
972
+				if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {
973
+					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [LP]")
978 974
 				} else {
979 975
 					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
980 976
 				}
... ...
@@ -1004,9 +1138,6 @@ func (c *Command) DebugFlags() {
1004 1004
 
1005 1005
 // Name returns the command's name: the first word in the use line.
1006 1006
 func (c *Command) Name() string {
1007
-	if c.name != "" {
1008
-		return c.name
1009
-	}
1010 1007
 	name := c.Use
1011 1008
 	i := strings.Index(name, " ")
1012 1009
 	if i >= 0 {
... ...
@@ -1025,40 +1156,53 @@ func (c *Command) HasAlias(s string) bool {
1025 1025
 	return false
1026 1026
 }
1027 1027
 
1028
-// HasNameOrAliasPrefix returns true if the Name or any of aliases start
1028
+// CalledAs returns the command name or alias that was used to invoke
1029
+// this command or an empty string if the command has not been called.
1030
+func (c *Command) CalledAs() string {
1031
+	if c.commandCalledAs.called {
1032
+		return c.commandCalledAs.name
1033
+	}
1034
+	return ""
1035
+}
1036
+
1037
+// hasNameOrAliasPrefix returns true if the Name or any of aliases start
1029 1038
 // with prefix
1030
-func (c *Command) HasNameOrAliasPrefix(prefix string) bool {
1039
+func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
1031 1040
 	if strings.HasPrefix(c.Name(), prefix) {
1041
+		c.commandCalledAs.name = c.Name()
1032 1042
 		return true
1033 1043
 	}
1034 1044
 	for _, alias := range c.Aliases {
1035 1045
 		if strings.HasPrefix(alias, prefix) {
1046
+			c.commandCalledAs.name = alias
1036 1047
 			return true
1037 1048
 		}
1038 1049
 	}
1039 1050
 	return false
1040 1051
 }
1041 1052
 
1053
+// NameAndAliases returns a list of the command name and all aliases
1042 1054
 func (c *Command) NameAndAliases() string {
1043 1055
 	return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
1044 1056
 }
1045 1057
 
1058
+// HasExample determines if the command has example.
1046 1059
 func (c *Command) HasExample() bool {
1047 1060
 	return len(c.Example) > 0
1048 1061
 }
1049 1062
 
1050
-// Runnable determines if the command is itself runnable
1063
+// Runnable determines if the command is itself runnable.
1051 1064
 func (c *Command) Runnable() bool {
1052 1065
 	return c.Run != nil || c.RunE != nil
1053 1066
 }
1054 1067
 
1055
-// HasSubCommands determines if the command has children commands
1068
+// HasSubCommands determines if the command has children commands.
1056 1069
 func (c *Command) HasSubCommands() bool {
1057 1070
 	return len(c.commands) > 0
1058 1071
 }
1059 1072
 
1060 1073
 // IsAvailableCommand determines if a command is available as a non-help command
1061
-// (this includes all non deprecated/hidden commands)
1074
+// (this includes all non deprecated/hidden commands).
1062 1075
 func (c *Command) IsAvailableCommand() bool {
1063 1076
 	if len(c.Deprecated) != 0 || c.Hidden {
1064 1077
 		return false
... ...
@@ -1075,11 +1219,12 @@ func (c *Command) IsAvailableCommand() bool {
1075 1075
 	return false
1076 1076
 }
1077 1077
 
1078
-// IsHelpCommand determines if a command is a 'help' command; a help command is
1079
-// determined by the fact that it is NOT runnable/hidden/deprecated, and has no
1080
-// sub commands that are runnable/hidden/deprecated
1081
-func (c *Command) IsHelpCommand() bool {
1082
-
1078
+// IsAdditionalHelpTopicCommand determines if a command is an additional
1079
+// help topic command; additional help topic command is determined by the
1080
+// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that
1081
+// are runnable/hidden/deprecated.
1082
+// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.
1083
+func (c *Command) IsAdditionalHelpTopicCommand() bool {
1083 1084
 	// if a command is runnable, deprecated, or hidden it is not a 'help' command
1084 1085
 	if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
1085 1086
 		return false
... ...
@@ -1087,7 +1232,7 @@ func (c *Command) IsHelpCommand() bool {
1087 1087
 
1088 1088
 	// if any non-help sub commands are found, the command is not a 'help' command
1089 1089
 	for _, sub := range c.commands {
1090
-		if !sub.IsHelpCommand() {
1090
+		if !sub.IsAdditionalHelpTopicCommand() {
1091 1091
 			return false
1092 1092
 		}
1093 1093
 	}
... ...
@@ -1096,14 +1241,13 @@ func (c *Command) IsHelpCommand() bool {
1096 1096
 	return true
1097 1097
 }
1098 1098
 
1099
-// HasHelpSubCommands determines if a command has any avilable 'help' sub commands
1099
+// HasHelpSubCommands determines if a command has any available 'help' sub commands
1100 1100
 // that need to be shown in the usage/help default template under 'additional help
1101
-// topics'
1101
+// topics'.
1102 1102
 func (c *Command) HasHelpSubCommands() bool {
1103
-
1104 1103
 	// return true on the first found available 'help' sub command
1105 1104
 	for _, sub := range c.commands {
1106
-		if sub.IsHelpCommand() {
1105
+		if sub.IsAdditionalHelpTopicCommand() {
1107 1106
 			return true
1108 1107
 		}
1109 1108
 	}
... ...
@@ -1113,9 +1257,8 @@ func (c *Command) HasHelpSubCommands() bool {
1113 1113
 }
1114 1114
 
1115 1115
 // HasAvailableSubCommands determines if a command has available sub commands that
1116
-// need to be shown in the usage/help default template under 'available commands'
1116
+// need to be shown in the usage/help default template under 'available commands'.
1117 1117
 func (c *Command) HasAvailableSubCommands() bool {
1118
-
1119 1118
 	// return true on the first found available (non deprecated/help/hidden)
1120 1119
 	// sub command
1121 1120
 	for _, sub := range c.commands {
... ...
@@ -1124,22 +1267,23 @@ func (c *Command) HasAvailableSubCommands() bool {
1124 1124
 		}
1125 1125
 	}
1126 1126
 
1127
-	// the command either has no sub comamnds, or no available (non deprecated/help/hidden)
1127
+	// the command either has no sub commands, or no available (non deprecated/help/hidden)
1128 1128
 	// sub commands
1129 1129
 	return false
1130 1130
 }
1131 1131
 
1132
-// Determine if the command is a child command
1132
+// HasParent determines if the command is a child command.
1133 1133
 func (c *Command) HasParent() bool {
1134 1134
 	return c.parent != nil
1135 1135
 }
1136 1136
 
1137
-// GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists
1137
+// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist.
1138 1138
 func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
1139 1139
 	return c.globNormFunc
1140 1140
 }
1141 1141
 
1142
-// Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents)
1142
+// Flags returns the complete FlagSet that applies
1143
+// to this command (local and persistent declared here and by all parents).
1143 1144
 func (c *Command) Flags() *flag.FlagSet {
1144 1145
 	if c.flags == nil {
1145 1146
 		c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
... ...
@@ -1148,10 +1292,11 @@ func (c *Command) Flags() *flag.FlagSet {
1148 1148
 		}
1149 1149
 		c.flags.SetOutput(c.flagErrorBuf)
1150 1150
 	}
1151
+
1151 1152
 	return c.flags
1152 1153
 }
1153 1154
 
1154
-// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands
1155
+// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.
1155 1156
 func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
1156 1157
 	persistentFlags := c.PersistentFlags()
1157 1158
 
... ...
@@ -1164,59 +1309,63 @@ func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
1164 1164
 	return out
1165 1165
 }
1166 1166
 
1167
-// Get the local FlagSet specifically set in the current command
1167
+// LocalFlags returns the local FlagSet specifically set in the current command.
1168 1168
 func (c *Command) LocalFlags() *flag.FlagSet {
1169 1169
 	c.mergePersistentFlags()
1170 1170
 
1171
-	local := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1172
-	c.lflags.VisitAll(func(f *flag.Flag) {
1173
-		local.AddFlag(f)
1174
-	})
1175
-	if !c.HasParent() {
1176
-		flag.CommandLine.VisitAll(func(f *flag.Flag) {
1177
-			if local.Lookup(f.Name) == nil {
1178
-				local.AddFlag(f)
1179
-			}
1180
-		})
1171
+	if c.lflags == nil {
1172
+		c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1173
+		if c.flagErrorBuf == nil {
1174
+			c.flagErrorBuf = new(bytes.Buffer)
1175
+		}
1176
+		c.lflags.SetOutput(c.flagErrorBuf)
1177
+	}
1178
+	c.lflags.SortFlags = c.Flags().SortFlags
1179
+	if c.globNormFunc != nil {
1180
+		c.lflags.SetNormalizeFunc(c.globNormFunc)
1181
+	}
1182
+
1183
+	addToLocal := func(f *flag.Flag) {
1184
+		if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
1185
+			c.lflags.AddFlag(f)
1186
+		}
1181 1187
 	}
1182
-	return local
1188
+	c.Flags().VisitAll(addToLocal)
1189
+	c.PersistentFlags().VisitAll(addToLocal)
1190
+	return c.lflags
1183 1191
 }
1184 1192
 
1185
-// All Flags which were inherited from parents commands
1193
+// InheritedFlags returns all flags which were inherited from parents commands.
1186 1194
 func (c *Command) InheritedFlags() *flag.FlagSet {
1187 1195
 	c.mergePersistentFlags()
1188 1196
 
1189
-	inherited := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1190
-	local := c.LocalFlags()
1191
-
1192
-	var rmerge func(x *Command)
1193
-
1194
-	rmerge = func(x *Command) {
1195
-		if x.HasPersistentFlags() {
1196
-			x.PersistentFlags().VisitAll(func(f *flag.Flag) {
1197
-				if inherited.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
1198
-					inherited.AddFlag(f)
1199
-				}
1200
-			})
1201
-		}
1202
-		if x.HasParent() {
1203
-			rmerge(x.parent)
1197
+	if c.iflags == nil {
1198
+		c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1199
+		if c.flagErrorBuf == nil {
1200
+			c.flagErrorBuf = new(bytes.Buffer)
1204 1201
 		}
1202
+		c.iflags.SetOutput(c.flagErrorBuf)
1205 1203
 	}
1206 1204
 
1207
-	if c.HasParent() {
1208
-		rmerge(c.parent)
1205
+	local := c.LocalFlags()
1206
+	if c.globNormFunc != nil {
1207
+		c.iflags.SetNormalizeFunc(c.globNormFunc)
1209 1208
 	}
1210 1209
 
1211
-	return inherited
1210
+	c.parentsPflags.VisitAll(func(f *flag.Flag) {
1211
+		if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
1212
+			c.iflags.AddFlag(f)
1213
+		}
1214
+	})
1215
+	return c.iflags
1212 1216
 }
1213 1217
 
1214
-// All Flags which were not inherited from parent commands
1218
+// NonInheritedFlags returns all flags which were not inherited from parent commands.
1215 1219
 func (c *Command) NonInheritedFlags() *flag.FlagSet {
1216 1220
 	return c.LocalFlags()
1217 1221
 }
1218 1222
 
1219
-// Get the Persistent FlagSet specifically set in the current command
1223
+// PersistentFlags returns the persistent FlagSet specifically set in the current command.
1220 1224
 func (c *Command) PersistentFlags() *flag.FlagSet {
1221 1225
 	if c.pflags == nil {
1222 1226
 		c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
... ...
@@ -1228,7 +1377,7 @@ func (c *Command) PersistentFlags() *flag.FlagSet {
1228 1228
 	return c.pflags
1229 1229
 }
1230 1230
 
1231
-// For use in testing
1231
+// ResetFlags deletes all flags from command.
1232 1232
 func (c *Command) ResetFlags() {
1233 1233
 	c.flagErrorBuf = new(bytes.Buffer)
1234 1234
 	c.flagErrorBuf.Reset()
... ...
@@ -1236,52 +1385,56 @@ func (c *Command) ResetFlags() {
1236 1236
 	c.flags.SetOutput(c.flagErrorBuf)
1237 1237
 	c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1238 1238
 	c.pflags.SetOutput(c.flagErrorBuf)
1239
+
1240
+	c.lflags = nil
1241
+	c.iflags = nil
1242
+	c.parentsPflags = nil
1239 1243
 }
1240 1244
 
1241
-// Does the command contain any flags (local plus persistent from the entire structure)
1245
+// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
1242 1246
 func (c *Command) HasFlags() bool {
1243 1247
 	return c.Flags().HasFlags()
1244 1248
 }
1245 1249
 
1246
-// Does the command contain persistent flags
1250
+// HasPersistentFlags checks if the command contains persistent flags.
1247 1251
 func (c *Command) HasPersistentFlags() bool {
1248 1252
 	return c.PersistentFlags().HasFlags()
1249 1253
 }
1250 1254
 
1251
-// Does the command has flags specifically declared locally
1255
+// HasLocalFlags checks if the command has flags specifically declared locally.
1252 1256
 func (c *Command) HasLocalFlags() bool {
1253 1257
 	return c.LocalFlags().HasFlags()
1254 1258
 }
1255 1259
 
1256
-// Does the command have flags inherited from its parent command
1260
+// HasInheritedFlags checks if the command has flags inherited from its parent command.
1257 1261
 func (c *Command) HasInheritedFlags() bool {
1258 1262
 	return c.InheritedFlags().HasFlags()
1259 1263
 }
1260 1264
 
1261
-// Does the command contain any flags (local plus persistent from the entire
1262
-// structure) which are not hidden or deprecated
1265
+// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire
1266
+// structure) which are not hidden or deprecated.
1263 1267
 func (c *Command) HasAvailableFlags() bool {
1264 1268
 	return c.Flags().HasAvailableFlags()
1265 1269
 }
1266 1270
 
1267
-// Does the command contain persistent flags which are not hidden or deprecated
1271
+// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.
1268 1272
 func (c *Command) HasAvailablePersistentFlags() bool {
1269 1273
 	return c.PersistentFlags().HasAvailableFlags()
1270 1274
 }
1271 1275
 
1272
-// Does the command has flags specifically declared locally which are not hidden
1273
-// or deprecated
1276
+// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden
1277
+// or deprecated.
1274 1278
 func (c *Command) HasAvailableLocalFlags() bool {
1275 1279
 	return c.LocalFlags().HasAvailableFlags()
1276 1280
 }
1277 1281
 
1278
-// Does the command have flags inherited from its parent command which are
1279
-// not hidden or deprecated
1282
+// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are
1283
+// not hidden or deprecated.
1280 1284
 func (c *Command) HasAvailableInheritedFlags() bool {
1281 1285
 	return c.InheritedFlags().HasAvailableFlags()
1282 1286
 }
1283 1287
 
1284
-// Flag climbs up the command tree looking for matching flag
1288
+// Flag climbs up the command tree looking for matching flag.
1285 1289
 func (c *Command) Flag(name string) (flag *flag.Flag) {
1286 1290
 	flag = c.Flags().Lookup(name)
1287 1291
 
... ...
@@ -1292,68 +1445,73 @@ func (c *Command) Flag(name string) (flag *flag.Flag) {
1292 1292
 	return
1293 1293
 }
1294 1294
 
1295
-// recursively find matching persistent flag
1295
+// Recursively find matching persistent flag.
1296 1296
 func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
1297 1297
 	if c.HasPersistentFlags() {
1298 1298
 		flag = c.PersistentFlags().Lookup(name)
1299 1299
 	}
1300 1300
 
1301
-	if flag == nil && c.HasParent() {
1302
-		flag = c.parent.persistentFlag(name)
1301
+	if flag == nil {
1302
+		c.updateParentsPflags()
1303
+		flag = c.parentsPflags.Lookup(name)
1303 1304
 	}
1304 1305
 	return
1305 1306
 }
1306 1307
 
1307
-// ParseFlags parses persistent flag tree & local flags
1308
-func (c *Command) ParseFlags(args []string) (err error) {
1308
+// ParseFlags parses persistent flag tree and local flags.
1309
+func (c *Command) ParseFlags(args []string) error {
1309 1310
 	if c.DisableFlagParsing {
1310 1311
 		return nil
1311 1312
 	}
1313
+
1314
+	if c.flagErrorBuf == nil {
1315
+		c.flagErrorBuf = new(bytes.Buffer)
1316
+	}
1317
+	beforeErrorBufLen := c.flagErrorBuf.Len()
1312 1318
 	c.mergePersistentFlags()
1313
-	err = c.Flags().Parse(args)
1314
-	return
1319
+
1320
+	//do it here after merging all flags and just before parse
1321
+	c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
1322
+
1323
+	err := c.Flags().Parse(args)
1324
+	// Print warnings if they occurred (e.g. deprecated flag messages).
1325
+	if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
1326
+		c.Print(c.flagErrorBuf.String())
1327
+	}
1328
+
1329
+	return err
1315 1330
 }
1316 1331
 
1317
-// Parent returns a commands parent command
1332
+// Parent returns a commands parent command.
1318 1333
 func (c *Command) Parent() *Command {
1319 1334
 	return c.parent
1320 1335
 }
1321 1336
 
1337
+// mergePersistentFlags merges c.PersistentFlags() to c.Flags()
1338
+// and adds missing persistent flags of all parents.
1322 1339
 func (c *Command) mergePersistentFlags() {
1323
-	var rmerge func(x *Command)
1340
+	c.updateParentsPflags()
1341
+	c.Flags().AddFlagSet(c.PersistentFlags())
1342
+	c.Flags().AddFlagSet(c.parentsPflags)
1343
+}
1324 1344
 
1325
-	// Save the set of local flags
1326
-	if c.lflags == nil {
1327
-		c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1328
-		if c.flagErrorBuf == nil {
1329
-			c.flagErrorBuf = new(bytes.Buffer)
1330
-		}
1331
-		c.lflags.SetOutput(c.flagErrorBuf)
1332
-		addtolocal := func(f *flag.Flag) {
1333
-			c.lflags.AddFlag(f)
1334
-		}
1335
-		c.Flags().VisitAll(addtolocal)
1336
-		c.PersistentFlags().VisitAll(addtolocal)
1337
-	}
1338
-	rmerge = func(x *Command) {
1339
-		if !x.HasParent() {
1340
-			flag.CommandLine.VisitAll(func(f *flag.Flag) {
1341
-				if x.PersistentFlags().Lookup(f.Name) == nil {
1342
-					x.PersistentFlags().AddFlag(f)
1343
-				}
1344
-			})
1345
-		}
1346
-		if x.HasPersistentFlags() {
1347
-			x.PersistentFlags().VisitAll(func(f *flag.Flag) {
1348
-				if c.Flags().Lookup(f.Name) == nil {
1349
-					c.Flags().AddFlag(f)
1350
-				}
1351
-			})
1352
-		}
1353
-		if x.HasParent() {
1354
-			rmerge(x.parent)
1355
-		}
1345
+// updateParentsPflags updates c.parentsPflags by adding
1346
+// new persistent flags of all parents.
1347
+// If c.parentsPflags == nil, it makes new.
1348
+func (c *Command) updateParentsPflags() {
1349
+	if c.parentsPflags == nil {
1350
+		c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1351
+		c.parentsPflags.SetOutput(c.flagErrorBuf)
1352
+		c.parentsPflags.SortFlags = false
1356 1353
 	}
1357 1354
 
1358
-	rmerge(c)
1355
+	if c.globNormFunc != nil {
1356
+		c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
1357
+	}
1358
+
1359
+	c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
1360
+
1361
+	c.VisitParents(func(parent *Command) {
1362
+		c.parentsPflags.AddFlagSet(parent.PersistentFlags())
1363
+	})
1359 1364
 }
... ...
@@ -11,14 +11,8 @@ import (
11 11
 
12 12
 var preExecHookFn = preExecHook
13 13
 
14
-// enables an information splash screen on Windows if the CLI is started from explorer.exe.
15
-var MousetrapHelpText string = `This is a command line tool
16
-
17
-You need to open cmd.exe and run it from there.
18
-`
19
-
20 14
 func preExecHook(c *Command) {
21
-	if mousetrap.StartedByExplorer() {
15
+	if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
22 16
 		c.Print(MousetrapHelpText)
23 17
 		time.Sleep(5 * time.Second)
24 18
 		os.Exit(1)
25 19
new file mode 100644
... ...
@@ -0,0 +1,126 @@
0
+package cobra
1
+
2
+import (
3
+	"bytes"
4
+	"fmt"
5
+	"io"
6
+	"os"
7
+	"strings"
8
+)
9
+
10
+// GenZshCompletionFile generates zsh completion file.
11
+func (c *Command) GenZshCompletionFile(filename string) error {
12
+	outFile, err := os.Create(filename)
13
+	if err != nil {
14
+		return err
15
+	}
16
+	defer outFile.Close()
17
+
18
+	return c.GenZshCompletion(outFile)
19
+}
20
+
21
+// GenZshCompletion generates a zsh completion file and writes to the passed writer.
22
+func (c *Command) GenZshCompletion(w io.Writer) error {
23
+	buf := new(bytes.Buffer)
24
+
25
+	writeHeader(buf, c)
26
+	maxDepth := maxDepth(c)
27
+	writeLevelMapping(buf, maxDepth)
28
+	writeLevelCases(buf, maxDepth, c)
29
+
30
+	_, err := buf.WriteTo(w)
31
+	return err
32
+}
33
+
34
+func writeHeader(w io.Writer, cmd *Command) {
35
+	fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name())
36
+}
37
+
38
+func maxDepth(c *Command) int {
39
+	if len(c.Commands()) == 0 {
40
+		return 0
41
+	}
42
+	maxDepthSub := 0
43
+	for _, s := range c.Commands() {
44
+		subDepth := maxDepth(s)
45
+		if subDepth > maxDepthSub {
46
+			maxDepthSub = subDepth
47
+		}
48
+	}
49
+	return 1 + maxDepthSub
50
+}
51
+
52
+func writeLevelMapping(w io.Writer, numLevels int) {
53
+	fmt.Fprintln(w, `_arguments \`)
54
+	for i := 1; i <= numLevels; i++ {
55
+		fmt.Fprintf(w, `  '%d: :->level%d' \`, i, i)
56
+		fmt.Fprintln(w)
57
+	}
58
+	fmt.Fprintf(w, `  '%d: :%s'`, numLevels+1, "_files")
59
+	fmt.Fprintln(w)
60
+}
61
+
62
+func writeLevelCases(w io.Writer, maxDepth int, root *Command) {
63
+	fmt.Fprintln(w, "case $state in")
64
+	defer fmt.Fprintln(w, "esac")
65
+
66
+	for i := 1; i <= maxDepth; i++ {
67
+		fmt.Fprintf(w, "  level%d)\n", i)
68
+		writeLevel(w, root, i)
69
+		fmt.Fprintln(w, "  ;;")
70
+	}
71
+	fmt.Fprintln(w, "  *)")
72
+	fmt.Fprintln(w, "    _arguments '*: :_files'")
73
+	fmt.Fprintln(w, "  ;;")
74
+}
75
+
76
+func writeLevel(w io.Writer, root *Command, i int) {
77
+	fmt.Fprintf(w, "    case $words[%d] in\n", i)
78
+	defer fmt.Fprintln(w, "    esac")
79
+
80
+	commands := filterByLevel(root, i)
81
+	byParent := groupByParent(commands)
82
+
83
+	for p, c := range byParent {
84
+		names := names(c)
85
+		fmt.Fprintf(w, "      %s)\n", p)
86
+		fmt.Fprintf(w, "        _arguments '%d: :(%s)'\n", i, strings.Join(names, " "))
87
+		fmt.Fprintln(w, "      ;;")
88
+	}
89
+	fmt.Fprintln(w, "      *)")
90
+	fmt.Fprintln(w, "        _arguments '*: :_files'")
91
+	fmt.Fprintln(w, "      ;;")
92
+
93
+}
94
+
95
+func filterByLevel(c *Command, l int) []*Command {
96
+	cs := make([]*Command, 0)
97
+	if l == 0 {
98
+		cs = append(cs, c)
99
+		return cs
100
+	}
101
+	for _, s := range c.Commands() {
102
+		cs = append(cs, filterByLevel(s, l-1)...)
103
+	}
104
+	return cs
105
+}
106
+
107
+func groupByParent(commands []*Command) map[string][]*Command {
108
+	m := make(map[string][]*Command)
109
+	for _, c := range commands {
110
+		parent := c.Parent()
111
+		if parent == nil {
112
+			continue
113
+		}
114
+		m[parent.Name()] = append(m[parent.Name()], c)
115
+	}
116
+	return m
117
+}
118
+
119
+func names(commands []*Command) []string {
120
+	ns := make([]string, len(commands))
121
+	for i, c := range commands {
122
+		ns[i] = c.Name()
123
+	}
124
+	return ns
125
+}
... ...
@@ -246,6 +246,25 @@ It is possible to mark a flag as hidden, meaning it will still function as norma
246 246
 flags.MarkHidden("secretFlag")
247 247
 ```
248 248
 
249
+## Disable sorting of flags
250
+`pflag` allows you to disable sorting of flags for help and usage message.
251
+
252
+**Example**:
253
+```go
254
+flags.BoolP("verbose", "v", false, "verbose output")
255
+flags.String("coolflag", "yeaah", "it's really cool flag")
256
+flags.Int("usefulflag", 777, "sometimes it's very useful")
257
+flags.SortFlags = false
258
+flags.PrintDefaults()
259
+```
260
+**Output**:
261
+```
262
+  -v, --verbose           verbose output
263
+      --coolflag string   it's really cool flag (default "yeaah")
264
+      --usefulflag int    sometimes it's very useful (default 777)
265
+```
266
+
267
+
249 268
 ## Supporting Go flags when using pflag
250 269
 In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary
251 270
 to support flags defined by third-party dependencies (e.g. `golang/glog`).
... ...
@@ -270,8 +289,8 @@ func main() {
270 270
 You can see the full reference documentation of the pflag package
271 271
 [at godoc.org][3], or through go's standard documentation system by
272 272
 running `godoc -http=:6060` and browsing to
273
-[http://localhost:6060/pkg/github.com/ogier/pflag][2] after
273
+[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
274 274
 installation.
275 275
 
276
-[2]: http://localhost:6060/pkg/github.com/ogier/pflag
277
-[3]: http://godoc.org/github.com/ogier/pflag
276
+[2]: http://localhost:6060/pkg/github.com/spf13/pflag
277
+[3]: http://godoc.org/github.com/spf13/pflag
278 278
new file mode 100644
... ...
@@ -0,0 +1,105 @@
0
+package pflag
1
+
2
+import (
3
+	"encoding/hex"
4
+	"fmt"
5
+	"strings"
6
+)
7
+
8
+// BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded
9
+type bytesHexValue []byte
10
+
11
+func (bytesHex bytesHexValue) String() string {
12
+	return fmt.Sprintf("%X", []byte(bytesHex))
13
+}
14
+
15
+func (bytesHex *bytesHexValue) Set(value string) error {
16
+	bin, err := hex.DecodeString(strings.TrimSpace(value))
17
+
18
+	if err != nil {
19
+		return err
20
+	}
21
+
22
+	*bytesHex = bin
23
+
24
+	return nil
25
+}
26
+
27
+func (*bytesHexValue) Type() string {
28
+	return "bytesHex"
29
+}
30
+
31
+func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue {
32
+	*p = val
33
+	return (*bytesHexValue)(p)
34
+}
35
+
36
+func bytesHexConv(sval string) (interface{}, error) {
37
+
38
+	bin, err := hex.DecodeString(sval)
39
+
40
+	if err == nil {
41
+		return bin, nil
42
+	}
43
+
44
+	return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
45
+}
46
+
47
+// GetBytesHex return the []byte value of a flag with the given name
48
+func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {
49
+	val, err := f.getFlagType(name, "bytesHex", bytesHexConv)
50
+
51
+	if err != nil {
52
+		return []byte{}, err
53
+	}
54
+
55
+	return val.([]byte), nil
56
+}
57
+
58
+// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
59
+// The argument p points to an []byte variable in which to store the value of the flag.
60
+func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {
61
+	f.VarP(newBytesHexValue(value, p), name, "", usage)
62
+}
63
+
64
+// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
65
+func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
66
+	f.VarP(newBytesHexValue(value, p), name, shorthand, usage)
67
+}
68
+
69
+// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
70
+// The argument p points to an []byte variable in which to store the value of the flag.
71
+func BytesHexVar(p *[]byte, name string, value []byte, usage string) {
72
+	CommandLine.VarP(newBytesHexValue(value, p), name, "", usage)
73
+}
74
+
75
+// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
76
+func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
77
+	CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)
78
+}
79
+
80
+// BytesHex defines an []byte flag with specified name, default value, and usage string.
81
+// The return value is the address of an []byte variable that stores the value of the flag.
82
+func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {
83
+	p := new([]byte)
84
+	f.BytesHexVarP(p, name, "", value, usage)
85
+	return p
86
+}
87
+
88
+// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
89
+func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
90
+	p := new([]byte)
91
+	f.BytesHexVarP(p, name, shorthand, value, usage)
92
+	return p
93
+}
94
+
95
+// BytesHex defines an []byte flag with specified name, default value, and usage string.
96
+// The return value is the address of an []byte variable that stores the value of the flag.
97
+func BytesHex(name string, value []byte, usage string) *[]byte {
98
+	return CommandLine.BytesHexP(name, "", value, usage)
99
+}
100
+
101
+// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
102
+func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
103
+	return CommandLine.BytesHexP(name, shorthand, value, usage)
104
+}
... ...
@@ -11,13 +11,13 @@ func newCountValue(val int, p *int) *countValue {
11 11
 }
12 12
 
13 13
 func (i *countValue) Set(s string) error {
14
-	v, err := strconv.ParseInt(s, 0, 64)
15
-	// -1 means that no specific value was passed, so increment
16
-	if v == -1 {
14
+	// "+1" means that no specific value was passed, so increment
15
+	if s == "+1" {
17 16
 		*i = countValue(*i + 1)
18
-	} else {
19
-		*i = countValue(v)
17
+		return nil
20 18
 	}
19
+	v, err := strconv.ParseInt(s, 0, 0)
20
+	*i = countValue(v)
21 21
 	return err
22 22
 }
23 23
 
... ...
@@ -54,7 +54,7 @@ func (f *FlagSet) CountVar(p *int, name string, usage string) {
54 54
 // CountVarP is like CountVar only take a shorthand for the flag name.
55 55
 func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
56 56
 	flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
57
-	flag.NoOptDefVal = "-1"
57
+	flag.NoOptDefVal = "+1"
58 58
 }
59 59
 
60 60
 // CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
... ...
@@ -83,7 +83,9 @@ func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
83 83
 	return p
84 84
 }
85 85
 
86
-// Count like Count only the flag is placed on the CommandLine isntead of a given flag set
86
+// Count defines a count flag with specified name, default value, and usage string.
87
+// The return value is the address of an int variable that stores the value of the flag.
88
+// A count flag will add 1 to its value evey time it is found on the command line
87 89
 func Count(name string, usage string) *int {
88 90
 	return CommandLine.CountP(name, "", usage)
89 91
 }
90 92
new file mode 100644
... ...
@@ -0,0 +1,128 @@
0
+package pflag
1
+
2
+import (
3
+	"fmt"
4
+	"strings"
5
+	"time"
6
+)
7
+
8
+// -- durationSlice Value
9
+type durationSliceValue struct {
10
+	value   *[]time.Duration
11
+	changed bool
12
+}
13
+
14
+func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue {
15
+	dsv := new(durationSliceValue)
16
+	dsv.value = p
17
+	*dsv.value = val
18
+	return dsv
19
+}
20
+
21
+func (s *durationSliceValue) Set(val string) error {
22
+	ss := strings.Split(val, ",")
23
+	out := make([]time.Duration, len(ss))
24
+	for i, d := range ss {
25
+		var err error
26
+		out[i], err = time.ParseDuration(d)
27
+		if err != nil {
28
+			return err
29
+		}
30
+
31
+	}
32
+	if !s.changed {
33
+		*s.value = out
34
+	} else {
35
+		*s.value = append(*s.value, out...)
36
+	}
37
+	s.changed = true
38
+	return nil
39
+}
40
+
41
+func (s *durationSliceValue) Type() string {
42
+	return "durationSlice"
43
+}
44
+
45
+func (s *durationSliceValue) String() string {
46
+	out := make([]string, len(*s.value))
47
+	for i, d := range *s.value {
48
+		out[i] = fmt.Sprintf("%s", d)
49
+	}
50
+	return "[" + strings.Join(out, ",") + "]"
51
+}
52
+
53
+func durationSliceConv(val string) (interface{}, error) {
54
+	val = strings.Trim(val, "[]")
55
+	// Empty string would cause a slice with one (empty) entry
56
+	if len(val) == 0 {
57
+		return []time.Duration{}, nil
58
+	}
59
+	ss := strings.Split(val, ",")
60
+	out := make([]time.Duration, len(ss))
61
+	for i, d := range ss {
62
+		var err error
63
+		out[i], err = time.ParseDuration(d)
64
+		if err != nil {
65
+			return nil, err
66
+		}
67
+
68
+	}
69
+	return out, nil
70
+}
71
+
72
+// GetDurationSlice returns the []time.Duration value of a flag with the given name
73
+func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) {
74
+	val, err := f.getFlagType(name, "durationSlice", durationSliceConv)
75
+	if err != nil {
76
+		return []time.Duration{}, err
77
+	}
78
+	return val.([]time.Duration), nil
79
+}
80
+
81
+// DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string.
82
+// The argument p points to a []time.Duration variable in which to store the value of the flag.
83
+func (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
84
+	f.VarP(newDurationSliceValue(value, p), name, "", usage)
85
+}
86
+
87
+// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
88
+func (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
89
+	f.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
90
+}
91
+
92
+// DurationSliceVar defines a duration[] flag with specified name, default value, and usage string.
93
+// The argument p points to a duration[] variable in which to store the value of the flag.
94
+func DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
95
+	CommandLine.VarP(newDurationSliceValue(value, p), name, "", usage)
96
+}
97
+
98
+// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
99
+func DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
100
+	CommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
101
+}
102
+
103
+// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
104
+// The return value is the address of a []time.Duration variable that stores the value of the flag.
105
+func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
106
+	p := []time.Duration{}
107
+	f.DurationSliceVarP(&p, name, "", value, usage)
108
+	return &p
109
+}
110
+
111
+// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
112
+func (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
113
+	p := []time.Duration{}
114
+	f.DurationSliceVarP(&p, name, shorthand, value, usage)
115
+	return &p
116
+}
117
+
118
+// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
119
+// The return value is the address of a []time.Duration variable that stores the value of the flag.
120
+func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
121
+	return CommandLine.DurationSliceP(name, "", value, usage)
122
+}
123
+
124
+// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
125
+func DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
126
+	return CommandLine.DurationSliceP(name, shorthand, value, usage)
127
+}
... ...
@@ -16,9 +16,9 @@ pflag is a drop-in replacement of Go's native flag package. If you import
16 16
 pflag under the name "flag" then all code should continue to function
17 17
 with no changes.
18 18
 
19
-	import flag "github.com/ogier/pflag"
19
+	import flag "github.com/spf13/pflag"
20 20
 
21
-	There is one exception to this: if you directly instantiate the Flag struct
21
+There is one exception to this: if you directly instantiate the Flag struct
22 22
 there is one more field "Shorthand" that you will need to set.
23 23
 Most code never instantiates this struct directly, and instead uses
24 24
 functions such as String(), BoolVar(), and Var(), and is therefore
... ...
@@ -101,6 +101,7 @@ package pflag
101 101
 import (
102 102
 	"bytes"
103 103
 	"errors"
104
+	goflag "flag"
104 105
 	"fmt"
105 106
 	"io"
106 107
 	"os"
... ...
@@ -123,6 +124,12 @@ const (
123 123
 	PanicOnError
124 124
 )
125 125
 
126
+// ParseErrorsWhitelist defines the parsing errors that can be ignored
127
+type ParseErrorsWhitelist struct {
128
+	// UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
129
+	UnknownFlags bool
130
+}
131
+
126 132
 // NormalizedName is a flag name that has been normalized according to rules
127 133
 // for the FlagSet (e.g. making '-' and '_' equivalent).
128 134
 type NormalizedName string
... ...
@@ -134,18 +141,30 @@ type FlagSet struct {
134 134
 	// a custom error handler.
135 135
 	Usage func()
136 136
 
137
+	// SortFlags is used to indicate, if user wants to have sorted flags in
138
+	// help/usage messages.
139
+	SortFlags bool
140
+
141
+	// ParseErrorsWhitelist is used to configure a whitelist of errors
142
+	ParseErrorsWhitelist ParseErrorsWhitelist
143
+
137 144
 	name              string
138 145
 	parsed            bool
139 146
 	actual            map[NormalizedName]*Flag
147
+	orderedActual     []*Flag
148
+	sortedActual      []*Flag
140 149
 	formal            map[NormalizedName]*Flag
150
+	orderedFormal     []*Flag
151
+	sortedFormal      []*Flag
141 152
 	shorthands        map[byte]*Flag
142 153
 	args              []string // arguments after flags
143 154
 	argsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --
144
-	exitOnError       bool     // does the program exit if there's an error?
145 155
 	errorHandling     ErrorHandling
146 156
 	output            io.Writer // nil means stderr; use out() accessor
147 157
 	interspersed      bool      // allow interspersed option/non-option args
148 158
 	normalizeNameFunc func(f *FlagSet, name string) NormalizedName
159
+
160
+	addedGoFlagSets []*goflag.FlagSet
149 161
 }
150 162
 
151 163
 // A Flag represents the state of a flag.
... ...
@@ -156,7 +175,7 @@ type Flag struct {
156 156
 	Value               Value               // value as set
157 157
 	DefValue            string              // default value (as text); for usage message
158 158
 	Changed             bool                // If the user set the value (or if left to default)
159
-	NoOptDefVal         string              //default value (as text); if the flag is on the command line without any options
159
+	NoOptDefVal         string              // default value (as text); if the flag is on the command line without any options
160 160
 	Deprecated          string              // If this flag is deprecated, this string is the new or now thing to use
161 161
 	Hidden              bool                // used by cobra.Command to allow flags to be hidden from help/usage text
162 162
 	ShorthandDeprecated string              // If the shorthand of this flag is deprecated, this string is the new or now thing to use
... ...
@@ -194,11 +213,19 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
194 194
 // "--getUrl" which may also be translated to "geturl" and everything will work.
195 195
 func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
196 196
 	f.normalizeNameFunc = n
197
-	for k, v := range f.formal {
198
-		delete(f.formal, k)
199
-		nname := f.normalizeFlagName(string(k))
200
-		f.formal[nname] = v
201
-		v.Name = string(nname)
197
+	f.sortedFormal = f.sortedFormal[:0]
198
+	for fname, flag := range f.formal {
199
+		nname := f.normalizeFlagName(flag.Name)
200
+		if fname == nname {
201
+			continue
202
+		}
203
+		flag.Name = string(nname)
204
+		delete(f.formal, fname)
205
+		f.formal[nname] = flag
206
+		if _, set := f.actual[fname]; set {
207
+			delete(f.actual, fname)
208
+			f.actual[nname] = flag
209
+		}
202 210
 	}
203 211
 }
204 212
 
... ...
@@ -229,46 +256,78 @@ func (f *FlagSet) SetOutput(output io.Writer) {
229 229
 	f.output = output
230 230
 }
231 231
 
232
-// VisitAll visits the flags in lexicographical order, calling fn for each.
232
+// VisitAll visits the flags in lexicographical order or
233
+// in primordial order if f.SortFlags is false, calling fn for each.
233 234
 // It visits all flags, even those not set.
234 235
 func (f *FlagSet) VisitAll(fn func(*Flag)) {
235
-	for _, flag := range sortFlags(f.formal) {
236
+	if len(f.formal) == 0 {
237
+		return
238
+	}
239
+
240
+	var flags []*Flag
241
+	if f.SortFlags {
242
+		if len(f.formal) != len(f.sortedFormal) {
243
+			f.sortedFormal = sortFlags(f.formal)
244
+		}
245
+		flags = f.sortedFormal
246
+	} else {
247
+		flags = f.orderedFormal
248
+	}
249
+
250
+	for _, flag := range flags {
236 251
 		fn(flag)
237 252
 	}
238 253
 }
239 254
 
240
-// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
255
+// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
241 256
 func (f *FlagSet) HasFlags() bool {
242 257
 	return len(f.formal) > 0
243 258
 }
244 259
 
245 260
 // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
246
-// definied that are not hidden or deprecated.
261
+// that are not hidden.
247 262
 func (f *FlagSet) HasAvailableFlags() bool {
248 263
 	for _, flag := range f.formal {
249
-		if !flag.Hidden && len(flag.Deprecated) == 0 {
264
+		if !flag.Hidden {
250 265
 			return true
251 266
 		}
252 267
 	}
253 268
 	return false
254 269
 }
255 270
 
256
-// VisitAll visits the command-line flags in lexicographical order, calling
257
-// fn for each.  It visits all flags, even those not set.
271
+// VisitAll visits the command-line flags in lexicographical order or
272
+// in primordial order if f.SortFlags is false, calling fn for each.
273
+// It visits all flags, even those not set.
258 274
 func VisitAll(fn func(*Flag)) {
259 275
 	CommandLine.VisitAll(fn)
260 276
 }
261 277
 
262
-// Visit visits the flags in lexicographical order, calling fn for each.
278
+// Visit visits the flags in lexicographical order or
279
+// in primordial order if f.SortFlags is false, calling fn for each.
263 280
 // It visits only those flags that have been set.
264 281
 func (f *FlagSet) Visit(fn func(*Flag)) {
265
-	for _, flag := range sortFlags(f.actual) {
282
+	if len(f.actual) == 0 {
283
+		return
284
+	}
285
+
286
+	var flags []*Flag
287
+	if f.SortFlags {
288
+		if len(f.actual) != len(f.sortedActual) {
289
+			f.sortedActual = sortFlags(f.actual)
290
+		}
291
+		flags = f.sortedActual
292
+	} else {
293
+		flags = f.orderedActual
294
+	}
295
+
296
+	for _, flag := range flags {
266 297
 		fn(flag)
267 298
 	}
268 299
 }
269 300
 
270
-// Visit visits the command-line flags in lexicographical order, calling fn
271
-// for each.  It visits only those flags that have been set.
301
+// Visit visits the command-line flags in lexicographical order or
302
+// in primordial order if f.SortFlags is false, calling fn for each.
303
+// It visits only those flags that have been set.
272 304
 func Visit(fn func(*Flag)) {
273 305
 	CommandLine.Visit(fn)
274 306
 }
... ...
@@ -278,6 +337,22 @@ func (f *FlagSet) Lookup(name string) *Flag {
278 278
 	return f.lookup(f.normalizeFlagName(name))
279 279
 }
280 280
 
281
+// ShorthandLookup returns the Flag structure of the short handed flag,
282
+// returning nil if none exists.
283
+// It panics, if len(name) > 1.
284
+func (f *FlagSet) ShorthandLookup(name string) *Flag {
285
+	if name == "" {
286
+		return nil
287
+	}
288
+	if len(name) > 1 {
289
+		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
290
+		fmt.Fprintf(f.out(), msg)
291
+		panic(msg)
292
+	}
293
+	c := name[0]
294
+	return f.shorthands[c]
295
+}
296
+
281 297
 // lookup returns the Flag structure of the named flag, returning nil if none exists.
282 298
 func (f *FlagSet) lookup(name NormalizedName) *Flag {
283 299
 	return f.formal[name]
... ...
@@ -319,10 +394,11 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
319 319
 	if flag == nil {
320 320
 		return fmt.Errorf("flag %q does not exist", name)
321 321
 	}
322
-	if len(usageMessage) == 0 {
322
+	if usageMessage == "" {
323 323
 		return fmt.Errorf("deprecated message for flag %q must be set", name)
324 324
 	}
325 325
 	flag.Deprecated = usageMessage
326
+	flag.Hidden = true
326 327
 	return nil
327 328
 }
328 329
 
... ...
@@ -334,7 +410,7 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
334 334
 	if flag == nil {
335 335
 		return fmt.Errorf("flag %q does not exist", name)
336 336
 	}
337
-	if len(usageMessage) == 0 {
337
+	if usageMessage == "" {
338 338
 		return fmt.Errorf("deprecated message for flag %q must be set", name)
339 339
 	}
340 340
 	flag.ShorthandDeprecated = usageMessage
... ...
@@ -358,6 +434,12 @@ func Lookup(name string) *Flag {
358 358
 	return CommandLine.Lookup(name)
359 359
 }
360 360
 
361
+// ShorthandLookup returns the Flag structure of the short handed flag,
362
+// returning nil if none exists.
363
+func ShorthandLookup(name string) *Flag {
364
+	return CommandLine.ShorthandLookup(name)
365
+}
366
+
361 367
 // Set sets the value of the named flag.
362 368
 func (f *FlagSet) Set(name, value string) error {
363 369
 	normalName := f.normalizeFlagName(name)
... ...
@@ -365,17 +447,30 @@ func (f *FlagSet) Set(name, value string) error {
365 365
 	if !ok {
366 366
 		return fmt.Errorf("no such flag -%v", name)
367 367
 	}
368
+
368 369
 	err := flag.Value.Set(value)
369 370
 	if err != nil {
370
-		return err
371
+		var flagName string
372
+		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
373
+			flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
374
+		} else {
375
+			flagName = fmt.Sprintf("--%s", flag.Name)
376
+		}
377
+		return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
371 378
 	}
372
-	if f.actual == nil {
373
-		f.actual = make(map[NormalizedName]*Flag)
379
+
380
+	if !flag.Changed {
381
+		if f.actual == nil {
382
+			f.actual = make(map[NormalizedName]*Flag)
383
+		}
384
+		f.actual[normalName] = flag
385
+		f.orderedActual = append(f.orderedActual, flag)
386
+
387
+		flag.Changed = true
374 388
 	}
375
-	f.actual[normalName] = flag
376
-	flag.Changed = true
377
-	if len(flag.Deprecated) > 0 {
378
-		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
389
+
390
+	if flag.Deprecated != "" {
391
+		fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
379 392
 	}
380 393
 	return nil
381 394
 }
... ...
@@ -482,6 +577,14 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
482 482
 		name = "int"
483 483
 	case "uint64":
484 484
 		name = "uint"
485
+	case "stringSlice":
486
+		name = "strings"
487
+	case "intSlice":
488
+		name = "ints"
489
+	case "uintSlice":
490
+		name = "uints"
491
+	case "boolSlice":
492
+		name = "bools"
485 493
 	}
486 494
 
487 495
 	return
... ...
@@ -496,11 +599,14 @@ func wrapN(i, slop int, s string) (string, string) {
496 496
 		return s, ""
497 497
 	}
498 498
 
499
-	w := strings.LastIndexAny(s[:i], " \t")
499
+	w := strings.LastIndexAny(s[:i], " \t\n")
500 500
 	if w <= 0 {
501 501
 		return s, ""
502 502
 	}
503
-
503
+	nlPos := strings.LastIndex(s[:i], "\n")
504
+	if nlPos > 0 && nlPos < w {
505
+		return s[:nlPos], s[nlPos+1:]
506
+	}
504 507
 	return s[:w], s[w+1:]
505 508
 }
506 509
 
... ...
@@ -509,7 +615,7 @@ func wrapN(i, slop int, s string) (string, string) {
509 509
 // caller). Pass `w` == 0 to do no wrapping
510 510
 func wrap(i, w int, s string) string {
511 511
 	if w == 0 {
512
-		return s
512
+		return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
513 513
 	}
514 514
 
515 515
 	// space between indent i and end of line width w into which
... ...
@@ -527,7 +633,7 @@ func wrap(i, w int, s string) string {
527 527
 	}
528 528
 	// If still not enough space then don't even try to wrap.
529 529
 	if wrap < 24 {
530
-		return s
530
+		return strings.Replace(s, "\n", r, -1)
531 531
 	}
532 532
 
533 533
 	// Try to avoid short orphan words on the final line, by
... ...
@@ -539,14 +645,14 @@ func wrap(i, w int, s string) string {
539 539
 	// Handle first line, which is indented by the caller (or the
540 540
 	// special case above)
541 541
 	l, s = wrapN(wrap, slop, s)
542
-	r = r + l
542
+	r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
543 543
 
544 544
 	// Now wrap the rest
545 545
 	for s != "" {
546 546
 		var t string
547 547
 
548 548
 		t, s = wrapN(wrap, slop, s)
549
-		r = r + "\n" + strings.Repeat(" ", i) + t
549
+		r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
550 550
 	}
551 551
 
552 552
 	return r
... ...
@@ -557,28 +663,28 @@ func wrap(i, w int, s string) string {
557 557
 // for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
558 558
 // wrapping)
559 559
 func (f *FlagSet) FlagUsagesWrapped(cols int) string {
560
-	x := new(bytes.Buffer)
560
+	buf := new(bytes.Buffer)
561 561
 
562 562
 	lines := make([]string, 0, len(f.formal))
563 563
 
564 564
 	maxlen := 0
565 565
 	f.VisitAll(func(flag *Flag) {
566
-		if len(flag.Deprecated) > 0 || flag.Hidden {
566
+		if flag.Hidden {
567 567
 			return
568 568
 		}
569 569
 
570 570
 		line := ""
571
-		if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
571
+		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
572 572
 			line = fmt.Sprintf("  -%s, --%s", flag.Shorthand, flag.Name)
573 573
 		} else {
574 574
 			line = fmt.Sprintf("      --%s", flag.Name)
575 575
 		}
576 576
 
577 577
 		varname, usage := UnquoteUsage(flag)
578
-		if len(varname) > 0 {
578
+		if varname != "" {
579 579
 			line += " " + varname
580 580
 		}
581
-		if len(flag.NoOptDefVal) > 0 {
581
+		if flag.NoOptDefVal != "" {
582 582
 			switch flag.Value.Type() {
583 583
 			case "string":
584 584
 				line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
... ...
@@ -586,6 +692,10 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
586 586
 				if flag.NoOptDefVal != "true" {
587 587
 					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
588 588
 				}
589
+			case "count":
590
+				if flag.NoOptDefVal != "+1" {
591
+					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
592
+				}
589 593
 			default:
590 594
 				line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
591 595
 			}
... ...
@@ -601,11 +711,14 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
601 601
 		line += usage
602 602
 		if !flag.defaultIsZeroValue() {
603 603
 			if flag.Value.Type() == "string" {
604
-				line += fmt.Sprintf(" (default \"%s\")", flag.DefValue)
604
+				line += fmt.Sprintf(" (default %q)", flag.DefValue)
605 605
 			} else {
606 606
 				line += fmt.Sprintf(" (default %s)", flag.DefValue)
607 607
 			}
608 608
 		}
609
+		if len(flag.Deprecated) != 0 {
610
+			line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
611
+		}
609 612
 
610 613
 		lines = append(lines, line)
611 614
 	})
... ...
@@ -614,10 +727,10 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
614 614
 		sidx := strings.Index(line, "\x00")
615 615
 		spacing := strings.Repeat(" ", maxlen-sidx)
616 616
 		// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
617
-		fmt.Fprintln(x, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
617
+		fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
618 618
 	}
619 619
 
620
-	return x.String()
620
+	return buf.String()
621 621
 }
622 622
 
623 623
 // FlagUsages returns a string containing the usage information for all flags in
... ...
@@ -714,11 +827,10 @@ func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
714 714
 
715 715
 // AddFlag will add the flag to the FlagSet
716 716
 func (f *FlagSet) AddFlag(flag *Flag) {
717
-	// Call normalizeFlagName function only once
718 717
 	normalizedFlagName := f.normalizeFlagName(flag.Name)
719 718
 
720
-	_, alreadythere := f.formal[normalizedFlagName]
721
-	if alreadythere {
719
+	_, alreadyThere := f.formal[normalizedFlagName]
720
+	if alreadyThere {
722 721
 		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
723 722
 		fmt.Fprintln(f.out(), msg)
724 723
 		panic(msg) // Happens only if flags are declared with identical names
... ...
@@ -729,28 +841,31 @@ func (f *FlagSet) AddFlag(flag *Flag) {
729 729
 
730 730
 	flag.Name = string(normalizedFlagName)
731 731
 	f.formal[normalizedFlagName] = flag
732
+	f.orderedFormal = append(f.orderedFormal, flag)
732 733
 
733
-	if len(flag.Shorthand) == 0 {
734
+	if flag.Shorthand == "" {
734 735
 		return
735 736
 	}
736 737
 	if len(flag.Shorthand) > 1 {
737
-		fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
738
-		panic("shorthand is more than one character")
738
+		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
739
+		fmt.Fprintf(f.out(), msg)
740
+		panic(msg)
739 741
 	}
740 742
 	if f.shorthands == nil {
741 743
 		f.shorthands = make(map[byte]*Flag)
742 744
 	}
743 745
 	c := flag.Shorthand[0]
744
-	old, alreadythere := f.shorthands[c]
745
-	if alreadythere {
746
-		fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
747
-		panic("shorthand redefinition")
746
+	used, alreadyThere := f.shorthands[c]
747
+	if alreadyThere {
748
+		msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
749
+		fmt.Fprintf(f.out(), msg)
750
+		panic(msg)
748 751
 	}
749 752
 	f.shorthands[c] = flag
750 753
 }
751 754
 
752 755
 // AddFlagSet adds one FlagSet to another. If a flag is already present in f
753
-// the flag from newSet will be ignored
756
+// the flag from newSet will be ignored.
754 757
 func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
755 758
 	if newSet == nil {
756 759
 		return
... ...
@@ -781,8 +896,10 @@ func VarP(value Value, name, shorthand, usage string) {
781 781
 // returns the error.
782 782
 func (f *FlagSet) failf(format string, a ...interface{}) error {
783 783
 	err := fmt.Errorf(format, a...)
784
-	fmt.Fprintln(f.out(), err)
785
-	f.usage()
784
+	if f.errorHandling != ContinueOnError {
785
+		fmt.Fprintln(f.out(), err)
786
+		f.usage()
787
+	}
786 788
 	return err
787 789
 }
788 790
 
... ...
@@ -798,32 +915,23 @@ func (f *FlagSet) usage() {
798 798
 	}
799 799
 }
800 800
 
801
-func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
802
-	if err := flag.Value.Set(value); err != nil {
803
-		return f.failf("invalid argument %q for %s: %v", value, origArg, err)
804
-	}
805
-	// mark as visited for Visit()
806
-	if f.actual == nil {
807
-		f.actual = make(map[NormalizedName]*Flag)
801
+//--unknown (args will be empty)
802
+//--unknown --next-flag ... (args will be --next-flag ...)
803
+//--unknown arg ... (args will be arg ...)
804
+func stripUnknownFlagValue(args []string) []string {
805
+	if len(args) == 0 {
806
+		//--unknown
807
+		return args
808 808
 	}
809
-	f.actual[f.normalizeFlagName(flag.Name)] = flag
810
-	flag.Changed = true
811
-	if len(flag.Deprecated) > 0 {
812
-		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
813
-	}
814
-	if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
815
-		fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
816
-	}
817
-	return nil
818
-}
819 809
 
820
-func containsShorthand(arg, shorthand string) bool {
821
-	// filter out flags --<flag_name>
822
-	if strings.HasPrefix(arg, "-") {
823
-		return false
810
+	first := args[0]
811
+	if first[0] == '-' {
812
+		//--unknown --next-flag ...
813
+		return args
824 814
 	}
825
-	arg = strings.SplitN(arg, "=", 2)[0]
826
-	return strings.Contains(arg, shorthand)
815
+
816
+	//--unknown arg ... (args will be arg ...)
817
+	return args[1:]
827 818
 }
828 819
 
829 820
 func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
... ...
@@ -833,22 +941,35 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
833 833
 		err = f.failf("bad flag syntax: %s", s)
834 834
 		return
835 835
 	}
836
+
836 837
 	split := strings.SplitN(name, "=", 2)
837 838
 	name = split[0]
838
-	flag, alreadythere := f.formal[f.normalizeFlagName(name)]
839
-	if !alreadythere {
840
-		if name == "help" { // special case for nice help message.
839
+	flag, exists := f.formal[f.normalizeFlagName(name)]
840
+
841
+	if !exists {
842
+		switch {
843
+		case name == "help":
841 844
 			f.usage()
842 845
 			return a, ErrHelp
846
+		case f.ParseErrorsWhitelist.UnknownFlags:
847
+			// --unknown=unknownval arg ...
848
+			// we do not want to lose arg in this case
849
+			if len(split) >= 2 {
850
+				return a, nil
851
+			}
852
+
853
+			return stripUnknownFlagValue(a), nil
854
+		default:
855
+			err = f.failf("unknown flag: --%s", name)
856
+			return
843 857
 		}
844
-		err = f.failf("unknown flag: --%s", name)
845
-		return
846 858
 	}
859
+
847 860
 	var value string
848 861
 	if len(split) == 2 {
849 862
 		// '--flag=arg'
850 863
 		value = split[1]
851
-	} else if len(flag.NoOptDefVal) > 0 {
864
+	} else if flag.NoOptDefVal != "" {
852 865
 		// '--flag' (arg was optional)
853 866
 		value = flag.NoOptDefVal
854 867
 	} else if len(a) > 0 {
... ...
@@ -860,7 +981,11 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
860 860
 		err = f.failf("flag needs an argument: %s", s)
861 861
 		return
862 862
 	}
863
-	err = fn(flag, value, s)
863
+
864
+	err = fn(flag, value)
865
+	if err != nil {
866
+		f.failf(err.Error())
867
+	}
864 868
 	return
865 869
 }
866 870
 
... ...
@@ -868,38 +993,64 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
868 868
 	if strings.HasPrefix(shorthands, "test.") {
869 869
 		return
870 870
 	}
871
+
871 872
 	outArgs = args
872 873
 	outShorts = shorthands[1:]
873 874
 	c := shorthands[0]
874 875
 
875
-	flag, alreadythere := f.shorthands[c]
876
-	if !alreadythere {
877
-		if c == 'h' { // special case for nice help message.
876
+	flag, exists := f.shorthands[c]
877
+	if !exists {
878
+		switch {
879
+		case c == 'h':
878 880
 			f.usage()
879 881
 			err = ErrHelp
880 882
 			return
883
+		case f.ParseErrorsWhitelist.UnknownFlags:
884
+			// '-f=arg arg ...'
885
+			// we do not want to lose arg in this case
886
+			if len(shorthands) > 2 && shorthands[1] == '=' {
887
+				outShorts = ""
888
+				return
889
+			}
890
+
891
+			outArgs = stripUnknownFlagValue(outArgs)
892
+			return
893
+		default:
894
+			err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
895
+			return
881 896
 		}
882
-		//TODO continue on error
883
-		err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
884
-		return
885 897
 	}
898
+
886 899
 	var value string
887 900
 	if len(shorthands) > 2 && shorthands[1] == '=' {
901
+		// '-f=arg'
888 902
 		value = shorthands[2:]
889 903
 		outShorts = ""
890
-	} else if len(flag.NoOptDefVal) > 0 {
904
+	} else if flag.NoOptDefVal != "" {
905
+		// '-f' (arg was optional)
891 906
 		value = flag.NoOptDefVal
892 907
 	} else if len(shorthands) > 1 {
908
+		// '-farg'
893 909
 		value = shorthands[1:]
894 910
 		outShorts = ""
895 911
 	} else if len(args) > 0 {
912
+		// '-f arg'
896 913
 		value = args[0]
897 914
 		outArgs = args[1:]
898 915
 	} else {
916
+		// '-f' (arg was required)
899 917
 		err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
900 918
 		return
901 919
 	}
902
-	err = fn(flag, value, shorthands)
920
+
921
+	if flag.ShorthandDeprecated != "" {
922
+		fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
923
+	}
924
+
925
+	err = fn(flag, value)
926
+	if err != nil {
927
+		f.failf(err.Error())
928
+	}
903 929
 	return
904 930
 }
905 931
 
... ...
@@ -907,6 +1058,7 @@ func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []stri
907 907
 	a = args
908 908
 	shorthands := s[1:]
909 909
 
910
+	// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
910 911
 	for len(shorthands) > 0 {
911 912
 		shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
912 913
 		if err != nil {
... ...
@@ -953,19 +1105,30 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
953 953
 // are defined and before flags are accessed by the program.
954 954
 // The return value will be ErrHelp if -help was set but not defined.
955 955
 func (f *FlagSet) Parse(arguments []string) error {
956
+	if f.addedGoFlagSets != nil {
957
+		for _, goFlagSet := range f.addedGoFlagSets {
958
+			goFlagSet.Parse(nil)
959
+		}
960
+	}
956 961
 	f.parsed = true
962
+
963
+	if len(arguments) < 0 {
964
+		return nil
965
+	}
966
+
957 967
 	f.args = make([]string, 0, len(arguments))
958 968
 
959
-	assign := func(flag *Flag, value, origArg string) error {
960
-		return f.setFlag(flag, value, origArg)
969
+	set := func(flag *Flag, value string) error {
970
+		return f.Set(flag.Name, value)
961 971
 	}
962 972
 
963
-	err := f.parseArgs(arguments, assign)
973
+	err := f.parseArgs(arguments, set)
964 974
 	if err != nil {
965 975
 		switch f.errorHandling {
966 976
 		case ContinueOnError:
967 977
 			return err
968 978
 		case ExitOnError:
979
+			fmt.Println(err)
969 980
 			os.Exit(2)
970 981
 		case PanicOnError:
971 982
 			panic(err)
... ...
@@ -974,7 +1137,7 @@ func (f *FlagSet) Parse(arguments []string) error {
974 974
 	return nil
975 975
 }
976 976
 
977
-type parseFunc func(flag *Flag, value, origArg string) error
977
+type parseFunc func(flag *Flag, value string) error
978 978
 
979 979
 // ParseAll parses flag definitions from the argument list, which should not
980 980
 // include the command name. The arguments for fn are flag and value. Must be
... ...
@@ -985,11 +1148,7 @@ func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string)
985 985
 	f.parsed = true
986 986
 	f.args = make([]string, 0, len(arguments))
987 987
 
988
-	assign := func(flag *Flag, value, origArg string) error {
989
-		return fn(flag, value)
990
-	}
991
-
992
-	err := f.parseArgs(arguments, assign)
988
+	err := f.parseArgs(arguments, fn)
993 989
 	if err != nil {
994 990
 		switch f.errorHandling {
995 991
 		case ContinueOnError:
... ...
@@ -1036,14 +1195,15 @@ func Parsed() bool {
1036 1036
 // CommandLine is the default set of command-line flags, parsed from os.Args.
1037 1037
 var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1038 1038
 
1039
-// NewFlagSet returns a new, empty flag set with the specified name and
1040
-// error handling property.
1039
+// NewFlagSet returns a new, empty flag set with the specified name,
1040
+// error handling property and SortFlags set to true.
1041 1041
 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1042 1042
 	f := &FlagSet{
1043 1043
 		name:          name,
1044 1044
 		errorHandling: errorHandling,
1045 1045
 		argsLenAtDash: -1,
1046 1046
 		interspersed:  true,
1047
+		SortFlags:     true,
1047 1048
 	}
1048 1049
 	return f
1049 1050
 }
... ...
@@ -98,4 +98,8 @@ func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
98 98
 	newSet.VisitAll(func(goflag *goflag.Flag) {
99 99
 		f.AddGoFlag(goflag)
100 100
 	})
101
+	if f.addedGoFlagSets == nil {
102
+		f.addedGoFlagSets = make([]*goflag.FlagSet, 0)
103
+	}
104
+	f.addedGoFlagSets = append(f.addedGoFlagSets, newSet)
101 105
 }
102 106
new file mode 100644
... ...
@@ -0,0 +1,88 @@
0
+package pflag
1
+
2
+import "strconv"
3
+
4
+// -- int16 Value
5
+type int16Value int16
6
+
7
+func newInt16Value(val int16, p *int16) *int16Value {
8
+	*p = val
9
+	return (*int16Value)(p)
10
+}
11
+
12
+func (i *int16Value) Set(s string) error {
13
+	v, err := strconv.ParseInt(s, 0, 16)
14
+	*i = int16Value(v)
15
+	return err
16
+}
17
+
18
+func (i *int16Value) Type() string {
19
+	return "int16"
20
+}
21
+
22
+func (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) }
23
+
24
+func int16Conv(sval string) (interface{}, error) {
25
+	v, err := strconv.ParseInt(sval, 0, 16)
26
+	if err != nil {
27
+		return 0, err
28
+	}
29
+	return int16(v), nil
30
+}
31
+
32
+// GetInt16 returns the int16 value of a flag with the given name
33
+func (f *FlagSet) GetInt16(name string) (int16, error) {
34
+	val, err := f.getFlagType(name, "int16", int16Conv)
35
+	if err != nil {
36
+		return 0, err
37
+	}
38
+	return val.(int16), nil
39
+}
40
+
41
+// Int16Var defines an int16 flag with specified name, default value, and usage string.
42
+// The argument p points to an int16 variable in which to store the value of the flag.
43
+func (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) {
44
+	f.VarP(newInt16Value(value, p), name, "", usage)
45
+}
46
+
47
+// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
48
+func (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
49
+	f.VarP(newInt16Value(value, p), name, shorthand, usage)
50
+}
51
+
52
+// Int16Var defines an int16 flag with specified name, default value, and usage string.
53
+// The argument p points to an int16 variable in which to store the value of the flag.
54
+func Int16Var(p *int16, name string, value int16, usage string) {
55
+	CommandLine.VarP(newInt16Value(value, p), name, "", usage)
56
+}
57
+
58
+// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
59
+func Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
60
+	CommandLine.VarP(newInt16Value(value, p), name, shorthand, usage)
61
+}
62
+
63
+// Int16 defines an int16 flag with specified name, default value, and usage string.
64
+// The return value is the address of an int16 variable that stores the value of the flag.
65
+func (f *FlagSet) Int16(name string, value int16, usage string) *int16 {
66
+	p := new(int16)
67
+	f.Int16VarP(p, name, "", value, usage)
68
+	return p
69
+}
70
+
71
+// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
72
+func (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 {
73
+	p := new(int16)
74
+	f.Int16VarP(p, name, shorthand, value, usage)
75
+	return p
76
+}
77
+
78
+// Int16 defines an int16 flag with specified name, default value, and usage string.
79
+// The return value is the address of an int16 variable that stores the value of the flag.
80
+func Int16(name string, value int16, usage string) *int16 {
81
+	return CommandLine.Int16P(name, "", value, usage)
82
+}
83
+
84
+// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
85
+func Int16P(name, shorthand string, value int16, usage string) *int16 {
86
+	return CommandLine.Int16P(name, shorthand, value, usage)
87
+}
... ...
@@ -52,7 +52,7 @@ func (f *FlagSet) GetStringArray(name string) ([]string, error) {
52 52
 
53 53
 // StringArrayVar defines a string flag with specified name, default value, and usage string.
54 54
 // The argument p points to a []string variable in which to store the values of the multiple flags.
55
-// The value of each argument will not try to be separated by comma
55
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
56 56
 func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {
57 57
 	f.VarP(newStringArrayValue(value, p), name, "", usage)
58 58
 }
... ...
@@ -64,7 +64,7 @@ func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []s
64 64
 
65 65
 // StringArrayVar defines a string flag with specified name, default value, and usage string.
66 66
 // The argument p points to a []string variable in which to store the value of the flag.
67
-// The value of each argument will not try to be separated by comma
67
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
68 68
 func StringArrayVar(p *[]string, name string, value []string, usage string) {
69 69
 	CommandLine.VarP(newStringArrayValue(value, p), name, "", usage)
70 70
 }
... ...
@@ -76,7 +76,7 @@ func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage
76 76
 
77 77
 // StringArray defines a string flag with specified name, default value, and usage string.
78 78
 // The return value is the address of a []string variable that stores the value of the flag.
79
-// The value of each argument will not try to be separated by comma
79
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
80 80
 func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {
81 81
 	p := []string{}
82 82
 	f.StringArrayVarP(&p, name, "", value, usage)
... ...
@@ -92,7 +92,7 @@ func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage str
92 92
 
93 93
 // StringArray defines a string flag with specified name, default value, and usage string.
94 94
 // The return value is the address of a []string variable that stores the value of the flag.
95
-// The value of each argument will not try to be separated by comma
95
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
96 96
 func StringArray(name string, value []string, usage string) *[]string {
97 97
 	return CommandLine.StringArrayP(name, "", value, usage)
98 98
 }
... ...
@@ -82,6 +82,11 @@ func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
82 82
 
83 83
 // StringSliceVar defines a string flag with specified name, default value, and usage string.
84 84
 // The argument p points to a []string variable in which to store the value of the flag.
85
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
86
+// For example:
87
+//   --ss="v1,v2" -ss="v3"
88
+// will result in
89
+//   []string{"v1", "v2", "v3"}
85 90
 func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
86 91
 	f.VarP(newStringSliceValue(value, p), name, "", usage)
87 92
 }
... ...
@@ -93,6 +98,11 @@ func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []s
93 93
 
94 94
 // StringSliceVar defines a string flag with specified name, default value, and usage string.
95 95
 // The argument p points to a []string variable in which to store the value of the flag.
96
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
97
+// For example:
98
+//   --ss="v1,v2" -ss="v3"
99
+// will result in
100
+//   []string{"v1", "v2", "v3"}
96 101
 func StringSliceVar(p *[]string, name string, value []string, usage string) {
97 102
 	CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
98 103
 }
... ...
@@ -104,6 +114,11 @@ func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage
104 104
 
105 105
 // StringSlice defines a string flag with specified name, default value, and usage string.
106 106
 // The return value is the address of a []string variable that stores the value of the flag.
107
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
108
+// For example:
109
+//   --ss="v1,v2" -ss="v3"
110
+// will result in
111
+//   []string{"v1", "v2", "v3"}
107 112
 func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
108 113
 	p := []string{}
109 114
 	f.StringSliceVarP(&p, name, "", value, usage)
... ...
@@ -119,6 +134,11 @@ func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage str
119 119
 
120 120
 // StringSlice defines a string flag with specified name, default value, and usage string.
121 121
 // The return value is the address of a []string variable that stores the value of the flag.
122
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
123
+// For example:
124
+//   --ss="v1,v2" -ss="v3"
125
+// will result in
126
+//   []string{"v1", "v2", "v3"}
122 127
 func StringSlice(name string, value []string, usage string) *[]string {
123 128
 	return CommandLine.StringSliceP(name, "", value, usage)
124 129
 }