diff options
Diffstat (limited to 'vendor')
| -rw-r--r-- | vendor/github.com/spf13/cobra/README.md | 5 | ||||
| -rw-r--r-- | vendor/github.com/spf13/cobra/active_help.go | 2 | ||||
| -rw-r--r-- | vendor/github.com/spf13/cobra/bash_completionsV2.go | 152 | ||||
| -rw-r--r-- | vendor/github.com/spf13/cobra/cobra.go | 16 | ||||
| -rw-r--r-- | vendor/github.com/spf13/cobra/command.go | 331 | ||||
| -rw-r--r-- | vendor/github.com/spf13/cobra/completions.go | 126 | ||||
| -rw-r--r-- | vendor/github.com/spf13/cobra/powershell_completions.go | 35 | ||||
| -rw-r--r-- | vendor/github.com/spf13/pflag/.editorconfig | 12 | ||||
| -rw-r--r-- | vendor/github.com/spf13/pflag/.golangci.yaml | 4 | ||||
| -rw-r--r-- | vendor/github.com/spf13/pflag/flag.go | 29 | ||||
| -rw-r--r-- | vendor/github.com/spf13/pflag/ip.go | 3 | ||||
| -rw-r--r-- | vendor/github.com/spf13/pflag/ipnet_slice.go | 147 | ||||
| -rw-r--r-- | vendor/github.com/spf13/pflag/string_array.go | 4 | ||||
| -rw-r--r-- | vendor/modules.txt | 4 | 
14 files changed, 697 insertions, 173 deletions
diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md index 6444f4b7f..71757151c 100644 --- a/vendor/github.com/spf13/cobra/README.md +++ b/vendor/github.com/spf13/cobra/README.md @@ -1,4 +1,5 @@ - + +  Cobra is a library for creating powerful modern CLI applications. @@ -105,7 +106,7 @@ go install github.com/spf13/cobra-cli@latest  For complete details on using the Cobra-CLI generator, please read [The Cobra Generator README](https://github.com/spf13/cobra-cli/blob/main/README.md) -For complete details on using the Cobra library, please read the [The Cobra User Guide](site/content/user_guide.md). +For complete details on using the Cobra library, please read [The Cobra User Guide](site/content/user_guide.md).  # License diff --git a/vendor/github.com/spf13/cobra/active_help.go b/vendor/github.com/spf13/cobra/active_help.go index 25c30e3cc..b3e2dadfe 100644 --- a/vendor/github.com/spf13/cobra/active_help.go +++ b/vendor/github.com/spf13/cobra/active_help.go @@ -35,7 +35,7 @@ const (  // This function can be called multiple times before and/or after completions are added to  // the array.  Each time this function is called with the same array, the new  // ActiveHelp line will be shown below the previous ones when completion is triggered. -func AppendActiveHelp(compArray []string, activeHelpStr string) []string { +func AppendActiveHelp(compArray []Completion, activeHelpStr string) []Completion {  	return append(compArray, fmt.Sprintf("%s%s", activeHelpMarker, activeHelpStr))  } diff --git a/vendor/github.com/spf13/cobra/bash_completionsV2.go b/vendor/github.com/spf13/cobra/bash_completionsV2.go index 1cce5c329..d2397aa36 100644 --- a/vendor/github.com/spf13/cobra/bash_completionsV2.go +++ b/vendor/github.com/spf13/cobra/bash_completionsV2.go @@ -146,7 +146,7 @@ __%[1]s_process_completion_results() {      if (((directive & shellCompDirectiveFilterFileExt) != 0)); then          # File extension filtering -        local fullFilter filter filteringCmd +        local fullFilter="" filter filteringCmd          # Do not use quotes around the $completions variable or else newline          # characters will be kept. @@ -177,20 +177,71 @@ __%[1]s_process_completion_results() {      __%[1]s_handle_special_char "$cur" =      # Print the activeHelp statements before we finish +    __%[1]s_handle_activeHelp +} + +__%[1]s_handle_activeHelp() { +    # Print the activeHelp statements      if ((${#activeHelp[*]} != 0)); then -        printf "\n"; -        printf "%%s\n" "${activeHelp[@]}" -        printf "\n" - -        # The prompt format is only available from bash 4.4. -        # We test if it is available before using it. -        if (x=${PS1@P}) 2> /dev/null; then -            printf "%%s" "${PS1@P}${COMP_LINE[@]}" -        else -            # Can't print the prompt.  Just print the -            # text the user had typed, it is workable enough. -            printf "%%s" "${COMP_LINE[@]}" +        if [ -z $COMP_TYPE ]; then +            # Bash v3 does not set the COMP_TYPE variable. +            printf "\n"; +            printf "%%s\n" "${activeHelp[@]}" +            printf "\n" +            __%[1]s_reprint_commandLine +            return          fi + +        # Only print ActiveHelp on the second TAB press +        if [ $COMP_TYPE -eq 63 ]; then +            printf "\n" +            printf "%%s\n" "${activeHelp[@]}" + +            if ((${#COMPREPLY[*]} == 0)); then +                # When there are no completion choices from the program, file completion +                # may kick in if the program has not disabled it; in such a case, we want +                # to know if any files will match what the user typed, so that we know if +                # there will be completions presented, so that we know how to handle ActiveHelp. +                # To find out, we actually trigger the file completion ourselves; +                # the call to _filedir will fill COMPREPLY if files match. +                if (((directive & shellCompDirectiveNoFileComp) == 0)); then +                    __%[1]s_debug "Listing files" +                    _filedir +                fi +            fi + +            if ((${#COMPREPLY[*]} != 0)); then +                # If there are completion choices to be shown, print a delimiter. +                # Re-printing the command-line will automatically be done +                # by the shell when it prints the completion choices. +                printf -- "--" +            else +                # When there are no completion choices at all, we need +                # to re-print the command-line since the shell will +                # not be doing it itself. +                __%[1]s_reprint_commandLine +            fi +        elif [ $COMP_TYPE -eq 37 ] || [ $COMP_TYPE -eq 42 ]; then +            # For completion type: menu-complete/menu-complete-backward and insert-completions +            # the completions are immediately inserted into the command-line, so we first +            # print the activeHelp message and reprint the command-line since the shell won't. +            printf "\n" +            printf "%%s\n" "${activeHelp[@]}" + +            __%[1]s_reprint_commandLine +        fi +    fi +} + +__%[1]s_reprint_commandLine() { +    # The prompt format is only available from bash 4.4. +    # We test if it is available before using it. +    if (x=${PS1@P}) 2> /dev/null; then +        printf "%%s" "${PS1@P}${COMP_LINE[@]}" +    else +        # Can't print the prompt.  Just print the +        # text the user had typed, it is workable enough. +        printf "%%s" "${COMP_LINE[@]}"      fi  } @@ -201,6 +252,8 @@ __%[1]s_extract_activeHelp() {      local endIndex=${#activeHelpMarker}      while IFS='' read -r comp; do +        [[ -z $comp ]] && continue +          if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then              comp=${comp:endIndex}              __%[1]s_debug "ActiveHelp found: $comp" @@ -223,16 +276,21 @@ __%[1]s_handle_completion_types() {          # If the user requested inserting one completion at a time, or all          # completions at once on the command-line we must remove the descriptions.          # https://github.com/spf13/cobra/issues/1508 -        local tab=$'\t' comp -        while IFS='' read -r comp; do -            [[ -z $comp ]] && continue -            # Strip any description -            comp=${comp%%%%$tab*} -            # Only consider the completions that match -            if [[ $comp == "$cur"* ]]; then -                COMPREPLY+=("$comp") -            fi -        done < <(printf "%%s\n" "${completions[@]}") + +        # If there are no completions, we don't need to do anything +        (( ${#completions[@]} == 0 )) && return 0 + +        local tab=$'\t' + +        # Strip any description and escape the completion to handled special characters +        IFS=$'\n' read -ra completions -d '' < <(printf "%%q\n" "${completions[@]%%%%$tab*}") + +        # Only consider the completions that match +        IFS=$'\n' read -ra COMPREPLY -d '' < <(IFS=$'\n'; compgen -W "${completions[*]}" -- "${cur}") + +        # compgen looses the escaping so we need to escape all completions again since they will +        # all be inserted on the command-line. +        IFS=$'\n' read -ra COMPREPLY -d '' < <(printf "%%q\n" "${COMPREPLY[@]}")          ;;      *) @@ -243,11 +301,25 @@ __%[1]s_handle_completion_types() {  }  __%[1]s_handle_standard_completion_case() { -    local tab=$'\t' comp +    local tab=$'\t' + +    # If there are no completions, we don't need to do anything +    (( ${#completions[@]} == 0 )) && return 0      # Short circuit to optimize if we don't have descriptions      if [[ "${completions[*]}" != *$tab* ]]; then -        IFS=$'\n' read -ra COMPREPLY -d '' < <(compgen -W "${completions[*]}" -- "$cur") +        # First, escape the completions to handle special characters +        IFS=$'\n' read -ra completions -d '' < <(printf "%%q\n" "${completions[@]}") +        # Only consider the completions that match what the user typed +        IFS=$'\n' read -ra COMPREPLY -d '' < <(IFS=$'\n'; compgen -W "${completions[*]}" -- "${cur}") + +        # compgen looses the escaping so, if there is only a single completion, we need to +        # escape it again because it will be inserted on the command-line.  If there are multiple +        # completions, we don't want to escape them because they will be printed in a list +        # and we don't want to show escape characters in that list. +        if (( ${#COMPREPLY[@]} == 1 )); then +            COMPREPLY[0]=$(printf "%%q" "${COMPREPLY[0]}") +        fi          return 0      fi @@ -256,23 +328,39 @@ __%[1]s_handle_standard_completion_case() {      # Look for the longest completion so that we can format things nicely      while IFS='' read -r compline; do          [[ -z $compline ]] && continue -        # Strip any description before checking the length -        comp=${compline%%%%$tab*} + +        # Before checking if the completion matches what the user typed, +        # we need to strip any description and escape the completion to handle special +        # characters because those escape characters are part of what the user typed. +        # Don't call "printf" in a sub-shell because it will be much slower +        # since we are in a loop. +        printf -v comp "%%q" "${compline%%%%$tab*}" &>/dev/null || comp=$(printf "%%q" "${compline%%%%$tab*}") +          # Only consider the completions that match          [[ $comp == "$cur"* ]] || continue + +        # The completions matches.  Add it to the list of full completions including +        # its description.  We don't escape the completion because it may get printed +        # in a list if there are more than one and we don't want show escape characters +        # in that list.          COMPREPLY+=("$compline") + +        # Strip any description before checking the length, and again, don't escape +        # the completion because this length is only used when printing the completions +        # in a list and we don't want show escape characters in that list. +        comp=${compline%%%%$tab*}          if ((${#comp}>longest)); then              longest=${#comp}          fi      done < <(printf "%%s\n" "${completions[@]}") -    # If there is a single completion left, remove the description text +    # If there is a single completion left, remove the description text and escape any special characters      if ((${#COMPREPLY[*]} == 1)); then          __%[1]s_debug "COMPREPLY[0]: ${COMPREPLY[0]}" -        comp="${COMPREPLY[0]%%%%$tab*}" -        __%[1]s_debug "Removed description from single completion, which is now: ${comp}" -        COMPREPLY[0]=$comp -    else # Format the descriptions +        COMPREPLY[0]=$(printf "%%q" "${COMPREPLY[0]%%%%$tab*}") +        __%[1]s_debug "Removed description from single completion, which is now: ${COMPREPLY[0]}" +    else +        # Format the descriptions          __%[1]s_format_comp_descriptions $longest      fi  } diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go index e0b0947b0..d9cd2414e 100644 --- a/vendor/github.com/spf13/cobra/cobra.go +++ b/vendor/github.com/spf13/cobra/cobra.go @@ -176,12 +176,16 @@ func rpad(s string, padding int) string {  	return fmt.Sprintf(formattedString, s)  } -// tmpl executes the given template text on data, writing the result to w. -func tmpl(w io.Writer, text string, data interface{}) error { -	t := template.New("top") -	t.Funcs(templateFuncs) -	template.Must(t.Parse(text)) -	return t.Execute(w, data) +func tmpl(text string) *tmplFunc { +	return &tmplFunc{ +		tmpl: text, +		fn: func(w io.Writer, data interface{}) error { +			t := template.New("top") +			t.Funcs(templateFuncs) +			template.Must(t.Parse(text)) +			return t.Execute(w, data) +		}, +	}  }  // ld compares two strings and returns the levenshtein distance between them. diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index 54748fc67..dbb2c298b 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -33,6 +33,9 @@ import (  const (  	FlagSetByCobraAnnotation     = "cobra_annotation_flag_set_by_cobra"  	CommandDisplayNameAnnotation = "cobra_annotation_command_display_name" + +	helpFlagName    = "help" +	helpCommandName = "help"  )  // FParseErrWhitelist configures Flag parse errors to be ignored @@ -80,11 +83,11 @@ type Command struct {  	Example string  	// ValidArgs is list of all valid non-flag arguments that are accepted in shell completions -	ValidArgs []string +	ValidArgs []Completion  	// ValidArgsFunction is an optional function that provides valid non-flag arguments for shell 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) +	ValidArgsFunction CompletionFunc  	// Expected arguments  	Args PositionalArgs @@ -168,12 +171,12 @@ type Command struct {  	// usageFunc is usage func defined by user.  	usageFunc func(*Command) error  	// usageTemplate is usage template defined by user. -	usageTemplate string +	usageTemplate *tmplFunc  	// flagErrorFunc is func defined by user and it's called when the parsing of  	// flags returns an error.  	flagErrorFunc func(*Command, error) error  	// helpTemplate is help template defined by user. -	helpTemplate string +	helpTemplate *tmplFunc  	// helpFunc is help func defined by user.  	helpFunc func(*Command, []string)  	// helpCommand is command with usage 'help'. If it's not defined by user, @@ -186,7 +189,7 @@ type Command struct {  	completionCommandGroupID string  	// versionTemplate is the version template defined by user. -	versionTemplate string +	versionTemplate *tmplFunc  	// errPrefix is the error message prefix defined by user.  	errPrefix string @@ -281,6 +284,7 @@ func (c *Command) SetArgs(a []string) {  // SetOutput sets the destination for usage and error messages.  // If output is nil, os.Stderr is used. +//  // Deprecated: Use SetOut and/or SetErr instead  func (c *Command) SetOutput(output io.Writer) {  	c.outWriter = output @@ -312,7 +316,11 @@ func (c *Command) SetUsageFunc(f func(*Command) error) {  // SetUsageTemplate sets usage template. Can be defined by Application.  func (c *Command) SetUsageTemplate(s string) { -	c.usageTemplate = s +	if s == "" { +		c.usageTemplate = nil +		return +	} +	c.usageTemplate = tmpl(s)  }  // SetFlagErrorFunc sets a function to generate an error when flag parsing @@ -348,12 +356,20 @@ func (c *Command) SetCompletionCommandGroupID(groupID string) {  // SetHelpTemplate sets help template to be used. Application can use it to set custom template.  func (c *Command) SetHelpTemplate(s string) { -	c.helpTemplate = s +	if s == "" { +		c.helpTemplate = nil +		return +	} +	c.helpTemplate = tmpl(s)  }  // SetVersionTemplate sets version template to be used. Application can use it to set custom template.  func (c *Command) SetVersionTemplate(s string) { -	c.versionTemplate = s +	if s == "" { +		c.versionTemplate = nil +		return +	} +	c.versionTemplate = tmpl(s)  }  // SetErrPrefix sets error message prefix to be used. Application can use it to set custom prefix. @@ -434,7 +450,8 @@ func (c *Command) UsageFunc() (f func(*Command) error) {  	}  	return func(c *Command) error {  		c.mergePersistentFlags() -		err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c) +		fn := c.getUsageTemplateFunc() +		err := fn(c.OutOrStderr(), c)  		if err != nil {  			c.PrintErrln(err)  		} @@ -442,6 +459,19 @@ func (c *Command) UsageFunc() (f func(*Command) error) {  	}  } +// getUsageTemplateFunc returns the usage template function for the command +// going up the command tree if necessary. +func (c *Command) getUsageTemplateFunc() func(w io.Writer, data interface{}) error { +	if c.usageTemplate != nil { +		return c.usageTemplate.fn +	} + +	if c.HasParent() { +		return c.parent.getUsageTemplateFunc() +	} +	return defaultUsageFunc +} +  // Usage puts out the usage for the command.  // Used when a user provides invalid input.  // Can be defined by user by overriding UsageFunc. @@ -460,15 +490,30 @@ func (c *Command) HelpFunc() func(*Command, []string) {  	}  	return func(c *Command, a []string) {  		c.mergePersistentFlags() +		fn := c.getHelpTemplateFunc()  		// The help should be sent to stdout  		// See https://github.com/spf13/cobra/issues/1002 -		err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c) +		err := fn(c.OutOrStdout(), c)  		if err != nil {  			c.PrintErrln(err)  		}  	}  } +// getHelpTemplateFunc returns the help template function for the command +// going up the command tree if necessary. +func (c *Command) getHelpTemplateFunc() func(w io.Writer, data interface{}) error { +	if c.helpTemplate != nil { +		return c.helpTemplate.fn +	} + +	if c.HasParent() { +		return c.parent.getHelpTemplateFunc() +	} + +	return defaultHelpFunc +} +  // Help puts out the help for the command.  // Used when a user calls help [command].  // Can be defined by user by overriding HelpFunc. @@ -543,71 +588,55 @@ func (c *Command) NamePadding() int {  }  // UsageTemplate returns usage template for the command. +// This function is kept for backwards-compatibility reasons.  func (c *Command) UsageTemplate() string { -	if c.usageTemplate != "" { -		return c.usageTemplate +	if c.usageTemplate != nil { +		return c.usageTemplate.tmpl  	}  	if c.HasParent() {  		return c.parent.UsageTemplate()  	} -	return `Usage:{{if .Runnable}} -  {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} -  {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} - -Aliases: -  {{.NameAndAliases}}{{end}}{{if .HasExample}} - -Examples: -{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}} - -Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}} -  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}} - -{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}} -  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}} - -Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}} -  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} - -Flags: -{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} - -Global Flags: -{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} - -Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} -  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} - -Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} -` +	return defaultUsageTemplate  }  // HelpTemplate return help template for the command. +// This function is kept for backwards-compatibility reasons.  func (c *Command) HelpTemplate() string { -	if c.helpTemplate != "" { -		return c.helpTemplate +	if c.helpTemplate != nil { +		return c.helpTemplate.tmpl  	}  	if c.HasParent() {  		return c.parent.HelpTemplate()  	} -	return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}} - -{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` +	return defaultHelpTemplate  }  // VersionTemplate return version template for the command. +// This function is kept for backwards-compatibility reasons.  func (c *Command) VersionTemplate() string { -	if c.versionTemplate != "" { -		return c.versionTemplate +	if c.versionTemplate != nil { +		return c.versionTemplate.tmpl  	}  	if c.HasParent() {  		return c.parent.VersionTemplate()  	} -	return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}} -` +	return defaultVersionTemplate +} + +// getVersionTemplateFunc returns the version template function for the command +// going up the command tree if necessary. +func (c *Command) getVersionTemplateFunc() func(w io.Writer, data interface{}) error { +	if c.versionTemplate != nil { +		return c.versionTemplate.fn +	} + +	if c.HasParent() { +		return c.parent.getVersionTemplateFunc() +	} +	return defaultVersionFunc  }  // ErrPrefix return error message prefix for the command @@ -894,7 +923,7 @@ func (c *Command) execute(a []string) (err error) {  	// If help is called, regardless of other flags, return we want help.  	// Also say we need help if the command isn't runnable. -	helpVal, err := c.Flags().GetBool("help") +	helpVal, err := c.Flags().GetBool(helpFlagName)  	if err != nil {  		// should be impossible to get here as we always declare a help  		// flag in InitDefaultHelpFlag() @@ -914,7 +943,8 @@ func (c *Command) execute(a []string) (err error) {  			return err  		}  		if versionVal { -			err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c) +			fn := c.getVersionTemplateFunc() +			err := fn(c.OutOrStdout(), c)  			if err != nil {  				c.Println(err)  			} @@ -1068,12 +1098,6 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {  	// initialize help at the last point to allow for user overriding  	c.InitDefaultHelpCmd() -	// initialize completion at the last point to allow for user overriding -	c.InitDefaultCompletionCmd() - -	// Now that all commands have been created, let's make sure all groups -	// are properly created also -	c.checkCommandGroups()  	args := c.args @@ -1082,9 +1106,16 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {  		args = os.Args[1:]  	} -	// initialize the hidden command to be used for shell completion +	// initialize the __complete command to be used for shell completion  	c.initCompleteCmd(args) +	// initialize the default completion command +	c.InitDefaultCompletionCmd(args...) + +	// Now that all commands have been created, let's make sure all groups +	// are properly created also +	c.checkCommandGroups() +  	var flags []string  	if c.TraverseChildren {  		cmd, flags, err = c.Traverse(args) @@ -1187,16 +1218,16 @@ func (c *Command) checkCommandGroups() {  // If c already has help flag, it will do nothing.  func (c *Command) InitDefaultHelpFlag() {  	c.mergePersistentFlags() -	if c.Flags().Lookup("help") == nil { +	if c.Flags().Lookup(helpFlagName) == nil {  		usage := "help for " -		name := c.displayName() +		name := c.DisplayName()  		if name == "" {  			usage += "this command"  		} else {  			usage += name  		} -		c.Flags().BoolP("help", "h", false, usage) -		_ = c.Flags().SetAnnotation("help", FlagSetByCobraAnnotation, []string{"true"}) +		c.Flags().BoolP(helpFlagName, "h", false, usage) +		_ = c.Flags().SetAnnotation(helpFlagName, FlagSetByCobraAnnotation, []string{"true"})  	}  } @@ -1215,7 +1246,7 @@ func (c *Command) InitDefaultVersionFlag() {  		if c.Name() == "" {  			usage += "this command"  		} else { -			usage += c.Name() +			usage += c.DisplayName()  		}  		if c.Flags().ShorthandLookup("v") == nil {  			c.Flags().BoolP("version", "v", false, usage) @@ -1239,9 +1270,9 @@ func (c *Command) InitDefaultHelpCmd() {  			Use:   "help [command]",  			Short: "Help about any command",  			Long: `Help provides help for any command in the application. -Simply type ` + c.displayName() + ` help [path to command] for full details.`, -			ValidArgsFunction: func(c *Command, args []string, toComplete string) ([]string, ShellCompDirective) { -				var completions []string +Simply type ` + c.DisplayName() + ` help [path to command] for full details.`, +			ValidArgsFunction: func(c *Command, args []string, toComplete string) ([]Completion, ShellCompDirective) { +				var completions []Completion  				cmd, _, e := c.Root().Find(args)  				if e != nil {  					return nil, ShellCompDirectiveNoFileComp @@ -1253,7 +1284,7 @@ Simply type ` + c.displayName() + ` help [path to command] for full details.`,  				for _, subCmd := range cmd.Commands() {  					if subCmd.IsAvailableCommand() || subCmd == cmd.helpCommand {  						if strings.HasPrefix(subCmd.Name(), toComplete) { -							completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short)) +							completions = append(completions, CompletionWithDesc(subCmd.Name(), subCmd.Short))  						}  					}  				} @@ -1430,10 +1461,12 @@ func (c *Command) CommandPath() string {  	if c.HasParent() {  		return c.Parent().CommandPath() + " " + c.Name()  	} -	return c.displayName() +	return c.DisplayName()  } -func (c *Command) displayName() string { +// DisplayName returns the name to display in help text. Returns command Name() +// If CommandDisplayNameAnnoation is not set +func (c *Command) DisplayName() string {  	if displayName, ok := c.Annotations[CommandDisplayNameAnnotation]; ok {  		return displayName  	} @@ -1443,7 +1476,7 @@ func (c *Command) displayName() string {  // UseLine puts out the full usage for a given command (including parents).  func (c *Command) UseLine() string {  	var useline string -	use := strings.Replace(c.Use, c.Name(), c.displayName(), 1) +	use := strings.Replace(c.Use, c.Name(), c.DisplayName(), 1)  	if c.HasParent() {  		useline = c.parent.CommandPath() + " " + use  	} else { @@ -1649,7 +1682,7 @@ func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) f  // to this command (local and persistent declared here and by all parents).  func (c *Command) Flags() *flag.FlagSet {  	if c.flags == nil { -		c.flags = flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +		c.flags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  		if c.flagErrorBuf == nil {  			c.flagErrorBuf = new(bytes.Buffer)  		} @@ -1664,7 +1697,7 @@ func (c *Command) Flags() *flag.FlagSet {  func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {  	persistentFlags := c.PersistentFlags() -	out := flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +	out := flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  	c.LocalFlags().VisitAll(func(f *flag.Flag) {  		if persistentFlags.Lookup(f.Name) == nil {  			out.AddFlag(f) @@ -1679,7 +1712,7 @@ func (c *Command) LocalFlags() *flag.FlagSet {  	c.mergePersistentFlags()  	if c.lflags == nil { -		c.lflags = flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +		c.lflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  		if c.flagErrorBuf == nil {  			c.flagErrorBuf = new(bytes.Buffer)  		} @@ -1707,7 +1740,7 @@ func (c *Command) InheritedFlags() *flag.FlagSet {  	c.mergePersistentFlags()  	if c.iflags == nil { -		c.iflags = flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +		c.iflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  		if c.flagErrorBuf == nil {  			c.flagErrorBuf = new(bytes.Buffer)  		} @@ -1736,7 +1769,7 @@ func (c *Command) NonInheritedFlags() *flag.FlagSet {  // PersistentFlags returns the persistent FlagSet specifically set in the current command.  func (c *Command) PersistentFlags() *flag.FlagSet {  	if c.pflags == nil { -		c.pflags = flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +		c.pflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  		if c.flagErrorBuf == nil {  			c.flagErrorBuf = new(bytes.Buffer)  		} @@ -1749,9 +1782,9 @@ func (c *Command) PersistentFlags() *flag.FlagSet {  func (c *Command) ResetFlags() {  	c.flagErrorBuf = new(bytes.Buffer)  	c.flagErrorBuf.Reset() -	c.flags = flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +	c.flags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  	c.flags.SetOutput(c.flagErrorBuf) -	c.pflags = flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +	c.pflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  	c.pflags.SetOutput(c.flagErrorBuf)  	c.lflags = nil @@ -1868,7 +1901,7 @@ func (c *Command) mergePersistentFlags() {  // If c.parentsPflags == nil, it makes new.  func (c *Command) updateParentsPflags() {  	if c.parentsPflags == nil { -		c.parentsPflags = flag.NewFlagSet(c.displayName(), flag.ContinueOnError) +		c.parentsPflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)  		c.parentsPflags.SetOutput(c.flagErrorBuf)  		c.parentsPflags.SortFlags = false  	} @@ -1894,3 +1927,141 @@ func commandNameMatches(s string, t string) bool {  	return s == t  } + +// tmplFunc holds a template and a function that will execute said template. +type tmplFunc struct { +	tmpl string +	fn   func(io.Writer, interface{}) error +} + +var defaultUsageTemplate = `Usage:{{if .Runnable}} +  {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} +  {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} + +Aliases: +  {{.NameAndAliases}}{{end}}{{if .HasExample}} + +Examples: +{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}} + +Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}} +  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}} + +{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}} +  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}} + +Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}} +  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} + +Flags: +{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} + +Global Flags: +{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} + +Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} +  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} +` + +// defaultUsageFunc is equivalent to executing defaultUsageTemplate. The two should be changed in sync. +func defaultUsageFunc(w io.Writer, in interface{}) error { +	c := in.(*Command) +	fmt.Fprint(w, "Usage:") +	if c.Runnable() { +		fmt.Fprintf(w, "\n  %s", c.UseLine()) +	} +	if c.HasAvailableSubCommands() { +		fmt.Fprintf(w, "\n  %s [command]", c.CommandPath()) +	} +	if len(c.Aliases) > 0 { +		fmt.Fprintf(w, "\n\nAliases:\n") +		fmt.Fprintf(w, "  %s", c.NameAndAliases()) +	} +	if c.HasExample() { +		fmt.Fprintf(w, "\n\nExamples:\n") +		fmt.Fprintf(w, "%s", c.Example) +	} +	if c.HasAvailableSubCommands() { +		cmds := c.Commands() +		if len(c.Groups()) == 0 { +			fmt.Fprintf(w, "\n\nAvailable Commands:") +			for _, subcmd := range cmds { +				if subcmd.IsAvailableCommand() || subcmd.Name() == helpCommandName { +					fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.Name(), subcmd.NamePadding()), subcmd.Short) +				} +			} +		} else { +			for _, group := range c.Groups() { +				fmt.Fprintf(w, "\n\n%s", group.Title) +				for _, subcmd := range cmds { +					if subcmd.GroupID == group.ID && (subcmd.IsAvailableCommand() || subcmd.Name() == helpCommandName) { +						fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.Name(), subcmd.NamePadding()), subcmd.Short) +					} +				} +			} +			if !c.AllChildCommandsHaveGroup() { +				fmt.Fprintf(w, "\n\nAdditional Commands:") +				for _, subcmd := range cmds { +					if subcmd.GroupID == "" && (subcmd.IsAvailableCommand() || subcmd.Name() == helpCommandName) { +						fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.Name(), subcmd.NamePadding()), subcmd.Short) +					} +				} +			} +		} +	} +	if c.HasAvailableLocalFlags() { +		fmt.Fprintf(w, "\n\nFlags:\n") +		fmt.Fprint(w, trimRightSpace(c.LocalFlags().FlagUsages())) +	} +	if c.HasAvailableInheritedFlags() { +		fmt.Fprintf(w, "\n\nGlobal Flags:\n") +		fmt.Fprint(w, trimRightSpace(c.InheritedFlags().FlagUsages())) +	} +	if c.HasHelpSubCommands() { +		fmt.Fprintf(w, "\n\nAdditional help topcis:") +		for _, subcmd := range c.Commands() { +			if subcmd.IsAdditionalHelpTopicCommand() { +				fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.CommandPath(), subcmd.CommandPathPadding()), subcmd.Short) +			} +		} +	} +	if c.HasAvailableSubCommands() { +		fmt.Fprintf(w, "\n\nUse \"%s [command] --help\" for more information about a command.", c.CommandPath()) +	} +	fmt.Fprintln(w) +	return nil +} + +var defaultHelpTemplate = `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}} + +{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` + +// defaultHelpFunc is equivalent to executing defaultHelpTemplate. The two should be changed in sync. +func defaultHelpFunc(w io.Writer, in interface{}) error { +	c := in.(*Command) +	usage := c.Long +	if usage == "" { +		usage = c.Short +	} +	usage = trimRightSpace(usage) +	if usage != "" { +		fmt.Fprintln(w, usage) +		fmt.Fprintln(w) +	} +	if c.Runnable() || c.HasSubCommands() { +		fmt.Fprint(w, c.UsageString()) +	} +	return nil +} + +var defaultVersionTemplate = `{{with .DisplayName}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}} +` + +// defaultVersionFunc is equivalent to executing defaultVersionTemplate. The two should be changed in sync. +func defaultVersionFunc(w io.Writer, in interface{}) error { +	c := in.(*Command) +	_, err := fmt.Fprintf(w, "%s version %s\n", c.DisplayName(), c.Version) +	return err +} diff --git a/vendor/github.com/spf13/cobra/completions.go b/vendor/github.com/spf13/cobra/completions.go index c0c08b057..a1752f763 100644 --- a/vendor/github.com/spf13/cobra/completions.go +++ b/vendor/github.com/spf13/cobra/completions.go @@ -35,7 +35,7 @@ const (  )  // Global map of flag completion functions. Make sure to use flagCompletionMutex before you try to read and write from it. -var flagCompletionFunctions = map[*pflag.Flag]func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective){} +var flagCompletionFunctions = map[*pflag.Flag]CompletionFunc{}  // lock for reading and writing from flagCompletionFunctions  var flagCompletionMutex = &sync.RWMutex{} @@ -117,22 +117,50 @@ type CompletionOptions struct {  	HiddenDefaultCmd bool  } +// Completion is a string that can be used for completions +// +// two formats are supported: +//   - the completion choice +//   - the completion choice with a textual description (separated by a TAB). +// +// [CompletionWithDesc] can be used to create a completion string with a textual description. +// +// Note: Go type alias is used to provide a more descriptive name in the documentation, but any string can be used. +type Completion = string + +// CompletionFunc is a function that provides completion results. +type CompletionFunc = func(cmd *Command, args []string, toComplete string) ([]Completion, ShellCompDirective) + +// CompletionWithDesc returns a [Completion] with a description by using the TAB delimited format. +func CompletionWithDesc(choice string, description string) Completion { +	return choice + "\t" + description +} +  // NoFileCompletions can be used to disable file completion for commands that should  // not trigger file completions. -func NoFileCompletions(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) { +// +// This method satisfies [CompletionFunc]. +// It can be used with [Command.RegisterFlagCompletionFunc] and for [Command.ValidArgsFunction]. +func NoFileCompletions(cmd *Command, args []string, toComplete string) ([]Completion, ShellCompDirective) {  	return nil, ShellCompDirectiveNoFileComp  }  // FixedCompletions can be used to create a completion function which always  // returns the same results. -func FixedCompletions(choices []string, directive ShellCompDirective) func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) { -	return func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) { +// +// This method returns a function that satisfies [CompletionFunc] +// It can be used with [Command.RegisterFlagCompletionFunc] and for [Command.ValidArgsFunction]. +func FixedCompletions(choices []Completion, directive ShellCompDirective) CompletionFunc { +	return func(cmd *Command, args []string, toComplete string) ([]Completion, ShellCompDirective) {  		return choices, directive  	}  }  // 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 { +// +// You can use pre-defined completion functions such as [FixedCompletions] or [NoFileCompletions], +// or you can define your own. +func (c *Command) RegisterFlagCompletionFunc(flagName string, f CompletionFunc) error {  	flag := c.Flag(flagName)  	if flag == nil {  		return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' does not exist", flagName) @@ -148,7 +176,7 @@ func (c *Command) RegisterFlagCompletionFunc(flagName string, f func(cmd *Comman  }  // GetFlagCompletionFunc returns the completion function for the given flag of the command, if available. -func (c *Command) GetFlagCompletionFunc(flagName string) (func(*Command, []string, string) ([]string, ShellCompDirective), bool) { +func (c *Command) GetFlagCompletionFunc(flagName string) (CompletionFunc, bool) {  	flag := c.Flag(flagName)  	if flag == nil {  		return nil, false @@ -270,7 +298,15 @@ func (c *Command) initCompleteCmd(args []string) {  	}  } -func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDirective, error) { +// SliceValue is a reduced version of [pflag.SliceValue]. It is used to detect +// flags that accept multiple values and therefore can provide completion +// multiple times. +type SliceValue interface { +	// GetSlice returns the flag value list as an array of strings. +	GetSlice() []string +} + +func (c *Command) getCompletions(args []string) (*Command, []Completion, ShellCompDirective, error) {  	// 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] @@ -298,7 +334,7 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  	}  	if err != nil {  		// Unable to find the real command. E.g., <program> someInvalidCmd <TAB> -		return c, []string{}, ShellCompDirectiveDefault, fmt.Errorf("unable to find a command for arguments: %v", trimmedArgs) +		return c, []Completion{}, ShellCompDirectiveDefault, fmt.Errorf("unable to find a command for arguments: %v", trimmedArgs)  	}  	finalCmd.ctx = c.ctx @@ -328,7 +364,7 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  	// Parse the flags early so we can check if required flags are set  	if err = finalCmd.ParseFlags(finalArgs); err != nil { -		return finalCmd, []string{}, ShellCompDirectiveDefault, fmt.Errorf("Error while parsing flags from args %v: %s", finalArgs, err.Error()) +		return finalCmd, []Completion{}, ShellCompDirectiveDefault, fmt.Errorf("Error while parsing flags from args %v: %s", finalArgs, err.Error())  	}  	realArgCount := finalCmd.Flags().NArg() @@ -340,14 +376,14 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  	if flagErr != nil {  		// If error type is flagCompError and we don't want flagCompletion we should ignore the error  		if _, ok := flagErr.(*flagCompError); !(ok && !flagCompletion) { -			return finalCmd, []string{}, ShellCompDirectiveDefault, flagErr +			return finalCmd, []Completion{}, ShellCompDirectiveDefault, flagErr  		}  	}  	// Look for the --help or --version flags.  If they are present,  	// there should be no further completions.  	if helpOrVersionFlagPresent(finalCmd) { -		return finalCmd, []string{}, ShellCompDirectiveNoFileComp, nil +		return finalCmd, []Completion{}, ShellCompDirectiveNoFileComp, nil  	}  	// We only remove the flags from the arguments if DisableFlagParsing is not set. @@ -376,11 +412,11 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  				return finalCmd, subDir, ShellCompDirectiveFilterDirs, nil  			}  			// Directory completion -			return finalCmd, []string{}, ShellCompDirectiveFilterDirs, nil +			return finalCmd, []Completion{}, ShellCompDirectiveFilterDirs, nil  		}  	} -	var completions []string +	var completions []Completion  	var directive ShellCompDirective  	// Enforce flag groups before doing flag completions @@ -399,10 +435,14 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  		// If we have not found any required flags, only then can we show regular flags  		if len(completions) == 0 {  			doCompleteFlags := func(flag *pflag.Flag) { -				if !flag.Changed || +				_, acceptsMultiple := flag.Value.(SliceValue) +				acceptsMultiple = acceptsMultiple ||  					strings.Contains(flag.Value.Type(), "Slice") || -					strings.Contains(flag.Value.Type(), "Array") { -					// If the flag is not already present, or if it can be specified multiple times (Array or Slice) +					strings.Contains(flag.Value.Type(), "Array") || +					strings.HasPrefix(flag.Value.Type(), "stringTo") + +				if !flag.Changed || acceptsMultiple { +					// If the flag is not already present, or if it can be specified multiple times (Array, Slice, or stringTo)  					// we suggest it as a completion  					completions = append(completions, getFlagNameCompletions(flag, toComplete)...)  				} @@ -462,7 +502,7 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  				for _, subCmd := range finalCmd.Commands() {  					if subCmd.IsAvailableCommand() || subCmd == finalCmd.helpCommand {  						if strings.HasPrefix(subCmd.Name(), toComplete) { -							completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short)) +							completions = append(completions, CompletionWithDesc(subCmd.Name(), subCmd.Short))  						}  						directive = ShellCompDirectiveNoFileComp  					} @@ -507,7 +547,7 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  	}  	// Find the completion function for the flag or command -	var completionFn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) +	var completionFn CompletionFunc  	if flag != nil && flagCompletion {  		flagCompletionMutex.RLock()  		completionFn = flagCompletionFunctions[flag] @@ -518,7 +558,7 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi  	if completionFn != nil {  		// Go custom completion defined for this flag or command.  		// Call the registered completion function to get the completions. -		var comps []string +		var comps []Completion  		comps, directive = completionFn(finalCmd, finalArgs, toComplete)  		completions = append(completions, comps...)  	} @@ -531,23 +571,23 @@ func helpOrVersionFlagPresent(cmd *Command) bool {  		len(versionFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && versionFlag.Changed {  		return true  	} -	if helpFlag := cmd.Flags().Lookup("help"); helpFlag != nil && +	if helpFlag := cmd.Flags().Lookup(helpFlagName); helpFlag != nil &&  		len(helpFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && helpFlag.Changed {  		return true  	}  	return false  } -func getFlagNameCompletions(flag *pflag.Flag, toComplete string) []string { +func getFlagNameCompletions(flag *pflag.Flag, toComplete string) []Completion {  	if nonCompletableFlag(flag) { -		return []string{} +		return []Completion{}  	} -	var completions []string +	var completions []Completion  	flagName := "--" + flag.Name  	if strings.HasPrefix(flagName, toComplete) {  		// Flag without the = -		completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage)) +		completions = append(completions, CompletionWithDesc(flagName, flag.Usage))  		// Why suggest both long forms: --flag and --flag= ?  		// This forces the user to *always* have to type either an = or a space after the flag name. @@ -559,20 +599,20 @@ func getFlagNameCompletions(flag *pflag.Flag, toComplete string) []string {  		// 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)) +		// 	completions = append(completions, CompletionWithDesc(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)) +		completions = append(completions, CompletionWithDesc(flagName, flag.Usage))  	}  	return completions  } -func completeRequireFlags(finalCmd *Command, toComplete string) []string { -	var completions []string +func completeRequireFlags(finalCmd *Command, toComplete string) []Completion { +	var completions []Completion  	doCompleteRequiredFlags := func(flag *pflag.Flag) {  		if _, present := flag.Annotations[BashCompOneRequiredFlag]; present { @@ -687,8 +727,8 @@ func checkIfFlagCompletion(finalCmd *Command, args []string, lastArg string) (*p  // 1- the feature has been explicitly disabled by the program,  // 2- c has no subcommands (to avoid creating one),  // 3- c already has a 'completion' command provided by the program. -func (c *Command) InitDefaultCompletionCmd() { -	if c.CompletionOptions.DisableDefaultCmd || !c.HasSubCommands() { +func (c *Command) InitDefaultCompletionCmd(args ...string) { +	if c.CompletionOptions.DisableDefaultCmd {  		return  	} @@ -701,6 +741,16 @@ func (c *Command) InitDefaultCompletionCmd() {  	haveNoDescFlag := !c.CompletionOptions.DisableNoDescFlag && !c.CompletionOptions.DisableDescriptions +	// Special case to know if there are sub-commands or not. +	hasSubCommands := false +	for _, cmd := range c.commands { +		if cmd.Name() != ShellCompRequestCmd && cmd.Name() != helpCommandName { +			// We found a real sub-command (not 'help' or '__complete') +			hasSubCommands = true +			break +		} +	} +  	completionCmd := &Command{  		Use:   compCmdName,  		Short: "Generate the autocompletion script for the specified shell", @@ -714,6 +764,22 @@ See each sub-command's help for details on how to use the generated script.  	}  	c.AddCommand(completionCmd) +	if !hasSubCommands { +		// If the 'completion' command will be the only sub-command, +		// we only create it if it is actually being called. +		// This avoids breaking programs that would suddenly find themselves with +		// a subcommand, which would prevent them from accepting arguments. +		// We also create the 'completion' command if the user is triggering +		// shell completion for it (prog __complete completion '') +		subCmd, cmdArgs, err := c.Find(args) +		if err != nil || subCmd.Name() != compCmdName && +			!(subCmd.Name() == ShellCompRequestCmd && len(cmdArgs) > 1 && cmdArgs[0] == compCmdName) { +			// The completion command is not being called or being completed so we remove it. +			c.RemoveCommand(completionCmd) +			return +		} +	} +  	out := c.OutOrStdout()  	noDesc := c.CompletionOptions.DisableDescriptions  	shortDesc := "Generate the autocompletion script for %s" diff --git a/vendor/github.com/spf13/cobra/powershell_completions.go b/vendor/github.com/spf13/cobra/powershell_completions.go index a830b7bca..746dcb92e 100644 --- a/vendor/github.com/spf13/cobra/powershell_completions.go +++ b/vendor/github.com/spf13/cobra/powershell_completions.go @@ -162,7 +162,10 @@ filter __%[1]s_escapeStringWithSpecialChars {          if (-Not $Description) {              $Description = " "          } -        @{Name="$Name";Description="$Description"} +        New-Object -TypeName PSCustomObject -Property @{ +            Name = "$Name" +            Description = "$Description" +        }      } @@ -240,7 +243,12 @@ filter __%[1]s_escapeStringWithSpecialChars {                      __%[1]s_debug "Only one completion left"                      # insert space after value -                    [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") +                    $CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space +                    if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){ +                        [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") +                    } else { +                        $CompletionText +                    }                  } else {                      # Add the proper number of spaces to align the descriptions @@ -255,7 +263,12 @@ filter __%[1]s_escapeStringWithSpecialChars {                          $Description = "  ($($comp.Description))"                      } -                    [System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)") +                    $CompletionText = "$($comp.Name)$Description" +                    if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){ +                        [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)") +                    } else { +                        $CompletionText +                    }                  }               } @@ -264,7 +277,13 @@ filter __%[1]s_escapeStringWithSpecialChars {                  # insert space after value                  # MenuComplete will automatically show the ToolTip of                  # the highlighted value at the bottom of the suggestions. -                [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") + +                $CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space +                if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){ +                    [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") +                } else { +                    $CompletionText +                }              }              # TabCompleteNext and in case we get something unknown @@ -272,7 +291,13 @@ filter __%[1]s_escapeStringWithSpecialChars {                  # Like MenuComplete but we don't want to add a space here because                  # the user need to press space anyway to get the completion.                  # Description will not be shown because that's not possible with TabCompleteNext -                [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)") + +                $CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars) +                if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){ +                    [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") +                } else { +                    $CompletionText +                }              }          } diff --git a/vendor/github.com/spf13/pflag/.editorconfig b/vendor/github.com/spf13/pflag/.editorconfig new file mode 100644 index 000000000..4492e9f9f --- /dev/null +++ b/vendor/github.com/spf13/pflag/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.go] +indent_style = tab diff --git a/vendor/github.com/spf13/pflag/.golangci.yaml b/vendor/github.com/spf13/pflag/.golangci.yaml new file mode 100644 index 000000000..b274f2484 --- /dev/null +++ b/vendor/github.com/spf13/pflag/.golangci.yaml @@ -0,0 +1,4 @@ +linters: +    disable-all: true +    enable: +        - nolintlint diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go index 24a5036e9..7c058de37 100644 --- a/vendor/github.com/spf13/pflag/flag.go +++ b/vendor/github.com/spf13/pflag/flag.go @@ -160,7 +160,7 @@ type FlagSet struct {  	args              []string // arguments after flags  	argsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --  	errorHandling     ErrorHandling -	output            io.Writer // nil means stderr; use out() accessor +	output            io.Writer // nil means stderr; use Output() accessor  	interspersed      bool      // allow interspersed option/non-option args  	normalizeNameFunc func(f *FlagSet, name string) NormalizedName @@ -255,13 +255,20 @@ func (f *FlagSet) normalizeFlagName(name string) NormalizedName {  	return n(f, name)  } -func (f *FlagSet) out() io.Writer { +// Output returns the destination for usage and error messages. os.Stderr is returned if +// output was not set or was set to nil. +func (f *FlagSet) Output() io.Writer {  	if f.output == nil {  		return os.Stderr  	}  	return f.output  } +// Name returns the name of the flag set. +func (f *FlagSet) Name() string { +	return f.name +} +  // SetOutput sets the destination for usage and error messages.  // If output is nil, os.Stderr is used.  func (f *FlagSet) SetOutput(output io.Writer) { @@ -358,7 +365,7 @@ func (f *FlagSet) ShorthandLookup(name string) *Flag {  	}  	if len(name) > 1 {  		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name) -		fmt.Fprintf(f.out(), msg) +		fmt.Fprintf(f.Output(), msg)  		panic(msg)  	}  	c := name[0] @@ -482,7 +489,7 @@ func (f *FlagSet) Set(name, value string) error {  	}  	if flag.Deprecated != "" { -		fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) +		fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)  	}  	return nil  } @@ -523,7 +530,7 @@ func Set(name, value string) error {  // otherwise, the default values of all defined flags in the set.  func (f *FlagSet) PrintDefaults() {  	usages := f.FlagUsages() -	fmt.Fprint(f.out(), usages) +	fmt.Fprint(f.Output(), usages)  }  // defaultIsZeroValue returns true if the default value for this flag represents @@ -758,7 +765,7 @@ func PrintDefaults() {  // defaultUsage is the default function to print a usage message.  func defaultUsage(f *FlagSet) { -	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name) +	fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)  	f.PrintDefaults()  } @@ -844,7 +851,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {  	_, alreadyThere := f.formal[normalizedFlagName]  	if alreadyThere {  		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name) -		fmt.Fprintln(f.out(), msg) +		fmt.Fprintln(f.Output(), msg)  		panic(msg) // Happens only if flags are declared with identical names  	}  	if f.formal == nil { @@ -860,7 +867,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {  	}  	if len(flag.Shorthand) > 1 {  		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand) -		fmt.Fprintf(f.out(), msg) +		fmt.Fprintf(f.Output(), msg)  		panic(msg)  	}  	if f.shorthands == nil { @@ -870,7 +877,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {  	used, alreadyThere := f.shorthands[c]  	if alreadyThere {  		msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name) -		fmt.Fprintf(f.out(), msg) +		fmt.Fprintf(f.Output(), msg)  		panic(msg)  	}  	f.shorthands[c] = flag @@ -909,7 +916,7 @@ func VarP(value Value, name, shorthand, usage string) {  func (f *FlagSet) failf(format string, a ...interface{}) error {  	err := fmt.Errorf(format, a...)  	if f.errorHandling != ContinueOnError { -		fmt.Fprintln(f.out(), err) +		fmt.Fprintln(f.Output(), err)  		f.usage()  	}  	return err @@ -1060,7 +1067,7 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse  	}  	if flag.ShorthandDeprecated != "" { -		fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) +		fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)  	}  	err = fn(flag, value) diff --git a/vendor/github.com/spf13/pflag/ip.go b/vendor/github.com/spf13/pflag/ip.go index 3d414ba69..06b8bcb57 100644 --- a/vendor/github.com/spf13/pflag/ip.go +++ b/vendor/github.com/spf13/pflag/ip.go @@ -16,6 +16,9 @@ func newIPValue(val net.IP, p *net.IP) *ipValue {  func (i *ipValue) String() string { return net.IP(*i).String() }  func (i *ipValue) Set(s string) error { +	if s == "" { +		return nil +	}  	ip := net.ParseIP(strings.TrimSpace(s))  	if ip == nil {  		return fmt.Errorf("failed to parse IP: %q", s) diff --git a/vendor/github.com/spf13/pflag/ipnet_slice.go b/vendor/github.com/spf13/pflag/ipnet_slice.go new file mode 100644 index 000000000..6b541aa87 --- /dev/null +++ b/vendor/github.com/spf13/pflag/ipnet_slice.go @@ -0,0 +1,147 @@ +package pflag + +import ( +	"fmt" +	"io" +	"net" +	"strings" +) + +// -- ipNetSlice Value +type ipNetSliceValue struct { +	value   *[]net.IPNet +	changed bool +} + +func newIPNetSliceValue(val []net.IPNet, p *[]net.IPNet) *ipNetSliceValue { +	ipnsv := new(ipNetSliceValue) +	ipnsv.value = p +	*ipnsv.value = val +	return ipnsv +} + +// Set converts, and assigns, the comma-separated IPNet argument string representation as the []net.IPNet value of this flag. +// If Set is called on a flag that already has a []net.IPNet assigned, the newly converted values will be appended. +func (s *ipNetSliceValue) Set(val string) error { + +	// remove all quote characters +	rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "") + +	// read flag arguments with CSV parser +	ipNetStrSlice, err := readAsCSV(rmQuote.Replace(val)) +	if err != nil && err != io.EOF { +		return err +	} + +	// parse ip values into slice +	out := make([]net.IPNet, 0, len(ipNetStrSlice)) +	for _, ipNetStr := range ipNetStrSlice { +		_, n, err := net.ParseCIDR(strings.TrimSpace(ipNetStr)) +		if err != nil { +			return fmt.Errorf("invalid string being converted to CIDR: %s", ipNetStr) +		} +		out = append(out, *n) +	} + +	if !s.changed { +		*s.value = out +	} else { +		*s.value = append(*s.value, out...) +	} + +	s.changed = true + +	return nil +} + +// Type returns a string that uniquely represents this flag's type. +func (s *ipNetSliceValue) Type() string { +	return "ipNetSlice" +} + +// String defines a "native" format for this net.IPNet slice flag value. +func (s *ipNetSliceValue) String() string { + +	ipNetStrSlice := make([]string, len(*s.value)) +	for i, n := range *s.value { +		ipNetStrSlice[i] = n.String() +	} + +	out, _ := writeAsCSV(ipNetStrSlice) +	return "[" + out + "]" +} + +func ipNetSliceConv(val string) (interface{}, error) { +	val = strings.Trim(val, "[]") +	// Emtpy string would cause a slice with one (empty) entry +	if len(val) == 0 { +		return []net.IPNet{}, nil +	} +	ss := strings.Split(val, ",") +	out := make([]net.IPNet, len(ss)) +	for i, sval := range ss { +		_, n, err := net.ParseCIDR(strings.TrimSpace(sval)) +		if err != nil { +			return nil, fmt.Errorf("invalid string being converted to CIDR: %s", sval) +		} +		out[i] = *n +	} +	return out, nil +} + +// GetIPNetSlice returns the []net.IPNet value of a flag with the given name +func (f *FlagSet) GetIPNetSlice(name string) ([]net.IPNet, error) { +	val, err := f.getFlagType(name, "ipNetSlice", ipNetSliceConv) +	if err != nil { +		return []net.IPNet{}, err +	} +	return val.([]net.IPNet), nil +} + +// IPNetSliceVar defines a ipNetSlice flag with specified name, default value, and usage string. +// The argument p points to a []net.IPNet variable in which to store the value of the flag. +func (f *FlagSet) IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { +	f.VarP(newIPNetSliceValue(value, p), name, "", usage) +} + +// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { +	f.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) +} + +// IPNetSliceVar defines a []net.IPNet flag with specified name, default value, and usage string. +// The argument p points to a []net.IPNet variable in which to store the value of the flag. +func IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { +	CommandLine.VarP(newIPNetSliceValue(value, p), name, "", usage) +} + +// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. +func IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { +	CommandLine.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) +} + +// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. +// The return value is the address of a []net.IPNet variable that stores the value of that flag. +func (f *FlagSet) IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { +	p := []net.IPNet{} +	f.IPNetSliceVarP(&p, name, "", value, usage) +	return &p +} + +// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { +	p := []net.IPNet{} +	f.IPNetSliceVarP(&p, name, shorthand, value, usage) +	return &p +} + +// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. +// The return value is the address of a []net.IP variable that stores the value of the flag. +func IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { +	return CommandLine.IPNetSliceP(name, "", value, usage) +} + +// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. +func IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { +	return CommandLine.IPNetSliceP(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/pflag/string_array.go b/vendor/github.com/spf13/pflag/string_array.go index 4894af818..d1ff0a96b 100644 --- a/vendor/github.com/spf13/pflag/string_array.go +++ b/vendor/github.com/spf13/pflag/string_array.go @@ -31,11 +31,7 @@ func (s *stringArrayValue) Append(val string) error {  func (s *stringArrayValue) Replace(val []string) error {  	out := make([]string, len(val))  	for i, d := range val { -		var err error  		out[i] = d -		if err != nil { -			return err -		}  	}  	*s.value = out  	return nil diff --git a/vendor/modules.txt b/vendor/modules.txt index dcd2faff7..4df510c7f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -601,10 +601,10 @@ github.com/spf13/afero/mem  # github.com/spf13/cast v1.6.0  ## explicit; go 1.19  github.com/spf13/cast -# github.com/spf13/cobra v1.8.1 +# github.com/spf13/cobra v1.9.1  ## explicit; go 1.15  github.com/spf13/cobra -# github.com/spf13/pflag v1.0.5 +# github.com/spf13/pflag v1.0.6  ## explicit; go 1.12  github.com/spf13/pflag  # github.com/spf13/viper v1.19.0  | 
