Ver Fonte

vendor: spf13/cobra v1.0.0

full diff: https://github.com/spf13/cobra/compare/v0.0.3...v1.0.0

Notable Changes

- Fish completion (including support for Go custom completion)
- API (urgent): Rename BashCompDirectives to ShellCompDirectives
- Remove/replace SetOutput on Command - deprecated
- Custom completions coded in Go (instead of Bash)
- Partial Revert of 922
- Correct documentation for InOrStdin
- Apply formatting to templates
- Revert change so help is printed on stdout again
- Update md2man to v2.0.0
- update viper to v1.4.0
- Update cmd/root.go example in README.md

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn há 5 anos atrás
pai
commit
dc0a400738

+ 1 - 1
cmd/dockerd/docker.go

@@ -93,7 +93,7 @@ func main() {
 	if err != nil {
 	if err != nil {
 		onError(err)
 		onError(err)
 	}
 	}
-	cmd.SetOutput(stdout)
+	cmd.SetOut(stdout)
 	if err := cmd.Execute(); err != nil {
 	if err := cmd.Execute(); err != nil {
 		onError(err)
 		onError(err)
 	}
 	}

+ 1 - 1
vendor.conf

@@ -160,7 +160,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus        c225b8c3b01faf2899099b768856
 github.com/cespare/xxhash/v2                        d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
 github.com/cespare/xxhash/v2                        d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
 
 
 # cli
 # cli
-github.com/spf13/cobra                              ef82de70bb3f60c65fb8eebacbb2d122ef517385 # v0.0.3
+github.com/spf13/cobra                              a684a6d7f5e37385d954dd3b5a14fc6912c6ab9d # v1.0.0
 github.com/spf13/pflag                              2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab # v1.0.5
 github.com/spf13/pflag                              2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab # v1.0.5
 github.com/inconshreveable/mousetrap                76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 # v1.0.0
 github.com/inconshreveable/mousetrap                76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 # v1.0.0
 github.com/morikuni/aec                             39771216ff4c63d11f5e604076f9c45e8be1067b # v1.0.0
 github.com/morikuni/aec                             39771216ff4c63d11f5e604076f9c45e8be1067b # v1.0.0

+ 101 - 67
vendor/github.com/spf13/cobra/README.md

@@ -2,29 +2,35 @@
 
 
 Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files.
 Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files.
 
 
-Many of the most widely used Go projects are built using Cobra including:
-
-* [Kubernetes](http://kubernetes.io/)
-* [Hugo](http://gohugo.io)
-* [rkt](https://github.com/coreos/rkt)
-* [etcd](https://github.com/coreos/etcd)
-* [Moby (former Docker)](https://github.com/moby/moby)
-* [Docker (distribution)](https://github.com/docker/distribution)
-* [OpenShift](https://www.openshift.com/)
-* [Delve](https://github.com/derekparker/delve)
-* [GopherJS](http://www.gopherjs.org/)
-* [CockroachDB](http://www.cockroachlabs.com/)
-* [Bleve](http://www.blevesearch.com/)
-* [ProjectAtomic (enterprise)](http://www.projectatomic.io/)
-* [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)
-* [Pouch](https://github.com/alibaba/pouch)
+Many of the most widely used Go projects are built using Cobra, such as:
+[Kubernetes](http://kubernetes.io/),
+[Hugo](http://gohugo.io),
+[rkt](https://github.com/coreos/rkt),
+[etcd](https://github.com/coreos/etcd),
+[Moby (former Docker)](https://github.com/moby/moby),
+[Docker (distribution)](https://github.com/docker/distribution),
+[OpenShift](https://www.openshift.com/),
+[Delve](https://github.com/derekparker/delve),
+[GopherJS](http://www.gopherjs.org/),
+[CockroachDB](http://www.cockroachlabs.com/),
+[Bleve](http://www.blevesearch.com/),
+[ProjectAtomic (enterprise)](http://www.projectatomic.io/),
+[Giant Swarm's gsctl](https://github.com/giantswarm/gsctl),
+[Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack),
+[rclone](http://rclone.org/),
+[nehm](https://github.com/bogem/nehm),
+[Pouch](https://github.com/alibaba/pouch),
+[Istio](https://istio.io),
+[Prototool](https://github.com/uber/prototool),
+[mattermost-server](https://github.com/mattermost/mattermost-server),
+[Gardener](https://github.com/gardener/gardenctl),
+[Linkerd](https://linkerd.io/),
+[Github CLI](https://github.com/cli/cli)
+etc.
 
 
 [![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra)
 [![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)
 [![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra)
+[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra)
 
 
 # Table of Contents
 # Table of Contents
 
 
@@ -45,6 +51,7 @@ Many of the most widely used Go projects are built using Cobra including:
   * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
   * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
   * [Generating documentation for your command](#generating-documentation-for-your-command)
   * [Generating documentation for your command](#generating-documentation-for-your-command)
   * [Generating bash completions](#generating-bash-completions)
   * [Generating bash completions](#generating-bash-completions)
+  * [Generating zsh completions](#generating-zsh-completions)
 - [Contributing](#contributing)
 - [Contributing](#contributing)
 - [License](#license)
 - [License](#license)
 
 
@@ -152,9 +159,6 @@ In a Cobra app, typically the main.go file is very bare. It serves one purpose:
 package main
 package main
 
 
 import (
 import (
-  "fmt"
-  "os"
-
   "{pathToYourApp}/cmd"
   "{pathToYourApp}/cmd"
 )
 )
 
 
@@ -206,51 +210,78 @@ You will additionally define flags and handle configuration in your init() funct
 For example cmd/root.go:
 For example cmd/root.go:
 
 
 ```go
 ```go
+package cmd
+
 import (
 import (
-  "fmt"
-  "os"
+	"fmt"
+	"os"
 
 
-  homedir "github.com/mitchellh/go-homedir"
-  "github.com/spf13/cobra"
-  "github.com/spf13/viper"
+	homedir "github.com/mitchellh/go-homedir"
+	"github.com/spf13/cobra"
+	"github.com/spf13/viper"
 )
 )
 
 
-func init() {
-  cobra.OnInitialize(initConfig)
-  rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
-  rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
-  rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
-  rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
-  rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
-  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
-  viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
-  viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
-  viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
-  viper.SetDefault("license", "apache")
+var (
+	// Used for flags.
+	cfgFile     string
+	userLicense string
+
+	rootCmd = &cobra.Command{
+		Use:   "cobra",
+		Short: "A generator for Cobra based Applications",
+		Long: `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.`,
+	}
+)
+
+// Execute executes the root command.
+func Execute() error {
+	return rootCmd.Execute()
 }
 }
 
 
-func initConfig() {
-  // Don't forget to read config either from cfgFile or from home directory!
-  if cfgFile != "" {
-    // Use config file from the flag.
-    viper.SetConfigFile(cfgFile)
-  } else {
-    // Find home directory.
-    home, err := homedir.Dir()
-    if err != nil {
-      fmt.Println(err)
-      os.Exit(1)
-    }
+func init() {
+	cobra.OnInitialize(initConfig)
+
+	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
+	rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
+	rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "name of license for the project")
+	rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration")
+	viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
+	viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
+	viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
+	viper.SetDefault("license", "apache")
+
+	rootCmd.AddCommand(addCmd)
+	rootCmd.AddCommand(initCmd)
+}
 
 
-    // Search config in home directory with name ".cobra" (without extension).
-    viper.AddConfigPath(home)
-    viper.SetConfigName(".cobra")
-  }
+func er(msg interface{}) {
+	fmt.Println("Error:", msg)
+	os.Exit(1)
+}
 
 
-  if err := viper.ReadInConfig(); err != nil {
-    fmt.Println("Can't read config:", err)
-    os.Exit(1)
-  }
+func initConfig() {
+	if cfgFile != "" {
+		// Use config file from the flag.
+		viper.SetConfigFile(cfgFile)
+	} else {
+		// Find home directory.
+		home, err := homedir.Dir()
+		if err != nil {
+			er(err)
+		}
+
+		// Search config in home directory with name ".cobra" (without extension).
+		viper.AddConfigPath(home)
+		viper.SetConfigName(".cobra")
+	}
+
+	viper.AutomaticEnv()
+
+	if err := viper.ReadInConfig(); err == nil {
+		fmt.Println("Using config file:", viper.ConfigFileUsed())
+	}
 }
 }
 ```
 ```
 
 
@@ -265,9 +296,6 @@ In a Cobra app, typically the main.go file is very bare. It serves, one purpose,
 package main
 package main
 
 
 import (
 import (
-  "fmt"
-  "os"
-
   "{pathToYourApp}/cmd"
   "{pathToYourApp}/cmd"
 )
 )
 
 
@@ -339,7 +367,7 @@ rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose out
 A flag can also be assigned locally which will only apply to that specific command.
 A flag can also be assigned locally which will only apply to that specific command.
 
 
 ```go
 ```go
-rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
+localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
 ```
 ```
 
 
 ### Local Flag on Parent Commands
 ### Local Flag on Parent Commands
@@ -395,6 +423,7 @@ The following validators are built in:
 - `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
 - `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
 - `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
 - `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
 - `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.
 - `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.
+- `ExactValidArgs(int)` - the command will report an error if there are not exactly N positional args OR if there are any positional args that are not in the `ValidArgs` field of `Command`
 - `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args.
 - `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args.
 
 
 An example of setting the custom validator:
 An example of setting the custom validator:
@@ -404,7 +433,7 @@ var cmd = &cobra.Command{
   Short: "hello",
   Short: "hello",
   Args: func(cmd *cobra.Command, args []string) error {
   Args: func(cmd *cobra.Command, args []string) error {
     if len(args) < 1 {
     if len(args) < 1 {
-      return errors.New("requires at least one arg")
+      return errors.New("requires a color argument")
     }
     }
     if myapp.IsValidColor(args[0]) {
     if myapp.IsValidColor(args[0]) {
       return nil
       return nil
@@ -459,12 +488,12 @@ For many years people have printed back to the screen.`,
 Echo works a lot like print, except it has a child command.`,
 Echo works a lot like print, except it has a child command.`,
     Args: cobra.MinimumNArgs(1),
     Args: cobra.MinimumNArgs(1),
     Run: func(cmd *cobra.Command, args []string) {
     Run: func(cmd *cobra.Command, args []string) {
-      fmt.Println("Print: " + strings.Join(args, " "))
+      fmt.Println("Echo: " + strings.Join(args, " "))
     },
     },
   }
   }
 
 
   var cmdTimes = &cobra.Command{
   var cmdTimes = &cobra.Command{
-    Use:   "times [# times] [string to echo]",
+    Use:   "times [string to echo]",
     Short: "Echo anything to the screen more times",
     Short: "Echo anything to the screen more times",
     Long: `echo things multiple times back to the user by providing
     Long: `echo things multiple times back to the user by providing
 a count and a string.`,
 a count and a string.`,
@@ -721,6 +750,11 @@ Cobra can generate documentation based on subcommands, flags, etc. in the follow
 
 
 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).
 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).
 
 
+## Generating zsh completions
+
+Cobra can generate zsh-completion file. Read more about it in
+[Zsh Completions](zsh_completions.md).
+
 # Contributing
 # Contributing
 
 
 1. Fork it
 1. Fork it

+ 21 - 1
vendor/github.com/spf13/cobra/args.go

@@ -2,6 +2,7 @@ package cobra
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"strings"
 )
 )
 
 
 type PositionalArgs func(cmd *Command, args []string) error
 type PositionalArgs func(cmd *Command, args []string) error
@@ -34,8 +35,15 @@ func NoArgs(cmd *Command, args []string) error {
 // 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 {
 func OnlyValidArgs(cmd *Command, args []string) error {
 	if len(cmd.ValidArgs) > 0 {
 	if len(cmd.ValidArgs) > 0 {
+		// Remove any description that may be included in ValidArgs.
+		// A description is following a tab character.
+		var validArgs []string
+		for _, v := range cmd.ValidArgs {
+			validArgs = append(validArgs, strings.Split(v, "\t")[0])
+		}
+
 		for _, v := range args {
 		for _, v := range args {
-			if !stringInSlice(v, cmd.ValidArgs) {
+			if !stringInSlice(v, validArgs) {
 				return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
 				return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
 			}
 			}
 		}
 		}
@@ -78,6 +86,18 @@ func ExactArgs(n int) PositionalArgs {
 	}
 	}
 }
 }
 
 
+// ExactValidArgs returns an error if
+// there are not exactly N positional args OR
+// there are any positional args that are not in the `ValidArgs` field of `Command`
+func ExactValidArgs(n int) PositionalArgs {
+	return func(cmd *Command, args []string) error {
+		if err := ExactArgs(n)(cmd, args); err != nil {
+			return err
+		}
+		return OnlyValidArgs(cmd, args)
+	}
+}
+
 // 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 {
 func RangeArgs(min int, max int) PositionalArgs {
 	return func(cmd *Command, args []string) error {
 	return func(cmd *Command, args []string) error {

+ 112 - 55
vendor/github.com/spf13/cobra/bash_completions.go

@@ -58,9 +58,71 @@ __%[1]s_contains_word()
     return 1
     return 1
 }
 }
 
 
+__%[1]s_handle_go_custom_completion()
+{
+    __%[1]s_debug "${FUNCNAME[0]}: cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}"
+
+    local out requestComp lastParam lastChar comp directive args
+
+    # Prepare the command to request completions for the program.
+    # Calling ${words[0]} instead of directly %[1]s allows to handle aliases
+    args=("${words[@]:1}")
+    requestComp="${words[0]} %[2]s ${args[*]}"
+
+    lastParam=${words[$((${#words[@]}-1))]}
+    lastChar=${lastParam:$((${#lastParam}-1)):1}
+    __%[1]s_debug "${FUNCNAME[0]}: lastParam ${lastParam}, lastChar ${lastChar}"
+
+    if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then
+        # If the last parameter is complete (there is a space following it)
+        # We add an extra empty parameter so we can indicate this to the go method.
+        __%[1]s_debug "${FUNCNAME[0]}: Adding extra empty parameter"
+        requestComp="${requestComp} \"\""
+    fi
+
+    __%[1]s_debug "${FUNCNAME[0]}: calling ${requestComp}"
+    # Use eval to handle any environment variables and such
+    out=$(eval "${requestComp}" 2>/dev/null)
+
+    # Extract the directive integer at the very end of the output following a colon (:)
+    directive=${out##*:}
+    # Remove the directive
+    out=${out%%:*}
+    if [ "${directive}" = "${out}" ]; then
+        # There is not directive specified
+        directive=0
+    fi
+    __%[1]s_debug "${FUNCNAME[0]}: the completion directive is: ${directive}"
+    __%[1]s_debug "${FUNCNAME[0]}: the completions are: ${out[*]}"
+
+    if [ $((directive & %[3]d)) -ne 0 ]; then
+        # Error code.  No completion.
+        __%[1]s_debug "${FUNCNAME[0]}: received error from custom completion go code"
+        return
+    else
+        if [ $((directive & %[4]d)) -ne 0 ]; then
+            if [[ $(type -t compopt) = "builtin" ]]; then
+                __%[1]s_debug "${FUNCNAME[0]}: activating no space"
+                compopt -o nospace
+            fi
+        fi
+        if [ $((directive & %[5]d)) -ne 0 ]; then
+            if [[ $(type -t compopt) = "builtin" ]]; then
+                __%[1]s_debug "${FUNCNAME[0]}: activating no file completion"
+                compopt +o default
+            fi
+        fi
+
+        while IFS='' read -r comp; do
+            COMPREPLY+=("$comp")
+        done < <(compgen -W "${out[*]}" -- "$cur")
+    fi
+}
+
 __%[1]s_handle_reply()
 __%[1]s_handle_reply()
 {
 {
     __%[1]s_debug "${FUNCNAME[0]}"
     __%[1]s_debug "${FUNCNAME[0]}"
+    local comp
     case $cur in
     case $cur in
         -*)
         -*)
             if [[ $(type -t compopt) = "builtin" ]]; then
             if [[ $(type -t compopt) = "builtin" ]]; then
@@ -72,7 +134,9 @@ __%[1]s_handle_reply()
             else
             else
                 allflags=("${flags[*]} ${two_word_flags[*]}")
                 allflags=("${flags[*]} ${two_word_flags[*]}")
             fi
             fi
-            COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
+            while IFS='' read -r comp; do
+                COMPREPLY+=("$comp")
+            done < <(compgen -W "${allflags[*]}" -- "$cur")
             if [[ $(type -t compopt) = "builtin" ]]; then
             if [[ $(type -t compopt) = "builtin" ]]; then
                 [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
                 [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
             fi
             fi
@@ -118,18 +182,32 @@ __%[1]s_handle_reply()
     completions=("${commands[@]}")
     completions=("${commands[@]}")
     if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
     if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
         completions=("${must_have_one_noun[@]}")
         completions=("${must_have_one_noun[@]}")
+    elif [[ -n "${has_completion_function}" ]]; then
+        # if a go completion function is provided, defer to that function
+        completions=()
+        __%[1]s_handle_go_custom_completion
     fi
     fi
     if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
     if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
         completions+=("${must_have_one_flag[@]}")
         completions+=("${must_have_one_flag[@]}")
     fi
     fi
-    COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
+    while IFS='' read -r comp; do
+        COMPREPLY+=("$comp")
+    done < <(compgen -W "${completions[*]}" -- "$cur")
 
 
     if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
     if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
-        COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
+        while IFS='' read -r comp; do
+            COMPREPLY+=("$comp")
+        done < <(compgen -W "${noun_aliases[*]}" -- "$cur")
     fi
     fi
 
 
     if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
     if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
-        declare -F __custom_func >/dev/null && __custom_func
+		if declare -F __%[1]s_custom_func >/dev/null; then
+			# try command name qualified custom func
+			__%[1]s_custom_func
+		else
+			# otherwise fall back to unqualified for compatibility
+			declare -F __custom_func >/dev/null && __custom_func
+		fi
     fi
     fi
 
 
     # available in bash-completion >= 2, not always present on macOS
     # available in bash-completion >= 2, not always present on macOS
@@ -154,7 +232,7 @@ __%[1]s_handle_filename_extension_flag()
 __%[1]s_handle_subdirs_in_dir_flag()
 __%[1]s_handle_subdirs_in_dir_flag()
 {
 {
     local dir="$1"
     local dir="$1"
-    pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
+    pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
 }
 }
 
 
 __%[1]s_handle_flag()
 __%[1]s_handle_flag()
@@ -193,7 +271,8 @@ __%[1]s_handle_flag()
     fi
     fi
 
 
     # skip the argument to a two word flag
     # skip the argument to a two word flag
-    if __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then
+    if [[ ${words[c]} != *"="* ]] && __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then
+			  __%[1]s_debug "${FUNCNAME[0]}: found a flag ${words[c]}, skip the next argument"
         c=$((c+1))
         c=$((c+1))
         # if we are looking for a flags value, don't show commands
         # if we are looking for a flags value, don't show commands
         if [[ $c -eq $cword ]]; then
         if [[ $c -eq $cword ]]; then
@@ -265,7 +344,7 @@ __%[1]s_handle_word()
     __%[1]s_handle_word
     __%[1]s_handle_word
 }
 }
 
 
-`, name))
+`, name, ShellCompNoDescRequestCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp))
 }
 }
 
 
 func writePostscript(buf *bytes.Buffer, name string) {
 func writePostscript(buf *bytes.Buffer, name string) {
@@ -290,6 +369,7 @@ func writePostscript(buf *bytes.Buffer, name string) {
     local commands=("%[1]s")
     local commands=("%[1]s")
     local must_have_one_flag=()
     local must_have_one_flag=()
     local must_have_one_noun=()
     local must_have_one_noun=()
+    local has_completion_function
     local last_command
     local last_command
     local nouns=()
     local nouns=()
 
 
@@ -373,6 +453,10 @@ func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
 	}
 	}
 	format += "\")\n"
 	format += "\")\n"
 	buf.WriteString(fmt.Sprintf(format, name))
 	buf.WriteString(fmt.Sprintf(format, name))
+	if len(flag.NoOptDefVal) == 0 {
+		format = "    two_word_flags+=(\"--%s\")\n"
+		buf.WriteString(fmt.Sprintf(format, name))
+	}
 	writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
 	writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
 }
 }
 
 
@@ -386,7 +470,22 @@ func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
 	buf.WriteString(fmt.Sprintf(format, name))
 	buf.WriteString(fmt.Sprintf(format, name))
 }
 }
 
 
+// Setup annotations for go completions for registered flags
+func prepareCustomAnnotationsForFlags(cmd *Command) {
+	for flag := range flagCompletionFunctions {
+		// Make sure the completion script calls the __*_go_custom_completion function for
+		// every registered flag.  We need to do this here (and not when the flag was registered
+		// for completion) so that we can know the root command name for the prefix
+		// of __<prefix>_go_custom_completion
+		if flag.Annotations == nil {
+			flag.Annotations = map[string][]string{}
+		}
+		flag.Annotations[BashCompCustom] = []string{fmt.Sprintf("__%[1]s_handle_go_custom_completion", cmd.Root().Name())}
+	}
+}
+
 func writeFlags(buf *bytes.Buffer, cmd *Command) {
 func writeFlags(buf *bytes.Buffer, cmd *Command) {
+	prepareCustomAnnotationsForFlags(cmd)
 	buf.WriteString(`    flags=()
 	buf.WriteString(`    flags=()
     two_word_flags=()
     two_word_flags=()
     local_nonpersistent_flags=()
     local_nonpersistent_flags=()
@@ -449,8 +548,14 @@ func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
 	buf.WriteString("    must_have_one_noun=()\n")
 	buf.WriteString("    must_have_one_noun=()\n")
 	sort.Sort(sort.StringSlice(cmd.ValidArgs))
 	sort.Sort(sort.StringSlice(cmd.ValidArgs))
 	for _, value := range cmd.ValidArgs {
 	for _, value := range cmd.ValidArgs {
+		// Remove any description that may be included following a tab character.
+		// Descriptions are not supported by bash completion.
+		value = strings.Split(value, "\t")[0]
 		buf.WriteString(fmt.Sprintf("    must_have_one_noun+=(%q)\n", value))
 		buf.WriteString(fmt.Sprintf("    must_have_one_noun+=(%q)\n", value))
 	}
 	}
+	if cmd.ValidArgsFunction != nil {
+		buf.WriteString("    has_completion_function=1\n")
+	}
 }
 }
 
 
 func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
 func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
@@ -534,51 +639,3 @@ func (c *Command) GenBashCompletionFile(filename string) error {
 
 
 	return c.GenBashCompletion(outFile)
 	return c.GenBashCompletion(outFile)
 }
 }
-
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
-// and causes your command to report an error if invoked without the flag.
-func (c *Command) MarkFlagRequired(name string) error {
-	return MarkFlagRequired(c.Flags(), name)
-}
-
-// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
-// and causes your command to report an error if invoked without the flag.
-func (c *Command) MarkPersistentFlagRequired(name string) error {
-	return MarkFlagRequired(c.PersistentFlags(), name)
-}
-
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
-// and causes your command to report an error if invoked without the flag.
-func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
-	return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
-}
-
-// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
-// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
-func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
-	return MarkFlagFilename(c.Flags(), name, extensions...)
-}
-
-// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
-// Generated bash autocompletion will call the bash function f for the flag.
-func (c *Command) MarkFlagCustom(name string, f string) error {
-	return MarkFlagCustom(c.Flags(), name, f)
-}
-
-// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
-// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
-func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
-	return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
-}
-
-// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
-// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
-func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
-	return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
-}
-
-// MarkFlagCustom adds the BashCompCustom annotation to the named flag in the flag set, if it exists.
-// Generated bash autocompletion will call the bash function f for the flag.
-func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
-	return flags.SetAnnotation(name, BashCompCustom, []string{f})
-}

+ 8 - 1
vendor/github.com/spf13/cobra/cobra.go

@@ -23,6 +23,7 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"text/template"
 	"text/template"
+	"time"
 	"unicode"
 	"unicode"
 )
 )
 
 
@@ -51,11 +52,17 @@ var EnableCommandSorting = true
 // if the CLI is started from explorer.exe.
 // if the CLI is started from explorer.exe.
 // To disable the mousetrap, just set this variable to blank string ("").
 // To disable the mousetrap, just set this variable to blank string ("").
 // Works only on Microsoft Windows.
 // Works only on Microsoft Windows.
-var MousetrapHelpText string = `This is a command line tool.
+var MousetrapHelpText = `This is a command line tool.
 
 
 You need to open cmd.exe and run it from there.
 You need to open cmd.exe and run it from there.
 `
 `
 
 
+// MousetrapDisplayDuration controls how long the MousetrapHelpText message is displayed on Windows
+// if the CLI is started from explorer.exe. Set to 0 to wait for the return key to be pressed.
+// To disable the mousetrap, just set MousetrapHelpText to blank string ("").
+// Works only on Microsoft Windows.
+var MousetrapDisplayDuration = 5 * time.Second
+
 // AddTemplateFunc adds a template function that's available to Usage and Help
 // AddTemplateFunc adds a template function that's available to Usage and Help
 // template generation.
 // template generation.
 func AddTemplateFunc(name string, tmplFunc interface{}) {
 func AddTemplateFunc(name string, tmplFunc interface{}) {

+ 134 - 17
vendor/github.com/spf13/cobra/command.go

@@ -17,6 +17,7 @@ package cobra
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"context"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"os"
 	"os"
@@ -56,6 +57,10 @@ type Command struct {
 
 
 	// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
 	// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
 	ValidArgs []string
 	ValidArgs []string
+	// ValidArgsFunction is an optional function that provides valid non-flag arguments for bash completion.
+	// It is a dynamic version of using ValidArgs.
+	// Only one of ValidArgs and ValidArgsFunction can be used for a command.
+	ValidArgsFunction func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)
 
 
 	// Expected arguments
 	// Expected arguments
 	Args PositionalArgs
 	Args PositionalArgs
@@ -80,7 +85,8 @@ type Command struct {
 
 
 	// Version defines the version for this command. If this value is non-empty and the command does not
 	// Version defines the version for this command. If this value is non-empty and the command does not
 	// define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
 	// define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
-	// will print content of the "Version" variable.
+	// will print content of the "Version" variable. A shorthand "v" flag will also be added if the
+	// command does not define one.
 	Version string
 	Version string
 
 
 	// The *Run functions are executed in the following order:
 	// The *Run functions are executed in the following order:
@@ -140,9 +146,11 @@ type Command struct {
 	// TraverseChildren parses flags on all parents before executing child command.
 	// TraverseChildren parses flags on all parents before executing child command.
 	TraverseChildren bool
 	TraverseChildren bool
 
 
-	//FParseErrWhitelist flag parse errors to be ignored
+	// FParseErrWhitelist flag parse errors to be ignored
 	FParseErrWhitelist FParseErrWhitelist
 	FParseErrWhitelist FParseErrWhitelist
 
 
+	ctx context.Context
+
 	// commands is the list of commands supported by this program.
 	// commands is the list of commands supported by this program.
 	commands []*Command
 	commands []*Command
 	// parent is a parent command for this command.
 	// parent is a parent command for this command.
@@ -177,8 +185,6 @@ type Command struct {
 	// that we can use on every pflag set and children commands
 	// that we can use on every pflag set and children commands
 	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
 	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
 
 
-	// output is an output writer defined by user.
-	output io.Writer
 	// usageFunc is usage func defined by user.
 	// usageFunc is usage func defined by user.
 	usageFunc func(*Command) error
 	usageFunc func(*Command) error
 	// usageTemplate is usage template defined by user.
 	// usageTemplate is usage template defined by user.
@@ -195,6 +201,19 @@ type Command struct {
 	helpCommand *Command
 	helpCommand *Command
 	// versionTemplate is the version template defined by user.
 	// versionTemplate is the version template defined by user.
 	versionTemplate string
 	versionTemplate string
+
+	// inReader is a reader defined by the user that replaces stdin
+	inReader io.Reader
+	// outWriter is a writer defined by the user that replaces stdout
+	outWriter io.Writer
+	// errWriter is a writer defined by the user that replaces stderr
+	errWriter io.Writer
+}
+
+// Context returns underlying command context. If command wasn't
+// executed with ExecuteContext Context returns Background context.
+func (c *Command) Context() context.Context {
+	return c.ctx
 }
 }
 
 
 // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
 // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
@@ -205,8 +224,28 @@ func (c *Command) SetArgs(a []string) {
 
 
 // SetOutput sets the destination for usage and error messages.
 // SetOutput sets the destination for usage and error messages.
 // If output is nil, os.Stderr is used.
 // If output is nil, os.Stderr is used.
+// Deprecated: Use SetOut and/or SetErr instead
 func (c *Command) SetOutput(output io.Writer) {
 func (c *Command) SetOutput(output io.Writer) {
-	c.output = output
+	c.outWriter = output
+	c.errWriter = output
+}
+
+// SetOut sets the destination for usage messages.
+// If newOut is nil, os.Stdout is used.
+func (c *Command) SetOut(newOut io.Writer) {
+	c.outWriter = newOut
+}
+
+// SetErr sets the destination for error messages.
+// If newErr is nil, os.Stderr is used.
+func (c *Command) SetErr(newErr io.Writer) {
+	c.errWriter = newErr
+}
+
+// SetIn sets the source for input data
+// If newIn is nil, os.Stdin is used.
+func (c *Command) SetIn(newIn io.Reader) {
+	c.inReader = newIn
 }
 }
 
 
 // SetUsageFunc sets usage function. Usage can be defined by application.
 // SetUsageFunc sets usage function. Usage can be defined by application.
@@ -267,9 +306,19 @@ func (c *Command) OutOrStderr() io.Writer {
 	return c.getOut(os.Stderr)
 	return c.getOut(os.Stderr)
 }
 }
 
 
+// ErrOrStderr returns output to stderr
+func (c *Command) ErrOrStderr() io.Writer {
+	return c.getErr(os.Stderr)
+}
+
+// InOrStdin returns input to stdin
+func (c *Command) InOrStdin() io.Reader {
+	return c.getIn(os.Stdin)
+}
+
 func (c *Command) getOut(def io.Writer) io.Writer {
 func (c *Command) getOut(def io.Writer) io.Writer {
-	if c.output != nil {
-		return c.output
+	if c.outWriter != nil {
+		return c.outWriter
 	}
 	}
 	if c.HasParent() {
 	if c.HasParent() {
 		return c.parent.getOut(def)
 		return c.parent.getOut(def)
@@ -277,6 +326,26 @@ func (c *Command) getOut(def io.Writer) io.Writer {
 	return def
 	return def
 }
 }
 
 
+func (c *Command) getErr(def io.Writer) io.Writer {
+	if c.errWriter != nil {
+		return c.errWriter
+	}
+	if c.HasParent() {
+		return c.parent.getErr(def)
+	}
+	return def
+}
+
+func (c *Command) getIn(def io.Reader) io.Reader {
+	if c.inReader != nil {
+		return c.inReader
+	}
+	if c.HasParent() {
+		return c.parent.getIn(def)
+	}
+	return def
+}
+
 // UsageFunc returns either the function set by SetUsageFunc for this command
 // UsageFunc returns either the function set by SetUsageFunc for this command
 // or a parent, or it returns a default usage function.
 // or a parent, or it returns a default usage function.
 func (c *Command) UsageFunc() (f func(*Command) error) {
 func (c *Command) UsageFunc() (f func(*Command) error) {
@@ -314,6 +383,8 @@ func (c *Command) HelpFunc() func(*Command, []string) {
 	}
 	}
 	return func(c *Command, a []string) {
 	return func(c *Command, a []string) {
 		c.mergePersistentFlags()
 		c.mergePersistentFlags()
+		// The help should be sent to stdout
+		// See https://github.com/spf13/cobra/issues/1002
 		err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
 		err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
 		if err != nil {
 		if err != nil {
 			c.Println(err)
 			c.Println(err)
@@ -329,13 +400,22 @@ func (c *Command) Help() error {
 	return nil
 	return nil
 }
 }
 
 
-// UsageString return usage string.
+// UsageString returns usage string.
 func (c *Command) UsageString() string {
 func (c *Command) UsageString() string {
-	tmpOutput := c.output
+	// Storing normal writers
+	tmpOutput := c.outWriter
+	tmpErr := c.errWriter
+
 	bb := new(bytes.Buffer)
 	bb := new(bytes.Buffer)
-	c.SetOutput(bb)
+	c.outWriter = bb
+	c.errWriter = bb
+
 	c.Usage()
 	c.Usage()
-	c.output = tmpOutput
+
+	// Setting things back to normal
+	c.outWriter = tmpOutput
+	c.errWriter = tmpErr
+
 	return bb.String()
 	return bb.String()
 }
 }
 
 
@@ -793,6 +873,13 @@ func (c *Command) preRun() {
 	}
 	}
 }
 }
 
 
+// ExecuteContext is the same as Execute(), but sets the ctx on the command.
+// Retrieve ctx by calling cmd.Context() inside your *Run lifecycle functions.
+func (c *Command) ExecuteContext(ctx context.Context) error {
+	c.ctx = ctx
+	return c.Execute()
+}
+
 // Execute uses the args (os.Args[1:] by default)
 // Execute uses the args (os.Args[1:] by default)
 // and run through the command tree finding appropriate matches
 // and run through the command tree finding appropriate matches
 // for commands and then corresponding flags.
 // for commands and then corresponding flags.
@@ -803,6 +890,10 @@ func (c *Command) Execute() error {
 
 
 // ExecuteC executes the command.
 // ExecuteC executes the command.
 func (c *Command) ExecuteC() (cmd *Command, err error) {
 func (c *Command) ExecuteC() (cmd *Command, err error) {
+	if c.ctx == nil {
+		c.ctx = context.Background()
+	}
+
 	// Regardless of what command execute is called on, run on Root only
 	// Regardless of what command execute is called on, run on Root only
 	if c.HasParent() {
 	if c.HasParent() {
 		return c.Root().ExecuteC()
 		return c.Root().ExecuteC()
@@ -817,15 +908,16 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
 	// overriding
 	// overriding
 	c.InitDefaultHelpCmd()
 	c.InitDefaultHelpCmd()
 
 
-	var args []string
+	args := c.args
 
 
 	// Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
 	// Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
 	if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
 	if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
 		args = os.Args[1:]
 		args = os.Args[1:]
-	} else {
-		args = c.args
 	}
 	}
 
 
+	// initialize the hidden command to be used for bash completion
+	c.initCompleteCmd(args)
+
 	var flags []string
 	var flags []string
 	if c.TraverseChildren {
 	if c.TraverseChildren {
 		cmd, flags, err = c.Traverse(args)
 		cmd, flags, err = c.Traverse(args)
@@ -849,6 +941,12 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
 		cmd.commandCalledAs.name = cmd.Name()
 		cmd.commandCalledAs.name = cmd.Name()
 	}
 	}
 
 
+	// We have to pass global context to children command
+	// if context is present on the parent command.
+	if cmd.ctx == nil {
+		cmd.ctx = c.ctx
+	}
+
 	err = cmd.execute(flags)
 	err = cmd.execute(flags)
 	if err != nil {
 	if err != nil {
 		// Always show help if requested, even if SilenceErrors is in
 		// Always show help if requested, even if SilenceErrors is in
@@ -932,7 +1030,11 @@ func (c *Command) InitDefaultVersionFlag() {
 		} else {
 		} else {
 			usage += c.Name()
 			usage += c.Name()
 		}
 		}
-		c.Flags().Bool("version", false, usage)
+		if c.Flags().ShorthandLookup("v") == nil {
+			c.Flags().BoolP("version", "v", false, usage)
+		} else {
+			c.Flags().Bool("version", false, usage)
+		}
 	}
 	}
 }
 }
 
 
@@ -1070,6 +1172,21 @@ func (c *Command) Printf(format string, i ...interface{}) {
 	c.Print(fmt.Sprintf(format, i...))
 	c.Print(fmt.Sprintf(format, i...))
 }
 }
 
 
+// PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set.
+func (c *Command) PrintErr(i ...interface{}) {
+	fmt.Fprint(c.ErrOrStderr(), i...)
+}
+
+// PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set.
+func (c *Command) PrintErrln(i ...interface{}) {
+	c.Print(fmt.Sprintln(i...))
+}
+
+// PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set.
+func (c *Command) PrintErrf(format string, i ...interface{}) {
+	c.Print(fmt.Sprintf(format, i...))
+}
+
 // CommandPath returns the full path to this command.
 // CommandPath returns the full path to this command.
 func (c *Command) CommandPath() string {
 func (c *Command) CommandPath() string {
 	if c.HasParent() {
 	if c.HasParent() {
@@ -1335,7 +1452,7 @@ func (c *Command) LocalFlags() *flag.FlagSet {
 	return c.lflags
 	return c.lflags
 }
 }
 
 
-// InheritedFlags returns all flags which were inherited from parents commands.
+// InheritedFlags returns all flags which were inherited from parent commands.
 func (c *Command) InheritedFlags() *flag.FlagSet {
 func (c *Command) InheritedFlags() *flag.FlagSet {
 	c.mergePersistentFlags()
 	c.mergePersistentFlags()
 
 
@@ -1470,7 +1587,7 @@ func (c *Command) ParseFlags(args []string) error {
 	beforeErrorBufLen := c.flagErrorBuf.Len()
 	beforeErrorBufLen := c.flagErrorBuf.Len()
 	c.mergePersistentFlags()
 	c.mergePersistentFlags()
 
 
-	//do it here after merging all flags and just before parse
+	// do it here after merging all flags and just before parse
 	c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
 	c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
 
 
 	err := c.Flags().Parse(args)
 	err := c.Flags().Parse(args)

+ 7 - 1
vendor/github.com/spf13/cobra/command_win.go

@@ -3,6 +3,7 @@
 package cobra
 package cobra
 
 
 import (
 import (
+	"fmt"
 	"os"
 	"os"
 	"time"
 	"time"
 
 
@@ -14,7 +15,12 @@ var preExecHookFn = preExecHook
 func preExecHook(c *Command) {
 func preExecHook(c *Command) {
 	if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
 	if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
 		c.Print(MousetrapHelpText)
 		c.Print(MousetrapHelpText)
-		time.Sleep(5 * time.Second)
+		if MousetrapDisplayDuration > 0 {
+			time.Sleep(MousetrapDisplayDuration)
+		} else {
+			c.Println("Press return to continue...")
+			fmt.Scanln()
+		}
 		os.Exit(1)
 		os.Exit(1)
 	}
 	}
 }
 }

+ 384 - 0
vendor/github.com/spf13/cobra/custom_completions.go

@@ -0,0 +1,384 @@
+package cobra
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"strings"
+
+	"github.com/spf13/pflag"
+)
+
+const (
+	// ShellCompRequestCmd is the name of the hidden command that is used to request
+	// completion results from the program.  It is used by the shell completion scripts.
+	ShellCompRequestCmd = "__complete"
+	// ShellCompNoDescRequestCmd is the name of the hidden command that is used to request
+	// completion results without their description.  It is used by the shell completion scripts.
+	ShellCompNoDescRequestCmd = "__completeNoDesc"
+)
+
+// Global map of flag completion functions.
+var flagCompletionFunctions = map[*pflag.Flag]func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective){}
+
+// ShellCompDirective is a bit map representing the different behaviors the shell
+// can be instructed to have once completions have been provided.
+type ShellCompDirective int
+
+const (
+	// ShellCompDirectiveError indicates an error occurred and completions should be ignored.
+	ShellCompDirectiveError ShellCompDirective = 1 << iota
+
+	// ShellCompDirectiveNoSpace indicates that the shell should not add a space
+	// after the completion even if there is a single completion provided.
+	ShellCompDirectiveNoSpace
+
+	// ShellCompDirectiveNoFileComp indicates that the shell should not provide
+	// file completion even when no completion is provided.
+	// This currently does not work for zsh or bash < 4
+	ShellCompDirectiveNoFileComp
+
+	// ShellCompDirectiveDefault indicates to let the shell perform its default
+	// behavior after completions have been provided.
+	ShellCompDirectiveDefault ShellCompDirective = 0
+)
+
+// RegisterFlagCompletionFunc should be called to register a function to provide completion for a flag.
+func (c *Command) RegisterFlagCompletionFunc(flagName string, f func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)) error {
+	flag := c.Flag(flagName)
+	if flag == nil {
+		return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' does not exist", flagName)
+	}
+	if _, exists := flagCompletionFunctions[flag]; exists {
+		return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' already registered", flagName)
+	}
+	flagCompletionFunctions[flag] = f
+	return nil
+}
+
+// Returns a string listing the different directive enabled in the specified parameter
+func (d ShellCompDirective) string() string {
+	var directives []string
+	if d&ShellCompDirectiveError != 0 {
+		directives = append(directives, "ShellCompDirectiveError")
+	}
+	if d&ShellCompDirectiveNoSpace != 0 {
+		directives = append(directives, "ShellCompDirectiveNoSpace")
+	}
+	if d&ShellCompDirectiveNoFileComp != 0 {
+		directives = append(directives, "ShellCompDirectiveNoFileComp")
+	}
+	if len(directives) == 0 {
+		directives = append(directives, "ShellCompDirectiveDefault")
+	}
+
+	if d > ShellCompDirectiveError+ShellCompDirectiveNoSpace+ShellCompDirectiveNoFileComp {
+		return fmt.Sprintf("ERROR: unexpected ShellCompDirective value: %d", d)
+	}
+	return strings.Join(directives, ", ")
+}
+
+// Adds a special hidden command that can be used to request custom completions.
+func (c *Command) initCompleteCmd(args []string) {
+	completeCmd := &Command{
+		Use:                   fmt.Sprintf("%s [command-line]", ShellCompRequestCmd),
+		Aliases:               []string{ShellCompNoDescRequestCmd},
+		DisableFlagsInUseLine: true,
+		Hidden:                true,
+		DisableFlagParsing:    true,
+		Args:                  MinimumNArgs(1),
+		Short:                 "Request shell completion choices for the specified command-line",
+		Long: fmt.Sprintf("%[2]s is a special command that is used by the shell completion logic\n%[1]s",
+			"to request completion choices for the specified command-line.", ShellCompRequestCmd),
+		Run: func(cmd *Command, args []string) {
+			finalCmd, completions, directive, err := cmd.getCompletions(args)
+			if err != nil {
+				CompErrorln(err.Error())
+				// Keep going for multiple reasons:
+				// 1- There could be some valid completions even though there was an error
+				// 2- Even without completions, we need to print the directive
+			}
+
+			noDescriptions := (cmd.CalledAs() == ShellCompNoDescRequestCmd)
+			for _, comp := range completions {
+				if noDescriptions {
+					// Remove any description that may be included following a tab character.
+					comp = strings.Split(comp, "\t")[0]
+				}
+				// Print each possible completion to stdout for the completion script to consume.
+				fmt.Fprintln(finalCmd.OutOrStdout(), comp)
+			}
+
+			if directive > ShellCompDirectiveError+ShellCompDirectiveNoSpace+ShellCompDirectiveNoFileComp {
+				directive = ShellCompDirectiveDefault
+			}
+
+			// As the last printout, print the completion directive for the completion script to parse.
+			// The directive integer must be that last character following a single colon (:).
+			// The completion script expects :<directive>
+			fmt.Fprintf(finalCmd.OutOrStdout(), ":%d\n", directive)
+
+			// Print some helpful info to stderr for the user to understand.
+			// Output from stderr must be ignored by the completion script.
+			fmt.Fprintf(finalCmd.ErrOrStderr(), "Completion ended with directive: %s\n", directive.string())
+		},
+	}
+	c.AddCommand(completeCmd)
+	subCmd, _, err := c.Find(args)
+	if err != nil || subCmd.Name() != ShellCompRequestCmd {
+		// Only create this special command if it is actually being called.
+		// This reduces possible side-effects of creating such a command;
+		// for example, having this command would cause problems to a
+		// cobra program that only consists of the root command, since this
+		// command would cause the root command to suddenly have a subcommand.
+		c.RemoveCommand(completeCmd)
+	}
+}
+
+func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDirective, error) {
+	var completions []string
+
+	// The last argument, which is not completely typed by the user,
+	// should not be part of the list of arguments
+	toComplete := args[len(args)-1]
+	trimmedArgs := args[:len(args)-1]
+
+	// Find the real command for which completion must be performed
+	finalCmd, finalArgs, err := c.Root().Find(trimmedArgs)
+	if err != nil {
+		// Unable to find the real command. E.g., <program> someInvalidCmd <TAB>
+		return c, completions, ShellCompDirectiveDefault, fmt.Errorf("Unable to find a command for arguments: %v", trimmedArgs)
+	}
+
+	// When doing completion of a flag name, as soon as an argument starts with
+	// a '-' we know it is a flag.  We cannot use isFlagArg() here as it requires
+	// the flag to be complete
+	if len(toComplete) > 0 && toComplete[0] == '-' && !strings.Contains(toComplete, "=") {
+		// We are completing a flag name
+		finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
+			completions = append(completions, getFlagNameCompletions(flag, toComplete)...)
+		})
+		finalCmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
+			completions = append(completions, getFlagNameCompletions(flag, toComplete)...)
+		})
+
+		directive := ShellCompDirectiveDefault
+		if len(completions) > 0 {
+			if strings.HasSuffix(completions[0], "=") {
+				directive = ShellCompDirectiveNoSpace
+			}
+		}
+		return finalCmd, completions, directive, nil
+	}
+
+	var flag *pflag.Flag
+	if !finalCmd.DisableFlagParsing {
+		// We only do flag completion if we are allowed to parse flags
+		// This is important for commands which have requested to do their own flag completion.
+		flag, finalArgs, toComplete, err = checkIfFlagCompletion(finalCmd, finalArgs, toComplete)
+		if err != nil {
+			// Error while attempting to parse flags
+			return finalCmd, completions, ShellCompDirectiveDefault, err
+		}
+	}
+
+	if flag == nil {
+		// Complete subcommand names
+		for _, subCmd := range finalCmd.Commands() {
+			if subCmd.IsAvailableCommand() && strings.HasPrefix(subCmd.Name(), toComplete) {
+				completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short))
+			}
+		}
+
+		if len(finalCmd.ValidArgs) > 0 {
+			// Always complete ValidArgs, even if we are completing a subcommand name.
+			// This is for commands that have both subcommands and ValidArgs.
+			for _, validArg := range finalCmd.ValidArgs {
+				if strings.HasPrefix(validArg, toComplete) {
+					completions = append(completions, validArg)
+				}
+			}
+
+			// If there are ValidArgs specified (even if they don't match), we stop completion.
+			// Only one of ValidArgs or ValidArgsFunction can be used for a single command.
+			return finalCmd, completions, ShellCompDirectiveNoFileComp, nil
+		}
+
+		// Always let the logic continue so as to add any ValidArgsFunction completions,
+		// even if we already found sub-commands.
+		// This is for commands that have subcommands but also specify a ValidArgsFunction.
+	}
+
+	// Parse the flags and extract the arguments to prepare for calling the completion function
+	if err = finalCmd.ParseFlags(finalArgs); err != nil {
+		return finalCmd, completions, ShellCompDirectiveDefault, fmt.Errorf("Error while parsing flags from args %v: %s", finalArgs, err.Error())
+	}
+
+	// We only remove the flags from the arguments if DisableFlagParsing is not set.
+	// This is important for commands which have requested to do their own flag completion.
+	if !finalCmd.DisableFlagParsing {
+		finalArgs = finalCmd.Flags().Args()
+	}
+
+	// Find the completion function for the flag or command
+	var completionFn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)
+	if flag != nil {
+		completionFn = flagCompletionFunctions[flag]
+	} else {
+		completionFn = finalCmd.ValidArgsFunction
+	}
+	if completionFn == nil {
+		// Go custom completion not supported/needed for this flag or command
+		return finalCmd, completions, ShellCompDirectiveDefault, nil
+	}
+
+	// Call the registered completion function to get the completions
+	comps, directive := completionFn(finalCmd, finalArgs, toComplete)
+	completions = append(completions, comps...)
+	return finalCmd, completions, directive, nil
+}
+
+func getFlagNameCompletions(flag *pflag.Flag, toComplete string) []string {
+	if nonCompletableFlag(flag) {
+		return []string{}
+	}
+
+	var completions []string
+	flagName := "--" + flag.Name
+	if strings.HasPrefix(flagName, toComplete) {
+		// Flag without the =
+		completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage))
+
+		if len(flag.NoOptDefVal) == 0 {
+			// Flag requires a value, so it can be suffixed with =
+			flagName += "="
+			completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage))
+		}
+	}
+
+	flagName = "-" + flag.Shorthand
+	if len(flag.Shorthand) > 0 && strings.HasPrefix(flagName, toComplete) {
+		completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage))
+	}
+
+	return completions
+}
+
+func checkIfFlagCompletion(finalCmd *Command, args []string, lastArg string) (*pflag.Flag, []string, string, error) {
+	var flagName string
+	trimmedArgs := args
+	flagWithEqual := false
+	if isFlagArg(lastArg) {
+		if index := strings.Index(lastArg, "="); index >= 0 {
+			flagName = strings.TrimLeft(lastArg[:index], "-")
+			lastArg = lastArg[index+1:]
+			flagWithEqual = true
+		} else {
+			return nil, nil, "", errors.New("Unexpected completion request for flag")
+		}
+	}
+
+	if len(flagName) == 0 {
+		if len(args) > 0 {
+			prevArg := args[len(args)-1]
+			if isFlagArg(prevArg) {
+				// Only consider the case where the flag does not contain an =.
+				// If the flag contains an = it means it has already been fully processed,
+				// so we don't need to deal with it here.
+				if index := strings.Index(prevArg, "="); index < 0 {
+					flagName = strings.TrimLeft(prevArg, "-")
+
+					// Remove the uncompleted flag or else there could be an error created
+					// for an invalid value for that flag
+					trimmedArgs = args[:len(args)-1]
+				}
+			}
+		}
+	}
+
+	if len(flagName) == 0 {
+		// Not doing flag completion
+		return nil, trimmedArgs, lastArg, nil
+	}
+
+	flag := findFlag(finalCmd, flagName)
+	if flag == nil {
+		// Flag not supported by this command, nothing to complete
+		err := fmt.Errorf("Subcommand '%s' does not support flag '%s'", finalCmd.Name(), flagName)
+		return nil, nil, "", err
+	}
+
+	if !flagWithEqual {
+		if len(flag.NoOptDefVal) != 0 {
+			// We had assumed dealing with a two-word flag but the flag is a boolean flag.
+			// In that case, there is no value following it, so we are not really doing flag completion.
+			// Reset everything to do noun completion.
+			trimmedArgs = args
+			flag = nil
+		}
+	}
+
+	return flag, trimmedArgs, lastArg, nil
+}
+
+func findFlag(cmd *Command, name string) *pflag.Flag {
+	flagSet := cmd.Flags()
+	if len(name) == 1 {
+		// First convert the short flag into a long flag
+		// as the cmd.Flag() search only accepts long flags
+		if short := flagSet.ShorthandLookup(name); short != nil {
+			name = short.Name
+		} else {
+			set := cmd.InheritedFlags()
+			if short = set.ShorthandLookup(name); short != nil {
+				name = short.Name
+			} else {
+				return nil
+			}
+		}
+	}
+	return cmd.Flag(name)
+}
+
+// CompDebug prints the specified string to the same file as where the
+// completion script prints its logs.
+// Note that completion printouts should never be on stdout as they would
+// be wrongly interpreted as actual completion choices by the completion script.
+func CompDebug(msg string, printToStdErr bool) {
+	msg = fmt.Sprintf("[Debug] %s", msg)
+
+	// Such logs are only printed when the user has set the environment
+	// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
+	if path := os.Getenv("BASH_COMP_DEBUG_FILE"); path != "" {
+		f, err := os.OpenFile(path,
+			os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+		if err == nil {
+			defer f.Close()
+			f.WriteString(msg)
+		}
+	}
+
+	if printToStdErr {
+		// Must print to stderr for this not to be read by the completion script.
+		fmt.Fprintf(os.Stderr, msg)
+	}
+}
+
+// CompDebugln prints the specified string with a newline at the end
+// to the same file as where the completion script prints its logs.
+// Such logs are only printed when the user has set the environment
+// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
+func CompDebugln(msg string, printToStdErr bool) {
+	CompDebug(fmt.Sprintf("%s\n", msg), printToStdErr)
+}
+
+// CompError prints the specified completion message to stderr.
+func CompError(msg string) {
+	msg = fmt.Sprintf("[Error] %s", msg)
+	CompDebug(msg, true)
+}
+
+// CompErrorln prints the specified completion message to stderr with a newline at the end.
+func CompErrorln(msg string) {
+	CompError(fmt.Sprintf("%s\n", msg))
+}

+ 172 - 0
vendor/github.com/spf13/cobra/fish_completions.go

@@ -0,0 +1,172 @@
+package cobra
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+)
+
+func genFishComp(buf *bytes.Buffer, name string, includeDesc bool) {
+	compCmd := ShellCompRequestCmd
+	if !includeDesc {
+		compCmd = ShellCompNoDescRequestCmd
+	}
+	buf.WriteString(fmt.Sprintf("# fish completion for %-36s -*- shell-script -*-\n", name))
+	buf.WriteString(fmt.Sprintf(`
+function __%[1]s_debug
+    set file "$BASH_COMP_DEBUG_FILE"
+    if test -n "$file"
+        echo "$argv" >> $file
+    end
+end
+
+function __%[1]s_perform_completion
+    __%[1]s_debug "Starting __%[1]s_perform_completion with: $argv"
+
+    set args (string split -- " " "$argv")
+    set lastArg "$args[-1]"
+
+    __%[1]s_debug "args: $args"
+    __%[1]s_debug "last arg: $lastArg"
+
+    set emptyArg ""
+    if test -z "$lastArg"
+        __%[1]s_debug "Setting emptyArg"
+        set emptyArg \"\"
+    end
+    __%[1]s_debug "emptyArg: $emptyArg"
+
+    set requestComp "$args[1] %[2]s $args[2..-1] $emptyArg"
+    __%[1]s_debug "Calling $requestComp"
+
+    set results (eval $requestComp 2> /dev/null)
+    set comps $results[1..-2]
+    set directiveLine $results[-1]
+
+    # For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)
+    # completions must be prefixed with the flag
+    set flagPrefix (string match -r -- '-.*=' "$lastArg")
+
+    __%[1]s_debug "Comps: $comps"
+    __%[1]s_debug "DirectiveLine: $directiveLine"
+    __%[1]s_debug "flagPrefix: $flagPrefix"
+
+    for comp in $comps
+        printf "%%s%%s\n" "$flagPrefix" "$comp"
+    end
+
+    printf "%%s\n" "$directiveLine"
+end
+
+# This function does three things:
+# 1- Obtain the completions and store them in the global __%[1]s_comp_results
+# 2- Set the __%[1]s_comp_do_file_comp flag if file completion should be performed
+#    and unset it otherwise
+# 3- Return true if the completion results are not empty
+function __%[1]s_prepare_completions
+    # Start fresh
+    set --erase __%[1]s_comp_do_file_comp
+    set --erase __%[1]s_comp_results
+
+    # Check if the command-line is already provided.  This is useful for testing.
+    if not set --query __%[1]s_comp_commandLine
+        set __%[1]s_comp_commandLine (commandline)
+    end
+    __%[1]s_debug "commandLine is: $__%[1]s_comp_commandLine"
+
+    set results (__%[1]s_perform_completion "$__%[1]s_comp_commandLine")
+    set --erase __%[1]s_comp_commandLine
+    __%[1]s_debug "Completion results: $results"
+
+    if test -z "$results"
+        __%[1]s_debug "No completion, probably due to a failure"
+        # Might as well do file completion, in case it helps
+        set --global __%[1]s_comp_do_file_comp 1
+        return 0
+    end
+
+    set directive (string sub --start 2 $results[-1])
+    set --global __%[1]s_comp_results $results[1..-2]
+
+    __%[1]s_debug "Completions are: $__%[1]s_comp_results"
+    __%[1]s_debug "Directive is: $directive"
+
+    if test -z "$directive"
+        set directive 0
+    end
+
+    set compErr (math (math --scale 0 $directive / %[3]d) %% 2)
+    if test $compErr -eq 1
+        __%[1]s_debug "Received error directive: aborting."
+        # Might as well do file completion, in case it helps
+        set --global __%[1]s_comp_do_file_comp 1
+        return 0
+    end
+
+    set nospace (math (math --scale 0 $directive / %[4]d) %% 2)
+    set nofiles (math (math --scale 0 $directive / %[5]d) %% 2)
+
+    __%[1]s_debug "nospace: $nospace, nofiles: $nofiles"
+
+    # Important not to quote the variable for count to work
+    set numComps (count $__%[1]s_comp_results)
+    __%[1]s_debug "numComps: $numComps"
+
+    if test $numComps -eq 1; and test $nospace -ne 0
+        # To support the "nospace" directive we trick the shell
+        # by outputting an extra, longer completion.
+        __%[1]s_debug "Adding second completion to perform nospace directive"
+        set --append __%[1]s_comp_results $__%[1]s_comp_results[1].
+    end
+
+    if test $numComps -eq 0; and test $nofiles -eq 0
+        __%[1]s_debug "Requesting file completion"
+        set --global __%[1]s_comp_do_file_comp 1
+    end
+
+    # If we don't want file completion, we must return true even if there
+    # are no completions found.  This is because fish will perform the last
+    # completion command, even if its condition is false, if no other
+    # completion command was triggered
+    return (not set --query __%[1]s_comp_do_file_comp)
+end
+
+# Remove any pre-existing completions for the program since we will be handling all of them
+# TODO this cleanup is not sufficient.  Fish completions are only loaded once the user triggers
+# them, so the below deletion will not work as it is run too early.  What else can we do?
+complete -c %[1]s -e
+
+# The order in which the below two lines are defined is very important so that __%[1]s_prepare_completions
+# is called first.  It is __%[1]s_prepare_completions that sets up the __%[1]s_comp_do_file_comp variable.
+#
+# This completion will be run second as complete commands are added FILO.
+# It triggers file completion choices when __%[1]s_comp_do_file_comp is set.
+complete -c %[1]s -n 'set --query __%[1]s_comp_do_file_comp'
+
+# This completion will be run first as complete commands are added FILO.
+# The call to __%[1]s_prepare_completions will setup both __%[1]s_comp_results abd __%[1]s_comp_do_file_comp.
+# It provides the program's completion choices.
+complete -c %[1]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
+
+`, name, compCmd, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp))
+}
+
+// GenFishCompletion generates fish completion file and writes to the passed writer.
+func (c *Command) GenFishCompletion(w io.Writer, includeDesc bool) error {
+	buf := new(bytes.Buffer)
+	genFishComp(buf, c.Name(), includeDesc)
+	_, err := buf.WriteTo(w)
+	return err
+}
+
+// GenFishCompletionFile generates fish completion file.
+func (c *Command) GenFishCompletionFile(filename string, includeDesc bool) error {
+	outFile, err := os.Create(filename)
+	if err != nil {
+		return err
+	}
+	defer outFile.Close()
+
+	return c.GenFishCompletion(outFile, includeDesc)
+}

+ 12 - 0
vendor/github.com/spf13/cobra/go.mod

@@ -0,0 +1,12 @@
+module github.com/spf13/cobra
+
+go 1.12
+
+require (
+	github.com/cpuguy83/go-md2man/v2 v2.0.0
+	github.com/inconshreveable/mousetrap v1.0.0
+	github.com/mitchellh/go-homedir v1.1.0
+	github.com/spf13/pflag v1.0.3
+	github.com/spf13/viper v1.4.0
+	gopkg.in/yaml.v2 v2.2.2
+)

+ 100 - 0
vendor/github.com/spf13/cobra/powershell_completions.go

@@ -0,0 +1,100 @@
+// PowerShell completions are based on the amazing work from clap:
+// https://github.com/clap-rs/clap/blob/3294d18efe5f264d12c9035f404c7d189d4824e1/src/completions/powershell.rs
+//
+// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but
+// can be downloaded separately for windows 7 or 8.1).
+
+package cobra
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"strings"
+
+	"github.com/spf13/pflag"
+)
+
+var powerShellCompletionTemplate = `using namespace System.Management.Automation
+using namespace System.Management.Automation.Language
+Register-ArgumentCompleter -Native -CommandName '%s' -ScriptBlock {
+    param($wordToComplete, $commandAst, $cursorPosition)
+    $commandElements = $commandAst.CommandElements
+    $command = @(
+        '%s'
+        for ($i = 1; $i -lt $commandElements.Count; $i++) {
+            $element = $commandElements[$i]
+            if ($element -isnot [StringConstantExpressionAst] -or
+                $element.StringConstantType -ne [StringConstantType]::BareWord -or
+                $element.Value.StartsWith('-')) {
+                break
+            }
+            $element.Value
+        }
+    ) -join ';'
+    $completions = @(switch ($command) {%s
+    })
+    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
+        Sort-Object -Property ListItemText
+}`
+
+func generatePowerShellSubcommandCases(out io.Writer, cmd *Command, previousCommandName string) {
+	var cmdName string
+	if previousCommandName == "" {
+		cmdName = cmd.Name()
+	} else {
+		cmdName = fmt.Sprintf("%s;%s", previousCommandName, cmd.Name())
+	}
+
+	fmt.Fprintf(out, "\n        '%s' {", cmdName)
+
+	cmd.Flags().VisitAll(func(flag *pflag.Flag) {
+		if nonCompletableFlag(flag) {
+			return
+		}
+		usage := escapeStringForPowerShell(flag.Usage)
+		if len(flag.Shorthand) > 0 {
+			fmt.Fprintf(out, "\n            [CompletionResult]::new('-%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Shorthand, flag.Shorthand, usage)
+		}
+		fmt.Fprintf(out, "\n            [CompletionResult]::new('--%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Name, flag.Name, usage)
+	})
+
+	for _, subCmd := range cmd.Commands() {
+		usage := escapeStringForPowerShell(subCmd.Short)
+		fmt.Fprintf(out, "\n            [CompletionResult]::new('%s', '%s', [CompletionResultType]::ParameterValue, '%s')", subCmd.Name(), subCmd.Name(), usage)
+	}
+
+	fmt.Fprint(out, "\n            break\n        }")
+
+	for _, subCmd := range cmd.Commands() {
+		generatePowerShellSubcommandCases(out, subCmd, cmdName)
+	}
+}
+
+func escapeStringForPowerShell(s string) string {
+	return strings.Replace(s, "'", "''", -1)
+}
+
+// GenPowerShellCompletion generates PowerShell completion file and writes to the passed writer.
+func (c *Command) GenPowerShellCompletion(w io.Writer) error {
+	buf := new(bytes.Buffer)
+
+	var subCommandCases bytes.Buffer
+	generatePowerShellSubcommandCases(&subCommandCases, c, "")
+	fmt.Fprintf(buf, powerShellCompletionTemplate, c.Name(), c.Name(), subCommandCases.String())
+
+	_, err := buf.WriteTo(w)
+	return err
+}
+
+// GenPowerShellCompletionFile generates PowerShell completion file.
+func (c *Command) GenPowerShellCompletionFile(filename string) error {
+	outFile, err := os.Create(filename)
+	if err != nil {
+		return err
+	}
+	defer outFile.Close()
+
+	return c.GenPowerShellCompletion(outFile)
+}

+ 85 - 0
vendor/github.com/spf13/cobra/shell_completions.go

@@ -0,0 +1,85 @@
+package cobra
+
+import (
+	"github.com/spf13/pflag"
+)
+
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
+// and causes your command to report an error if invoked without the flag.
+func (c *Command) MarkFlagRequired(name string) error {
+	return MarkFlagRequired(c.Flags(), name)
+}
+
+// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
+// and causes your command to report an error if invoked without the flag.
+func (c *Command) MarkPersistentFlagRequired(name string) error {
+	return MarkFlagRequired(c.PersistentFlags(), name)
+}
+
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
+// and causes your command to report an error if invoked without the flag.
+func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
+	return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
+}
+
+// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
+// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
+func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
+	return MarkFlagFilename(c.Flags(), name, extensions...)
+}
+
+// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
+// Generated bash autocompletion will call the bash function f for the flag.
+func (c *Command) MarkFlagCustom(name string, f string) error {
+	return MarkFlagCustom(c.Flags(), name, f)
+}
+
+// MarkPersistentFlagFilename instructs the various shell completion
+// implementations to limit completions for this persistent flag to the
+// specified extensions (patterns).
+//
+// Shell Completion compatibility matrix: bash, zsh
+func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
+	return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
+}
+
+// MarkFlagFilename instructs the various shell completion implementations to
+// limit completions for this flag to the specified extensions (patterns).
+//
+// Shell Completion compatibility matrix: bash, zsh
+func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
+	return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
+}
+
+// MarkFlagCustom instructs the various shell completion implementations to
+// limit completions for this flag to the specified extensions (patterns).
+//
+// Shell Completion compatibility matrix: bash, zsh
+func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
+	return flags.SetAnnotation(name, BashCompCustom, []string{f})
+}
+
+// MarkFlagDirname instructs the various shell completion implementations to
+// complete only directories with this named flag.
+//
+// Shell Completion compatibility matrix: zsh
+func (c *Command) MarkFlagDirname(name string) error {
+	return MarkFlagDirname(c.Flags(), name)
+}
+
+// MarkPersistentFlagDirname instructs the various shell completion
+// implementations to complete only directories with this persistent named flag.
+//
+// Shell Completion compatibility matrix: zsh
+func (c *Command) MarkPersistentFlagDirname(name string) error {
+	return MarkFlagDirname(c.PersistentFlags(), name)
+}
+
+// MarkFlagDirname instructs the various shell completion implementations to
+// complete only directories with this specified flag.
+//
+// Shell Completion compatibility matrix: zsh
+func MarkFlagDirname(flags *pflag.FlagSet, name string) error {
+	zshPattern := "-(/)"
+	return flags.SetAnnotation(name, zshCompDirname, []string{zshPattern})
+}

+ 284 - 74
vendor/github.com/spf13/cobra/zsh_completions.go

@@ -1,13 +1,102 @@
 package cobra
 package cobra
 
 
 import (
 import (
-	"bytes"
+	"encoding/json"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"os"
 	"os"
+	"sort"
 	"strings"
 	"strings"
+	"text/template"
+
+	"github.com/spf13/pflag"
+)
+
+const (
+	zshCompArgumentAnnotation   = "cobra_annotations_zsh_completion_argument_annotation"
+	zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion"
+	zshCompArgumentWordComp     = "cobra_annotations_zsh_completion_argument_word_completion"
+	zshCompDirname              = "cobra_annotations_zsh_dirname"
+)
+
+var (
+	zshCompFuncMap = template.FuncMap{
+		"genZshFuncName":              zshCompGenFuncName,
+		"extractFlags":                zshCompExtractFlag,
+		"genFlagEntryForZshArguments": zshCompGenFlagEntryForArguments,
+		"extractArgsCompletions":      zshCompExtractArgumentCompletionHintsForRendering,
+	}
+	zshCompletionText = `
+{{/* should accept Command (that contains subcommands) as parameter */}}
+{{define "argumentsC" -}}
+{{ $cmdPath := genZshFuncName .}}
+function {{$cmdPath}} {
+  local -a commands
+
+  _arguments -C \{{- range extractFlags .}}
+    {{genFlagEntryForZshArguments .}} \{{- end}}
+    "1: :->cmnds" \
+    "*::arg:->args"
+
+  case $state in
+  cmnds)
+    commands=({{range .Commands}}{{if not .Hidden}}
+      "{{.Name}}:{{.Short}}"{{end}}{{end}}
+    )
+    _describe "command" commands
+    ;;
+  esac
+
+  case "$words[1]" in {{- range .Commands}}{{if not .Hidden}}
+  {{.Name}})
+    {{$cmdPath}}_{{.Name}}
+    ;;{{end}}{{end}}
+  esac
+}
+{{range .Commands}}{{if not .Hidden}}
+{{template "selectCmdTemplate" .}}
+{{- end}}{{end}}
+{{- end}}
+
+{{/* should accept Command without subcommands as parameter */}}
+{{define "arguments" -}}
+function {{genZshFuncName .}} {
+{{"  _arguments"}}{{range extractFlags .}} \
+    {{genFlagEntryForZshArguments . -}}
+{{end}}{{range extractArgsCompletions .}} \
+    {{.}}{{end}}
+}
+{{end}}
+
+{{/* dispatcher for commands with or without subcommands */}}
+{{define "selectCmdTemplate" -}}
+{{if .Hidden}}{{/* ignore hidden*/}}{{else -}}
+{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}}
+{{- end}}
+{{- end}}
+
+{{/* template entry point */}}
+{{define "Main" -}}
+#compdef _{{.Name}} {{.Name}}
+
+{{template "selectCmdTemplate" .}}
+{{end}}
+`
 )
 )
 
 
+// zshCompArgsAnnotation is used to encode/decode zsh completion for
+// arguments to/from Command.Annotations.
+type zshCompArgsAnnotation map[int]zshCompArgHint
+
+type zshCompArgHint struct {
+	// Indicates the type of the completion to use. One of:
+	// zshCompArgumentFilenameComp or zshCompArgumentWordComp
+	Tipe string `json:"type"`
+
+	// A value for the type above (globs for file completion or words)
+	Options []string `json:"options"`
+}
+
 // GenZshCompletionFile generates zsh completion file.
 // GenZshCompletionFile generates zsh completion file.
 func (c *Command) GenZshCompletionFile(filename string) error {
 func (c *Command) GenZshCompletionFile(filename string) error {
 	outFile, err := os.Create(filename)
 	outFile, err := os.Create(filename)
@@ -19,108 +108,229 @@ func (c *Command) GenZshCompletionFile(filename string) error {
 	return c.GenZshCompletion(outFile)
 	return c.GenZshCompletion(outFile)
 }
 }
 
 
-// GenZshCompletion generates a zsh completion file and writes to the passed writer.
+// GenZshCompletion generates a zsh completion file and writes to the passed
+// writer. The completion always run on the root command regardless of the
+// command it was called from.
 func (c *Command) GenZshCompletion(w io.Writer) error {
 func (c *Command) GenZshCompletion(w io.Writer) error {
-	buf := new(bytes.Buffer)
-
-	writeHeader(buf, c)
-	maxDepth := maxDepth(c)
-	writeLevelMapping(buf, maxDepth)
-	writeLevelCases(buf, maxDepth, c)
+	tmpl, err := template.New("Main").Funcs(zshCompFuncMap).Parse(zshCompletionText)
+	if err != nil {
+		return fmt.Errorf("error creating zsh completion template: %v", err)
+	}
+	return tmpl.Execute(w, c.Root())
+}
 
 
-	_, err := buf.WriteTo(w)
-	return err
+// MarkZshCompPositionalArgumentFile marks the specified argument (first
+// argument is 1) as completed by file selection. patterns (e.g. "*.txt") are
+// optional - if not provided the completion will search for all files.
+func (c *Command) MarkZshCompPositionalArgumentFile(argPosition int, patterns ...string) error {
+	if argPosition < 1 {
+		return fmt.Errorf("Invalid argument position (%d)", argPosition)
+	}
+	annotation, err := c.zshCompGetArgsAnnotations()
+	if err != nil {
+		return err
+	}
+	if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) {
+		return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition)
+	}
+	annotation[argPosition] = zshCompArgHint{
+		Tipe:    zshCompArgumentFilenameComp,
+		Options: patterns,
+	}
+	return c.zshCompSetArgsAnnotations(annotation)
 }
 }
 
 
-func writeHeader(w io.Writer, cmd *Command) {
-	fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name())
+// MarkZshCompPositionalArgumentWords marks the specified positional argument
+// (first argument is 1) as completed by the provided words. At east one word
+// must be provided, spaces within words will be offered completion with
+// "word\ word".
+func (c *Command) MarkZshCompPositionalArgumentWords(argPosition int, words ...string) error {
+	if argPosition < 1 {
+		return fmt.Errorf("Invalid argument position (%d)", argPosition)
+	}
+	if len(words) == 0 {
+		return fmt.Errorf("Trying to set empty word list for positional argument %d", argPosition)
+	}
+	annotation, err := c.zshCompGetArgsAnnotations()
+	if err != nil {
+		return err
+	}
+	if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) {
+		return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition)
+	}
+	annotation[argPosition] = zshCompArgHint{
+		Tipe:    zshCompArgumentWordComp,
+		Options: words,
+	}
+	return c.zshCompSetArgsAnnotations(annotation)
 }
 }
 
 
-func maxDepth(c *Command) int {
-	if len(c.Commands()) == 0 {
-		return 0
+func zshCompExtractArgumentCompletionHintsForRendering(c *Command) ([]string, error) {
+	var result []string
+	annotation, err := c.zshCompGetArgsAnnotations()
+	if err != nil {
+		return nil, err
 	}
 	}
-	maxDepthSub := 0
-	for _, s := range c.Commands() {
-		subDepth := maxDepth(s)
-		if subDepth > maxDepthSub {
-			maxDepthSub = subDepth
+	for k, v := range annotation {
+		s, err := zshCompRenderZshCompArgHint(k, v)
+		if err != nil {
+			return nil, err
 		}
 		}
+		result = append(result, s)
 	}
 	}
-	return 1 + maxDepthSub
+	if len(c.ValidArgs) > 0 {
+		if _, positionOneExists := annotation[1]; !positionOneExists {
+			s, err := zshCompRenderZshCompArgHint(1, zshCompArgHint{
+				Tipe:    zshCompArgumentWordComp,
+				Options: c.ValidArgs,
+			})
+			if err != nil {
+				return nil, err
+			}
+			result = append(result, s)
+		}
+	}
+	sort.Strings(result)
+	return result, nil
 }
 }
 
 
-func writeLevelMapping(w io.Writer, numLevels int) {
-	fmt.Fprintln(w, `_arguments \`)
-	for i := 1; i <= numLevels; i++ {
-		fmt.Fprintf(w, `  '%d: :->level%d' \`, i, i)
-		fmt.Fprintln(w)
+func zshCompRenderZshCompArgHint(i int, z zshCompArgHint) (string, error) {
+	switch t := z.Tipe; t {
+	case zshCompArgumentFilenameComp:
+		var globs []string
+		for _, g := range z.Options {
+			globs = append(globs, fmt.Sprintf(`-g "%s"`, g))
+		}
+		return fmt.Sprintf(`'%d: :_files %s'`, i, strings.Join(globs, " ")), nil
+	case zshCompArgumentWordComp:
+		var words []string
+		for _, w := range z.Options {
+			words = append(words, fmt.Sprintf("%q", w))
+		}
+		return fmt.Sprintf(`'%d: :(%s)'`, i, strings.Join(words, " ")), nil
+	default:
+		return "", fmt.Errorf("Invalid zsh argument completion annotation: %s", t)
 	}
 	}
-	fmt.Fprintf(w, `  '%d: :%s'`, numLevels+1, "_files")
-	fmt.Fprintln(w)
 }
 }
 
 
-func writeLevelCases(w io.Writer, maxDepth int, root *Command) {
-	fmt.Fprintln(w, "case $state in")
-	defer fmt.Fprintln(w, "esac")
+func (c *Command) zshcompArgsAnnotationnIsDuplicatePosition(annotation zshCompArgsAnnotation, position int) bool {
+	_, dup := annotation[position]
+	return dup
+}
 
 
-	for i := 1; i <= maxDepth; i++ {
-		fmt.Fprintf(w, "  level%d)\n", i)
-		writeLevel(w, root, i)
-		fmt.Fprintln(w, "  ;;")
+func (c *Command) zshCompGetArgsAnnotations() (zshCompArgsAnnotation, error) {
+	annotation := make(zshCompArgsAnnotation)
+	annotationString, ok := c.Annotations[zshCompArgumentAnnotation]
+	if !ok {
+		return annotation, nil
+	}
+	err := json.Unmarshal([]byte(annotationString), &annotation)
+	if err != nil {
+		return annotation, fmt.Errorf("Error unmarshaling zsh argument annotation: %v", err)
 	}
 	}
-	fmt.Fprintln(w, "  *)")
-	fmt.Fprintln(w, "    _arguments '*: :_files'")
-	fmt.Fprintln(w, "  ;;")
+	return annotation, nil
 }
 }
 
 
-func writeLevel(w io.Writer, root *Command, i int) {
-	fmt.Fprintf(w, "    case $words[%d] in\n", i)
-	defer fmt.Fprintln(w, "    esac")
-
-	commands := filterByLevel(root, i)
-	byParent := groupByParent(commands)
+func (c *Command) zshCompSetArgsAnnotations(annotation zshCompArgsAnnotation) error {
+	jsn, err := json.Marshal(annotation)
+	if err != nil {
+		return fmt.Errorf("Error marshaling zsh argument annotation: %v", err)
+	}
+	if c.Annotations == nil {
+		c.Annotations = make(map[string]string)
+	}
+	c.Annotations[zshCompArgumentAnnotation] = string(jsn)
+	return nil
+}
 
 
-	for p, c := range byParent {
-		names := names(c)
-		fmt.Fprintf(w, "      %s)\n", p)
-		fmt.Fprintf(w, "        _arguments '%d: :(%s)'\n", i, strings.Join(names, " "))
-		fmt.Fprintln(w, "      ;;")
+func zshCompGenFuncName(c *Command) string {
+	if c.HasParent() {
+		return zshCompGenFuncName(c.Parent()) + "_" + c.Name()
 	}
 	}
-	fmt.Fprintln(w, "      *)")
-	fmt.Fprintln(w, "        _arguments '*: :_files'")
-	fmt.Fprintln(w, "      ;;")
+	return "_" + c.Name()
+}
 
 
+func zshCompExtractFlag(c *Command) []*pflag.Flag {
+	var flags []*pflag.Flag
+	c.LocalFlags().VisitAll(func(f *pflag.Flag) {
+		if !f.Hidden {
+			flags = append(flags, f)
+		}
+	})
+	c.InheritedFlags().VisitAll(func(f *pflag.Flag) {
+		if !f.Hidden {
+			flags = append(flags, f)
+		}
+	})
+	return flags
 }
 }
 
 
-func filterByLevel(c *Command, l int) []*Command {
-	cs := make([]*Command, 0)
-	if l == 0 {
-		cs = append(cs, c)
-		return cs
+// zshCompGenFlagEntryForArguments returns an entry that matches _arguments
+// zsh-completion parameters. It's too complicated to generate in a template.
+func zshCompGenFlagEntryForArguments(f *pflag.Flag) string {
+	if f.Name == "" || f.Shorthand == "" {
+		return zshCompGenFlagEntryForSingleOptionFlag(f)
 	}
 	}
-	for _, s := range c.Commands() {
-		cs = append(cs, filterByLevel(s, l-1)...)
+	return zshCompGenFlagEntryForMultiOptionFlag(f)
+}
+
+func zshCompGenFlagEntryForSingleOptionFlag(f *pflag.Flag) string {
+	var option, multiMark, extras string
+
+	if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) {
+		multiMark = "*"
 	}
 	}
-	return cs
+
+	option = "--" + f.Name
+	if option == "--" {
+		option = "-" + f.Shorthand
+	}
+	extras = zshCompGenFlagEntryExtras(f)
+
+	return fmt.Sprintf(`'%s%s[%s]%s'`, multiMark, option, zshCompQuoteFlagDescription(f.Usage), extras)
 }
 }
 
 
-func groupByParent(commands []*Command) map[string][]*Command {
-	m := make(map[string][]*Command)
-	for _, c := range commands {
-		parent := c.Parent()
-		if parent == nil {
-			continue
-		}
-		m[parent.Name()] = append(m[parent.Name()], c)
+func zshCompGenFlagEntryForMultiOptionFlag(f *pflag.Flag) string {
+	var options, parenMultiMark, curlyMultiMark, extras string
+
+	if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) {
+		parenMultiMark = "*"
+		curlyMultiMark = "\\*"
 	}
 	}
-	return m
+
+	options = fmt.Sprintf(`'(%s-%s %s--%s)'{%s-%s,%s--%s}`,
+		parenMultiMark, f.Shorthand, parenMultiMark, f.Name, curlyMultiMark, f.Shorthand, curlyMultiMark, f.Name)
+	extras = zshCompGenFlagEntryExtras(f)
+
+	return fmt.Sprintf(`%s'[%s]%s'`, options, zshCompQuoteFlagDescription(f.Usage), extras)
 }
 }
 
 
-func names(commands []*Command) []string {
-	ns := make([]string, len(commands))
-	for i, c := range commands {
-		ns[i] = c.Name()
+func zshCompGenFlagEntryExtras(f *pflag.Flag) string {
+	if f.NoOptDefVal != "" {
+		return ""
 	}
 	}
-	return ns
+
+	extras := ":" // allow options for flag (even without assistance)
+	for key, values := range f.Annotations {
+		switch key {
+		case zshCompDirname:
+			extras = fmt.Sprintf(":filename:_files -g %q", values[0])
+		case BashCompFilenameExt:
+			extras = ":filename:_files"
+			for _, pattern := range values {
+				extras = extras + fmt.Sprintf(` -g "%s"`, pattern)
+			}
+		}
+	}
+
+	return extras
+}
+
+func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool {
+	return strings.Contains(f.Value.Type(), "Slice") ||
+		strings.Contains(f.Value.Type(), "Array")
+}
+
+func zshCompQuoteFlagDescription(s string) string {
+	return strings.Replace(s, "'", `'\''`, -1)
 }
 }