summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2025-02-17 11:43:32 +0000
committerLibravatar GitHub <noreply@github.com>2025-02-17 11:43:32 +0000
commitc73497b58ca6e9cf085b91649ccf12c8389baf5c (patch)
tree9e3e4537a6648e1f3009f76a7483a009cc3e58ff
parent[chore]: Bump golang.org/x/net from 0.34.0 to 0.35.0 (#3804) (diff)
downloadgotosocial-c73497b58ca6e9cf085b91649ccf12c8389baf5c.tar.xz
[chore]: Bump github.com/spf13/cobra from 1.8.1 to 1.9.1 (#3805)
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.1 to 1.9.1. - [Release notes](https://github.com/spf13/cobra/releases) - [Commits](https://github.com/spf13/cobra/compare/v1.8.1...v1.9.1) --- updated-dependencies: - dependency-name: github.com/spf13/cobra dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
-rw-r--r--go.mod4
-rw-r--r--go.sum10
-rw-r--r--vendor/github.com/spf13/cobra/README.md5
-rw-r--r--vendor/github.com/spf13/cobra/active_help.go2
-rw-r--r--vendor/github.com/spf13/cobra/bash_completionsV2.go152
-rw-r--r--vendor/github.com/spf13/cobra/cobra.go16
-rw-r--r--vendor/github.com/spf13/cobra/command.go331
-rw-r--r--vendor/github.com/spf13/cobra/completions.go126
-rw-r--r--vendor/github.com/spf13/cobra/powershell_completions.go35
-rw-r--r--vendor/github.com/spf13/pflag/.editorconfig12
-rw-r--r--vendor/github.com/spf13/pflag/.golangci.yaml4
-rw-r--r--vendor/github.com/spf13/pflag/flag.go29
-rw-r--r--vendor/github.com/spf13/pflag/ip.go3
-rw-r--r--vendor/github.com/spf13/pflag/ipnet_slice.go147
-rw-r--r--vendor/github.com/spf13/pflag/string_array.go4
-rw-r--r--vendor/modules.txt4
16 files changed, 704 insertions, 180 deletions
diff --git a/go.mod b/go.mod
index 80437e475..a016b955f 100644
--- a/go.mod
+++ b/go.mod
@@ -52,7 +52,7 @@ require (
github.com/oklog/ulid v1.3.1
github.com/prometheus/client_golang v1.20.5
github.com/rivo/uniseg v0.4.7
- github.com/spf13/cobra v1.8.1
+ github.com/spf13/cobra v1.9.1
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
github.com/superseriousbusiness/activity v1.10.0-gts
@@ -194,7 +194,7 @@ require (
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
+ github.com/spf13/pflag v1.0.6 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect
github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB // indirect
diff --git a/go.sum b/go.sum
index 25deb3c20..451d3b1be 100644
--- a/go.sum
+++ b/go.sum
@@ -125,7 +125,7 @@ github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdk
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4=
github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -497,10 +497,10 @@ github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNo
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
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 logo](assets/CobraMain.png)
+
+![cobra logo](https://github.com/user-attachments/assets/cbc3adf8-0dff-46e9-a88d-5e2d971c169e)
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