summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/spf13/cobra
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/spf13/cobra')
-rw-r--r--vendor/github.com/spf13/cobra/README.md435
-rw-r--r--vendor/github.com/spf13/cobra/args.go25
-rw-r--r--vendor/github.com/spf13/cobra/args_test.go241
-rw-r--r--vendor/github.com/spf13/cobra/bash_completions.go2
-rw-r--r--vendor/github.com/spf13/cobra/bash_completions_test.go236
-rw-r--r--vendor/github.com/spf13/cobra/cobra.go9
-rw-r--r--vendor/github.com/spf13/cobra/cobra/README.md94
-rw-r--r--vendor/github.com/spf13/cobra/cobra/cmd/helpers.go23
-rw-r--r--vendor/github.com/spf13/cobra/cobra/cmd/licenses.go2
-rw-r--r--vendor/github.com/spf13/cobra/cobra_test.go1228
-rw-r--r--vendor/github.com/spf13/cobra/command.go187
-rw-r--r--vendor/github.com/spf13/cobra/command_test.go1473
-rw-r--r--vendor/github.com/spf13/cobra/doc/cmd_test.go157
-rw-r--r--vendor/github.com/spf13/cobra/doc/man_docs_test.go147
-rw-r--r--vendor/github.com/spf13/cobra/doc/md_docs_test.go96
-rw-r--r--vendor/github.com/spf13/cobra/doc/rest_docs.go185
-rw-r--r--vendor/github.com/spf13/cobra/doc/rest_docs.md114
-rw-r--r--vendor/github.com/spf13/cobra/doc/rest_docs_test.go76
-rw-r--r--vendor/github.com/spf13/cobra/doc/yaml_docs_test.go89
-rw-r--r--vendor/github.com/spf13/cobra/zsh_completions_test.go7
20 files changed, 2587 insertions, 2239 deletions
diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md
index da9aa881e..d8b5c96c8 100644
--- a/vendor/github.com/spf13/cobra/README.md
+++ b/vendor/github.com/spf13/cobra/README.md
@@ -19,13 +19,33 @@ Many of the most widely used Go projects are built using Cobra including:
* [GiantSwarm's swarm](https://github.com/giantswarm/cli)
* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
* [rclone](http://rclone.org/)
-
+* [nehm](https://github.com/bogem/nehm)
[![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra)
[![CircleCI status](https://circleci.com/gh/spf13/cobra.png?circle-token=:circle-token "CircleCI status")](https://circleci.com/gh/spf13/cobra)
[![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra)
-![cobra](https://cloud.githubusercontent.com/assets/173412/10911369/84832a8e-8212-11e5-9f82-cc96660a4794.gif)
+# Table of Contents
+
+- [Overview](#overview)
+- [Concepts](#concepts)
+ * [Commands](#commands)
+ * [Flags](#flags)
+- [Installing](#installing)
+- [Getting Started](#getting-started)
+ * [Using the Cobra Generator](#using-the-cobra-generator)
+ * [Using the Cobra Library](#using-the-cobra-library)
+ * [Working with Flags](#working-with-flags)
+ * [Positional and Custom Arguments](#positional-and-custom-arguments)
+ * [Example](#example)
+ * [Help Command](#help-command)
+ * [Usage Message](#usage-message)
+ * [PreRun and PostRun Hooks](#prerun-and-postrun-hooks)
+ * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
+ * [Generating documentation for your command](#generating-documentation-for-your-command)
+ * [Generating bash completions](#generating-bash-completions)
+- [Contributing](#contributing)
+- [License](#license)
# Overview
@@ -43,7 +63,6 @@ Cobra provides:
* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname`
* Intelligent suggestions (`app srver`... did you mean `app server`?)
* Automatic help generation for commands and flags
-* Automatic detailed help for `app help [command]`
* Automatic help flag recognition of `-h`, `--help`, etc.
* Automatically generated bash autocomplete for your application
* Automatically generated man pages for your application
@@ -51,16 +70,6 @@ Cobra provides:
* The flexibility to define your own help, usage, etc.
* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
-Cobra has an exceptionally clean interface and simple design without needless
-constructors or initialization methods.
-
-Applications built with Cobra commands are designed to be as user-friendly as
-possible. Flags can be placed before or after the command (as long as a
-confusing space isn’t provided). Both short and long flags can be used. A
-command need not even be fully typed. Help is automatically generated and
-available for the application or for a specific command using either the help
-command or the `--help` flag.
-
# Concepts
Cobra is built on a structure of commands, arguments & flags.
@@ -93,20 +102,11 @@ have children commands and optionally run an action.
In the example above, 'server' is the command.
-A Command has the following structure:
-
-```go
-type Command struct {
- Use string // The one-line usage message.
- Short string // The short description shown in the 'help' output.
- Long string // The long message shown in the 'help <this-command>' output.
- Run func(cmd *Command, args []string) // Run runs the command.
-}
-```
+[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command)
## Flags
-A Flag is a way to modify the behavior of a command. Cobra supports
+A flag is a way to modify the behavior of a command. Cobra supports
fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
A Cobra command can define flags that persist through to children commands
and flags that are only available to that command.
@@ -170,106 +170,14 @@ func main() {
Cobra provides its own program that will create your application and add any
commands you want. It's the easiest way to incorporate Cobra into your application.
-In order to use the cobra command, compile it using the following command:
+[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it.
- go get github.com/spf13/cobra/cobra
-
-This will create the cobra executable under your `$GOPATH/bin` directory.
-
-### cobra init
-
-The `cobra init [yourApp]` command will create your initial application code
-for you. It is a very powerful application that will populate your program with
-the right structure so you can immediately enjoy all the benefits of Cobra. It
-will also automatically apply the license you specify to your application.
-
-Cobra init is pretty smart. You can provide it a full path, or simply a path
-similar to what is expected in the import.
-
-```
-cobra init github.com/spf13/newAppName
-```
-
-### cobra add
-
-Once an application is initialized Cobra can create additional commands for you.
-Let's say you created an app and you wanted the following commands for it:
-
-* app serve
-* app config
-* app config create
-
-In your project directory (where your main.go file is) you would run the following:
-
-```
-cobra add serve
-cobra add config
-cobra add create -p 'configCmd'
-```
-
-*Note: Use camelCase (not snake_case/snake-case) for command names.
-Otherwise, you will encounter errors.
-For example, `cobra add add-user` is incorrect, but `cobra add addUser` is valid.*
-
-Once you have run these three commands you would have an app structure similar to
-the following:
-
-```
- ▾ app/
- ▾ cmd/
- serve.go
- config.go
- create.go
- main.go
-```
-
-At this point you can run `go run main.go` and it would run your app. `go run
-main.go serve`, `go run main.go config`, `go run main.go config create` along
-with `go run main.go help serve`, etc. would all work.
-
-Obviously you haven't added your own code to these yet. The commands are ready
-for you to give them their tasks. Have fun!
-
-### Configuring the cobra generator
-
-The Cobra generator will be easier to use if you provide a simple configuration
-file which will help you eliminate providing a bunch of repeated information in
-flags over and over.
-
-An example ~/.cobra.yaml file:
-
-```yaml
-author: Steve Francia <spf@spf13.com>
-license: MIT
-```
-
-You can specify no license by setting `license` to `none` or you can specify
-a custom license:
-
-```yaml
-license:
- header: This file is part of {{ .appName }}.
- text: |
- {{ .copyright }}
-
- This is my license. There are many like it, but this one is mine.
- My license is my best friend. It is my life. I must master it as I must
- master my life.
-```
-
-You can also use built-in licenses. For example, **GPLv2**, **GPLv3**, **LGPL**,
-**AGPL**, **MIT**, **2-Clause BSD** or **3-Clause BSD**.
-
-## Manually implementing Cobra
+## Using the Cobra Library
To manually implement Cobra you need to create a bare main.go file and a RootCmd file.
You will optionally provide additional commands as you see fit.
-### Create the root command
-
-The root command represents your binary itself.
-
-#### Manually create rootCmd
+### Create rootCmd
Cobra doesn't require any special constructors. Simply create your commands.
@@ -316,10 +224,6 @@ func init() {
viper.SetDefault("license", "apache")
}
-func Execute() {
- RootCmd.Execute()
-}
-
func initConfig() {
// Don't forget to read config either from cfgFile or from home directory!
if cfgFile != "" {
@@ -400,17 +304,6 @@ var versionCmd = &cobra.Command{
}
```
-### Attach command to its parent
-
-
-If you notice in the above example we attach the command to its parent. In
-this case the parent is the rootCmd. In this example we are attaching it to the
-root, but commands can be attached at any level.
-
-```go
-RootCmd.AddCommand(versionCmd)
-```
-
## Working with Flags
Flags provide modifiers to control how the action command operates.
@@ -446,6 +339,19 @@ A flag can also be assigned locally which will only apply to that specific comma
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
```
+### Local Flag on Parent Commands
+
+By default Cobra only parses local flags on the target command, any local flags on
+parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will
+parse local flags on each command before executing the target command.
+
+```go
+command := cobra.Command{
+ Use: "print [OPTIONS] [COMMANDS]",
+ TraverseChildren: true,
+}
+```
+
### Bind Flags with Config
You can also bind your flags with [viper](https://github.com/spf13/viper):
@@ -569,7 +475,7 @@ a count and a string.`,
For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
-## The Help Command
+## Help Command
Cobra automatically adds a help command to your application when you have subcommands.
This will be called when a user runs 'app help'. Additionally, help will also
@@ -582,60 +488,28 @@ create' is called. Every command will automatically have the '--help' flag adde
The following output is automatically generated by Cobra. Nothing beyond the
command and flag definitions are needed.
- > hugo help
+ $ cobra help
- hugo is the main command, used to build your Hugo site.
-
- Hugo is a Fast and Flexible Static Site Generator
- built with love by spf13 and friends in Go.
-
- Complete documentation is available at http://gohugo.io/.
+ Cobra is a CLI library for Go that empowers applications.
+ This application is a tool to generate the needed files
+ to quickly create a Cobra application.
Usage:
- hugo [flags]
- hugo [command]
+ cobra [command]
Available Commands:
- server Hugo runs its own webserver to render the files
- version Print the version number of Hugo
- config Print the site configuration
- check Check content in the source directory
- benchmark Benchmark hugo by building a site a number of times.
- convert Convert your content to different formats
- new Create new content for your site
- list Listing out various types of content
- undraft Undraft changes the content's draft status from 'True' to 'False'
- genautocomplete Generate shell autocompletion script for Hugo
- gendoc Generate Markdown documentation for the Hugo CLI.
- genman Generate man page for Hugo
- import Import your site from others.
+ add Add a command to a Cobra Application
+ help Help about any command
+ init Initialize a Cobra Application
Flags:
- -b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
- -D, --buildDrafts[=false]: include content marked as draft
- -F, --buildFuture[=false]: include content with publishdate in the future
- --cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
- --canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
- --config="": config file (default is path/config.yaml|json|toml)
- -d, --destination="": filesystem path to write files to
- --disableRSS[=false]: Do not build RSS files
- --disableSitemap[=false]: Do not build Sitemap file
- --editor="": edit new content with this editor, if provided
- --ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
- --log[=false]: Enable Logging
- --logFile="": Log File path (if set, logging enabled automatically)
- --noTimes[=false]: Don't sync modification time of files
- --pluralizeListTitles[=true]: Pluralize titles in lists using inflect
- --preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
- -s, --source="": filesystem path to read files relative from
- --stepAnalysis[=false]: display memory and timing of different steps of the program
- -t, --theme="": theme to use (located in /themes/THEMENAME/)
- --uglyURLs[=false]: if true, use /filename.html instead of /filename/
- -v, --verbose[=false]: verbose output
- --verboseLog[=false]: verbose logging
- -w, --watch[=false]: watch filesystem for changes and recreate as needed
-
- Use "hugo [command] --help" for more information about a command.
+ -a, --author string author name for copyright attribution (default "YOUR NAME")
+ --config string config file (default is $HOME/.cobra.yaml)
+ -h, --help help for cobra
+ -l, --license string name of license for the project
+ --viper use Viper for configuration (default true)
+
+ Use "cobra [command] --help" for more information about a command.
Help is just a command like any other. There is no special logic or behavior
@@ -643,36 +517,18 @@ around it. In fact, you can provide your own if you want.
### Defining your own help
-You can provide your own Help command or your own template for the default command to use.
-
-The default help command is
+You can provide your own Help command or your own template for the default command to use
+with followind functions:
```go
-func (c *Command) initHelp() {
- if c.helpCommand == nil {
- c.helpCommand = &Command{
- Use: "help [command]",
- Short: "Help about any command",
- Long: `Help provides help for any command in the application.
- Simply type ` + c.Name() + ` help [path to command] for full details.`,
- Run: c.HelpFunc(),
- }
- }
- c.AddCommand(c.helpCommand)
-}
-```
-
-You can provide your own command, function or template through the following methods:
-
-```go
-command.SetHelpCommand(cmd *Command)
-command.SetHelpFunc(f func(*Command, []string))
-command.SetHelpTemplate(s string)
+cmd.SetHelpCommand(cmd *Command)
+cmd.SetHelpFunc(f func(*Command, []string))
+cmd.SetHelpTemplate(s string)
```
The latter two will also apply to any children commands.
-## Usage
+## Usage Message
When the user provides an invalid flag or invalid command, Cobra responds by
showing the user the 'usage'.
@@ -681,71 +537,35 @@ showing the user the 'usage'.
You may recognize this from the help above. That's because the default help
embeds the usage as part of its output.
+ $ cobra --invalid
+ Error: unknown flag: --invalid
Usage:
- hugo [flags]
- hugo [command]
+ cobra [command]
Available Commands:
- server Hugo runs its own webserver to render the files
- version Print the version number of Hugo
- config Print the site configuration
- check Check content in the source directory
- benchmark Benchmark hugo by building a site a number of times.
- convert Convert your content to different formats
- new Create new content for your site
- list Listing out various types of content
- undraft Undraft changes the content's draft status from 'True' to 'False'
- genautocomplete Generate shell autocompletion script for Hugo
- gendoc Generate Markdown documentation for the Hugo CLI.
- genman Generate man page for Hugo
- import Import your site from others.
+ add Add a command to a Cobra Application
+ help Help about any command
+ init Initialize a Cobra Application
Flags:
- -b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
- -D, --buildDrafts[=false]: include content marked as draft
- -F, --buildFuture[=false]: include content with publishdate in the future
- --cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
- --canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
- --config="": config file (default is path/config.yaml|json|toml)
- -d, --destination="": filesystem path to write files to
- --disableRSS[=false]: Do not build RSS files
- --disableSitemap[=false]: Do not build Sitemap file
- --editor="": edit new content with this editor, if provided
- --ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
- --log[=false]: Enable Logging
- --logFile="": Log File path (if set, logging enabled automatically)
- --noTimes[=false]: Don't sync modification time of files
- --pluralizeListTitles[=true]: Pluralize titles in lists using inflect
- --preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
- -s, --source="": filesystem path to read files relative from
- --stepAnalysis[=false]: display memory and timing of different steps of the program
- -t, --theme="": theme to use (located in /themes/THEMENAME/)
- --uglyURLs[=false]: if true, use /filename.html instead of /filename/
- -v, --verbose[=false]: verbose output
- --verboseLog[=false]: verbose logging
- -w, --watch[=false]: watch filesystem for changes and recreate as needed
+ -a, --author string author name for copyright attribution (default "YOUR NAME")
+ --config string config file (default is $HOME/.cobra.yaml)
+ -h, --help help for cobra
+ -l, --license string name of license for the project
+ --viper use Viper for configuration (default true)
+
+ Use "cobra [command] --help" for more information about a command.
### Defining your own usage
You can provide your own usage function or template for Cobra to use.
-
-The default usage function is:
-
-```go
-return func(c *Command) error {
- err := tmpl(c.Out(), c.UsageTemplate(), c)
- return err
-}
-```
-
Like help, the function and template are overridable through public methods:
```go
-command.SetUsageFunc(f func(*Command) error)
-
-command.SetUsageTemplate(s string)
+cmd.SetUsageFunc(f func(*Command) error)
+cmd.SetUsageTemplate(s string)
```
-## PreRun or PostRun Hooks
+## PreRun and PostRun Hooks
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:
@@ -815,51 +635,19 @@ func main() {
}
```
+Output:
+```
+Inside rootCmd PersistentPreRun with args: []
+Inside rootCmd PreRun with args: []
+Inside rootCmd Run with args: []
+Inside rootCmd PostRun with args: []
+Inside rootCmd PersistentPostRun with args: []
-## Alternative Error Handling
-
-Cobra also has functions where the return signature is an error. This allows for errors to bubble up to the top,
-providing a way to handle the errors in one location. The current list of functions that return an error is:
-
-* PersistentPreRunE
-* PreRunE
-* RunE
-* PostRunE
-* PersistentPostRunE
-
-If you would like to silence the default `error` and `usage` output in favor of your own, you can set `SilenceUsage`
-and `SilenceErrors` to `true` on the command. A child command respects these flags if they are set on the parent
-command.
-
-**Example Usage using RunE:**
-
-```go
-package main
-
-import (
- "errors"
- "log"
-
- "github.com/spf13/cobra"
-)
-
-func main() {
- var rootCmd = &cobra.Command{
- Use: "hugo",
- Short: "Hugo is a very fast static site generator",
- Long: `A Fast and Flexible Static Site Generator built with
-love by spf13 and friends in Go.
-Complete documentation is available at http://hugo.spf13.com`,
- RunE: func(cmd *cobra.Command, args []string) error {
- // Do Stuff Here
- return errors.New("some random error")
- },
- }
-
- if err := rootCmd.Execute(); err != nil {
- log.Fatal(err)
- }
-}
+Inside rootCmd PersistentPreRun with args: [arg1 arg2]
+Inside subCmd PreRun with args: [arg1 arg2]
+Inside subCmd Run with args: [arg1 arg2]
+Inside subCmd PostRun with args: [arg1 arg2]
+Inside subCmd PersistentPostRun with args: [arg1 arg2]
```
## Suggestions when "unknown command" happens
@@ -902,41 +690,28 @@ Did you mean this?
Run 'kubectl help' for usage.
```
-## Generating Markdown-formatted documentation for your command
+## Generating documentation for your command
-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).
+Cobra can generate documentation based on subcommands, flags, etc. in the following formats:
-## Generating man pages for your command
+- [Markdown](doc/md_docs.md)
+- [ReStructured Text](doc/rest_docs.md)
+- [Man Page](doc/man_docs.md)
-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).
-
-## Generating bash completions for your command
+## Generating bash completions
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).
-
-## Extensions
-
-Libraries for extending Cobra:
-
-* [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`.
-
-## Contributing
+# Contributing
1. Fork it
-2. Create your feature branch (`git checkout -b my-new-feature`)
-3. Commit your changes (`git commit -am 'Add some feature'`)
-4. Push to the branch (`git push origin my-new-feature`)
-5. Create new Pull Request
-
-## Contributors
-
-Names in no particular order:
-
-* [spf13](https://github.com/spf13),
-[eparis](https://github.com/eparis),
-[bep](https://github.com/bep), and many more!
-
-## License
+2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)
+3. Create your feature branch (`git checkout -b my-new-feature`)
+4. Make changes and add them (`git add .`)
+5. Commit your changes (`git commit -m 'Add some feature'`)
+6. Push to the branch (`git push origin my-new-feature`)
+7. Create new pull request
+
+# License
Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go
index 94a6ca273..a5d8a9273 100644
--- a/vendor/github.com/spf13/cobra/args.go
+++ b/vendor/github.com/spf13/cobra/args.go
@@ -16,14 +16,14 @@ func legacyArgs(cmd *Command, args []string) error {
return nil
}
- // root command with subcommands, do subcommand checking
+ // root command with subcommands, do subcommand checking.
if !cmd.HasParent() && len(args) > 0 {
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
}
return nil
}
-// NoArgs returns an error if any args are included
+// NoArgs returns an error if any args are included.
func NoArgs(cmd *Command, args []string) error {
if len(args) > 0 {
return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
@@ -31,7 +31,7 @@ func NoArgs(cmd *Command, args []string) error {
return nil
}
-// OnlyValidArgs returns an error if any args are not in the list of ValidArgs
+// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
func OnlyValidArgs(cmd *Command, args []string) error {
if len(cmd.ValidArgs) > 0 {
for _, v := range args {
@@ -43,21 +43,12 @@ func OnlyValidArgs(cmd *Command, args []string) error {
return nil
}
-func stringInSlice(a string, list []string) bool {
- for _, b := range list {
- if b == a {
- return true
- }
- }
- return false
-}
-
-// ArbitraryArgs never returns an error
+// ArbitraryArgs never returns an error.
func ArbitraryArgs(cmd *Command, args []string) error {
return nil
}
-// MinimumNArgs returns an error if there is not at least N args
+// MinimumNArgs returns an error if there is not at least N args.
func MinimumNArgs(n int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) < n {
@@ -67,7 +58,7 @@ func MinimumNArgs(n int) PositionalArgs {
}
}
-// MaximumNArgs returns an error if there are more than N args
+// MaximumNArgs returns an error if there are more than N args.
func MaximumNArgs(n int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) > n {
@@ -77,7 +68,7 @@ func MaximumNArgs(n int) PositionalArgs {
}
}
-// ExactArgs returns an error if there are not exactly n args
+// ExactArgs returns an error if there are not exactly n args.
func ExactArgs(n int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) != n {
@@ -87,7 +78,7 @@ func ExactArgs(n int) PositionalArgs {
}
}
-// RangeArgs returns an error if the number of args is not within the expected range
+// RangeArgs returns an error if the number of args is not within the expected range.
func RangeArgs(min int, max int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) < min || len(args) > max {
diff --git a/vendor/github.com/spf13/cobra/args_test.go b/vendor/github.com/spf13/cobra/args_test.go
new file mode 100644
index 000000000..d797b6f58
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/args_test.go
@@ -0,0 +1,241 @@
+package cobra
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestNoArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: NoArgs, Run: emptyRun}
+
+ output, err := executeCommand(c)
+ if output != "" {
+ t.Errorf("Unexpected string: %v", output)
+ }
+ if err != nil {
+ t.Fatalf("Unexpected error: %v", err)
+ }
+}
+
+func TestNoArgsWithArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: NoArgs, Run: emptyRun}
+
+ _, err := executeCommand(c, "illegal")
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := `unknown command "illegal" for "c"`
+ if got != expected {
+ t.Errorf("Expected: %q, got: %q", expected, got)
+ }
+}
+
+func TestOnlyValidArgs(t *testing.T) {
+ c := &Command{
+ Use: "c",
+ Args: OnlyValidArgs,
+ ValidArgs: []string{"one", "two"},
+ Run: emptyRun,
+ }
+
+ output, err := executeCommand(c, "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Fatalf("Unexpected error: %v", err)
+ }
+}
+
+func TestOnlyValidArgsWithInvalidArgs(t *testing.T) {
+ c := &Command{
+ Use: "c",
+ Args: OnlyValidArgs,
+ ValidArgs: []string{"one", "two"},
+ Run: emptyRun,
+ }
+
+ _, err := executeCommand(c, "three")
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := `invalid argument "three" for "c"`
+ if got != expected {
+ t.Errorf("Expected: %q, got: %q", expected, got)
+ }
+}
+
+func TestArbitraryArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: ArbitraryArgs, Run: emptyRun}
+ output, err := executeCommand(c, "a", "b")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+}
+
+func TestMinimumNArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: MinimumNArgs(2), Run: emptyRun}
+ output, err := executeCommand(c, "a", "b", "c")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+}
+
+func TestMinimumNArgsWithLessArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: MinimumNArgs(2), Run: emptyRun}
+ _, err := executeCommand(c, "a")
+
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := "requires at least 2 arg(s), only received 1"
+ if got != expected {
+ t.Fatalf("Expected %q, got %q", expected, got)
+ }
+}
+
+func TestMaximumNArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: MaximumNArgs(3), Run: emptyRun}
+ output, err := executeCommand(c, "a", "b")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+}
+
+func TestMaximumNArgsWithMoreArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: MaximumNArgs(2), Run: emptyRun}
+ _, err := executeCommand(c, "a", "b", "c")
+
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := "accepts at most 2 arg(s), received 3"
+ if got != expected {
+ t.Fatalf("Expected %q, got %q", expected, got)
+ }
+}
+
+func TestExactArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: ExactArgs(3), Run: emptyRun}
+ output, err := executeCommand(c, "a", "b", "c")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+}
+
+func TestExactArgsWithInvalidCount(t *testing.T) {
+ c := &Command{Use: "c", Args: ExactArgs(2), Run: emptyRun}
+ _, err := executeCommand(c, "a", "b", "c")
+
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := "accepts 2 arg(s), received 3"
+ if got != expected {
+ t.Fatalf("Expected %q, got %q", expected, got)
+ }
+}
+
+func TestRangeArgs(t *testing.T) {
+ c := &Command{Use: "c", Args: RangeArgs(2, 4), Run: emptyRun}
+ output, err := executeCommand(c, "a", "b", "c")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+}
+
+func TestRangeArgsWithInvalidCount(t *testing.T) {
+ c := &Command{Use: "c", Args: RangeArgs(2, 4), Run: emptyRun}
+ _, err := executeCommand(c, "a")
+
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := "accepts between 2 and 4 arg(s), received 1"
+ if got != expected {
+ t.Fatalf("Expected %q, got %q", expected, got)
+ }
+}
+
+func TestRootTakesNoArgs(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ _, err := executeCommand(rootCmd, "illegal", "args")
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := `unknown command "illegal" for "root"`
+ if !strings.Contains(got, expected) {
+ t.Errorf("expected %q, got %q", expected, got)
+ }
+}
+
+func TestRootTakesArgs(t *testing.T) {
+ rootCmd := &Command{Use: "root", Args: ArbitraryArgs, Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ _, err := executeCommand(rootCmd, "legal", "args")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+}
+
+func TestChildTakesNoArgs(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Args: NoArgs, Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ _, err := executeCommand(rootCmd, "child", "illegal", "args")
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+
+ got := err.Error()
+ expected := `unknown command "illegal" for "root child"`
+ if !strings.Contains(got, expected) {
+ t.Errorf("expected %q, got %q", expected, got)
+ }
+}
+
+func TestChildTakesArgs(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Args: ArbitraryArgs, Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ _, err := executeCommand(rootCmd, "child", "legal", "args")
+ if err != nil {
+ t.Fatalf("Unexpected error: %v", err)
+ }
+}
diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go
index e402065dd..c19fe7a06 100644
--- a/vendor/github.com/spf13/cobra/bash_completions.go
+++ b/vendor/github.com/spf13/cobra/bash_completions.go
@@ -92,7 +92,7 @@ __handle_reply()
cur="${cur#*=}"
${flags_completion[${index}]}
if [ -n "${ZSH_VERSION}" ]; then
- # zfs completion needs --flag= prefix
+ # zsh completion needs --flag= prefix
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
fi
fi
diff --git a/vendor/github.com/spf13/cobra/bash_completions_test.go b/vendor/github.com/spf13/cobra/bash_completions_test.go
index a3b13a32a..a0da87148 100644
--- a/vendor/github.com/spf13/cobra/bash_completions_test.go
+++ b/vendor/github.com/spf13/cobra/bash_completions_test.go
@@ -10,13 +10,13 @@ import (
func checkOmit(t *testing.T, found, unexpected string) {
if strings.Contains(found, unexpected) {
- t.Errorf("Unexpected response.\nGot: %q\nBut should not have!\n", unexpected)
+ t.Errorf("Got: %q\nBut should not have!\n", unexpected)
}
}
func check(t *testing.T, found, expected string) {
if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
+ t.Errorf("Expecting to contain: \n %q\nGot:\n %q\n", expected, found)
}
}
@@ -33,162 +33,164 @@ func runShellCheck(s string) error {
return err
}
go func() {
- defer stdin.Close()
stdin.Write([]byte(s))
+ stdin.Close()
}()
return cmd.Run()
}
// World worst custom function, just keep telling you to enter hello!
-const (
- bashCompletionFunc = `__custom_func() {
-COMPREPLY=( "hello" )
+const bashCompletionFunc = `__custom_func() {
+ COMPREPLY=( "hello" )
}
`
-)
func TestBashCompletions(t *testing.T) {
- c := initializeWithRootCmd()
- cmdEcho.AddCommand(cmdTimes)
- c.AddCommand(cmdEcho, cmdPrint, cmdDeprecated, cmdColon)
-
- // custom completion function
- c.BashCompletionFunction = bashCompletionFunc
-
- // required flag
- c.MarkFlagRequired("introot")
-
- // valid nouns
- validArgs := []string{"pod", "node", "service", "replicationcontroller"}
- c.ValidArgs = validArgs
-
- // noun aliases
- argAliases := []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"}
- c.ArgAliases = argAliases
-
- // filename
- var flagval string
- c.Flags().StringVar(&flagval, "filename", "", "Enter a filename")
- c.MarkFlagFilename("filename", "json", "yaml", "yml")
-
- // persistent filename
- var flagvalPersistent string
- c.PersistentFlags().StringVar(&flagvalPersistent, "persistent-filename", "", "Enter a filename")
- c.MarkPersistentFlagFilename("persistent-filename")
- c.MarkPersistentFlagRequired("persistent-filename")
-
- // filename extensions
- var flagvalExt string
- c.Flags().StringVar(&flagvalExt, "filename-ext", "", "Enter a filename (extension limited)")
- c.MarkFlagFilename("filename-ext")
-
- // filename extensions
- var flagvalCustom string
- c.Flags().StringVar(&flagvalCustom, "custom", "", "Enter a filename (extension limited)")
- c.MarkFlagCustom("custom", "__complete_custom")
-
- // subdirectories in a given directory
- var flagvalTheme string
- c.Flags().StringVar(&flagvalTheme, "theme", "", "theme to use (located in /themes/THEMENAME/)")
- c.Flags().SetAnnotation("theme", BashCompSubdirsInDir, []string{"themes"})
-
- out := new(bytes.Buffer)
- c.GenBashCompletion(out)
- str := out.String()
-
- check(t, str, "_cobra-test")
- check(t, str, "_cobra-test_echo")
- check(t, str, "_cobra-test_echo_times")
- check(t, str, "_cobra-test_print")
- check(t, str, "_cobra-test_cmd__colon")
+ rootCmd := &Command{
+ Use: "root",
+ ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"},
+ ValidArgs: []string{"pod", "node", "service", "replicationcontroller"},
+ BashCompletionFunction: bashCompletionFunc,
+ Run: emptyRun,
+ }
+ rootCmd.Flags().IntP("introot", "i", -1, "help message for flag introot")
+ rootCmd.MarkFlagRequired("introot")
+
+ // Filename.
+ rootCmd.Flags().String("filename", "", "Enter a filename")
+ rootCmd.MarkFlagFilename("filename", "json", "yaml", "yml")
+
+ // Persistent filename.
+ rootCmd.PersistentFlags().String("persistent-filename", "", "Enter a filename")
+ rootCmd.MarkPersistentFlagFilename("persistent-filename")
+ rootCmd.MarkPersistentFlagRequired("persistent-filename")
+
+ // Filename extensions.
+ rootCmd.Flags().String("filename-ext", "", "Enter a filename (extension limited)")
+ rootCmd.MarkFlagFilename("filename-ext")
+ rootCmd.Flags().String("custom", "", "Enter a filename (extension limited)")
+ rootCmd.MarkFlagCustom("custom", "__complete_custom")
+
+ // Subdirectories in a given directory.
+ rootCmd.Flags().String("theme", "", "theme to use (located in /themes/THEMENAME/)")
+ rootCmd.Flags().SetAnnotation("theme", BashCompSubdirsInDir, []string{"themes"})
+
+ echoCmd := &Command{
+ Use: "echo [string to echo]",
+ Aliases: []string{"say"},
+ Short: "Echo anything to the screen",
+ Long: "an utterly useless command for testing.",
+ Example: "Just run cobra-test echo",
+ Run: emptyRun,
+ }
+
+ printCmd := &Command{
+ Use: "print [string to print]",
+ Args: MinimumNArgs(1),
+ Short: "Print anything to the screen",
+ Long: "an absolutely utterly useless command for testing.",
+ Run: emptyRun,
+ }
+
+ deprecatedCmd := &Command{
+ Use: "deprecated [can't do anything here]",
+ Args: NoArgs,
+ Short: "A command which is deprecated",
+ Long: "an absolutely utterly useless command for testing deprecation!.",
+ Deprecated: "Please use echo instead",
+ Run: emptyRun,
+ }
+
+ colonCmd := &Command{
+ Use: "cmd:colon",
+ Run: emptyRun,
+ }
+
+ timesCmd := &Command{
+ Use: "times [# times] [string to echo]",
+ SuggestFor: []string{"counts"},
+ Args: OnlyValidArgs,
+ ValidArgs: []string{"one", "two", "three", "four"},
+ Short: "Echo anything to the screen more times",
+ Long: "a slightly useless command for testing.",
+ Run: emptyRun,
+ }
+
+ echoCmd.AddCommand(timesCmd)
+ rootCmd.AddCommand(echoCmd, printCmd, deprecatedCmd, colonCmd)
+
+ buf := new(bytes.Buffer)
+ rootCmd.GenBashCompletion(buf)
+ output := buf.String()
+
+ check(t, output, "_root")
+ check(t, output, "_root_echo")
+ check(t, output, "_root_echo_times")
+ check(t, output, "_root_print")
+ check(t, output, "_root_cmd__colon")
// check for required flags
- check(t, str, `must_have_one_flag+=("--introot=")`)
- check(t, str, `must_have_one_flag+=("--persistent-filename=")`)
+ check(t, output, `must_have_one_flag+=("--introot=")`)
+ check(t, output, `must_have_one_flag+=("--persistent-filename=")`)
// check for custom completion function
- check(t, str, `COMPREPLY=( "hello" )`)
+ check(t, output, `COMPREPLY=( "hello" )`)
// check for required nouns
- check(t, str, `must_have_one_noun+=("pod")`)
+ check(t, output, `must_have_one_noun+=("pod")`)
// check for noun aliases
- check(t, str, `noun_aliases+=("pods")`)
- check(t, str, `noun_aliases+=("rc")`)
- checkOmit(t, str, `must_have_one_noun+=("pods")`)
+ check(t, output, `noun_aliases+=("pods")`)
+ check(t, output, `noun_aliases+=("rc")`)
+ checkOmit(t, output, `must_have_one_noun+=("pods")`)
// check for filename extension flags
- check(t, str, `flags_completion+=("_filedir")`)
+ check(t, output, `flags_completion+=("_filedir")`)
// check for filename extension flags
- check(t, str, `must_have_one_noun+=("three")`)
+ check(t, output, `must_have_one_noun+=("three")`)
// check for filename extension flags
- check(t, str, `flags_completion+=("__handle_filename_extension_flag json|yaml|yml")`)
+ check(t, output, `flags_completion+=("__handle_filename_extension_flag json|yaml|yml")`)
// check for custom flags
- check(t, str, `flags_completion+=("__complete_custom")`)
+ check(t, output, `flags_completion+=("__complete_custom")`)
// check for subdirs_in_dir flags
- check(t, str, `flags_completion+=("__handle_subdirs_in_dir_flag themes")`)
+ check(t, output, `flags_completion+=("__handle_subdirs_in_dir_flag themes")`)
- checkOmit(t, str, cmdDeprecated.Name())
+ checkOmit(t, output, deprecatedCmd.Name())
- // if available, run shellcheck against the script
+ // If available, run shellcheck against the script.
if err := exec.Command("which", "shellcheck").Run(); err != nil {
return
}
- err := runShellCheck(str)
- if err != nil {
+ if err := runShellCheck(output); err != nil {
t.Fatalf("shellcheck failed: %v", err)
}
}
func TestBashCompletionHiddenFlag(t *testing.T) {
- var cmdTrue = &Command{
- Use: "does nothing",
- Run: func(cmd *Command, args []string) {},
- }
+ c := &Command{Use: "c", Run: emptyRun}
- const flagName = "hidden-foo-bar-baz"
+ const flagName = "hiddenFlag"
+ c.Flags().Bool(flagName, false, "")
+ c.Flags().MarkHidden(flagName)
- var flagValue bool
- cmdTrue.Flags().BoolVar(&flagValue, flagName, false, "hidden flag")
- cmdTrue.Flags().MarkHidden(flagName)
+ buf := new(bytes.Buffer)
+ c.GenBashCompletion(buf)
+ output := buf.String()
- out := new(bytes.Buffer)
- cmdTrue.GenBashCompletion(out)
- bashCompletion := out.String()
- if strings.Contains(bashCompletion, flagName) {
- t.Errorf("expected completion to not include %q flag: Got %v", flagName, bashCompletion)
+ if strings.Contains(output, flagName) {
+ t.Errorf("Expected completion to not include %q flag: Got %v", flagName, output)
}
}
func TestBashCompletionDeprecatedFlag(t *testing.T) {
- var cmdTrue = &Command{
- Use: "does nothing",
- Run: func(cmd *Command, args []string) {},
- }
-
- const flagName = "deprecated-foo-bar-baz"
-
- var flagValue bool
- cmdTrue.Flags().BoolVar(&flagValue, flagName, false, "hidden flag")
- cmdTrue.Flags().MarkDeprecated(flagName, "use --does-not-exist instead")
-
- out := new(bytes.Buffer)
- cmdTrue.GenBashCompletion(out)
- bashCompletion := out.String()
- if strings.Contains(bashCompletion, flagName) {
- t.Errorf("expected completion to not include %q flag: Got %v", flagName, bashCompletion)
- }
-}
+ c := &Command{Use: "c", Run: emptyRun}
-func BenchmarkBashCompletion(b *testing.B) {
- c := initializeWithRootCmd()
- cmdEcho.AddCommand(cmdTimes)
- c.AddCommand(cmdEcho, cmdPrint, cmdDeprecated, cmdColon)
+ const flagName = "deprecated-flag"
+ c.Flags().Bool(flagName, false, "")
+ c.Flags().MarkDeprecated(flagName, "use --not-deprecated instead")
buf := new(bytes.Buffer)
+ c.GenBashCompletion(buf)
+ output := buf.String()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- buf.Reset()
- if err := c.GenBashCompletion(buf); err != nil {
- b.Fatal(err)
- }
+ if strings.Contains(output, flagName) {
+ t.Errorf("expected completion to not include %q flag: Got %v", flagName, output)
}
}
diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go
index 8928cefc2..e4b910c5d 100644
--- a/vendor/github.com/spf13/cobra/cobra.go
+++ b/vendor/github.com/spf13/cobra/cobra.go
@@ -188,3 +188,12 @@ func ld(s, t string, ignoreCase bool) int {
}
return d[len(s)][len(t)]
}
+
+func stringInSlice(a string, list []string) bool {
+ for _, b := range list {
+ if b == a {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/spf13/cobra/cobra/README.md b/vendor/github.com/spf13/cobra/cobra/README.md
new file mode 100644
index 000000000..6054f95c5
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/cobra/README.md
@@ -0,0 +1,94 @@
+# Cobra Generator
+
+Cobra provides its own program that will create your application and add any
+commands you want. It's the easiest way to incorporate Cobra into your application.
+
+In order to use the cobra command, compile it using the following command:
+
+ go get github.com/spf13/cobra/cobra
+
+This will create the cobra executable under your `$GOPATH/bin` directory.
+
+### cobra init
+
+The `cobra init [app]` command will create your initial application code
+for you. It is a very powerful application that will populate your program with
+the right structure so you can immediately enjoy all the benefits of Cobra. It
+will also automatically apply the license you specify to your application.
+
+Cobra init is pretty smart. You can provide it a full path, or simply a path
+similar to what is expected in the import.
+
+```
+cobra init github.com/spf13/newApp
+```
+
+### cobra add
+
+Once an application is initialized, Cobra can create additional commands for you.
+Let's say you created an app and you wanted the following commands for it:
+
+* app serve
+* app config
+* app config create
+
+In your project directory (where your main.go file is) you would run the following:
+
+```
+cobra add serve
+cobra add config
+cobra add create -p 'configCmd'
+```
+
+*Note: Use camelCase (not snake_case/snake-case) for command names.
+Otherwise, you will encounter errors.
+For example, `cobra add add-user` is incorrect, but `cobra add addUser` is valid.*
+
+Once you have run these three commands you would have an app structure similar to
+the following:
+
+```
+ ▾ app/
+ ▾ cmd/
+ serve.go
+ config.go
+ create.go
+ main.go
+```
+
+At this point you can run `go run main.go` and it would run your app. `go run
+main.go serve`, `go run main.go config`, `go run main.go config create` along
+with `go run main.go help serve`, etc. would all work.
+
+Obviously you haven't added your own code to these yet. The commands are ready
+for you to give them their tasks. Have fun!
+
+### Configuring the cobra generator
+
+The Cobra generator will be easier to use if you provide a simple configuration
+file which will help you eliminate providing a bunch of repeated information in
+flags over and over.
+
+An example ~/.cobra.yaml file:
+
+```yaml
+author: Steve Francia <spf@spf13.com>
+license: MIT
+```
+
+You can specify no license by setting `license` to `none` or you can specify
+a custom license:
+
+```yaml
+license:
+ header: This file is part of {{ .appName }}.
+ text: |
+ {{ .copyright }}
+
+ This is my license. There are many like it, but this one is mine.
+ My license is my best friend. It is my life. I must master it as I must
+ master my life.
+```
+
+You can also use built-in licenses. For example, **GPLv2**, **GPLv3**, **LGPL**,
+**AGPL**, **MIT**, **2-Clause BSD** or **3-Clause BSD**.
diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go b/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go
index c5e261ce3..e5b37ec72 100644
--- a/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go
+++ b/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go
@@ -18,6 +18,7 @@ import (
"fmt"
"io"
"os"
+ "os/exec"
"path/filepath"
"strings"
"text/template"
@@ -31,7 +32,27 @@ func init() {
envGoPath := os.Getenv("GOPATH")
goPaths := filepath.SplitList(envGoPath)
if len(goPaths) == 0 {
- er("$GOPATH is not set")
+ // Adapted from https://github.com/Masterminds/glide/pull/798/files.
+ // As of Go 1.8 the GOPATH is no longer required to be set. Instead there
+ // is a default value. If there is no GOPATH check for the default value.
+ // Note, checking the GOPATH first to avoid invoking the go toolchain if
+ // possible.
+
+ goExecutable := os.Getenv("COBRA_GO_EXECUTABLE")
+ if len(goExecutable) <= 0 {
+ goExecutable = "go"
+ }
+
+ out, err := exec.Command(goExecutable, "env", "GOPATH").Output()
+ if err != nil {
+ er(err)
+ }
+
+ toolchainGoPath := strings.TrimSpace(string(out))
+ goPaths = filepath.SplitList(toolchainGoPath)
+ if len(goPaths) == 0 {
+ er("$GOPATH is not set")
+ }
}
srcPaths = make([]string, 0, len(goPaths))
for _, goPath := range goPaths {
diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go b/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go
index cf2a6b7af..a070134dd 100644
--- a/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go
+++ b/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go
@@ -63,7 +63,7 @@ func getLicense() License {
// If user wants to have custom license, use that.
if viper.IsSet("license.header") || viper.IsSet("license.text") {
return License{Header: viper.GetString("license.header"),
- Text: "license.text"}
+ Text: viper.GetString("license.text")}
}
// If user wants to have built-in license, use that.
diff --git a/vendor/github.com/spf13/cobra/cobra_test.go b/vendor/github.com/spf13/cobra/cobra_test.go
index d5df951e6..0d1755bdb 100644
--- a/vendor/github.com/spf13/cobra/cobra_test.go
+++ b/vendor/github.com/spf13/cobra/cobra_test.go
@@ -1,1200 +1,10 @@
package cobra
import (
- "bytes"
- "fmt"
- "os"
- "reflect"
- "runtime"
- "strings"
"testing"
"text/template"
-
- "github.com/spf13/pflag"
)
-var tp, te, tt, tr []string
-var rootPersPre, echoPre, echoPersPre, timesPersPre []string
-var flagb1, flagb2, flagb3, flagbr, flagbp bool
-var flags1, flags2a, flags2b, flags3, outs string
-var flagi1, flagi2, flagi3, flagi4, flagir int
-var rootcalled bool
-var versionUsed int
-
-const strtwoParentHelp = "help message for parent flag strtwo"
-const strtwoChildHelp = "help message for child flag strtwo"
-
-var cmdHidden = &Command{
- Use: "hide [secret string to print]",
- Short: "Print anything to screen (if command is known)",
- Long: `an absolutely utterly useless command for testing.`,
- Run: func(cmd *Command, args []string) {
- outs = "hidden"
- },
- Hidden: true,
-}
-
-var cmdPrint = &Command{
- Use: "print [string to print]",
- Args: MinimumNArgs(1),
- Short: "Print anything to the screen",
- Long: `an absolutely utterly useless command for testing.`,
- Run: func(cmd *Command, args []string) {
- tp = args
- },
-}
-
-var cmdEcho = &Command{
- Use: "echo [string to echo]",
- Aliases: []string{"say"},
- Short: "Echo anything to the screen",
- Long: `an utterly useless command for testing.`,
- Example: "Just run cobra-test echo",
- PersistentPreRun: func(cmd *Command, args []string) {
- echoPersPre = args
- },
- PreRun: func(cmd *Command, args []string) {
- echoPre = args
- },
- Run: func(cmd *Command, args []string) {
- te = args
- },
-}
-
-var cmdEchoSub = &Command{
- Use: "echosub [string to print]",
- Short: "second sub command for echo",
- Long: `an absolutely utterly useless command for testing gendocs!.`,
- Run: func(cmd *Command, args []string) {
- },
-}
-
-var cmdDeprecated = &Command{
- Use: "deprecated [can't do anything here]",
- Short: "A command which is deprecated",
- Long: `an absolutely utterly useless command for testing deprecation!.`,
- Deprecated: "Please use echo instead",
- Run: func(cmd *Command, args []string) {
- },
- Args: NoArgs,
-}
-
-var cmdTimes = &Command{
- Use: "times [# times] [string to echo]",
- SuggestFor: []string{"counts"},
- Short: "Echo anything to the screen more times",
- Long: `a slightly useless command for testing.`,
- PersistentPreRun: func(cmd *Command, args []string) {
- timesPersPre = args
- },
- Run: func(cmd *Command, args []string) {
- tt = args
- },
- Args: OnlyValidArgs,
- ValidArgs: []string{"one", "two", "three", "four"},
-}
-
-var cmdRootNoRun = &Command{
- Use: "cobra-test",
- Short: "The root can run its own function",
- Long: "The root description for help",
- PersistentPreRun: func(cmd *Command, args []string) {
- rootPersPre = args
- },
-}
-
-var cmdRootSameName = &Command{
- Use: "print",
- Short: "Root with the same name as a subcommand",
- Long: "The root description for help",
-}
-
-var cmdRootTakesArgs = &Command{
- Use: "root-with-args [random args]",
- Short: "The root can run it's own function and takes args!",
- Long: "The root description for help, and some args",
- Run: func(cmd *Command, args []string) {
- tr = args
- },
- Args: ArbitraryArgs,
-}
-
-var cmdRootWithRun = &Command{
- Use: "cobra-test",
- Short: "The root can run its own function",
- Long: "The root description for help",
- Run: func(cmd *Command, args []string) {
- tr = args
- rootcalled = true
- },
-}
-
-var cmdSubNoRun = &Command{
- Use: "subnorun",
- Short: "A subcommand without a Run function",
- Long: "A long output about a subcommand without a Run function",
-}
-
-var cmdCustomFlags = &Command{
- Use: "customflags [flags] -- REMOTE_COMMAND",
- Short: "A command that expects flags in a custom location",
- Long: "A long output about a command that expects flags in a custom location",
- Run: func(cmd *Command, args []string) {
- },
-}
-
-var cmdVersion1 = &Command{
- Use: "version",
- Short: "Print the version number",
- Long: `First version of the version command`,
- Run: func(cmd *Command, args []string) {
- versionUsed = 1
- },
-}
-
-var cmdVersion2 = &Command{
- Use: "version",
- Short: "Print the version number",
- Long: `Second version of the version command`,
- Run: func(cmd *Command, args []string) {
- versionUsed = 2
- },
-}
-
-var cmdColon = &Command{
- Use: "cmd:colon",
- Run: func(cmd *Command, args []string) {
- },
-}
-
-func flagInit() {
- cmdEcho.ResetFlags()
- cmdPrint.ResetFlags()
- cmdTimes.ResetFlags()
- cmdRootNoRun.ResetFlags()
- cmdRootSameName.ResetFlags()
- cmdRootWithRun.ResetFlags()
- cmdSubNoRun.ResetFlags()
- cmdCustomFlags.ResetFlags()
- cmdVersion1.ResetFlags()
- cmdVersion2.ResetFlags()
-
- cmdRootNoRun.PersistentFlags().StringVarP(&flags2a, "strtwo", "t", "two", strtwoParentHelp)
- cmdCustomFlags.Flags().IntVar(&flagi4, "intfour", 456, "help message for flag intfour")
- cmdEcho.Flags().BoolVarP(&flagb1, "boolone", "b", true, "help message for flag boolone")
- cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone")
- cmdEcho.PersistentFlags().BoolVarP(&flagbp, "persistentbool", "p", false, "help message for flag persistentbool")
- cmdEcho.PersistentFlags().StringVarP(&flags1, "strone", "s", "one", "help message for flag strone")
- cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree")
- cmdTimes.Flags().BoolVarP(&flagb2, "booltwo", "c", false, "help message for flag booltwo")
- cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
- cmdTimes.Flags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
- cmdTimes.PersistentFlags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
- cmdPrint.Flags().BoolVarP(&flagb3, "boolthree", "b", true, "help message for flag boolthree")
- cmdPrint.PersistentFlags().StringVarP(&flags3, "strthree", "s", "three", "help message for flag strthree")
-}
-
-func commandInit() {
- cmdEcho.ResetCommands()
- cmdPrint.ResetCommands()
- cmdTimes.ResetCommands()
- cmdRootNoRun.ResetCommands()
- cmdRootSameName.ResetCommands()
- cmdRootWithRun.ResetCommands()
- cmdSubNoRun.ResetCommands()
- cmdCustomFlags.ResetCommands()
-}
-
-func initialize() *Command {
- tt, tp, te = nil, nil, nil
- rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
-
- var c = cmdRootNoRun
- flagInit()
- commandInit()
- return c
-}
-
-func initializeWithSameName() *Command {
- tt, tp, te = nil, nil, nil
- rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
- var c = cmdRootSameName
- flagInit()
- commandInit()
- return c
-}
-
-func initializeWithRootCmd() *Command {
- cmdRootWithRun.ResetCommands()
- tt, tp, te, tr, rootcalled = nil, nil, nil, nil, false
- flagInit()
- cmdRootWithRun.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot")
- cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag introot")
- commandInit()
- return cmdRootWithRun
-}
-
-type resulter struct {
- Error error
- Output string
- Command *Command
-}
-
-func fullSetupTest(args ...string) resulter {
- c := initializeWithRootCmd()
-
- return fullTester(c, args...)
-}
-
-func noRRSetupTestSilenced(args ...string) resulter {
- c := initialize()
- c.SilenceErrors = true
- c.SilenceUsage = true
- return fullTester(c, args...)
-}
-
-func noRRSetupTest(args ...string) resulter {
- c := initialize()
-
- return fullTester(c, args...)
-}
-
-func rootOnlySetupTest(args ...string) resulter {
- c := initializeWithRootCmd()
-
- return simpleTester(c, args...)
-}
-
-func simpleTester(c *Command, args ...string) resulter {
- buf := new(bytes.Buffer)
- // Testing flag with invalid input
- c.SetOutput(buf)
- c.SetArgs(args)
-
- err := c.Execute()
- output := buf.String()
-
- return resulter{err, output, c}
-}
-
-func simpleTesterC(c *Command, args ...string) resulter {
- buf := new(bytes.Buffer)
- // Testing flag with invalid input
- c.SetOutput(buf)
- c.SetArgs(args)
-
- cmd, err := c.ExecuteC()
- output := buf.String()
-
- return resulter{err, output, cmd}
-}
-
-func fullTester(c *Command, args ...string) resulter {
- buf := new(bytes.Buffer)
- // Testing flag with invalid input
- c.SetOutput(buf)
- cmdEcho.AddCommand(cmdTimes)
- c.AddCommand(cmdPrint, cmdEcho, cmdSubNoRun, cmdCustomFlags, cmdDeprecated)
- c.SetArgs(args)
-
- err := c.Execute()
- output := buf.String()
-
- return resulter{err, output, c}
-}
-
-func logErr(t *testing.T, found, expected string) {
- out := new(bytes.Buffer)
-
- _, _, line, ok := runtime.Caller(2)
- if ok {
- fmt.Fprintf(out, "Line: %d ", line)
- }
- fmt.Fprintf(out, "Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- t.Errorf(out.String())
-}
-
-func checkStringContains(t *testing.T, found, expected string) {
- if !strings.Contains(found, expected) {
- logErr(t, found, expected)
- }
-}
-
-func checkResultContains(t *testing.T, x resulter, check string) {
- checkStringContains(t, x.Output, check)
-}
-
-func checkStringOmits(t *testing.T, found, expected string) {
- if strings.Contains(found, expected) {
- logErr(t, found, expected)
- }
-}
-
-func checkResultOmits(t *testing.T, x resulter, check string) {
- checkStringOmits(t, x.Output, check)
-}
-
-func checkOutputContains(t *testing.T, c *Command, check string) {
- buf := new(bytes.Buffer)
- c.SetOutput(buf)
- c.Execute()
-
- if !strings.Contains(buf.String(), check) {
- logErr(t, buf.String(), check)
- }
-}
-
-func TestSingleCommand(t *testing.T) {
- noRRSetupTest("print", "one", "two")
-
- if te != nil || tt != nil {
- t.Error("Wrong command called")
- }
- if tp == nil {
- t.Error("Wrong command called")
- }
- if strings.Join(tp, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
-}
-
-func TestChildCommand(t *testing.T) {
- noRRSetupTest("echo", "times", "one", "two")
-
- if te != nil || tp != nil {
- t.Error("Wrong command called")
- }
- if tt == nil {
- t.Error("Wrong command called")
- }
- if strings.Join(tt, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
-}
-
-func TestCommandAlias(t *testing.T) {
- noRRSetupTest("say", "times", "one", "two")
-
- if te != nil || tp != nil {
- t.Error("Wrong command called")
- }
- if tt == nil {
- t.Error("Wrong command called")
- }
- if strings.Join(tt, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
-}
-
-func TestPrefixMatching(t *testing.T) {
- EnablePrefixMatching = true
- noRRSetupTest("ech", "times", "one", "two")
-
- if te != nil || tp != nil {
- t.Error("Wrong command called")
- }
- if tt == nil {
- t.Error("Wrong command called")
- }
- if strings.Join(tt, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
-
- EnablePrefixMatching = false
-}
-
-func TestNoPrefixMatching(t *testing.T) {
- EnablePrefixMatching = false
-
- noRRSetupTest("ech", "times", "one", "two")
-
- if !(tt == nil && te == nil && tp == nil) {
- t.Error("Wrong command called")
- }
-}
-
-func TestAliasPrefixMatching(t *testing.T) {
- EnablePrefixMatching = true
- noRRSetupTest("sa", "times", "one", "two")
-
- if te != nil || tp != nil {
- t.Error("Wrong command called")
- }
- if tt == nil {
- t.Error("Wrong command called")
- }
- if strings.Join(tt, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
- EnablePrefixMatching = false
-}
-
-func TestChildSameName(t *testing.T) {
- c := initializeWithSameName()
- c.AddCommand(cmdPrint, cmdEcho)
- c.SetArgs([]string{"print", "one", "two"})
- c.Execute()
-
- if te != nil || tt != nil {
- t.Error("Wrong command called")
- }
- if tp == nil {
- t.Error("Wrong command called")
- }
- if strings.Join(tp, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
-}
-
-func TestGrandChildSameName(t *testing.T) {
- c := initializeWithSameName()
- cmdTimes.AddCommand(cmdPrint)
- c.AddCommand(cmdTimes)
- c.SetArgs([]string{"times", "print", "one", "two"})
- c.Execute()
-
- if te != nil || tt != nil {
- t.Error("Wrong command called")
- }
- if tp == nil {
- t.Error("Wrong command called")
- }
- if strings.Join(tp, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
-}
-
-func TestUsage(t *testing.T) {
- x := fullSetupTest("help")
- checkResultContains(t, x, cmdRootWithRun.Use+" [flags]")
- x = fullSetupTest("help", "customflags")
- checkResultContains(t, x, cmdCustomFlags.Use)
- checkResultOmits(t, x, cmdCustomFlags.Use+" [flags]")
-}
-
-func TestRootTakesNoArgs(t *testing.T) {
- c := initializeWithSameName()
- c.AddCommand(cmdPrint, cmdEcho)
- result := simpleTester(c, "illegal")
-
- if result.Error == nil {
- t.Fatal("Expected an error")
- }
-
- expectedError := `unknown command "illegal" for "print"`
- if !strings.Contains(result.Error.Error(), expectedError) {
- t.Errorf("exptected %v, got %v", expectedError, result.Error.Error())
- }
-}
-
-func TestRootTakesArgs(t *testing.T) {
- c := cmdRootTakesArgs
- result := simpleTester(c, "legal")
-
- if result.Error != nil {
- t.Errorf("expected no error, but got %v", result.Error)
- }
-}
-
-func TestSubCmdTakesNoArgs(t *testing.T) {
- result := fullSetupTest("deprecated", "illegal")
-
- if result.Error == nil {
- t.Fatal("Expected an error")
- }
-
- expectedError := `unknown command "illegal" for "cobra-test deprecated"`
- if !strings.Contains(result.Error.Error(), expectedError) {
- t.Errorf("expected %v, got %v", expectedError, result.Error.Error())
- }
-}
-
-func TestSubCmdTakesArgs(t *testing.T) {
- noRRSetupTest("echo", "times", "one", "two")
- if strings.Join(tt, " ") != "one two" {
- t.Error("Command didn't parse correctly")
- }
-}
-
-func TestCmdOnlyValidArgs(t *testing.T) {
- result := noRRSetupTest("echo", "times", "one", "two", "five")
-
- if result.Error == nil {
- t.Fatal("Expected an error")
- }
-
- expectedError := `invalid argument "five"`
- if !strings.Contains(result.Error.Error(), expectedError) {
- t.Errorf("expected %v, got %v", expectedError, result.Error.Error())
- }
-}
-
-func TestFlagLong(t *testing.T) {
- noRRSetupTest("echo", "--intone=13", "something", "--", "here")
-
- if cmdEcho.ArgsLenAtDash() != 1 {
- t.Errorf("expected argsLenAtDash: %d but got %d", 1, cmdRootNoRun.ArgsLenAtDash())
- }
- if strings.Join(te, " ") != "something here" {
- t.Errorf("flags didn't leave proper args remaining..%s given", te)
- }
- if flagi1 != 13 {
- t.Errorf("int flag didn't get correct value, had %d", flagi1)
- }
- if flagi2 != 234 {
- t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
- }
-}
-
-func TestFlagShort(t *testing.T) {
- noRRSetupTest("echo", "-i13", "--", "something", "here")
-
- if cmdEcho.ArgsLenAtDash() != 0 {
- t.Errorf("expected argsLenAtDash: %d but got %d", 0, cmdRootNoRun.ArgsLenAtDash())
- }
- if strings.Join(te, " ") != "something here" {
- t.Errorf("flags didn't leave proper args remaining..%s given", te)
- }
- if flagi1 != 13 {
- t.Errorf("int flag didn't get correct value, had %d", flagi1)
- }
- if flagi2 != 234 {
- t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
- }
-
- noRRSetupTest("echo", "-i", "13", "something", "here")
-
- if strings.Join(te, " ") != "something here" {
- t.Errorf("flags didn't leave proper args remaining..%s given", te)
- }
- if flagi1 != 13 {
- t.Errorf("int flag didn't get correct value, had %d", flagi1)
- }
- if flagi2 != 234 {
- t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
- }
-
- noRRSetupTest("print", "-i99", "one", "two")
-
- if strings.Join(tp, " ") != "one two" {
- t.Errorf("flags didn't leave proper args remaining..%s given", tp)
- }
- if flagi3 != 99 {
- t.Errorf("int flag didn't get correct value, had %d", flagi3)
- }
- if flagi1 != 123 {
- t.Errorf("default flag value changed on different command with same shortname, 234 expected, %d given", flagi2)
- }
-}
-
-func TestChildCommandFlags(t *testing.T) {
- noRRSetupTest("echo", "times", "-j", "99", "one", "two")
-
- if strings.Join(tt, " ") != "one two" {
- t.Errorf("flags didn't leave proper args remaining..%s given", tt)
- }
-
- // Testing with flag that shouldn't be persistent
- r := noRRSetupTest("echo", "times", "-j", "99", "-i77", "one", "two")
-
- if r.Error == nil {
- t.Errorf("invalid flag should generate error")
- }
-
- if !strings.Contains(r.Error.Error(), "unknown shorthand") {
- t.Errorf("Wrong error message displayed, \n %s", r.Error)
- }
-
- if flagi2 != 99 {
- t.Errorf("flag value should be 99, %d given", flagi2)
- }
-
- if flagi1 != 123 {
- t.Errorf("unset flag should have default value, expecting 123, given %d", flagi1)
- }
-
- // Testing with flag only existing on child
- r = noRRSetupTest("echo", "-j", "99", "-i77", "one", "two")
-
- if r.Error == nil {
- t.Errorf("invalid flag should generate error")
- }
- if !strings.Contains(r.Error.Error(), "unknown shorthand flag") {
- t.Errorf("Wrong error message displayed, \n %s", r.Error)
- }
-
- // Testing with persistent flag overwritten by child
- noRRSetupTest("echo", "times", "--strtwo=child", "one", "two")
-
- if flags2b != "child" {
- t.Errorf("flag value should be child, %s given", flags2b)
- }
-
- if flags2a != "two" {
- t.Errorf("unset flag should have default value, expecting two, given %s", flags2a)
- }
-
- // Testing flag with invalid input
- r = noRRSetupTest("echo", "-i10E")
-
- if r.Error == nil {
- t.Errorf("invalid input should generate error")
- }
- if !strings.Contains(r.Error.Error(), "invalid syntax") {
- t.Errorf("Wrong error message displayed, \n %s", r.Error)
- }
-}
-
-func TestTrailingCommandFlags(t *testing.T) {
- x := fullSetupTest("echo", "two", "-x")
-
- if x.Error == nil {
- t.Errorf("invalid flag should generate error")
- }
-}
-
-func TestInvalidSubcommandFlags(t *testing.T) {
- cmd := initializeWithRootCmd()
- cmd.AddCommand(cmdTimes)
-
- result := simpleTester(cmd, "times", "--inttwo=2", "--badflag=bar")
- // given that we are not checking here result.Error we check for
- // stock usage message
- checkResultContains(t, result, "cobra-test times [# times]")
- if strings.Contains(result.Error.Error(), "unknown flag: --inttwo") {
- t.Errorf("invalid --badflag flag shouldn't fail on 'unknown' --inttwo flag")
- }
-
-}
-
-func TestSubcommandExecuteC(t *testing.T) {
- cmd := initializeWithRootCmd()
- double := &Command{
- Use: "double message",
- Run: func(c *Command, args []string) {
- msg := strings.Join(args, " ")
- c.Println(msg, msg)
- },
- }
-
- echo := &Command{
- Use: "echo message",
- Run: func(c *Command, args []string) {
- msg := strings.Join(args, " ")
- c.Println(msg)
- },
- }
-
- cmd.AddCommand(double, echo)
-
- result := simpleTesterC(cmd, "double", "hello", "world")
- checkResultContains(t, result, "hello world hello world")
-
- if result.Command.Name() != "double" {
- t.Errorf("invalid cmd returned from ExecuteC: should be 'double' but got %s", result.Command.Name())
- }
-
- result = simpleTesterC(cmd, "echo", "msg", "to", "be", "echoed")
- checkResultContains(t, result, "msg to be echoed")
-
- if result.Command.Name() != "echo" {
- t.Errorf("invalid cmd returned from ExecuteC: should be 'echo' but got %s", result.Command.Name())
- }
-}
-
-func TestSubcommandArgEvaluation(t *testing.T) {
- cmd := initializeWithRootCmd()
-
- first := &Command{
- Use: "first",
- Run: func(cmd *Command, args []string) {
- },
- }
- cmd.AddCommand(first)
-
- second := &Command{
- Use: "second",
- Run: func(cmd *Command, args []string) {
- fmt.Fprintf(cmd.OutOrStdout(), "%v", args)
- },
- }
- first.AddCommand(second)
-
- result := simpleTester(cmd, "first", "second", "first", "third")
-
- expectedOutput := fmt.Sprint([]string{"first third"})
- if result.Output != expectedOutput {
- t.Errorf("exptected %v, got %v", expectedOutput, result.Output)
- }
-}
-
-func TestPersistentFlags(t *testing.T) {
- fullSetupTest("echo", "-s", "something", "-p", "more", "here")
-
- // persistentFlag should act like normal flag on its own command
- if strings.Join(te, " ") != "more here" {
- t.Errorf("flags didn't leave proper args remaining..%s given", te)
- }
- if flags1 != "something" {
- t.Errorf("string flag didn't get correct value, had %v", flags1)
- }
- if !flagbp {
- t.Errorf("persistent bool flag not parsed correctly. Expected true, had %v", flagbp)
- }
-
- // persistentFlag should act like normal flag on its own command
- fullSetupTest("echo", "times", "-s", "again", "-c", "-p", "one", "two")
-
- if strings.Join(tt, " ") != "one two" {
- t.Errorf("flags didn't leave proper args remaining. %s given", tt)
- }
-
- if flags1 != "again" {
- t.Errorf("string flag didn't get correct value, had %v", flags1)
- }
-
- if !flagb2 {
- t.Errorf("local flag not parsed correctly. Expected true, had %v", flagb2)
- }
- if !flagbp {
- t.Errorf("persistent bool flag not parsed correctly. Expected true, had %v", flagbp)
- }
-}
-
-func TestHelpCommand(t *testing.T) {
- x := fullSetupTest("help")
- checkResultContains(t, x, cmdRootWithRun.Long)
-
- x = fullSetupTest("help", "echo")
- checkResultContains(t, x, cmdEcho.Long)
-
- x = fullSetupTest("help", "echo", "times")
- checkResultContains(t, x, cmdTimes.Long)
-}
-
-func TestChildCommandHelp(t *testing.T) {
- c := noRRSetupTest("print", "--help")
- checkResultContains(t, c, strtwoParentHelp)
- r := noRRSetupTest("echo", "times", "--help")
- checkResultContains(t, r, strtwoChildHelp)
-}
-
-func TestNonRunChildHelp(t *testing.T) {
- x := noRRSetupTest("subnorun")
- checkResultContains(t, x, cmdSubNoRun.Long)
-}
-
-func TestRunnableRootCommand(t *testing.T) {
- x := fullSetupTest("")
-
- if !rootcalled {
- t.Errorf("Root Function was not called\n out:%v", x.Error)
- }
-}
-
-func TestVisitParents(t *testing.T) {
- c := &Command{Use: "app"}
- sub := &Command{Use: "sub"}
- dsub := &Command{Use: "dsub"}
- sub.AddCommand(dsub)
- c.AddCommand(sub)
- total := 0
- add := func(x *Command) {
- total++
- }
- sub.VisitParents(add)
- if total != 1 {
- t.Errorf("Should have visited 1 parent but visited %d", total)
- }
-
- total = 0
- dsub.VisitParents(add)
- if total != 2 {
- t.Errorf("Should have visited 2 parent but visited %d", total)
- }
-
- total = 0
- c.VisitParents(add)
- if total != 0 {
- t.Errorf("Should have not visited any parent but visited %d", total)
- }
-}
-
-func TestRunnableRootCommandNilInput(t *testing.T) {
- c := initializeWithRootCmd()
-
- buf := new(bytes.Buffer)
- // Testing flag with invalid input
- c.SetOutput(buf)
- cmdEcho.AddCommand(cmdTimes)
- c.AddCommand(cmdPrint, cmdEcho)
- c.SetArgs([]string{})
-
- err := c.Execute()
- if err != nil {
- t.Errorf("Execute() failed with %v", err)
- }
-
- if !rootcalled {
- t.Errorf("Root Function was not called")
- }
-}
-
-func TestRunnableRootCommandEmptyInput(t *testing.T) {
- args := []string{"", "--introot=12", ""}
- c := initializeWithRootCmd()
-
- buf := new(bytes.Buffer)
- // Testing flag with invalid input
- c.SetOutput(buf)
- cmdEcho.AddCommand(cmdTimes)
- c.AddCommand(cmdPrint, cmdEcho)
- c.SetArgs(args)
-
- c.Execute()
-
- if !rootcalled {
- t.Errorf("Root Function was not called.\nOutput was:\n%s\n", buf)
- }
-}
-
-func TestInvalidSubcommandWhenArgsAllowed(t *testing.T) {
- fullSetupTest("echo", "invalid-sub")
-
- if te[0] != "invalid-sub" {
- t.Errorf("Subcommand didn't work...")
- }
-}
-
-func TestRootFlags(t *testing.T) {
- fullSetupTest("-i", "17", "-b")
-
- if !flagbr {
- t.Errorf("flag value should be true, %v given", flagbr)
- }
-
- if flagir != 17 {
- t.Errorf("flag value should be 17, %d given", flagir)
- }
-}
-
-func TestRootHelp(t *testing.T) {
- x := fullSetupTest("--help")
-
- checkResultContains(t, x, "Available Commands:")
- checkResultContains(t, x, "for more information about a command")
-
- if strings.Contains(x.Output, "unknown flag: --help") {
- t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
- }
-
- if strings.Contains(x.Output, cmdEcho.Use) {
- t.Errorf("--help shouldn't display subcommand's usage, Got: \n %s", x.Output)
- }
-
- x = fullSetupTest("echo", "--help")
-
- if strings.Contains(x.Output, cmdTimes.Use) {
- t.Errorf("--help shouldn't display subsubcommand's usage, Got: \n %s", x.Output)
- }
-
- checkResultContains(t, x, "Available Commands:")
- checkResultContains(t, x, "for more information about a command")
-
- if strings.Contains(x.Output, "unknown flag: --help") {
- t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
- }
-
-}
-
-func TestFlagAccess(t *testing.T) {
- initialize()
-
- local := cmdTimes.LocalFlags()
- inherited := cmdTimes.InheritedFlags()
-
- for _, f := range []string{"inttwo", "strtwo", "booltwo"} {
- if local.Lookup(f) == nil {
- t.Errorf("LocalFlags expected to contain %s, Got: nil", f)
- }
- }
- if inherited.Lookup("strone") == nil {
- t.Errorf("InheritedFlags expected to contain strone, Got: nil")
- }
- if inherited.Lookup("strtwo") != nil {
- t.Errorf("InheritedFlags shouldn not contain overwritten flag strtwo")
- }
-}
-
-func TestNoNRunnableRootCommandNilInput(t *testing.T) {
- c := initialize()
-
- buf := new(bytes.Buffer)
- // Testing flag with invalid input
- c.SetOutput(buf)
- cmdEcho.AddCommand(cmdTimes)
- c.AddCommand(cmdPrint, cmdEcho)
- c.SetArgs([]string{})
-
- c.Execute()
-
- if !strings.Contains(buf.String(), cmdRootNoRun.Long) {
- t.Errorf("Expected to get help output, Got: \n %s", buf)
- }
-}
-
-func TestRootNoCommandHelp(t *testing.T) {
- x := rootOnlySetupTest("--help")
-
- checkResultOmits(t, x, "Available Commands:")
- checkResultOmits(t, x, "for more information about a command")
-
- if strings.Contains(x.Output, "unknown flag: --help") {
- t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
- }
-
- x = rootOnlySetupTest("echo", "--help")
-
- checkResultOmits(t, x, "Available Commands:")
- checkResultOmits(t, x, "for more information about a command")
-
- if strings.Contains(x.Output, "unknown flag: --help") {
- t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
- }
-}
-
-func TestRootUnknownCommand(t *testing.T) {
- r := noRRSetupTest("bogus")
- s := "Error: unknown command \"bogus\" for \"cobra-test\"\nRun 'cobra-test --help' for usage.\n"
-
- if r.Output != s {
- t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output)
- }
-
- r = noRRSetupTest("--strtwo=a", "bogus")
- if r.Output != s {
- t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output)
- }
-}
-
-func TestRootUnknownCommandSilenced(t *testing.T) {
- r := noRRSetupTestSilenced("bogus")
-
- if r.Output != "" {
- t.Errorf("Unexpected response.\nExpecting to be: \n\"\"\n Got:\n %q\n", r.Output)
- }
-
- r = noRRSetupTestSilenced("--strtwo=a", "bogus")
- if r.Output != "" {
- t.Errorf("Unexpected response.\nExpecting to be:\n\"\"\nGot:\n %q\n", r.Output)
- }
-}
-
-func TestRootSuggestions(t *testing.T) {
- outputWithSuggestions := "Error: unknown command \"%s\" for \"cobra-test\"\n\nDid you mean this?\n\t%s\n\nRun 'cobra-test --help' for usage.\n"
- outputWithoutSuggestions := "Error: unknown command \"%s\" for \"cobra-test\"\nRun 'cobra-test --help' for usage.\n"
-
- cmd := initializeWithRootCmd()
- cmd.AddCommand(cmdTimes)
-
- tests := map[string]string{
- "time": "times",
- "tiems": "times",
- "tims": "times",
- "timeS": "times",
- "rimes": "times",
- "ti": "times",
- "t": "times",
- "timely": "times",
- "ri": "",
- "timezone": "",
- "foo": "",
- "counts": "times",
- }
-
- for typo, suggestion := range tests {
- for _, suggestionsDisabled := range []bool{false, true} {
- cmd.DisableSuggestions = suggestionsDisabled
- result := simpleTester(cmd, typo)
- expected := ""
- if len(suggestion) == 0 || suggestionsDisabled {
- expected = fmt.Sprintf(outputWithoutSuggestions, typo)
- } else {
- expected = fmt.Sprintf(outputWithSuggestions, typo, suggestion)
- }
- if result.Output != expected {
- t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", expected, result.Output)
- }
- }
- }
-}
-
-func TestFlagsBeforeCommand(t *testing.T) {
- // short without space
- x := fullSetupTest("-i10", "echo")
- if x.Error != nil {
- t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
- }
-
- x = noRRSetupTest("echo", "-i=10")
- if x.Error != nil {
- t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error)
- }
-
- // long with equals
- x = noRRSetupTest("--intone=123", "echo", "one", "two")
- if x.Error != nil {
- t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error)
- }
-
- // With parsing error properly reported
- x = fullSetupTest("-i10E", "echo")
- if !strings.Contains(x.Error.Error(), "invalid syntax") {
- t.Errorf("Wrong error message displayed, \n %s", x.Error)
- }
-}
-
-func TestRemoveCommand(t *testing.T) {
- versionUsed = 0
- c := initializeWithRootCmd()
- c.AddCommand(cmdVersion1)
- c.RemoveCommand(cmdVersion1)
- x := fullTester(c, "version")
- if x.Error == nil {
- t.Errorf("Removed command should not have been called\n")
- return
- }
-}
-
-func TestCommandWithoutSubcommands(t *testing.T) {
- c := initializeWithRootCmd()
-
- x := simpleTester(c, "")
- if x.Error != nil {
- t.Errorf("Calling command without subcommands should not have error: %v", x.Error)
- return
- }
-}
-
-func TestCommandWithoutSubcommandsWithArg(t *testing.T) {
- c := initializeWithRootCmd()
- expectedArgs := []string{"arg"}
-
- x := simpleTester(c, "arg")
- if x.Error != nil {
- t.Errorf("Calling command without subcommands but with arg should not have error: %v", x.Error)
- return
- }
- if !reflect.DeepEqual(expectedArgs, tr) {
- t.Errorf("Calling command without subcommands but with arg has wrong args: expected: %v, actual: %v", expectedArgs, tr)
- return
- }
-}
-
-func TestReplaceCommandWithRemove(t *testing.T) {
- versionUsed = 0
- c := initializeWithRootCmd()
- c.AddCommand(cmdVersion1)
- c.RemoveCommand(cmdVersion1)
- c.AddCommand(cmdVersion2)
- x := fullTester(c, "version")
- if x.Error != nil {
- t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
- return
- }
- if versionUsed == 1 {
- t.Errorf("Removed command shouldn't be called\n")
- }
- if versionUsed != 2 {
- t.Errorf("Replacing command should have been called but didn't\n")
- }
-}
-
-func TestDeprecatedSub(t *testing.T) {
- c := fullSetupTest("deprecated")
-
- checkResultContains(t, c, cmdDeprecated.Deprecated)
-}
-
-func TestPreRun(t *testing.T) {
- noRRSetupTest("echo", "one", "two")
- if echoPre == nil || echoPersPre == nil {
- t.Error("PreRun or PersistentPreRun not called")
- }
- if rootPersPre != nil || timesPersPre != nil {
- t.Error("Wrong *Pre functions called!")
- }
-
- noRRSetupTest("echo", "times", "one", "two")
- if timesPersPre == nil {
- t.Error("PreRun or PersistentPreRun not called")
- }
- if echoPre != nil || echoPersPre != nil || rootPersPre != nil {
- t.Error("Wrong *Pre functions called!")
- }
-
- noRRSetupTest("print", "one", "two")
- if rootPersPre == nil {
- t.Error("Parent PersistentPreRun not called but should not have been")
- }
- if echoPre != nil || echoPersPre != nil || timesPersPre != nil {
- t.Error("Wrong *Pre functions called!")
- }
-}
-
-// Check if cmdEchoSub gets PersistentPreRun from rootCmd even if is added last
-func TestPeristentPreRunPropagation(t *testing.T) {
- rootCmd := initialize()
-
- // First add the cmdEchoSub to cmdPrint
- cmdPrint.AddCommand(cmdEchoSub)
- // Now add cmdPrint to rootCmd
- rootCmd.AddCommand(cmdPrint)
-
- rootCmd.SetArgs([]string{"print", "echosub", "lala"})
- rootCmd.Execute()
-
- if len(rootPersPre) == 0 || rootPersPre[0] != "lala" {
- t.Error("RootCmd PersistentPreRun not called but should have been")
- }
-}
-
-func TestGlobalNormFuncPropagation(t *testing.T) {
- normFunc := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
- return pflag.NormalizedName(name)
- }
-
- rootCmd := initialize()
- rootCmd.SetGlobalNormalizationFunc(normFunc)
- if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() {
- t.Error("rootCmd seems to have a wrong normalization function")
- }
-
- // First add the cmdEchoSub to cmdPrint
- cmdPrint.AddCommand(cmdEchoSub)
- if cmdPrint.GlobalNormalizationFunc() != nil && cmdEchoSub.GlobalNormalizationFunc() != nil {
- t.Error("cmdPrint and cmdEchoSub should had no normalization functions")
- }
-
- // Now add cmdPrint to rootCmd
- rootCmd.AddCommand(cmdPrint)
- if reflect.ValueOf(cmdPrint.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() ||
- reflect.ValueOf(cmdEchoSub.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() {
- t.Error("cmdPrint and cmdEchoSub should had the normalization function of rootCmd")
- }
-}
-
-func TestFlagOnPflagCommandLine(t *testing.T) {
- flagName := "flagOnCommandLine"
- pflag.String(flagName, "", "about my flag")
- r := fullSetupTest("--help")
-
- checkResultContains(t, r, flagName)
-
- // Reset pflag.CommandLine flagset.
- pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
-}
-
func TestAddTemplateFunctions(t *testing.T) {
AddTemplateFunc("t", func() bool { return true })
AddTemplateFuncs(template.FuncMap{
@@ -1202,43 +12,11 @@ func TestAddTemplateFunctions(t *testing.T) {
"h": func() string { return "Hello," },
"w": func() string { return "world." }})
- const usage = "Hello, world."
-
c := &Command{}
c.SetUsageTemplate(`{{if t}}{{h}}{{end}}{{if f}}{{h}}{{end}} {{w}}`)
- if us := c.UsageString(); us != usage {
- t.Errorf("c.UsageString() != \"%s\", is \"%s\"", usage, us)
- }
-}
-
-func TestUsageIsNotPrintedTwice(t *testing.T) {
- var cmd = &Command{Use: "root"}
- var sub = &Command{Use: "sub"}
- cmd.AddCommand(sub)
-
- r := simpleTester(cmd, "")
- if strings.Count(r.Output, "Usage:") != 1 {
- t.Error("Usage output is not printed exactly once")
- }
-}
-
-func BenchmarkInheritedFlags(b *testing.B) {
- initialize()
- cmdEcho.AddCommand(cmdTimes)
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- cmdTimes.InheritedFlags()
- }
-}
-
-func BenchmarkLocalFlags(b *testing.B) {
- initialize()
- cmdEcho.AddCommand(cmdTimes)
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- cmdTimes.LocalFlags()
+ const expected = "Hello, world."
+ if got := c.UsageString(); got != expected {
+ t.Errorf("Expected UsageString: %v\nGot: %v", expected, got)
}
}
diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go
index 185e45263..6cb642647 100644
--- a/vendor/github.com/spf13/cobra/command.go
+++ b/vendor/github.com/spf13/cobra/command.go
@@ -125,8 +125,9 @@ type Command struct {
// Must be > 0.
SuggestionsMinimumDistance int
- // name is the command name, usually the executable's name.
- name string
+ // TraverseChildren parses flags on all parents before executing child command.
+ TraverseChildren bool
+
// commands is the list of commands supported by this program.
commands []*Command
// parent is a parent command for this command.
@@ -475,13 +476,14 @@ func argsMinusFirstX(args []string, x string) []string {
return args
}
+func isFlagArg(arg string) bool {
+ return ((len(arg) >= 3 && arg[1] == '-') ||
+ (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
+}
+
// Find the target command given the args and command tree
// Meant to be run on the highest node. Only searches down.
func (c *Command) Find(args []string) (*Command, []string, error) {
- if c == nil {
- return nil, nil, fmt.Errorf("Called find() on a nil Command")
- }
-
var innerfind func(*Command, []string) (*Command, []string)
innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
@@ -490,28 +492,11 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
return c, innerArgs
}
nextSubCmd := argsWOflags[0]
- matches := make([]*Command, 0)
- for _, cmd := range c.commands {
- if cmd.Name() == nextSubCmd || cmd.HasAlias(nextSubCmd) { // exact name or alias match
- return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
- }
- if EnablePrefixMatching {
- if strings.HasPrefix(cmd.Name(), nextSubCmd) { // prefix match
- matches = append(matches, cmd)
- }
- for _, x := range cmd.Aliases {
- if strings.HasPrefix(x, nextSubCmd) {
- matches = append(matches, cmd)
- }
- }
- }
- }
- // only accept a single prefix match - multiple matches would be ambiguous
- if len(matches) == 1 {
- return innerfind(matches[0], argsMinusFirstX(innerArgs, argsWOflags[0]))
+ cmd := c.findNext(nextSubCmd)
+ if cmd != nil {
+ return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
}
-
return c, innerArgs
}
@@ -539,6 +524,66 @@ func (c *Command) findSuggestions(arg string) string {
return suggestionsString
}
+func (c *Command) findNext(next string) *Command {
+ matches := make([]*Command, 0)
+ for _, cmd := range c.commands {
+ if cmd.Name() == next || cmd.HasAlias(next) {
+ return cmd
+ }
+ if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
+ matches = append(matches, cmd)
+ }
+ }
+
+ if len(matches) == 1 {
+ return matches[0]
+ }
+ return nil
+}
+
+// Traverse the command tree to find the command, and parse args for
+// each parent.
+func (c *Command) Traverse(args []string) (*Command, []string, error) {
+ flags := []string{}
+ inFlag := false
+
+ for i, arg := range args {
+ switch {
+ // A long flag with a space separated value
+ case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
+ // TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
+ inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
+ flags = append(flags, arg)
+ continue
+ // A short flag with a space separated value
+ case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
+ inFlag = true
+ flags = append(flags, arg)
+ continue
+ // The value for a flag
+ case inFlag:
+ inFlag = false
+ flags = append(flags, arg)
+ continue
+ // A flag without a value, or with an `=` separated value
+ case isFlagArg(arg):
+ flags = append(flags, arg)
+ continue
+ }
+
+ cmd := c.findNext(arg)
+ if cmd == nil {
+ return c, args, nil
+ }
+
+ if err := c.ParseFlags(flags); err != nil {
+ return nil, args, err
+ }
+ return cmd.Traverse(args[i+1:])
+ }
+ return c, args, nil
+}
+
// SuggestionsFor provides suggestions for the typedName.
func (c *Command) SuggestionsFor(typedName string) []string {
suggestions := []string{}
@@ -576,10 +621,8 @@ func (c *Command) Root() *Command {
return c
}
-// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
-// found during arg parsing. This allows your program to know which args were
-// before the -- and which came after. (Description from
-// https://godoc.org/github.com/spf13/pflag#FlagSet.ArgsLenAtDash).
+// ArgsLenAtDash will return the length of c.Flags().Args at the moment
+// when a -- was found during args parsing.
func (c *Command) ArgsLenAtDash() int {
return c.Flags().ArgsLenAtDash()
}
@@ -646,6 +689,9 @@ func (c *Command) execute(a []string) (err error) {
c.PreRun(c, argWoFlags)
}
+ if err := c.validateRequiredFlags(); err != nil {
+ return err
+ }
if c.RunE != nil {
if err := c.RunE(c, argWoFlags); err != nil {
return err
@@ -714,7 +760,12 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
args = c.args
}
- cmd, flags, err := c.Find(args)
+ var flags []string
+ if c.TraverseChildren {
+ cmd, flags, err = c.Traverse(args)
+ } else {
+ cmd, flags, err = c.Find(args)
+ }
if err != nil {
// If found parse to a subcommand and then failed, talk about the subcommand
if cmd != nil {
@@ -726,6 +777,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
}
return c, err
}
+
err = cmd.execute(flags)
if err != nil {
// Always show help if requested, even if SilenceErrors is in
@@ -757,6 +809,25 @@ func (c *Command) ValidateArgs(args []string) error {
return c.Args(c, args)
}
+func (c *Command) validateRequiredFlags() error {
+ flags := c.Flags()
+ missingFlagNames := []string{}
+ flags.VisitAll(func(pflag *flag.Flag) {
+ requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
+ if !found {
+ return
+ }
+ if (requiredAnnotation[0] == "true") && !pflag.Changed {
+ missingFlagNames = append(missingFlagNames, pflag.Name)
+ }
+ })
+
+ if len(missingFlagNames) > 0 {
+ return fmt.Errorf(`Required flag(s) "%s" have/has not been set`, strings.Join(missingFlagNames, `", "`))
+ }
+ return nil
+}
+
// InitDefaultHelpFlag adds default help flag to c.
// It is called automatically by executing the c or by calling help and usage.
// If c already has help flag, it will do nothing.
@@ -804,8 +875,9 @@ Simply type ` + c.Name() + ` help [path to command] for full details.`,
c.AddCommand(c.helpCommand)
}
-// ResetCommands used for testing.
+// ResetCommands delete parent, subcommand and help command from c.
func (c *Command) ResetCommands() {
+ c.parent = nil
c.commands = nil
c.helpCommand = nil
c.parentsPflags = nil
@@ -971,15 +1043,12 @@ func (c *Command) DebugFlags() {
// Name returns the command's name: the first word in the use line.
func (c *Command) Name() string {
- if c.name == "" {
- name := c.Use
- i := strings.Index(name, " ")
- if i >= 0 {
- name = name[:i]
- }
- c.name = name
+ name := c.Use
+ i := strings.Index(name, " ")
+ if i >= 0 {
+ name = name[:i]
}
- return c.name
+ return name
}
// HasAlias determines if a given string is an alias of the command.
@@ -992,7 +1061,21 @@ func (c *Command) HasAlias(s string) bool {
return false
}
-// NameAndAliases returns string containing name and all aliases
+// hasNameOrAliasPrefix returns true if the Name or any of aliases start
+// with prefix
+func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
+ if strings.HasPrefix(c.Name(), prefix) {
+ return true
+ }
+ for _, alias := range c.Aliases {
+ if strings.HasPrefix(alias, prefix) {
+ return true
+ }
+ }
+ return false
+}
+
+// NameAndAliases returns a list of the command name and all aliases
func (c *Command) NameAndAliases() string {
return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
}
@@ -1078,7 +1161,7 @@ func (c *Command) HasAvailableSubCommands() bool {
}
}
- // the command either has no sub comamnds, or no available (non deprecated/help/hidden)
+ // the command either has no sub commands, or no available (non deprecated/help/hidden)
// sub commands
return false
}
@@ -1132,6 +1215,9 @@ func (c *Command) LocalFlags() *flag.FlagSet {
c.lflags.SetOutput(c.flagErrorBuf)
}
c.lflags.SortFlags = c.Flags().SortFlags
+ if c.globNormFunc != nil {
+ c.lflags.SetNormalizeFunc(c.globNormFunc)
+ }
addToLocal := func(f *flag.Flag) {
if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
@@ -1156,6 +1242,10 @@ func (c *Command) InheritedFlags() *flag.FlagSet {
}
local := c.LocalFlags()
+ if c.globNormFunc != nil {
+ c.iflags.SetNormalizeFunc(c.globNormFunc)
+ }
+
c.parentsPflags.VisitAll(func(f *flag.Flag) {
if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
c.iflags.AddFlag(f)
@@ -1181,7 +1271,7 @@ func (c *Command) PersistentFlags() *flag.FlagSet {
return c.pflags
}
-// ResetFlags is used in testing.
+// ResetFlags deletes all flags from command.
func (c *Command) ResetFlags() {
c.flagErrorBuf = new(bytes.Buffer)
c.flagErrorBuf.Reset()
@@ -1189,6 +1279,10 @@ func (c *Command) ResetFlags() {
c.flags.SetOutput(c.flagErrorBuf)
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
c.pflags.SetOutput(c.flagErrorBuf)
+
+ c.lflags = nil
+ c.iflags = nil
+ c.parentsPflags = nil
}
// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
@@ -1264,6 +1358,9 @@ func (c *Command) ParseFlags(args []string) error {
return nil
}
+ if c.flagErrorBuf == nil {
+ c.flagErrorBuf = new(bytes.Buffer)
+ }
beforeErrorBufLen := c.flagErrorBuf.Len()
c.mergePersistentFlags()
err := c.Flags().Parse(args)
@@ -1298,6 +1395,10 @@ func (c *Command) updateParentsPflags() {
c.parentsPflags.SortFlags = false
}
+ if c.globNormFunc != nil {
+ c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
+ }
+
c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
c.VisitParents(func(parent *Command) {
diff --git a/vendor/github.com/spf13/cobra/command_test.go b/vendor/github.com/spf13/cobra/command_test.go
index aa6658f85..edffc1501 100644
--- a/vendor/github.com/spf13/cobra/command_test.go
+++ b/vendor/github.com/spf13/cobra/command_test.go
@@ -11,27 +11,450 @@ import (
"github.com/spf13/pflag"
)
-// test to ensure hidden commands run as intended
-func TestHiddenCommandExecutes(t *testing.T) {
+func emptyRun(*Command, []string) {}
+
+func executeCommand(root *Command, args ...string) (output string, err error) {
+ _, output, err = executeCommandC(root, args...)
+ return output, err
+}
+
+func executeCommandC(root *Command, args ...string) (c *Command, output string, err error) {
+ buf := new(bytes.Buffer)
+ root.SetOutput(buf)
+ root.SetArgs(args)
+
+ c, err = root.ExecuteC()
+
+ return c, buf.String(), err
+}
+
+func resetCommandLineFlagSet() {
+ pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
+}
+
+func checkStringContains(t *testing.T, got, expected string) {
+ if !strings.Contains(got, expected) {
+ t.Errorf("Expected to contain: \n %v\nGot:\n %v\n", expected, got)
+ }
+}
+
+func checkStringOmits(t *testing.T, got, expected string) {
+ if strings.Contains(got, expected) {
+ t.Errorf("Expected to not contain: \n %v\nGot: %v", expected, got)
+ }
+}
- // ensure that outs does not already equal what the command will be setting it
- // to, if it did this test would not actually be testing anything...
- if outs == "hidden" {
- t.Errorf("outs should NOT EQUAL hidden")
+func TestSingleCommand(t *testing.T) {
+ var rootCmdArgs []string
+ rootCmd := &Command{
+ Use: "root",
+ Args: ExactArgs(2),
+ Run: func(_ *Command, args []string) { rootCmdArgs = args },
}
+ aCmd := &Command{Use: "a", Args: NoArgs, Run: emptyRun}
+ bCmd := &Command{Use: "b", Args: NoArgs, Run: emptyRun}
+ rootCmd.AddCommand(aCmd, bCmd)
- cmdHidden.Execute()
+ output, err := executeCommand(rootCmd, "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
- // upon running the command, the value of outs should now be 'hidden'
- if outs != "hidden" {
- t.Errorf("Hidden command failed to run!")
+ got := strings.Join(rootCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("rootCmdArgs expected: %q, got: %q", expected, got)
}
}
-// test to ensure hidden commands do not show up in usage/help text
-func TestHiddenCommandIsHidden(t *testing.T) {
- if cmdHidden.IsAvailableCommand() {
- t.Errorf("Hidden command found!")
+func TestChildCommand(t *testing.T) {
+ var child1CmdArgs []string
+ rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
+ child1Cmd := &Command{
+ Use: "child1",
+ Args: ExactArgs(2),
+ Run: func(_ *Command, args []string) { child1CmdArgs = args },
+ }
+ child2Cmd := &Command{Use: "child2", Args: NoArgs, Run: emptyRun}
+ rootCmd.AddCommand(child1Cmd, child2Cmd)
+
+ output, err := executeCommand(rootCmd, "child1", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ got := strings.Join(child1CmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("child1CmdArgs expected: %q, got: %q", expected, got)
+ }
+}
+
+func TestCallCommandWithoutSubcommands(t *testing.T) {
+ rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
+ _, err := executeCommand(rootCmd)
+ if err != nil {
+ t.Errorf("Calling command without subcommands should not have error: %v", err)
+ }
+}
+
+func TestRootExecuteUnknownCommand(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+ output, _ := executeCommand(rootCmd, "unknown")
+
+ expected := "Error: unknown command \"unknown\" for \"root\"\nRun 'root --help' for usage.\n"
+
+ if output != expected {
+ t.Errorf("Expected:\n %q\nGot:\n %q\n", expected, output)
+ }
+}
+
+func TestSubcommandExecuteC(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ c, output, err := executeCommandC(rootCmd, "child")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if c.Name() != "child" {
+ t.Errorf(`invalid command returned from ExecuteC: expected "child"', got %q`, c.Name())
+ }
+}
+
+func TestRootUnknownCommandSilenced(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ rootCmd.SilenceErrors = true
+ rootCmd.SilenceUsage = true
+ rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+ output, _ := executeCommand(rootCmd, "unknown")
+ if output != "" {
+ t.Errorf("Expected blank output, because of silenced usage.\nGot:\n %q\n", output)
+ }
+}
+
+func TestCommandAlias(t *testing.T) {
+ var timesCmdArgs []string
+ rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
+ echoCmd := &Command{
+ Use: "echo",
+ Aliases: []string{"say", "tell"},
+ Args: NoArgs,
+ Run: emptyRun,
+ }
+ timesCmd := &Command{
+ Use: "times",
+ Args: ExactArgs(2),
+ Run: func(_ *Command, args []string) { timesCmdArgs = args },
+ }
+ echoCmd.AddCommand(timesCmd)
+ rootCmd.AddCommand(echoCmd)
+
+ output, err := executeCommand(rootCmd, "tell", "times", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ got := strings.Join(timesCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("timesCmdArgs expected: %v, got: %v", expected, got)
+ }
+}
+
+func TestEnablePrefixMatching(t *testing.T) {
+ EnablePrefixMatching = true
+
+ var aCmdArgs []string
+ rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
+ aCmd := &Command{
+ Use: "aCmd",
+ Args: ExactArgs(2),
+ Run: func(_ *Command, args []string) { aCmdArgs = args },
+ }
+ bCmd := &Command{Use: "bCmd", Args: NoArgs, Run: emptyRun}
+ rootCmd.AddCommand(aCmd, bCmd)
+
+ output, err := executeCommand(rootCmd, "a", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ got := strings.Join(aCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("aCmdArgs expected: %q, got: %q", expected, got)
+ }
+
+ EnablePrefixMatching = false
+}
+
+func TestAliasPrefixMatching(t *testing.T) {
+ EnablePrefixMatching = true
+
+ var timesCmdArgs []string
+ rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
+ echoCmd := &Command{
+ Use: "echo",
+ Aliases: []string{"say", "tell"},
+ Args: NoArgs,
+ Run: emptyRun,
+ }
+ timesCmd := &Command{
+ Use: "times",
+ Args: ExactArgs(2),
+ Run: func(_ *Command, args []string) { timesCmdArgs = args },
+ }
+ echoCmd.AddCommand(timesCmd)
+ rootCmd.AddCommand(echoCmd)
+
+ output, err := executeCommand(rootCmd, "sa", "times", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ got := strings.Join(timesCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("timesCmdArgs expected: %v, got: %v", expected, got)
+ }
+
+ EnablePrefixMatching = false
+}
+
+// TestChildSameName checks the correct behaviour of cobra in cases,
+// when an application with name "foo" and with subcommand "foo"
+// is executed with args "foo foo".
+func TestChildSameName(t *testing.T) {
+ var fooCmdArgs []string
+ rootCmd := &Command{Use: "foo", Args: NoArgs, Run: emptyRun}
+ fooCmd := &Command{
+ Use: "foo",
+ Args: ExactArgs(2),
+ Run: func(_ *Command, args []string) { fooCmdArgs = args },
+ }
+ barCmd := &Command{Use: "bar", Args: NoArgs, Run: emptyRun}
+ rootCmd.AddCommand(fooCmd, barCmd)
+
+ output, err := executeCommand(rootCmd, "foo", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ got := strings.Join(fooCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("fooCmdArgs expected: %v, got: %v", expected, got)
+ }
+}
+
+// TestGrandChildSameName checks the correct behaviour of cobra in cases,
+// when user has a root command and a grand child
+// with the same name.
+func TestGrandChildSameName(t *testing.T) {
+ var fooCmdArgs []string
+ rootCmd := &Command{Use: "foo", Args: NoArgs, Run: emptyRun}
+ barCmd := &Command{Use: "bar", Args: NoArgs, Run: emptyRun}
+ fooCmd := &Command{
+ Use: "foo",
+ Args: ExactArgs(2),
+ Run: func(_ *Command, args []string) { fooCmdArgs = args },
+ }
+ barCmd.AddCommand(fooCmd)
+ rootCmd.AddCommand(barCmd)
+
+ output, err := executeCommand(rootCmd, "bar", "foo", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ got := strings.Join(fooCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("fooCmdArgs expected: %v, got: %v", expected, got)
+ }
+}
+
+func TestFlagLong(t *testing.T) {
+ var cArgs []string
+ c := &Command{
+ Use: "c",
+ Args: ArbitraryArgs,
+ Run: func(_ *Command, args []string) { cArgs = args },
+ }
+
+ var intFlagValue int
+ var stringFlagValue string
+ c.Flags().IntVar(&intFlagValue, "intf", -1, "")
+ c.Flags().StringVar(&stringFlagValue, "sf", "", "")
+
+ output, err := executeCommand(c, "--intf=7", "--sf=abc", "one", "--", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", err)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if c.ArgsLenAtDash() != 1 {
+ t.Errorf("Expected ArgsLenAtDash: %v but got %v", 1, c.ArgsLenAtDash())
+ }
+ if intFlagValue != 7 {
+ t.Errorf("Expected intFlagValue: %v, got %v", 7, intFlagValue)
+ }
+ if stringFlagValue != "abc" {
+ t.Errorf("Expected stringFlagValue: %q, got %q", "abc", stringFlagValue)
+ }
+
+ got := strings.Join(cArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("Expected arguments: %q, got %q", expected, got)
+ }
+}
+
+func TestFlagShort(t *testing.T) {
+ var cArgs []string
+ c := &Command{
+ Use: "c",
+ Args: ArbitraryArgs,
+ Run: func(_ *Command, args []string) { cArgs = args },
+ }
+
+ var intFlagValue int
+ var stringFlagValue string
+ c.Flags().IntVarP(&intFlagValue, "intf", "i", -1, "")
+ c.Flags().StringVarP(&stringFlagValue, "sf", "s", "", "")
+
+ output, err := executeCommand(c, "-i", "7", "-sabc", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", err)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if intFlagValue != 7 {
+ t.Errorf("Expected flag value: %v, got %v", 7, intFlagValue)
+ }
+ if stringFlagValue != "abc" {
+ t.Errorf("Expected stringFlagValue: %q, got %q", "abc", stringFlagValue)
+ }
+
+ got := strings.Join(cArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("Expected arguments: %q, got %q", expected, got)
+ }
+}
+
+func TestChildFlag(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ var intFlagValue int
+ childCmd.Flags().IntVarP(&intFlagValue, "intf", "i", -1, "")
+
+ output, err := executeCommand(rootCmd, "child", "-i7")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", err)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if intFlagValue != 7 {
+ t.Errorf("Expected flag value: %v, got %v", 7, intFlagValue)
+ }
+}
+
+func TestChildFlagWithParentLocalFlag(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ var intFlagValue int
+ rootCmd.Flags().StringP("sf", "s", "", "")
+ childCmd.Flags().IntVarP(&intFlagValue, "intf", "i", -1, "")
+
+ _, err := executeCommand(rootCmd, "child", "-i7", "-sabc")
+ if err == nil {
+ t.Errorf("Invalid flag should generate error")
+ }
+
+ checkStringContains(t, err.Error(), "unknown shorthand")
+
+ if intFlagValue != 7 {
+ t.Errorf("Expected flag value: %v, got %v", 7, intFlagValue)
+ }
+}
+
+func TestFlagInvalidInput(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ rootCmd.Flags().IntP("intf", "i", -1, "")
+
+ _, err := executeCommand(rootCmd, "-iabc")
+ if err == nil {
+ t.Errorf("Invalid flag value should generate error")
+ }
+
+ checkStringContains(t, err.Error(), "invalid syntax")
+}
+
+func TestFlagBeforeCommand(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ var flagValue int
+ childCmd.Flags().IntVarP(&flagValue, "intf", "i", -1, "")
+
+ // With short flag.
+ _, err := executeCommand(rootCmd, "-i7", "child")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+ if flagValue != 7 {
+ t.Errorf("Expected flag value: %v, got %v", 7, flagValue)
+ }
+
+ // With long flag.
+ _, err = executeCommand(rootCmd, "--intf=8", "child")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+ if flagValue != 8 {
+ t.Errorf("Expected flag value: %v, got %v", 9, flagValue)
}
}
@@ -45,11 +468,11 @@ func TestStripFlags(t *testing.T) {
[]string{"foo", "bar"},
},
{
- []string{"foo", "--bar", "-b"},
+ []string{"foo", "--str", "-s"},
[]string{"foo"},
},
{
- []string{"-b", "foo", "--bar", "bar"},
+ []string{"-s", "foo", "--str", "bar"},
[]string{},
},
{
@@ -65,7 +488,7 @@ func TestStripFlags(t *testing.T) {
[]string{"echo"},
},
{
- []string{"-ib", "echo", "-bfoo", "baz"},
+ []string{"-ib", "echo", "-sfoo", "baz"},
[]string{"echo", "baz"},
},
{
@@ -73,15 +496,15 @@ func TestStripFlags(t *testing.T) {
[]string{"bar", "blah"},
},
{
- []string{"--int=baz", "-bbar", "-i", "foo", "blah"},
+ []string{"--int=baz", "-sbar", "-i", "foo", "blah"},
[]string{"blah"},
},
{
- []string{"--cat", "bar", "-i", "foo", "blah"},
+ []string{"--bool", "bar", "-i", "foo", "blah"},
[]string{"bar", "blah"},
},
{
- []string{"-c", "bar", "-i", "foo", "blah"},
+ []string{"-b", "bar", "-i", "foo", "blah"},
[]string{"bar", "blah"},
},
{
@@ -94,61 +517,757 @@ func TestStripFlags(t *testing.T) {
},
}
- cmdPrint := &Command{
- Use: "print [string to print]",
- Short: "Print anything to the screen",
- Long: `an utterly useless command for testing.`,
- Run: func(cmd *Command, args []string) {
- tp = args
- },
- }
-
- var flagi int
- var flagstr string
- var flagbool bool
- cmdPrint.PersistentFlags().BoolVarP(&flagbool, "persist", "p", false, "help for persistent one")
- cmdPrint.Flags().IntVarP(&flagi, "int", "i", 345, "help message for flag int")
- cmdPrint.Flags().StringVarP(&flagstr, "bar", "b", "bar", "help message for flag string")
- cmdPrint.Flags().BoolVarP(&flagbool, "cat", "c", false, "help message for flag bool")
+ c := &Command{Use: "c", Run: emptyRun}
+ c.PersistentFlags().BoolP("persist", "p", false, "")
+ c.Flags().IntP("int", "i", -1, "")
+ c.Flags().StringP("str", "s", "", "")
+ c.Flags().BoolP("bool", "b", false, "")
- for _, test := range tests {
- output := stripFlags(test.input, cmdPrint)
- if !reflect.DeepEqual(test.output, output) {
- t.Errorf("expected: %v, got: %v", test.output, output)
+ for i, test := range tests {
+ got := stripFlags(test.input, c)
+ if !reflect.DeepEqual(test.output, got) {
+ t.Errorf("(%v) Expected: %v, got: %v", i, test.output, got)
}
}
}
func TestDisableFlagParsing(t *testing.T) {
- targs := []string{}
- cmdPrint := &Command{
+ var cArgs []string
+ c := &Command{
+ Use: "c",
DisableFlagParsing: true,
- Run: func(cmd *Command, args []string) {
- targs = args
+ Run: func(_ *Command, args []string) {
+ cArgs = args
},
}
+
args := []string{"cmd", "-v", "-race", "-file", "foo.go"}
- cmdPrint.SetArgs(args)
- err := cmdPrint.Execute()
+ output, err := executeCommand(c, args...)
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if !reflect.DeepEqual(args, cArgs) {
+ t.Errorf("Expected: %v, got: %v", args, cArgs)
+ }
+}
+
+func TestPersistentFlagsOnSameCommand(t *testing.T) {
+ var rootCmdArgs []string
+ rootCmd := &Command{
+ Use: "root",
+ Args: ArbitraryArgs,
+ Run: func(_ *Command, args []string) { rootCmdArgs = args },
+ }
+
+ var flagValue int
+ rootCmd.PersistentFlags().IntVarP(&flagValue, "intf", "i", -1, "")
+
+ output, err := executeCommand(rootCmd, "-i7", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
if err != nil {
- t.Error(err)
+ t.Errorf("Unexpected error: %v", err)
}
- if !reflect.DeepEqual(args, targs) {
- t.Errorf("expected: %v, got: %v", args, targs)
+
+ got := strings.Join(rootCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("rootCmdArgs expected: %q, got %q", expected, got)
+ }
+ if flagValue != 7 {
+ t.Errorf("flagValue expected: %v, got %v", 7, flagValue)
+ }
+}
+
+// TestEmptyInputs checks,
+// if flags correctly parsed with blank strings in args.
+func TestEmptyInputs(t *testing.T) {
+ c := &Command{Use: "c", Run: emptyRun}
+
+ var flagValue int
+ c.Flags().IntVarP(&flagValue, "intf", "i", -1, "")
+
+ output, err := executeCommand(c, "", "-i7", "")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if flagValue != 7 {
+ t.Errorf("flagValue expected: %v, got %v", 7, flagValue)
+ }
+}
+
+func TestOverwrittenFlag(t *testing.T) {
+ // TODO: This test fails, but should work.
+ t.Skip()
+
+ parent := &Command{Use: "parent", Run: emptyRun}
+ child := &Command{Use: "child", Run: emptyRun}
+
+ parent.PersistentFlags().Bool("boolf", false, "")
+ parent.PersistentFlags().Int("intf", -1, "")
+ child.Flags().String("strf", "", "")
+ child.Flags().Int("intf", -1, "")
+
+ parent.AddCommand(child)
+
+ childInherited := child.InheritedFlags()
+ childLocal := child.LocalFlags()
+
+ if childLocal.Lookup("strf") == nil {
+ t.Error(`LocalFlags expected to contain "strf", got "nil"`)
+ }
+ if childInherited.Lookup("boolf") == nil {
+ t.Error(`InheritedFlags expected to contain "boolf", got "nil"`)
+ }
+
+ if childInherited.Lookup("intf") != nil {
+ t.Errorf(`InheritedFlags should not contain overwritten flag "intf"`)
+ }
+ if childLocal.Lookup("intf") == nil {
+ t.Error(`LocalFlags expected to contain "intf", got "nil"`)
+ }
+}
+
+func TestPersistentFlagsOnChild(t *testing.T) {
+ var childCmdArgs []string
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{
+ Use: "child",
+ Args: ArbitraryArgs,
+ Run: func(_ *Command, args []string) { childCmdArgs = args },
+ }
+ rootCmd.AddCommand(childCmd)
+
+ var parentFlagValue int
+ var childFlagValue int
+ rootCmd.PersistentFlags().IntVarP(&parentFlagValue, "parentf", "p", -1, "")
+ childCmd.Flags().IntVarP(&childFlagValue, "childf", "c", -1, "")
+
+ output, err := executeCommand(rootCmd, "child", "-c7", "-p8", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ got := strings.Join(childCmdArgs, " ")
+ expected := "one two"
+ if got != expected {
+ t.Errorf("childCmdArgs expected: %q, got %q", expected, got)
+ }
+ if parentFlagValue != 8 {
+ t.Errorf("parentFlagValue expected: %v, got %v", 8, parentFlagValue)
+ }
+ if childFlagValue != 7 {
+ t.Errorf("childFlagValue expected: %v, got %v", 7, childFlagValue)
+ }
+}
+
+func TestRequiredFlags(t *testing.T) {
+ c := &Command{Use: "c", Run: emptyRun}
+ c.Flags().String("foo1", "", "")
+ c.MarkFlagRequired("foo1")
+ c.Flags().String("foo2", "", "")
+ c.MarkFlagRequired("foo2")
+ c.Flags().String("bar", "", "")
+
+ expected := fmt.Sprintf("Required flag(s) %q, %q have/has not been set", "foo1", "foo2")
+
+ _, err := executeCommand(c)
+ got := err.Error()
+
+ if got != expected {
+ t.Errorf("Expected error: %q, got: %q", expected, got)
+ }
+}
+
+func TestPersistentRequiredFlags(t *testing.T) {
+ parent := &Command{Use: "parent", Run: emptyRun}
+ parent.PersistentFlags().String("foo1", "", "")
+ parent.MarkPersistentFlagRequired("foo1")
+ parent.PersistentFlags().String("foo2", "", "")
+ parent.MarkPersistentFlagRequired("foo2")
+ parent.Flags().String("foo3", "", "")
+
+ child := &Command{Use: "child", Run: emptyRun}
+ child.Flags().String("bar1", "", "")
+ child.MarkFlagRequired("bar1")
+ child.Flags().String("bar2", "", "")
+ child.MarkFlagRequired("bar2")
+ child.Flags().String("bar3", "", "")
+
+ parent.AddCommand(child)
+
+ expected := fmt.Sprintf("Required flag(s) %q, %q, %q, %q have/has not been set", "bar1", "bar2", "foo1", "foo2")
+
+ _, err := executeCommand(parent, "child")
+ if err.Error() != expected {
+ t.Errorf("Expected %q, got %q", expected, err.Error())
}
}
func TestInitHelpFlagMergesFlags(t *testing.T) {
usage := "custom flag"
- baseCmd := Command{Use: "testcmd"}
- baseCmd.PersistentFlags().Bool("help", false, usage)
- cmd := Command{Use: "do"}
- baseCmd.AddCommand(&cmd)
+ rootCmd := &Command{Use: "root"}
+ rootCmd.PersistentFlags().Bool("help", false, "custom flag")
+ childCmd := &Command{Use: "child"}
+ rootCmd.AddCommand(childCmd)
+
+ childCmd.InitDefaultHelpFlag()
+ got := childCmd.Flags().Lookup("help").Usage
+ if got != usage {
+ t.Errorf("Expected the help flag from the root command with usage: %v\nGot the default with usage: %v", usage, got)
+ }
+}
+
+func TestHelpCommandExecuted(t *testing.T) {
+ rootCmd := &Command{Use: "root", Long: "Long description", Run: emptyRun}
+ rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+ output, err := executeCommand(rootCmd, "help")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, rootCmd.Long)
+}
- cmd.InitDefaultHelpFlag()
- actual := cmd.Flags().Lookup("help").Usage
- if actual != usage {
- t.Fatalf("Expected the help flag from the base command with usage '%s', but got the default with usage '%s'", usage, actual)
+func TestHelpCommandExecutedOnChild(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Long: "Long description", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ output, err := executeCommand(rootCmd, "help", "child")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, childCmd.Long)
+}
+
+func TestSetHelpCommand(t *testing.T) {
+ c := &Command{Use: "c", Run: emptyRun}
+ c.AddCommand(&Command{Use: "empty", Run: emptyRun})
+
+ expected := "WORKS"
+ c.SetHelpCommand(&Command{
+ Use: "help [command]",
+ Short: "Help about any command",
+ Long: `Help provides help for any command in the application.
+ Simply type ` + c.Name() + ` help [path to command] for full details.`,
+ Run: func(c *Command, _ []string) { c.Print(expected) },
+ })
+
+ got, err := executeCommand(c, "help")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if got != expected {
+ t.Errorf("Expected to contain %q, got %q", expected, got)
+ }
+}
+
+func TestHelpFlagExecuted(t *testing.T) {
+ rootCmd := &Command{Use: "root", Long: "Long description", Run: emptyRun}
+
+ output, err := executeCommand(rootCmd, "--help")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, rootCmd.Long)
+}
+
+func TestHelpFlagExecutedOnChild(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Long: "Long description", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ output, err := executeCommand(rootCmd, "child", "--help")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, childCmd.Long)
+}
+
+// TestHelpFlagInHelp checks,
+// if '--help' flag is shown in help for child (executing `parent help child`),
+// that has no other flags.
+// Related to https://github.com/spf13/cobra/issues/302.
+func TestHelpFlagInHelp(t *testing.T) {
+ parentCmd := &Command{Use: "parent", Run: func(*Command, []string) {}}
+
+ childCmd := &Command{Use: "child", Run: func(*Command, []string) {}}
+ parentCmd.AddCommand(childCmd)
+
+ output, err := executeCommand(parentCmd, "help", "child")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, "[flags]")
+}
+
+func TestFlagsInUsage(t *testing.T) {
+ rootCmd := &Command{Use: "root", Args: NoArgs, Run: func(*Command, []string) {}}
+ output, err := executeCommand(rootCmd, "--help")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, "[flags]")
+}
+
+func TestHelpExecutedOnNonRunnableChild(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Long: "Long description"}
+ rootCmd.AddCommand(childCmd)
+
+ output, err := executeCommand(rootCmd, "child")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, childCmd.Long)
+}
+
+func TestUsageIsNotPrintedTwice(t *testing.T) {
+ var cmd = &Command{Use: "root"}
+ var sub = &Command{Use: "sub"}
+ cmd.AddCommand(sub)
+
+ output, _ := executeCommand(cmd, "")
+ if strings.Count(output, "Usage:") != 1 {
+ t.Error("Usage output is not printed exactly once")
+ }
+}
+
+func TestVisitParents(t *testing.T) {
+ c := &Command{Use: "app"}
+ sub := &Command{Use: "sub"}
+ dsub := &Command{Use: "dsub"}
+ sub.AddCommand(dsub)
+ c.AddCommand(sub)
+
+ total := 0
+ add := func(x *Command) {
+ total++
+ }
+ sub.VisitParents(add)
+ if total != 1 {
+ t.Errorf("Should have visited 1 parent but visited %d", total)
+ }
+
+ total = 0
+ dsub.VisitParents(add)
+ if total != 2 {
+ t.Errorf("Should have visited 2 parents but visited %d", total)
+ }
+
+ total = 0
+ c.VisitParents(add)
+ if total != 0 {
+ t.Errorf("Should have visited no parents but visited %d", total)
+ }
+}
+
+func TestSuggestions(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ timesCmd := &Command{
+ Use: "times",
+ SuggestFor: []string{"counts"},
+ Run: emptyRun,
+ }
+ rootCmd.AddCommand(timesCmd)
+
+ templateWithSuggestions := "Error: unknown command \"%s\" for \"root\"\n\nDid you mean this?\n\t%s\n\nRun 'root --help' for usage.\n"
+ templateWithoutSuggestions := "Error: unknown command \"%s\" for \"root\"\nRun 'root --help' for usage.\n"
+
+ tests := map[string]string{
+ "time": "times",
+ "tiems": "times",
+ "tims": "times",
+ "timeS": "times",
+ "rimes": "times",
+ "ti": "times",
+ "t": "times",
+ "timely": "times",
+ "ri": "",
+ "timezone": "",
+ "foo": "",
+ "counts": "times",
+ }
+
+ for typo, suggestion := range tests {
+ for _, suggestionsDisabled := range []bool{true, false} {
+ rootCmd.DisableSuggestions = suggestionsDisabled
+
+ var expected string
+ output, _ := executeCommand(rootCmd, typo)
+
+ if suggestion == "" || suggestionsDisabled {
+ expected = fmt.Sprintf(templateWithoutSuggestions, typo)
+ } else {
+ expected = fmt.Sprintf(templateWithSuggestions, typo, suggestion)
+ }
+
+ if output != expected {
+ t.Errorf("Unexpected response.\nExpected:\n %q\nGot:\n %q\n", expected, output)
+ }
+ }
+ }
+}
+
+func TestRemoveCommand(t *testing.T) {
+ rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+ rootCmd.RemoveCommand(childCmd)
+
+ _, err := executeCommand(rootCmd, "child")
+ if err == nil {
+ t.Error("Expected error on calling removed command. Got nil.")
+ }
+}
+
+func TestReplaceCommandWithRemove(t *testing.T) {
+ childUsed := 0
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ child1Cmd := &Command{
+ Use: "child",
+ Run: func(*Command, []string) { childUsed = 1 },
+ }
+ child2Cmd := &Command{
+ Use: "child",
+ Run: func(*Command, []string) { childUsed = 2 },
+ }
+ rootCmd.AddCommand(child1Cmd)
+ rootCmd.RemoveCommand(child1Cmd)
+ rootCmd.AddCommand(child2Cmd)
+
+ output, err := executeCommand(rootCmd, "child")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if childUsed == 1 {
+ t.Error("Removed command shouldn't be called")
+ }
+ if childUsed != 2 {
+ t.Error("Replacing command should have been called but didn't")
+ }
+}
+
+func TestDeprecatedCommand(t *testing.T) {
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ deprecatedCmd := &Command{
+ Use: "deprecated",
+ Deprecated: "This command is deprecated",
+ Run: emptyRun,
+ }
+ rootCmd.AddCommand(deprecatedCmd)
+
+ output, err := executeCommand(rootCmd, "deprecated")
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ checkStringContains(t, output, deprecatedCmd.Deprecated)
+}
+
+func TestHooks(t *testing.T) {
+ var (
+ persPreArgs string
+ preArgs string
+ runArgs string
+ postArgs string
+ persPostArgs string
+ )
+
+ c := &Command{
+ Use: "c",
+ PersistentPreRun: func(_ *Command, args []string) {
+ persPreArgs = strings.Join(args, " ")
+ },
+ PreRun: func(_ *Command, args []string) {
+ preArgs = strings.Join(args, " ")
+ },
+ Run: func(_ *Command, args []string) {
+ runArgs = strings.Join(args, " ")
+ },
+ PostRun: func(_ *Command, args []string) {
+ postArgs = strings.Join(args, " ")
+ },
+ PersistentPostRun: func(_ *Command, args []string) {
+ persPostArgs = strings.Join(args, " ")
+ },
+ }
+
+ output, err := executeCommand(c, "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if persPreArgs != "one two" {
+ t.Errorf("Expected persPreArgs %q, got %q", "one two", persPreArgs)
+ }
+ if preArgs != "one two" {
+ t.Errorf("Expected preArgs %q, got %q", "one two", preArgs)
+ }
+ if runArgs != "one two" {
+ t.Errorf("Expected runArgs %q, got %q", "one two", runArgs)
+ }
+ if postArgs != "one two" {
+ t.Errorf("Expected postArgs %q, got %q", "one two", postArgs)
+ }
+ if persPostArgs != "one two" {
+ t.Errorf("Expected persPostArgs %q, got %q", "one two", persPostArgs)
+ }
+}
+
+func TestPersistentHooks(t *testing.T) {
+ var (
+ parentPersPreArgs string
+ parentPreArgs string
+ parentRunArgs string
+ parentPostArgs string
+ parentPersPostArgs string
+ )
+
+ var (
+ childPersPreArgs string
+ childPreArgs string
+ childRunArgs string
+ childPostArgs string
+ childPersPostArgs string
+ )
+
+ parentCmd := &Command{
+ Use: "parent",
+ PersistentPreRun: func(_ *Command, args []string) {
+ parentPersPreArgs = strings.Join(args, " ")
+ },
+ PreRun: func(_ *Command, args []string) {
+ parentPreArgs = strings.Join(args, " ")
+ },
+ Run: func(_ *Command, args []string) {
+ parentRunArgs = strings.Join(args, " ")
+ },
+ PostRun: func(_ *Command, args []string) {
+ parentPostArgs = strings.Join(args, " ")
+ },
+ PersistentPostRun: func(_ *Command, args []string) {
+ parentPersPostArgs = strings.Join(args, " ")
+ },
+ }
+
+ childCmd := &Command{
+ Use: "child",
+ PersistentPreRun: func(_ *Command, args []string) {
+ childPersPreArgs = strings.Join(args, " ")
+ },
+ PreRun: func(_ *Command, args []string) {
+ childPreArgs = strings.Join(args, " ")
+ },
+ Run: func(_ *Command, args []string) {
+ childRunArgs = strings.Join(args, " ")
+ },
+ PostRun: func(_ *Command, args []string) {
+ childPostArgs = strings.Join(args, " ")
+ },
+ PersistentPostRun: func(_ *Command, args []string) {
+ childPersPostArgs = strings.Join(args, " ")
+ },
+ }
+ parentCmd.AddCommand(childCmd)
+
+ output, err := executeCommand(parentCmd, "child", "one", "two")
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ // TODO: This test fails, but should not.
+ // Related to https://github.com/spf13/cobra/issues/252.
+ //
+ // if parentPersPreArgs != "one two" {
+ // t.Errorf("Expected parentPersPreArgs %q, got %q", "one two", parentPersPreArgs)
+ // }
+ if parentPreArgs != "" {
+ t.Errorf("Expected blank parentPreArgs, got %q", parentPreArgs)
+ }
+ if parentRunArgs != "" {
+ t.Errorf("Expected blank parentRunArgs, got %q", parentRunArgs)
+ }
+ if parentPostArgs != "" {
+ t.Errorf("Expected blank parentPostArgs, got %q", parentPostArgs)
+ }
+ // TODO: This test fails, but should not.
+ // Related to https://github.com/spf13/cobra/issues/252.
+ //
+ // if parentPersPostArgs != "one two" {
+ // t.Errorf("Expected parentPersPostArgs %q, got %q", "one two", parentPersPostArgs)
+ // }
+
+ if childPersPreArgs != "one two" {
+ t.Errorf("Expected childPersPreArgs %q, got %q", "one two", childPersPreArgs)
+ }
+ if childPreArgs != "one two" {
+ t.Errorf("Expected childPreArgs %q, got %q", "one two", childPreArgs)
+ }
+ if childRunArgs != "one two" {
+ t.Errorf("Expected childRunArgs %q, got %q", "one two", childRunArgs)
+ }
+ if childPostArgs != "one two" {
+ t.Errorf("Expected childPostArgs %q, got %q", "one two", childPostArgs)
+ }
+ if childPersPostArgs != "one two" {
+ t.Errorf("Expected childPersPostArgs %q, got %q", "one two", childPersPostArgs)
+ }
+}
+
+// Related to https://github.com/spf13/cobra/issues/521.
+func TestGlobalNormFuncPropagation(t *testing.T) {
+ normFunc := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ return pflag.NormalizedName(name)
+ }
+
+ rootCmd := &Command{Use: "root", Run: emptyRun}
+ childCmd := &Command{Use: "child", Run: emptyRun}
+ rootCmd.AddCommand(childCmd)
+
+ rootCmd.SetGlobalNormalizationFunc(normFunc)
+ if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() {
+ t.Error("rootCmd seems to have a wrong normalization function")
+ }
+
+ if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(childCmd.GlobalNormalizationFunc()).Pointer() {
+ t.Error("childCmd should have had the normalization function of rootCmd")
+ }
+}
+
+// Related to https://github.com/spf13/cobra/issues/521.
+func TestNormPassedOnLocal(t *testing.T) {
+ toUpper := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ return pflag.NormalizedName(strings.ToUpper(name))
+ }
+
+ c := &Command{}
+ c.Flags().Bool("flagname", true, "this is a dummy flag")
+ c.SetGlobalNormalizationFunc(toUpper)
+ if c.LocalFlags().Lookup("flagname") != c.LocalFlags().Lookup("FLAGNAME") {
+ t.Error("Normalization function should be passed on to Local flag set")
+ }
+}
+
+// Related to https://github.com/spf13/cobra/issues/521.
+func TestNormPassedOnInherited(t *testing.T) {
+ toUpper := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ return pflag.NormalizedName(strings.ToUpper(name))
+ }
+
+ c := &Command{}
+ c.SetGlobalNormalizationFunc(toUpper)
+
+ child1 := &Command{}
+ c.AddCommand(child1)
+
+ c.PersistentFlags().Bool("flagname", true, "")
+
+ child2 := &Command{}
+ c.AddCommand(child2)
+
+ inherited := child1.InheritedFlags()
+ if inherited.Lookup("flagname") == nil || inherited.Lookup("flagname") != inherited.Lookup("FLAGNAME") {
+ t.Error("Normalization function should be passed on to inherited flag set in command added before flag")
+ }
+
+ inherited = child2.InheritedFlags()
+ if inherited.Lookup("flagname") == nil || inherited.Lookup("flagname") != inherited.Lookup("FLAGNAME") {
+ t.Error("Normalization function should be passed on to inherited flag set in command added after flag")
+ }
+}
+
+// Related to https://github.com/spf13/cobra/issues/521.
+func TestConsistentNormalizedName(t *testing.T) {
+ toUpper := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ return pflag.NormalizedName(strings.ToUpper(name))
+ }
+ n := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ return pflag.NormalizedName(name)
+ }
+
+ c := &Command{}
+ c.Flags().Bool("flagname", true, "")
+ c.SetGlobalNormalizationFunc(toUpper)
+ c.SetGlobalNormalizationFunc(n)
+
+ if c.LocalFlags().Lookup("flagname") == c.LocalFlags().Lookup("FLAGNAME") {
+ t.Error("Normalizing flag names should not result in duplicate flags")
+ }
+}
+
+func TestFlagOnPflagCommandLine(t *testing.T) {
+ flagName := "flagOnCommandLine"
+ pflag.String(flagName, "", "about my flag")
+
+ c := &Command{Use: "c", Run: emptyRun}
+ c.AddCommand(&Command{Use: "child", Run: emptyRun})
+
+ output, _ := executeCommand(c, "--help")
+ checkStringContains(t, output, flagName)
+
+ resetCommandLineFlagSet()
+}
+
+// TestHiddenCommandExecutes checks,
+// if hidden commands run as intended.
+func TestHiddenCommandExecutes(t *testing.T) {
+ executed := false
+ c := &Command{
+ Use: "c",
+ Hidden: true,
+ Run: func(*Command, []string) { executed = true },
+ }
+
+ output, err := executeCommand(c)
+ if output != "" {
+ t.Errorf("Unexpected output: %v", output)
+ }
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+
+ if !executed {
+ t.Error("Hidden command should have been executed")
+ }
+}
+
+// test to ensure hidden commands do not show up in usage/help text
+func TestHiddenCommandIsHidden(t *testing.T) {
+ c := &Command{Use: "c", Hidden: true, Run: emptyRun}
+ if c.IsAvailableCommand() {
+ t.Errorf("Hidden command should be unavailable")
}
}
@@ -158,15 +1277,16 @@ func TestCommandsAreSorted(t *testing.T) {
originalNames := []string{"middle", "zlast", "afirst"}
expectedNames := []string{"afirst", "middle", "zlast"}
- var tmpCommand = &Command{Use: "tmp"}
+ var rootCmd = &Command{Use: "root"}
for _, name := range originalNames {
- tmpCommand.AddCommand(&Command{Use: name})
+ rootCmd.AddCommand(&Command{Use: name})
}
- for i, c := range tmpCommand.Commands() {
- if expectedNames[i] != c.Name() {
- t.Errorf("expected: %s, got: %s", expectedNames[i], c.Name())
+ for i, c := range rootCmd.Commands() {
+ got := c.Name()
+ if expectedNames[i] != got {
+ t.Errorf("Expected: %s, got: %s", expectedNames[i], got)
}
}
@@ -178,15 +1298,16 @@ func TestEnableCommandSortingIsDisabled(t *testing.T) {
originalNames := []string{"middle", "zlast", "afirst"}
- var tmpCommand = &Command{Use: "tmp"}
+ var rootCmd = &Command{Use: "root"}
for _, name := range originalNames {
- tmpCommand.AddCommand(&Command{Use: name})
+ rootCmd.AddCommand(&Command{Use: name})
}
- for i, c := range tmpCommand.Commands() {
- if originalNames[i] != c.Name() {
- t.Errorf("expected: %s, got: %s", originalNames[i], c.Name())
+ for i, c := range rootCmd.Commands() {
+ got := c.Name()
+ if originalNames[i] != got {
+ t.Errorf("expected: %s, got: %s", originalNames[i], got)
}
}
@@ -194,33 +1315,27 @@ func TestEnableCommandSortingIsDisabled(t *testing.T) {
}
func TestSetOutput(t *testing.T) {
- cmd := &Command{}
- cmd.SetOutput(nil)
- if out := cmd.OutOrStdout(); out != os.Stdout {
- t.Fatalf("expected setting output to nil to revert back to stdout, got %v", out)
+ c := &Command{}
+ c.SetOutput(nil)
+ if out := c.OutOrStdout(); out != os.Stdout {
+ t.Errorf("Expected setting output to nil to revert back to stdout")
}
}
func TestFlagErrorFunc(t *testing.T) {
- cmd := &Command{
- Use: "print",
- RunE: func(cmd *Command, args []string) error {
- return nil
- },
- }
- expectedFmt := "This is expected: %s"
+ c := &Command{Use: "c", Run: emptyRun}
- cmd.SetFlagErrorFunc(func(c *Command, err error) error {
+ expectedFmt := "This is expected: %v"
+ c.SetFlagErrorFunc(func(_ *Command, err error) error {
return fmt.Errorf(expectedFmt, err)
})
- cmd.SetArgs([]string{"--bogus-flag"})
- cmd.SetOutput(new(bytes.Buffer))
- err := cmd.Execute()
+ _, err := executeCommand(c, "--unknown-flag")
- expected := fmt.Sprintf(expectedFmt, "unknown flag: --bogus-flag")
- if err.Error() != expected {
- t.Errorf("expected %v, got %v", expected, err.Error())
+ got := err.Error()
+ expected := fmt.Sprintf(expectedFmt, "unknown flag: --unknown-flag")
+ if got != expected {
+ t.Errorf("Expected %v, got %v", expected, got)
}
}
@@ -228,19 +1343,19 @@ func TestFlagErrorFunc(t *testing.T) {
// if cmd.LocalFlags() is unsorted when cmd.Flags().SortFlags set to false.
// Related to https://github.com/spf13/cobra/issues/404.
func TestSortedFlags(t *testing.T) {
- cmd := &Command{}
- cmd.Flags().SortFlags = false
+ c := &Command{}
+ c.Flags().SortFlags = false
names := []string{"C", "B", "A", "D"}
for _, name := range names {
- cmd.Flags().Bool(name, false, "")
+ c.Flags().Bool(name, false, "")
}
i := 0
- cmd.LocalFlags().VisitAll(func(f *pflag.Flag) {
+ c.LocalFlags().VisitAll(func(f *pflag.Flag) {
if i == len(names) {
return
}
- if isStringInStringSlice(f.Name, names) {
+ if stringInSlice(f.Name, names) {
if names[i] != f.Name {
t.Errorf("Incorrect order. Expected %v, got %v", names[i], f.Name)
}
@@ -249,101 +1364,145 @@ func TestSortedFlags(t *testing.T) {
})
}
-// contains checks, if s is in ss.
-func isStringInStringSlice(s string, ss []string) bool {
- for _, v := range ss {
- if v == s {
- return true
- }
- }
- return false
-}
-
-// TestHelpFlagInHelp checks,
-// if '--help' flag is shown in help for child (executing `parent help child`),
-// that has no other flags.
-// Related to https://github.com/spf13/cobra/issues/302.
-func TestHelpFlagInHelp(t *testing.T) {
- output := new(bytes.Buffer)
- parent := &Command{Use: "parent", Run: func(*Command, []string) {}}
- parent.SetOutput(output)
-
- child := &Command{Use: "child", Run: func(*Command, []string) {}}
- parent.AddCommand(child)
-
- parent.SetArgs([]string{"help", "child"})
- err := parent.Execute()
- if err != nil {
- t.Fatal(err)
- }
-
- if !strings.Contains(output.String(), "[flags]") {
- t.Errorf("\nExpecting to contain: %v\nGot: %v", "[flags]", output.String())
- }
-}
-
// TestMergeCommandLineToFlags checks,
// if pflag.CommandLine is correctly merged to c.Flags() after first call
// of c.mergePersistentFlags.
// Related to https://github.com/spf13/cobra/issues/443.
func TestMergeCommandLineToFlags(t *testing.T) {
pflag.Bool("boolflag", false, "")
- c := &Command{Use: "c", Run: func(*Command, []string) {}}
+ c := &Command{Use: "c", Run: emptyRun}
c.mergePersistentFlags()
if c.Flags().Lookup("boolflag") == nil {
t.Fatal("Expecting to have flag from CommandLine in c.Flags()")
}
- // Reset pflag.CommandLine flagset.
- pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
+ resetCommandLineFlagSet()
}
// TestUseDeprecatedFlags checks,
// if cobra.Execute() prints a message, if a deprecated flag is used.
// Related to https://github.com/spf13/cobra/issues/463.
func TestUseDeprecatedFlags(t *testing.T) {
- c := &Command{Use: "c", Run: func(*Command, []string) {}}
- output := new(bytes.Buffer)
- c.SetOutput(output)
+ c := &Command{Use: "c", Run: emptyRun}
c.Flags().BoolP("deprecated", "d", false, "deprecated flag")
c.Flags().MarkDeprecated("deprecated", "This flag is deprecated")
- c.SetArgs([]string{"c", "-d"})
- if err := c.Execute(); err != nil {
+ output, err := executeCommand(c, "c", "-d")
+ if err != nil {
t.Error("Unexpected error:", err)
}
- if !strings.Contains(output.String(), "This flag is deprecated") {
- t.Errorf("Expected to contain deprecated message, but got %q", output.String())
+ checkStringContains(t, output, "This flag is deprecated")
+}
+
+func TestTraverseWithParentFlags(t *testing.T) {
+ rootCmd := &Command{Use: "root", TraverseChildren: true}
+ rootCmd.Flags().String("str", "", "")
+ rootCmd.Flags().BoolP("bool", "b", false, "")
+
+ childCmd := &Command{Use: "child"}
+ childCmd.Flags().Int("int", -1, "")
+
+ rootCmd.AddCommand(childCmd)
+
+ c, args, err := rootCmd.Traverse([]string{"-b", "--str", "ok", "child", "--int"})
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+ if len(args) != 1 && args[0] != "--add" {
+ t.Errorf("Wrong args: %v", args)
+ }
+ if c.Name() != childCmd.Name() {
+ t.Errorf("Expected command: %q, got: %q", childCmd.Name(), c.Name())
}
}
-// TestSetHelpCommand checks, if SetHelpCommand works correctly.
-func TestSetHelpCommand(t *testing.T) {
- c := &Command{Use: "c", Run: func(*Command, []string) {}}
- output := new(bytes.Buffer)
- c.SetOutput(output)
- c.SetArgs([]string{"help"})
-
- // Help will not be shown, if c has no subcommands.
- c.AddCommand(&Command{
- Use: "empty",
- Run: func(cmd *Command, args []string) {},
- })
+func TestTraverseNoParentFlags(t *testing.T) {
+ rootCmd := &Command{Use: "root", TraverseChildren: true}
+ rootCmd.Flags().String("foo", "", "foo things")
- correctMessage := "WORKS"
- c.SetHelpCommand(&Command{
- Use: "help [command]",
- Short: "Help about any command",
- Long: `Help provides help for any command in the application.
- Simply type ` + c.Name() + ` help [path to command] for full details.`,
- Run: func(c *Command, args []string) { c.Print(correctMessage) },
- })
+ childCmd := &Command{Use: "child"}
+ childCmd.Flags().String("str", "", "")
+ rootCmd.AddCommand(childCmd)
- if err := c.Execute(); err != nil {
- t.Error("Unexpected error:", err)
+ c, args, err := rootCmd.Traverse([]string{"child"})
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+ if len(args) != 0 {
+ t.Errorf("Wrong args %v", args)
+ }
+ if c.Name() != childCmd.Name() {
+ t.Errorf("Expected command: %q, got: %q", childCmd.Name(), c.Name())
+ }
+}
+
+func TestTraverseWithBadParentFlags(t *testing.T) {
+ rootCmd := &Command{Use: "root", TraverseChildren: true}
+
+ childCmd := &Command{Use: "child"}
+ childCmd.Flags().String("str", "", "")
+ rootCmd.AddCommand(childCmd)
+
+ expected := "unknown flag: --str"
+
+ c, _, err := rootCmd.Traverse([]string{"--str", "ok", "child"})
+ if err == nil || !strings.Contains(err.Error(), expected) {
+ t.Errorf("Expected error, %q, got %q", expected, err)
+ }
+ if c != nil {
+ t.Errorf("Expected nil command")
}
+}
+
+func TestTraverseWithBadChildFlag(t *testing.T) {
+ rootCmd := &Command{Use: "root", TraverseChildren: true}
+ rootCmd.Flags().String("str", "", "")
+
+ childCmd := &Command{Use: "child"}
+ rootCmd.AddCommand(childCmd)
+
+ // Expect no error because the last commands args shouldn't be parsed in
+ // Traverse.
+ c, args, err := rootCmd.Traverse([]string{"child", "--str"})
+ if err != nil {
+ t.Errorf("Unexpected error: %v", err)
+ }
+ if len(args) != 1 && args[0] != "--str" {
+ t.Errorf("Wrong args: %v", args)
+ }
+ if c.Name() != childCmd.Name() {
+ t.Errorf("Expected command %q, got: %q", childCmd.Name(), c.Name())
+ }
+}
+
+func TestTraverseWithTwoSubcommands(t *testing.T) {
+ rootCmd := &Command{Use: "root", TraverseChildren: true}
+
+ subCmd := &Command{Use: "sub", TraverseChildren: true}
+ rootCmd.AddCommand(subCmd)
+
+ subsubCmd := &Command{
+ Use: "subsub",
+ }
+ subCmd.AddCommand(subsubCmd)
+
+ c, _, err := rootCmd.Traverse([]string{"sub", "subsub"})
+ if err != nil {
+ t.Fatalf("Unexpected error: %v", err)
+ }
+ if c.Name() != subsubCmd.Name() {
+ t.Fatalf("Expected command: %q, got %q", subsubCmd.Name(), c.Name())
+ }
+}
+
+// TestUpdateName checks if c.Name() updates on changed c.Use.
+// Related to https://github.com/spf13/cobra/pull/422#discussion_r143918343.
+func TestUpdateName(t *testing.T) {
+ c := &Command{Use: "name xyz"}
+ originalName := c.Name()
- if output.String() != correctMessage {
- t.Errorf("Expected to contain %q message, but got %q", correctMessage, output.String())
+ c.Use = "changedName abc"
+ if originalName == c.Name() || c.Name() != "changedName" {
+ t.Error("c.Name() should be updated on changed c.Use")
}
}
diff --git a/vendor/github.com/spf13/cobra/doc/cmd_test.go b/vendor/github.com/spf13/cobra/doc/cmd_test.go
index a4b5568fa..d29c577df 100644
--- a/vendor/github.com/spf13/cobra/doc/cmd_test.go
+++ b/vendor/github.com/spf13/cobra/doc/cmd_test.go
@@ -1,145 +1,86 @@
package doc
import (
- "bytes"
- "fmt"
- "runtime"
"strings"
"testing"
"github.com/spf13/cobra"
)
-var flagb1, flagb2, flagb3, flagbr, flagbp bool
-var flags1, flags2a, flags2b, flags3 string
-var flagi1, flagi2, flagi3, flagir int
+func emptyRun(*cobra.Command, []string) {}
-const strtwoParentHelp = "help message for parent flag strtwo"
-const strtwoChildHelp = "help message for child flag strtwo"
+func init() {
+ rootCmd.PersistentFlags().StringP("rootflag", "r", "two", "")
+ rootCmd.PersistentFlags().StringP("strtwo", "t", "two", "help message for parent flag strtwo")
-var cmdEcho = &cobra.Command{
+ echoCmd.PersistentFlags().StringP("strone", "s", "one", "help message for flag strone")
+ echoCmd.PersistentFlags().BoolP("persistentbool", "p", false, "help message for flag persistentbool")
+ echoCmd.Flags().IntP("intone", "i", 123, "help message for flag intone")
+ echoCmd.Flags().BoolP("boolone", "b", true, "help message for flag boolone")
+
+ timesCmd.PersistentFlags().StringP("strtwo", "t", "2", "help message for child flag strtwo")
+ timesCmd.Flags().IntP("inttwo", "j", 234, "help message for flag inttwo")
+ timesCmd.Flags().BoolP("booltwo", "c", false, "help message for flag booltwo")
+
+ printCmd.PersistentFlags().StringP("strthree", "s", "three", "help message for flag strthree")
+ printCmd.Flags().IntP("intthree", "i", 345, "help message for flag intthree")
+ printCmd.Flags().BoolP("boolthree", "b", true, "help message for flag boolthree")
+
+ echoCmd.AddCommand(timesCmd, echoSubCmd, deprecatedCmd)
+ rootCmd.AddCommand(printCmd, echoCmd)
+}
+
+var rootCmd = &cobra.Command{
+ Use: "root",
+ Short: "Root short description",
+ Long: "Root long description",
+ Run: emptyRun,
+}
+
+var echoCmd = &cobra.Command{
Use: "echo [string to echo]",
Aliases: []string{"say"},
Short: "Echo anything to the screen",
- Long: `an utterly useless command for testing.`,
+ Long: "an utterly useless command for testing",
Example: "Just run cobra-test echo",
}
-var cmdEchoSub = &cobra.Command{
+var echoSubCmd = &cobra.Command{
Use: "echosub [string to print]",
Short: "second sub command for echo",
- Long: `an absolutely utterly useless command for testing gendocs!.`,
- Run: func(cmd *cobra.Command, args []string) {},
+ Long: "an absolutely utterly useless command for testing gendocs!.",
+ Run: emptyRun,
+}
+
+var timesCmd = &cobra.Command{
+ Use: "times [# times] [string to echo]",
+ SuggestFor: []string{"counts"},
+ Short: "Echo anything to the screen more times",
+ Long: `a slightly useless command for testing.`,
+ Run: emptyRun,
}
-var cmdDeprecated = &cobra.Command{
+var deprecatedCmd = &cobra.Command{
Use: "deprecated [can't do anything here]",
Short: "A command which is deprecated",
Long: `an absolutely utterly useless command for testing deprecation!.`,
Deprecated: "Please use echo instead",
}
-var cmdTimes = &cobra.Command{
- Use: "times [# times] [string to echo]",
- SuggestFor: []string{"counts"},
- Short: "Echo anything to the screen more times",
- Long: `a slightly useless command for testing.`,
- PersistentPreRun: func(cmd *cobra.Command, args []string) {},
- Run: func(cmd *cobra.Command, args []string) {},
-}
-
-var cmdPrint = &cobra.Command{
+var printCmd = &cobra.Command{
Use: "print [string to print]",
Short: "Print anything to the screen",
Long: `an absolutely utterly useless command for testing.`,
}
-var cmdRootNoRun = &cobra.Command{
- Use: "cobra-test",
- Short: "The root can run its own function",
- Long: "The root description for help",
-}
-
-var cmdRootSameName = &cobra.Command{
- Use: "print",
- Short: "Root with the same name as a subcommand",
- Long: "The root description for help",
-}
-
-var cmdRootWithRun = &cobra.Command{
- Use: "cobra-test",
- Short: "The root can run its own function",
- Long: "The root description for help",
-}
-
-var cmdSubNoRun = &cobra.Command{
- Use: "subnorun",
- Short: "A subcommand without a Run function",
- Long: "A long output about a subcommand without a Run function",
-}
-
-var cmdVersion1 = &cobra.Command{
- Use: "version",
- Short: "Print the version number",
- Long: `First version of the version command`,
-}
-
-var cmdVersion2 = &cobra.Command{
- Use: "version",
- Short: "Print the version number",
- Long: `Second version of the version command`,
-}
-
-func flagInit() {
- cmdEcho.ResetFlags()
- cmdPrint.ResetFlags()
- cmdTimes.ResetFlags()
- cmdRootNoRun.ResetFlags()
- cmdRootSameName.ResetFlags()
- cmdRootWithRun.ResetFlags()
- cmdSubNoRun.ResetFlags()
- cmdRootNoRun.PersistentFlags().StringVarP(&flags2a, "strtwo", "t", "two", strtwoParentHelp)
- cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone")
- cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
- cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree")
- cmdEcho.PersistentFlags().StringVarP(&flags1, "strone", "s", "one", "help message for flag strone")
- cmdEcho.PersistentFlags().BoolVarP(&flagbp, "persistentbool", "p", false, "help message for flag persistentbool")
- cmdTimes.PersistentFlags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
- cmdPrint.PersistentFlags().StringVarP(&flags3, "strthree", "s", "three", "help message for flag strthree")
- cmdEcho.Flags().BoolVarP(&flagb1, "boolone", "b", true, "help message for flag boolone")
- cmdTimes.Flags().BoolVarP(&flagb2, "booltwo", "c", false, "help message for flag booltwo")
- cmdPrint.Flags().BoolVarP(&flagb3, "boolthree", "b", true, "help message for flag boolthree")
- cmdVersion1.ResetFlags()
- cmdVersion2.ResetFlags()
-}
-
-func initializeWithRootCmd() *cobra.Command {
- cmdRootWithRun.ResetCommands()
- flagInit()
- cmdRootWithRun.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot")
- cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag introot")
- return cmdRootWithRun
-}
-
-func checkStringContains(t *testing.T, found, expected string) {
- if !strings.Contains(found, expected) {
- logErr(t, found, expected)
+func checkStringContains(t *testing.T, got, expected string) {
+ if !strings.Contains(got, expected) {
+ t.Errorf("Expected to contain: \n %v\nGot:\n %v\n", expected, got)
}
}
-func checkStringOmits(t *testing.T, found, expected string) {
- if strings.Contains(found, expected) {
- logErr(t, found, expected)
- }
-}
-
-func logErr(t *testing.T, found, expected string) {
- out := new(bytes.Buffer)
-
- _, _, line, ok := runtime.Caller(2)
- if ok {
- fmt.Fprintf(out, "Line: %d ", line)
+func checkStringOmits(t *testing.T, got, expected string) {
+ if strings.Contains(got, expected) {
+ t.Errorf("Expected to not contain: \n %v\nGot: %v", expected, got)
}
- fmt.Fprintf(out, "Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- t.Errorf(out.String())
}
diff --git a/vendor/github.com/spf13/cobra/doc/man_docs_test.go b/vendor/github.com/spf13/cobra/doc/man_docs_test.go
index 87991063e..62f85e47f 100644
--- a/vendor/github.com/spf13/cobra/doc/man_docs_test.go
+++ b/vendor/github.com/spf13/cobra/doc/man_docs_test.go
@@ -18,135 +18,97 @@ func translate(in string) string {
}
func TestGenManDoc(t *testing.T) {
- c := initializeWithRootCmd()
- // Need two commands to run the command alphabetical sort
- cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
- c.AddCommand(cmdPrint, cmdEcho)
- cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
-
- out := new(bytes.Buffer)
-
header := &GenManHeader{
Title: "Project",
Section: "2",
}
+
// We generate on a subcommand so we have both subcommands and parents
- if err := GenMan(cmdEcho, header, out); err != nil {
+ buf := new(bytes.Buffer)
+ if err := GenMan(echoCmd, header, buf); err != nil {
t.Fatal(err)
}
- found := out.String()
+ output := buf.String()
// Make sure parent has - in CommandPath() in SEE ALSO:
- parentPath := cmdEcho.Parent().CommandPath()
+ parentPath := echoCmd.Parent().CommandPath()
dashParentPath := strings.Replace(parentPath, " ", "-", -1)
expected := translate(dashParentPath)
expected = expected + "(" + header.Section + ")"
- checkStringContains(t, found, expected)
-
- // Our description
- expected = translate(cmdEcho.Name())
- checkStringContains(t, found, expected)
-
- // Better have our example
- expected = translate(cmdEcho.Name())
- checkStringContains(t, found, expected)
-
- // A local flag
- expected = "boolone"
- checkStringContains(t, found, expected)
-
- // persistent flag on parent
- expected = "rootflag"
- checkStringContains(t, found, expected)
-
- // We better output info about our parent
- expected = translate(cmdRootWithRun.Name())
- checkStringContains(t, found, expected)
-
- // And about subcommands
- expected = translate(cmdEchoSub.Name())
- checkStringContains(t, found, expected)
-
- unexpected := translate(cmdDeprecated.Name())
- checkStringOmits(t, found, unexpected)
-
- // auto generated
- expected = translate("Auto generated")
- checkStringContains(t, found, expected)
+ checkStringContains(t, output, expected)
+
+ checkStringContains(t, output, translate(echoCmd.Name()))
+ checkStringContains(t, output, translate(echoCmd.Name()))
+ checkStringContains(t, output, "boolone")
+ checkStringContains(t, output, "rootflag")
+ checkStringContains(t, output, translate(rootCmd.Name()))
+ checkStringContains(t, output, translate(echoSubCmd.Name()))
+ checkStringOmits(t, output, translate(deprecatedCmd.Name()))
+ checkStringContains(t, output, translate("Auto generated"))
}
func TestGenManNoGenTag(t *testing.T) {
- c := initializeWithRootCmd()
- // Need two commands to run the command alphabetical sort
- cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
- c.AddCommand(cmdPrint, cmdEcho)
- cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
- cmdEcho.DisableAutoGenTag = true
- out := new(bytes.Buffer)
+ echoCmd.DisableAutoGenTag = true
+ defer func() { echoCmd.DisableAutoGenTag = false }()
header := &GenManHeader{
Title: "Project",
Section: "2",
}
+
// We generate on a subcommand so we have both subcommands and parents
- if err := GenMan(cmdEcho, header, out); err != nil {
+ buf := new(bytes.Buffer)
+ if err := GenMan(echoCmd, header, buf); err != nil {
t.Fatal(err)
}
- found := out.String()
+ output := buf.String()
unexpected := translate("#HISTORY")
- checkStringOmits(t, found, unexpected)
+ checkStringOmits(t, output, unexpected)
}
func TestGenManSeeAlso(t *testing.T) {
- noop := func(cmd *cobra.Command, args []string) {}
-
- top := &cobra.Command{Use: "top", Run: noop}
- aaa := &cobra.Command{Use: "aaa", Run: noop, Hidden: true} // #229
- bbb := &cobra.Command{Use: "bbb", Run: noop}
- ccc := &cobra.Command{Use: "ccc", Run: noop}
- top.AddCommand(aaa, bbb, ccc)
+ rootCmd := &cobra.Command{Use: "root", Run: emptyRun}
+ aCmd := &cobra.Command{Use: "aaa", Run: emptyRun, Hidden: true} // #229
+ bCmd := &cobra.Command{Use: "bbb", Run: emptyRun}
+ cCmd := &cobra.Command{Use: "ccc", Run: emptyRun}
+ rootCmd.AddCommand(aCmd, bCmd, cCmd)
- out := new(bytes.Buffer)
+ buf := new(bytes.Buffer)
header := &GenManHeader{}
- if err := GenMan(top, header, out); err != nil {
+ if err := GenMan(rootCmd, header, buf); err != nil {
t.Fatal(err)
}
+ scanner := bufio.NewScanner(buf)
- scanner := bufio.NewScanner(out)
-
- if err := AssertLineFound(scanner, ".SH SEE ALSO"); err != nil {
- t.Fatal(fmt.Errorf("Couldn't find SEE ALSO section header: %s", err.Error()))
+ if err := assertLineFound(scanner, ".SH SEE ALSO"); err != nil {
+ t.Fatalf("Couldn't find SEE ALSO section header: %v", err)
}
-
- if err := AssertNextLineEquals(scanner, ".PP"); err != nil {
- t.Fatal(fmt.Errorf("First line after SEE ALSO wasn't break-indent: %s", err.Error()))
+ if err := assertNextLineEquals(scanner, ".PP"); err != nil {
+ t.Fatalf("First line after SEE ALSO wasn't break-indent: %v", err)
}
-
- if err := AssertNextLineEquals(scanner, `\fBtop\-bbb(1)\fP, \fBtop\-ccc(1)\fP`); err != nil {
- t.Fatal(fmt.Errorf("Second line after SEE ALSO wasn't correct: %s", err.Error()))
+ if err := assertNextLineEquals(scanner, `\fBroot\-bbb(1)\fP, \fBroot\-ccc(1)\fP`); err != nil {
+ t.Fatalf("Second line after SEE ALSO wasn't correct: %v", err)
}
}
func TestManPrintFlagsHidesShortDeperecated(t *testing.T) {
- cmd := &cobra.Command{}
- flags := cmd.Flags()
- flags.StringP("foo", "f", "default", "Foo flag")
- flags.MarkShorthandDeprecated("foo", "don't use it no more")
+ c := &cobra.Command{}
+ c.Flags().StringP("foo", "f", "default", "Foo flag")
+ c.Flags().MarkShorthandDeprecated("foo", "don't use it no more")
- out := new(bytes.Buffer)
- manPrintFlags(out, flags)
+ buf := new(bytes.Buffer)
+ manPrintFlags(buf, c.Flags())
+ got := buf.String()
expected := "**--foo**=\"default\"\n\tFoo flag\n\n"
- if out.String() != expected {
- t.Fatalf("Expected %s, but got %s", expected, out.String())
+ if got != expected {
+ t.Errorf("Expected %v, got %v", expected, got)
}
}
func TestGenManTree(t *testing.T) {
- cmd := &cobra.Command{
- Use: "do [OPTIONS] arg1 arg2",
- }
+ c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"}
header := &GenManHeader{Section: "2"}
tmpdir, err := ioutil.TempDir("", "test-gen-man-tree")
if err != nil {
@@ -154,7 +116,7 @@ func TestGenManTree(t *testing.T) {
}
defer os.RemoveAll(tmpdir)
- if err := GenManTree(cmd, header, tmpdir); err != nil {
+ if err := GenManTree(c, header, tmpdir); err != nil {
t.Fatalf("GenManTree failed: %s", err.Error())
}
@@ -167,7 +129,7 @@ func TestGenManTree(t *testing.T) {
}
}
-func AssertLineFound(scanner *bufio.Scanner, expectedLine string) error {
+func assertLineFound(scanner *bufio.Scanner, expectedLine string) error {
for scanner.Scan() {
line := scanner.Text()
if line == expectedLine {
@@ -176,30 +138,29 @@ func AssertLineFound(scanner *bufio.Scanner, expectedLine string) error {
}
if err := scanner.Err(); err != nil {
- return fmt.Errorf("AssertLineFound: scan failed: %s", err.Error())
+ return fmt.Errorf("scan failed: %s", err)
}
- return fmt.Errorf("AssertLineFound: hit EOF before finding %#v", expectedLine)
+ return fmt.Errorf("hit EOF before finding %v", expectedLine)
}
-func AssertNextLineEquals(scanner *bufio.Scanner, expectedLine string) error {
+func assertNextLineEquals(scanner *bufio.Scanner, expectedLine string) error {
if scanner.Scan() {
line := scanner.Text()
if line == expectedLine {
return nil
}
- return fmt.Errorf("AssertNextLineEquals: got %#v, not %#v", line, expectedLine)
+ return fmt.Errorf("got %v, not %v", line, expectedLine)
}
if err := scanner.Err(); err != nil {
- return fmt.Errorf("AssertNextLineEquals: scan failed: %s", err.Error())
+ return fmt.Errorf("scan failed: %v", err)
}
- return fmt.Errorf("AssertNextLineEquals: hit EOF before finding %#v", expectedLine)
+ return fmt.Errorf("hit EOF before finding %v", expectedLine)
}
func BenchmarkGenManToFile(b *testing.B) {
- c := initializeWithRootCmd()
file, err := ioutil.TempFile("", "")
if err != nil {
b.Fatal(err)
@@ -209,7 +170,7 @@ func BenchmarkGenManToFile(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- if err := GenMan(c, nil, file); err != nil {
+ if err := GenMan(rootCmd, nil, file); err != nil {
b.Fatal(err)
}
}
diff --git a/vendor/github.com/spf13/cobra/doc/md_docs_test.go b/vendor/github.com/spf13/cobra/doc/md_docs_test.go
index ba6b9a46e..b0fa68c0b 100644
--- a/vendor/github.com/spf13/cobra/doc/md_docs_test.go
+++ b/vendor/github.com/spf13/cobra/doc/md_docs_test.go
@@ -5,100 +5,51 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "strings"
"testing"
"github.com/spf13/cobra"
)
func TestGenMdDoc(t *testing.T) {
- c := initializeWithRootCmd()
- // Need two commands to run the command alphabetical sort
- cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
- c.AddCommand(cmdPrint, cmdEcho)
- cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
-
- out := new(bytes.Buffer)
-
- // We generate on s subcommand so we have both subcommands and parents
- if err := GenMarkdown(cmdEcho, out); err != nil {
+ // We generate on subcommand so we have both subcommands and parents.
+ buf := new(bytes.Buffer)
+ if err := GenMarkdown(echoCmd, buf); err != nil {
t.Fatal(err)
}
- found := out.String()
-
- // Our description
- expected := cmdEcho.Long
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // Better have our example
- expected = cmdEcho.Example
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // A local flag
- expected = "boolone"
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // persistent flag on parent
- expected = "rootflag"
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // We better output info about our parent
- expected = cmdRootWithRun.Short
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // And about subcommands
- expected = cmdEchoSub.Short
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- unexpected := cmdDeprecated.Short
- if strings.Contains(found, unexpected) {
- t.Errorf("Unexpected response.\nFound: %v\nBut should not have!!\n", unexpected)
- }
+ output := buf.String()
+
+ checkStringContains(t, output, echoCmd.Long)
+ checkStringContains(t, output, echoCmd.Example)
+ checkStringContains(t, output, "boolone")
+ checkStringContains(t, output, "rootflag")
+ checkStringContains(t, output, rootCmd.Short)
+ checkStringContains(t, output, echoSubCmd.Short)
+ checkStringOmits(t, output, deprecatedCmd.Short)
}
func TestGenMdNoTag(t *testing.T) {
- c := initializeWithRootCmd()
- // Need two commands to run the command alphabetical sort
- cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
- c.AddCommand(cmdPrint, cmdEcho)
- c.DisableAutoGenTag = true
- cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
- out := new(bytes.Buffer)
+ rootCmd.DisableAutoGenTag = true
+ defer func() { rootCmd.DisableAutoGenTag = false }()
- if err := GenMarkdown(c, out); err != nil {
+ buf := new(bytes.Buffer)
+ if err := GenMarkdown(rootCmd, buf); err != nil {
t.Fatal(err)
}
- found := out.String()
-
- unexpected := "Auto generated"
- checkStringOmits(t, found, unexpected)
+ output := buf.String()
+ checkStringOmits(t, output, "Auto generated")
}
func TestGenMdTree(t *testing.T) {
- cmd := &cobra.Command{
- Use: "do [OPTIONS] arg1 arg2",
- }
+ c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"}
tmpdir, err := ioutil.TempDir("", "test-gen-md-tree")
if err != nil {
- t.Fatalf("Failed to create tmpdir: %s", err.Error())
+ t.Fatalf("Failed to create tmpdir: %v", err)
}
defer os.RemoveAll(tmpdir)
- if err := GenMarkdownTree(cmd, tmpdir); err != nil {
- t.Fatalf("GenMarkdownTree failed: %s", err.Error())
+ if err := GenMarkdownTree(c, tmpdir); err != nil {
+ t.Fatalf("GenMarkdownTree failed: %v", err)
}
if _, err := os.Stat(filepath.Join(tmpdir, "do.md")); err != nil {
@@ -107,7 +58,6 @@ func TestGenMdTree(t *testing.T) {
}
func BenchmarkGenMarkdownToFile(b *testing.B) {
- c := initializeWithRootCmd()
file, err := ioutil.TempFile("", "")
if err != nil {
b.Fatal(err)
@@ -117,7 +67,7 @@ func BenchmarkGenMarkdownToFile(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- if err := GenMarkdown(c, file); err != nil {
+ if err := GenMarkdown(rootCmd, file); err != nil {
b.Fatal(err)
}
}
diff --git a/vendor/github.com/spf13/cobra/doc/rest_docs.go b/vendor/github.com/spf13/cobra/doc/rest_docs.go
new file mode 100644
index 000000000..4913e3ee2
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/doc/rest_docs.go
@@ -0,0 +1,185 @@
+//Copyright 2015 Red Hat Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package doc
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/spf13/cobra"
+)
+
+func printOptionsReST(buf *bytes.Buffer, cmd *cobra.Command, name string) error {
+ flags := cmd.NonInheritedFlags()
+ flags.SetOutput(buf)
+ if flags.HasFlags() {
+ buf.WriteString("Options\n")
+ buf.WriteString("~~~~~~~\n\n::\n\n")
+ flags.PrintDefaults()
+ buf.WriteString("\n")
+ }
+
+ parentFlags := cmd.InheritedFlags()
+ parentFlags.SetOutput(buf)
+ if parentFlags.HasFlags() {
+ buf.WriteString("Options inherited from parent commands\n")
+ buf.WriteString("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n")
+ parentFlags.PrintDefaults()
+ buf.WriteString("\n")
+ }
+ return nil
+}
+
+// linkHandler for default ReST hyperlink markup
+func defaultLinkHandler(name, ref string) string {
+ return fmt.Sprintf("`%s <%s.rst>`_", name, ref)
+}
+
+// GenReST creates reStructured Text output.
+func GenReST(cmd *cobra.Command, w io.Writer) error {
+ return GenReSTCustom(cmd, w, defaultLinkHandler)
+}
+
+// GenReSTCustom creates custom reStructured Text output.
+func GenReSTCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string, string) string) error {
+ cmd.InitDefaultHelpCmd()
+ cmd.InitDefaultHelpFlag()
+
+ buf := new(bytes.Buffer)
+ name := cmd.CommandPath()
+
+ short := cmd.Short
+ long := cmd.Long
+ if len(long) == 0 {
+ long = short
+ }
+ ref := strings.Replace(name, " ", "_", -1)
+
+ buf.WriteString(".. _" + ref + ":\n\n")
+ buf.WriteString(name + "\n")
+ buf.WriteString(strings.Repeat("-", len(name)) + "\n\n")
+ buf.WriteString(short + "\n\n")
+ buf.WriteString("Synopsis\n")
+ buf.WriteString("~~~~~~~~\n\n")
+ buf.WriteString("\n" + long + "\n\n")
+
+ if cmd.Runnable() {
+ buf.WriteString(fmt.Sprintf("::\n\n %s\n\n", cmd.UseLine()))
+ }
+
+ if len(cmd.Example) > 0 {
+ buf.WriteString("Examples\n")
+ buf.WriteString("~~~~~~~~\n\n")
+ buf.WriteString(fmt.Sprintf("::\n\n%s\n\n", indentString(cmd.Example, " ")))
+ }
+
+ if err := printOptionsReST(buf, cmd, name); err != nil {
+ return err
+ }
+ if hasSeeAlso(cmd) {
+ buf.WriteString("SEE ALSO\n")
+ buf.WriteString("~~~~~~~~\n\n")
+ if cmd.HasParent() {
+ parent := cmd.Parent()
+ pname := parent.CommandPath()
+ ref = strings.Replace(pname, " ", "_", -1)
+ buf.WriteString(fmt.Sprintf("* %s \t - %s\n", linkHandler(pname, ref), parent.Short))
+ cmd.VisitParents(func(c *cobra.Command) {
+ if c.DisableAutoGenTag {
+ cmd.DisableAutoGenTag = c.DisableAutoGenTag
+ }
+ })
+ }
+
+ children := cmd.Commands()
+ sort.Sort(byName(children))
+
+ for _, child := range children {
+ if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
+ continue
+ }
+ cname := name + " " + child.Name()
+ ref = strings.Replace(cname, " ", "_", -1)
+ buf.WriteString(fmt.Sprintf("* %s \t - %s\n", linkHandler(cname, ref), child.Short))
+ }
+ buf.WriteString("\n")
+ }
+ if !cmd.DisableAutoGenTag {
+ buf.WriteString("*Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "*\n")
+ }
+ _, err := buf.WriteTo(w)
+ return err
+}
+
+// GenReSTTree will generate a ReST page for this command and all
+// descendants in the directory given.
+// This function may not work correctly if your command names have `-` in them.
+// If you have `cmd` with two subcmds, `sub` and `sub-third`,
+// and `sub` has a subcommand called `third`, it is undefined which
+// help output will be in the file `cmd-sub-third.1`.
+func GenReSTTree(cmd *cobra.Command, dir string) error {
+ emptyStr := func(s string) string { return "" }
+ return GenReSTTreeCustom(cmd, dir, emptyStr, defaultLinkHandler)
+}
+
+// GenReSTTreeCustom is the the same as GenReSTTree, but
+// with custom filePrepender and linkHandler.
+func GenReSTTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string, linkHandler func(string, string) string) error {
+ for _, c := range cmd.Commands() {
+ if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
+ continue
+ }
+ if err := GenReSTTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
+ return err
+ }
+ }
+
+ basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".rst"
+ filename := filepath.Join(dir, basename)
+ f, err := os.Create(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
+ return err
+ }
+ if err := GenReSTCustom(cmd, f, linkHandler); err != nil {
+ return err
+ }
+ return nil
+}
+
+// adapted from: https://github.com/kr/text/blob/main/indent.go
+func indentString(s, p string) string {
+ var res []byte
+ b := []byte(s)
+ prefix := []byte(p)
+ bol := true
+ for _, c := range b {
+ if bol && c != '\n' {
+ res = append(res, prefix...)
+ }
+ res = append(res, c)
+ bol = c == '\n'
+ }
+ return string(res)
+}
diff --git a/vendor/github.com/spf13/cobra/doc/rest_docs.md b/vendor/github.com/spf13/cobra/doc/rest_docs.md
new file mode 100644
index 000000000..6098430ef
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/doc/rest_docs.md
@@ -0,0 +1,114 @@
+# Generating ReStructured Text Docs For Your Own cobra.Command
+
+Generating ReST pages from a cobra command is incredibly easy. An example is as follows:
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/spf13/cobra"
+ "github.com/spf13/cobra/doc"
+)
+
+func main() {
+ cmd := &cobra.Command{
+ Use: "test",
+ Short: "my test program",
+ }
+ err := doc.GenReSTTree(cmd, "/tmp")
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
+That will get you a ReST document `/tmp/test.rst`
+
+## Generate ReST docs for the entire command tree
+
+This program can actually generate docs for the kubectl command in the kubernetes project
+
+```go
+package main
+
+import (
+ "log"
+ "io/ioutil"
+ "os"
+
+ "k8s.io/kubernetes/pkg/kubectl/cmd"
+ cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
+
+ "github.com/spf13/cobra/doc"
+)
+
+func main() {
+ kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
+ err := doc.GenReSTTree(kubectl, "./")
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
+This will generate a whole series of files, one for each command in the tree, in the directory specified (in this case "./")
+
+## Generate ReST docs for a single command
+
+You may wish to have more control over the output, or only generate for a single command, instead of the entire command tree. If this is the case you may prefer to `GenReST` instead of `GenReSTTree`
+
+```go
+ out := new(bytes.Buffer)
+ err := doc.GenReST(cmd, out)
+ if err != nil {
+ log.Fatal(err)
+ }
+```
+
+This will write the ReST doc for ONLY "cmd" into the out, buffer.
+
+## Customize the output
+
+Both `GenReST` and `GenReSTTree` have alternate versions with callbacks to get some control of the output:
+
+```go
+func GenReSTTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string, string) string) error {
+ //...
+}
+```
+
+```go
+func GenReSTCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string, string) string) error {
+ //...
+}
+```
+
+The `filePrepender` will prepend the return value given the full filepath to the rendered ReST file. A common use case is to add front matter to use the generated documentation with [Hugo](http://gohugo.io/):
+
+```go
+const fmTemplate = `---
+date: %s
+title: "%s"
+slug: %s
+url: %s
+---
+`
+filePrepender := func(filename string) string {
+ now := time.Now().Format(time.RFC3339)
+ name := filepath.Base(filename)
+ base := strings.TrimSuffix(name, path.Ext(name))
+ url := "/commands/" + strings.ToLower(base) + "/"
+ return fmt.Sprintf(fmTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
+}
+```
+
+The `linkHandler` can be used to customize the rendered links to the commands, given a command name and reference. This is useful while converting rst to html or while generating documentation with tools like Sphinx where `:ref:` is used:
+
+```go
+// Sphinx cross-referencing format
+linkHandler := func(name, ref string) string {
+ return fmt.Sprintf(":ref:`%s <%s>`", name, ref)
+}
+```
diff --git a/vendor/github.com/spf13/cobra/doc/rest_docs_test.go b/vendor/github.com/spf13/cobra/doc/rest_docs_test.go
new file mode 100644
index 000000000..aa3186e8f
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/doc/rest_docs_test.go
@@ -0,0 +1,76 @@
+package doc
+
+import (
+ "bytes"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/spf13/cobra"
+)
+
+func TestGenRSTDoc(t *testing.T) {
+ // We generate on a subcommand so we have both subcommands and parents
+ buf := new(bytes.Buffer)
+ if err := GenReST(echoCmd, buf); err != nil {
+ t.Fatal(err)
+ }
+ output := buf.String()
+
+ checkStringContains(t, output, echoCmd.Long)
+ checkStringContains(t, output, echoCmd.Example)
+ checkStringContains(t, output, "boolone")
+ checkStringContains(t, output, "rootflag")
+ checkStringContains(t, output, rootCmd.Short)
+ checkStringContains(t, output, echoSubCmd.Short)
+ checkStringOmits(t, output, deprecatedCmd.Short)
+}
+
+func TestGenRSTNoTag(t *testing.T) {
+ rootCmd.DisableAutoGenTag = true
+ defer func() { rootCmd.DisableAutoGenTag = false }()
+
+ buf := new(bytes.Buffer)
+ if err := GenReST(rootCmd, buf); err != nil {
+ t.Fatal(err)
+ }
+ output := buf.String()
+
+ unexpected := "Auto generated"
+ checkStringOmits(t, output, unexpected)
+}
+
+func TestGenRSTTree(t *testing.T) {
+ c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"}
+
+ tmpdir, err := ioutil.TempDir("", "test-gen-rst-tree")
+ if err != nil {
+ t.Fatalf("Failed to create tmpdir: %s", err.Error())
+ }
+ defer os.RemoveAll(tmpdir)
+
+ if err := GenReSTTree(c, tmpdir); err != nil {
+ t.Fatalf("GenReSTTree failed: %s", err.Error())
+ }
+
+ if _, err := os.Stat(filepath.Join(tmpdir, "do.rst")); err != nil {
+ t.Fatalf("Expected file 'do.rst' to exist")
+ }
+}
+
+func BenchmarkGenReSTToFile(b *testing.B) {
+ file, err := ioutil.TempFile("", "")
+ if err != nil {
+ b.Fatal(err)
+ }
+ defer os.Remove(file.Name())
+ defer file.Close()
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ if err := GenReST(rootCmd, file); err != nil {
+ b.Fatal(err)
+ }
+ }
+}
diff --git a/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go b/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go
index 29e985e40..c5a63594f 100644
--- a/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go
+++ b/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go
@@ -5,92 +5,42 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "strings"
"testing"
"github.com/spf13/cobra"
)
func TestGenYamlDoc(t *testing.T) {
- c := initializeWithRootCmd()
- // Need two commands to run the command alphabetical sort
- cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
- c.AddCommand(cmdPrint, cmdEcho)
- cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
-
- out := new(bytes.Buffer)
-
// We generate on s subcommand so we have both subcommands and parents
- if err := GenYaml(cmdEcho, out); err != nil {
+ buf := new(bytes.Buffer)
+ if err := GenYaml(echoCmd, buf); err != nil {
t.Fatal(err)
}
- found := out.String()
-
- // Our description
- expected := cmdEcho.Long
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // Better have our example
- expected = cmdEcho.Example
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // A local flag
- expected = "boolone"
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // persistent flag on parent
- expected = "rootflag"
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // We better output info about our parent
- expected = cmdRootWithRun.Short
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- // And about subcommands
- expected = cmdEchoSub.Short
- if !strings.Contains(found, expected) {
- t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found)
- }
-
- unexpected := cmdDeprecated.Short
- if strings.Contains(found, unexpected) {
- t.Errorf("Unexpected response.\nFound: %v\nBut should not have!!\n", unexpected)
- }
+ output := buf.String()
+
+ checkStringContains(t, output, echoCmd.Long)
+ checkStringContains(t, output, echoCmd.Example)
+ checkStringContains(t, output, "boolone")
+ checkStringContains(t, output, "rootflag")
+ checkStringContains(t, output, rootCmd.Short)
+ checkStringContains(t, output, echoSubCmd.Short)
}
func TestGenYamlNoTag(t *testing.T) {
- c := initializeWithRootCmd()
- // Need two commands to run the command alphabetical sort
- cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
- c.AddCommand(cmdPrint, cmdEcho)
- c.DisableAutoGenTag = true
- cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
- out := new(bytes.Buffer)
+ rootCmd.DisableAutoGenTag = true
+ defer func() { rootCmd.DisableAutoGenTag = false }()
- if err := GenYaml(c, out); err != nil {
+ buf := new(bytes.Buffer)
+ if err := GenYaml(rootCmd, buf); err != nil {
t.Fatal(err)
}
- found := out.String()
-
- unexpected := "Auto generated"
- checkStringOmits(t, found, unexpected)
+ output := buf.String()
+ checkStringOmits(t, output, "Auto generated")
}
func TestGenYamlTree(t *testing.T) {
- cmd := &cobra.Command{
- Use: "do [OPTIONS] arg1 arg2",
- }
+ c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"}
tmpdir, err := ioutil.TempDir("", "test-gen-yaml-tree")
if err != nil {
@@ -98,7 +48,7 @@ func TestGenYamlTree(t *testing.T) {
}
defer os.RemoveAll(tmpdir)
- if err := GenYamlTree(cmd, tmpdir); err != nil {
+ if err := GenYamlTree(c, tmpdir); err != nil {
t.Fatalf("GenYamlTree failed: %s", err.Error())
}
@@ -108,7 +58,6 @@ func TestGenYamlTree(t *testing.T) {
}
func BenchmarkGenYamlToFile(b *testing.B) {
- c := initializeWithRootCmd()
file, err := ioutil.TempFile("", "")
if err != nil {
b.Fatal(err)
@@ -118,7 +67,7 @@ func BenchmarkGenYamlToFile(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- if err := GenYaml(c, file); err != nil {
+ if err := GenYaml(rootCmd, file); err != nil {
b.Fatal(err)
}
}
diff --git a/vendor/github.com/spf13/cobra/zsh_completions_test.go b/vendor/github.com/spf13/cobra/zsh_completions_test.go
index 08b851591..34e69496f 100644
--- a/vendor/github.com/spf13/cobra/zsh_completions_test.go
+++ b/vendor/github.com/spf13/cobra/zsh_completions_test.go
@@ -77,10 +77,11 @@ func TestZshCompletion(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
buf := new(bytes.Buffer)
tc.root.GenZshCompletion(buf)
- completion := buf.String()
+ output := buf.String()
+
for _, expectedExpression := range tc.expectedExpressions {
- if !strings.Contains(completion, expectedExpression) {
- t.Errorf("expected completion to contain '%v' somewhere; got '%v'", expectedExpression, completion)
+ if !strings.Contains(output, expectedExpression) {
+ t.Errorf("Expected completion to contain %q somewhere; got %q", expectedExpression, output)
}
}
})