From c8cb318b17c124aade6bc6a422ae1ec7a632bb06 Mon Sep 17 00:00:00 2001 From: Chmouel Boudjnah Date: Tue, 20 Aug 2019 14:28:09 +0200 Subject: [PATCH] Use forked version of cobra We use a forked version of cobra on `github.com/chmouel/cobra@zsh-completion-fixes` which includes two patches that hasn't been merged : https://github.com/spf13/cobra/pull/884 https://github.com/spf13/cobra/pull/899 hopefully this won't needed when those issues gets merged. Signed-off-by: Chmouel Boudjnah --- Makefile | 2 +- go.mod | 2 ++ go.sum | 2 ++ vendor/github.com/spf13/cobra/.gitignore | 5 +-- vendor/github.com/spf13/cobra/README.md | 3 ++ .../spf13/cobra/bash_completions.go | 14 +++++--- vendor/github.com/spf13/cobra/cobra.go | 4 +-- vendor/github.com/spf13/cobra/command.go | 22 ++++++++++--- .../spf13/cobra/shell_completions.go | 6 ++++ .../github.com/spf13/cobra/zsh_completions.go | 33 +++++++++++++++++-- vendor/modules.txt | 2 +- 11 files changed, 79 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index ddc1700e7..71ab55ee4 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ lint: ## run linter(s) .PHONY: test-unit test-unit: ./vendor ## run unit tests @echo "Running unit tests..." - @go test -v -cover ./... + @go test -failfast -v -cover ./... .PHONY: test-e2e test-e2e: ./vendor ## run e2e tests diff --git a/go.mod b/go.mod index 346a31cf9..87d0b4dd2 100644 --- a/go.mod +++ b/go.mod @@ -62,3 +62,5 @@ require ( ) replace github.com/kr/pty => github.com/creack/pty v1.1.7 + +replace github.com/spf13/cobra => github.com/chmouel/cobra v0.0.0-20190820110723-8f09bb39b20d diff --git a/go.sum b/go.sum index aed1ba75e..3831ccb91 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBT github.com/census-instrumentation/opencensus-proto v0.0.2-0.20180913191712-f303ae3f8d6a/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.1.0 h1:VwZ9smxzX8u14/125wHIX7ARV+YhR+L4JADswwxWK0Y= github.com/census-instrumentation/opencensus-proto v0.1.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chmouel/cobra v0.0.0-20190820110723-8f09bb39b20d h1:rZ/9d/lEvSkKIdobXFmmz6qMqtfJVEaj5R6RLrKydRU= +github.com/chmouel/cobra v0.0.0-20190820110723-8f09bb39b20d/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= diff --git a/vendor/github.com/spf13/cobra/.gitignore b/vendor/github.com/spf13/cobra/.gitignore index 3b053c59e..b2b848e77 100644 --- a/vendor/github.com/spf13/cobra/.gitignore +++ b/vendor/github.com/spf13/cobra/.gitignore @@ -32,7 +32,8 @@ Session.vim tags *.exe - +cobra cobra.test -.idea/* +.idea/ +*.iml diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md index 60c5a425b..649e2e2f7 100644 --- a/vendor/github.com/spf13/cobra/README.md +++ b/vendor/github.com/spf13/cobra/README.md @@ -24,6 +24,7 @@ Many of the most widely used Go projects are built using Cobra, such as: [Prototool](https://github.com/uber/prototool), [mattermost-server](https://github.com/mattermost/mattermost-server), [Gardener](https://github.com/gardener/gardenctl), +[Linkerd](https://linkerd.io/), etc. [![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra) @@ -217,6 +218,8 @@ import ( "github.com/spf13/viper" ) +var cfgFile string + func init() { cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)") diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go index 57bb8e1b3..03ddda27a 100644 --- a/vendor/github.com/spf13/cobra/bash_completions.go +++ b/vendor/github.com/spf13/cobra/bash_completions.go @@ -72,7 +72,9 @@ __%[1]s_handle_reply() else allflags=("${flags[*]} ${two_word_flags[*]}") fi - COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") ) + while IFS='' read -r c; do + COMPREPLY+=("$c") + done < <(compgen -W "${allflags[*]}" -- "$cur") if [[ $(type -t compopt) = "builtin" ]]; then [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace fi @@ -122,10 +124,14 @@ __%[1]s_handle_reply() if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then completions+=("${must_have_one_flag[@]}") fi - COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") ) + while IFS='' read -r c; do + COMPREPLY+=("$c") + done < <(compgen -W "${completions[*]}" -- "$cur") 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 c; do + COMPREPLY+=("$c") + done < <(compgen -W "${noun_aliases[*]}" -- "$cur") fi if [[ ${#COMPREPLY[@]} -eq 0 ]]; then @@ -160,7 +166,7 @@ __%[1]s_handle_filename_extension_flag() __%[1]s_handle_subdirs_in_dir_flag() { 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() diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go index 6505c070b..d01becc8f 100644 --- a/vendor/github.com/spf13/cobra/cobra.go +++ b/vendor/github.com/spf13/cobra/cobra.go @@ -52,7 +52,7 @@ var EnableCommandSorting = true // if the CLI is started from explorer.exe. // To disable the mousetrap, just set this variable to blank string (""). // 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. ` @@ -61,7 +61,7 @@ You need to open cmd.exe and run it from there. // 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 time.Duration = 5 * time.Second +var MousetrapDisplayDuration = 5 * time.Second // AddTemplateFunc adds a template function that's available to Usage and Help // template generation. diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index c7e898303..a33b90aac 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -17,6 +17,7 @@ package cobra import ( "bytes" + "errors" "fmt" "io" "os" @@ -27,6 +28,8 @@ import ( flag "github.com/spf13/pflag" ) +var ErrSubCommandRequired = errors.New("subcommand is required") + // FParseErrWhitelist configures Flag parse errors to be ignored type FParseErrWhitelist flag.ParseErrorsWhitelist @@ -68,6 +71,9 @@ type Command struct { // BashCompletionFunction is custom functions used by the bash autocompletion generator. BashCompletionFunction string + // ZshCompletionFunction is custom functions used by the zsh autocompletion generator. + ZshCompletionFunction string + // Deprecated defines, if this command is deprecated and should print this string when used. Deprecated string @@ -228,7 +234,7 @@ func (c *Command) SetErr(newErr io.Writer) { c.errWriter = newErr } -// SetOut sets the source for input data +// 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 @@ -297,7 +303,7 @@ func (c *Command) ErrOrStderr() io.Writer { return c.getErr(os.Stderr) } -// ErrOrStderr returns output to stderr +// InOrStdin returns output to stderr func (c *Command) InOrStdin() io.Reader { return c.getIn(os.Stdin) } @@ -369,7 +375,7 @@ func (c *Command) HelpFunc() func(*Command, []string) { } return func(c *Command, a []string) { c.mergePersistentFlags() - err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c) + err := tmpl(c.OutOrStderr(), c.HelpTemplate(), c) if err != nil { c.Println(err) } @@ -786,7 +792,7 @@ func (c *Command) execute(a []string) (err error) { } if !c.Runnable() { - return flag.ErrHelp + return ErrSubCommandRequired } c.preRun() @@ -920,6 +926,14 @@ func (c *Command) ExecuteC() (cmd *Command, err error) { return cmd, nil } + // If command wasn't runnable, show full help, but do return the error. + // This will result in apps by default returning a non-success exit code, but also gives them the option to + // handle specially. + if err == ErrSubCommandRequired { + cmd.HelpFunc()(cmd, args) + return cmd, err + } + // If root command has SilentErrors flagged, // all subcommands should respect it if !cmd.SilenceErrors && !c.SilenceErrors { diff --git a/vendor/github.com/spf13/cobra/shell_completions.go b/vendor/github.com/spf13/cobra/shell_completions.go index ba0af9cb5..a936830e6 100644 --- a/vendor/github.com/spf13/cobra/shell_completions.go +++ b/vendor/github.com/spf13/cobra/shell_completions.go @@ -34,6 +34,12 @@ func (c *Command) MarkFlagCustom(name string, f string) error { return MarkFlagCustom(c.Flags(), name, f) } +// MarkPFlagCustom adds the BashCompCustom annotation to the named pflag, if it exists. +// Generated shell autocompletion will call the function f for the flag. +func (c *Command) MarkPFlagCustom(name string, f string) error { + return MarkFlagCustom(c.PersistentFlags(), name, f) +} + // MarkPersistentFlagFilename instructs the various shell completion // implementations to limit completions for this persistent flag to the // specified extensions (patterns). diff --git a/vendor/github.com/spf13/cobra/zsh_completions.go b/vendor/github.com/spf13/cobra/zsh_completions.go index 12755482f..6f497c3fe 100644 --- a/vendor/github.com/spf13/cobra/zsh_completions.go +++ b/vendor/github.com/spf13/cobra/zsh_completions.go @@ -14,6 +14,7 @@ import ( const ( zshCompArgumentAnnotation = "cobra_annotations_zsh_completion_argument_annotation" + zshCompArgumentCustomComp = "cobra_annotations_zsh_completion_argument_custom_completion" zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion" zshCompArgumentWordComp = "cobra_annotations_zsh_completion_argument_word_completion" zshCompDirname = "cobra_annotations_zsh_dirname" @@ -79,6 +80,8 @@ function {{genZshFuncName .}} { {{define "Main" -}} #compdef _{{.Name}} {{.Name}} +{{.ZshCompletionFunction}} + {{template "selectCmdTemplate" .}} {{end}} ` @@ -119,6 +122,26 @@ func (c *Command) GenZshCompletion(w io.Writer) error { return tmpl.Execute(w, c.Root()) } +// MarkZshCompPositionalArgumentCustom marks the specified argument (first +// argument is 1) as custom. +func (c *Command) MarkZshCompPositionalArgumentCustom(argPosition int, function 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: zshCompArgumentCustomComp, + Options: []string{function}, + } + return c.zshCompSetArgsAnnotations(annotation) +} + // 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. @@ -208,6 +231,8 @@ func zshCompRenderZshCompArgHint(i int, z zshCompArgHint) (string, error) { words = append(words, fmt.Sprintf("%q", w)) } return fmt.Sprintf(`'%d: :(%s)'`, i, strings.Join(words, " ")), nil + case zshCompArgumentCustomComp: + return fmt.Sprintf(`'%d: :%s'`, i, z.Options[0]), nil default: return "", fmt.Errorf("Invalid zsh argument completion annotation: %s", t) } @@ -310,7 +335,7 @@ func zshCompGenFlagEntryExtras(f *pflag.Flag) string { return "" } - extras := ":" // allow options for flag (even without assistance) + extras := ":()" // allow options for flag (even without assistance) for key, values := range f.Annotations { switch key { case zshCompDirname: @@ -320,6 +345,8 @@ func zshCompGenFlagEntryExtras(f *pflag.Flag) string { for _, pattern := range values { extras = extras + fmt.Sprintf(` -g "%s"`, pattern) } + case BashCompCustom: + extras = ": :" + values[0] } } @@ -332,5 +359,7 @@ func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool { } func zshCompQuoteFlagDescription(s string) string { - return strings.Replace(s, "'", `'\''`, -1) + return strings.NewReplacer("'", `'\''`, + "[", `\[`, + "]", `\]`).Replace(s) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 21b54b049..f01db370e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -202,7 +202,7 @@ github.com/prometheus/procfs/xfs github.com/prometheus/procfs/internal/util # github.com/russross/blackfriday v1.5.2 github.com/russross/blackfriday -# github.com/spf13/cobra v0.0.5 +# github.com/spf13/cobra v0.0.5 => github.com/chmouel/cobra v0.0.0-20190820110723-8f09bb39b20d github.com/spf13/cobra # github.com/spf13/pflag v1.0.3 github.com/spf13/pflag