From 5a138f143f25d616c6c195356a6560ed4fbbfdd4 Mon Sep 17 00:00:00 2001 From: Leonhard Stemplinger <42673430+lstemplinger@users.noreply.github.com> Date: Mon, 4 Nov 2024 01:45:01 +0100 Subject: [PATCH 1/7] Make Powershell completion script work in constrained mode (#2196) Creating CompletionResult objects is not allowed in Powershell constrained mode, so return results as strings if constrained mode is enabled Store results as PsCustomObjects instead of hashtables. This prevents Sort-Object from trying to convert the hashtable to a object, which is blocked in constrained mode. PsCustomObjects are created using New-Object to work around https://github.com/PowerShell/PowerShell/issues/20767 --- powershell_completions.go | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/powershell_completions.go b/powershell_completions.go index a830b7b..746dcb9 100644 --- a/powershell_completions.go +++ b/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 + } } } From 02326d52c0704d79169819698693b0698e748f55 Mon Sep 17 00:00:00 2001 From: Vui Lam Date: Tue, 5 Nov 2024 03:19:24 -0800 Subject: [PATCH 2/7] Fix broken links in active_help.md (#2202) Small change to fix a couple of broken links in active_help.md Signed-off-by: Vui Lam --- site/content/active_help.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/active_help.md b/site/content/active_help.md index 1b02c70..ae6d723 100644 --- a/site/content/active_help.md +++ b/site/content/active_help.md @@ -20,12 +20,12 @@ bin/ internal/ scripts/ pkg/ testdata/ ## Supported shells Active Help is currently only supported for the following shells: -- Bash (using [bash completion V2](shell_completions.md#bash-completion-v2) only). Note that bash 4.4 or higher is required for the prompt to appear when an Active Help message is printed. +- Bash (using [bash completion V2](completions/_index.md#bash-completion-v2) only). Note that bash 4.4 or higher is required for the prompt to appear when an Active Help message is printed. - Zsh ## Adding Active Help messages -As Active Help uses the shell completion system, the implementation of Active Help messages is done by enhancing custom dynamic completions. If you are not familiar with dynamic completions, please refer to [Shell Completions](shell_completions.md). +As Active Help uses the shell completion system, the implementation of Active Help messages is done by enhancing custom dynamic completions. If you are not familiar with dynamic completions, please refer to [Shell Completions](completions/_index.md). Adding Active Help is done through the use of the `cobra.AppendActiveHelp(...)` function, where the program repeatedly adds Active Help messages to the list of completions. Keep reading for details. @@ -148,7 +148,7 @@ details for your users. ## Debugging Active Help -Debugging your Active Help code is done in the same way as debugging your dynamic completion code, which is with Cobra's hidden `__complete` command. Please refer to [debugging shell completion](shell_completions.md#debugging) for details. +Debugging your Active Help code is done in the same way as debugging your dynamic completion code, which is with Cobra's hidden `__complete` command. Please refer to [debugging shell completion](completions/_index.md#debugging) for details. When debugging with the `__complete` command, if you want to specify different Active Help configurations, you should use the active help environment variable. That variable is named `_ACTIVE_HELP` where any non-ASCII-alphanumeric characters are replaced by an `_`. For example, we can test deactivating some Active Help as shown below: From 85196307501d10f7723712ca0b81e37a1c2e7bf8 Mon Sep 17 00:00:00 2001 From: Mikel Olasagasti Uranga Date: Wed, 11 Dec 2024 13:26:08 +0100 Subject: [PATCH 3/7] Update to latest go-md2man (#2201) Since cpuguy83/go-md2man 2.0.5 no paraTag is written after "SEE ALSO". With go-md2man 2.0.4: .SH SEE ALSO .PP \fBroot-bbb(1)\fP, \fBroot-ccc(1)\fP With go-md2man 2.0.5: .SH SEE ALSO \fBroot-bbb(1)\fP, \fBroot-ccc(1)\fP See: https://github.com/cpuguy83/go-md2man/pull/122 Signed-off-by: Mikel Olasagasti Uranga --- doc/man_docs_test.go | 3 --- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/man_docs_test.go b/doc/man_docs_test.go index dfa5e16..ae6c8e5 100644 --- a/doc/man_docs_test.go +++ b/doc/man_docs_test.go @@ -141,9 +141,6 @@ func TestGenManSeeAlso(t *testing.T) { if err := assertLineFound(scanner, ".SH SEE ALSO"); err != nil { t.Fatalf("Couldn't find SEE ALSO section header: %v", err) } - if err := assertNextLineEquals(scanner, ".PP"); err != nil { - t.Fatalf("First line after SEE ALSO wasn't break-indent: %v", err) - } if err := assertNextLineEquals(scanner, `\fBroot-bbb(1)\fP, \fBroot-ccc(1)\fP`); err != nil { t.Fatalf("Second line after SEE ALSO wasn't correct: %v", err) } diff --git a/go.mod b/go.mod index 8c80da0..7f4c761 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/spf13/cobra go 1.15 require ( - github.com/cpuguy83/go-md2man/v2 v2.0.4 + github.com/cpuguy83/go-md2man/v2 v2.0.5 github.com/inconshreveable/mousetrap v1.1.0 github.com/spf13/pflag v1.0.5 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index ab40b43..324e3f0 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= From 9f9056765ccb3bfb1c72a560b4c6edbff71c0f32 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 17 Dec 2024 03:26:34 +0100 Subject: [PATCH 4/7] build(deps): bump github.com/cpuguy83/go-md2man/v2 from 2.0.5 to 2.0.6 (#2206) fix compatibility with go versions before go1.17 diff: https://github.com/cpuguy83/go-md2man/compare/v2.0.5...v2.0.6 Signed-off-by: Sebastiaan van Stijn --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7f4c761..3959690 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/spf13/cobra go 1.15 require ( - github.com/cpuguy83/go-md2man/v2 v2.0.5 + github.com/cpuguy83/go-md2man/v2 v2.0.6 github.com/inconshreveable/mousetrap v1.1.0 github.com/spf13/pflag v1.0.5 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 324e3f0..1be8028 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= -github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= From d1e9d85fcf592461f3bc2f4b6d5e140c4c0aabf8 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 28 Dec 2024 23:07:03 +0100 Subject: [PATCH 5/7] Make detection for test-binary more universal (#2173) When running tests in verbose mode (or other options), tests involving Cobra may fail if the test does not explicitly set Command.args to an empty slice; in this case, Cobra defaults to using `os.Args`, which will contain arguments passed to the test (such as `-v` (verbose)). Commits e5762054c9a6429fa7c234897707d and 1ef0913976db2004980575ed815c3 implemented a workaround for this when running (unit) tests for Cobra itself, but this check is specifig to Cobra (checking for `cobra.test`), and don't work on Windows (which will have a `.exe` extension), This patch implements a more universal check, so that users of Cobra as a module also benefit from this workaround. go1.21 and up provides a `testing.Testing()` utility ([1]); as the Cobra module still supports Go1.16 and up, an alternative implementation was added for older versions, based on golang.org/x/mod/lazyregexp [2]. Before this patch: go test -c -o foo.test ./foo.test -test.run TestNoArgs --- FAIL: TestNoArgs (0.00s) args_test.go:37: Unexpected output: Error: unknown command "TestNoArgs" for "c" Usage: c [flags] Flags: -h, --help help for c args_test.go:40: Unexpected error: unknown command "TestNoArgs" for "c" FAIL After this patch: go test -c -o foo.test ./foo.test -test.run TestNoArgs PASS [1]: https://pkg.go.dev/testing#Testing [2]: https://cs.opensource.google/go/x/mod/+/refs/tags/v0.19.0:internal/lazyregexp/lazyre.go;l=66-78 Signed-off-by: Sebastiaan van Stijn Signed-off-by: Marc Khouzam Co-authored-by: Marc Khouzam --- command.go | 8 +++++--- command_go120.go | 33 +++++++++++++++++++++++++++++++++ command_go121.go | 25 +++++++++++++++++++++++++ command_test.go | 13 +++++++++++++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 command_go120.go create mode 100644 command_go121.go diff --git a/command.go b/command.go index 4cd712b..1960294 100644 --- a/command.go +++ b/command.go @@ -23,7 +23,6 @@ import ( "fmt" "io" "os" - "path/filepath" "sort" "strings" @@ -1078,8 +1077,11 @@ func (c *Command) ExecuteC() (cmd *Command, err error) { args := c.args - // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155 - if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" { + // If running unit tests, we don't want to take the os.Args, see #155 and #2173. + // For example, the following would fail: + // go test -c -o foo.test + // ./foo.test -test.run TestNoArgs + if c.args == nil && !isTesting() { args = os.Args[1:] } diff --git a/command_go120.go b/command_go120.go new file mode 100644 index 0000000..23bc0fe --- /dev/null +++ b/command_go120.go @@ -0,0 +1,33 @@ +// Copyright 2013-2024 The Cobra Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !go1.21 +// +build !go1.21 + +package cobra + +import ( + "os" + "strings" +) + +// based on golang.org/x/mod/internal/lazyregexp: https://cs.opensource.google/go/x/mod/+/refs/tags/v0.19.0:internal/lazyregexp/lazyre.go;l=66 +// For a non-go-test program which still has a name ending with ".test[.exe]", it will need to either: +// 1- Use go >= 1.21, or +// 2- call "rootCmd.SetArgs(os.Args[1:])" before calling "rootCmd.Execute()" +var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") + +func isTesting() bool { + return inTest +} diff --git a/command_go121.go b/command_go121.go new file mode 100644 index 0000000..8b69f15 --- /dev/null +++ b/command_go121.go @@ -0,0 +1,25 @@ +// Copyright 2013-2024 The Cobra Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build go1.21 +// +build go1.21 + +package cobra + +import "testing" + +func isTesting() bool { + // Only available starting with go 1.21 + return testing.Testing() +} diff --git a/command_test.go b/command_test.go index cd44992..9d5066c 100644 --- a/command_test.go +++ b/command_test.go @@ -2839,3 +2839,16 @@ func TestUnknownFlagShouldReturnSameErrorRegardlessOfArgPosition(t *testing.T) { }) } } + +// This tests verifies that when running unit tests, os.Args are not used. +// This is because we don't want to process any arguments that are provided +// by "go test"; instead, unit tests must set the arguments they need using +// rootCmd.SetArgs(). +func TestNoOSArgsWhenTesting(t *testing.T) { + root := &Command{Use: "root", Run: emptyRun} + os.Args = append(os.Args, "--unknown") + + if _, err := root.ExecuteC(); err != nil { + t.Errorf("error: %v", err) + } +} From 0745e5576205cd05fada5bb2e01500d97e1a04be Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 28 Dec 2024 23:41:43 +0100 Subject: [PATCH 6/7] completion: improve detection for flags that accept multiple values (#2210) The completion code attempts to detect whether a flag can be specified more than once, and therefore should provide completion even if already set. Currently, this code depends on conventions used in the pflag package, which uses an "Array" or "Slice" suffix or for some types a "stringTo" prefix. Cobra allows custom value types to be used, which may not use the same convention for naming, and therefore currently aren't detected to allow multiple values. The pflag module defines a [SliceValue] interface, which is implemented by the Slice and Array value types it provides (unfortunately, it's not currently implemented by the "stringTo" values). This patch adds a reduced interface based on the [SliceValue] interface mentioned above to allow detecting Value-types that accept multiple values. Custom types can implement this interface to make completion work for those values. I deliberately used a reduced interface to keep the requirements for this detection as low as possible, without enforcing the other methods defined in the interface (Append, Replace) which may not apply to all custom types. Future improvements can likely still be made, considering either implementing the SliceValue interface for the "stringTo" values or defining a separate "MapValue" interface for those types. Possibly providing the reduced interface as part of the pflag module and to export it. [SliceValue]: https://github.com/spf13/pflag/blob/d5e0c0615acee7028e1e2740a11102313be88de1/flag.go#L193-L203 Signed-off-by: Sebastiaan van Stijn Signed-off-by: Marc Khouzam Co-authored-by: Marc Khouzam --- completions.go | 15 +++++++++++++-- completions_test.go | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/completions.go b/completions.go index 8fccdaf..0862d3f 100644 --- a/completions.go +++ b/completions.go @@ -270,6 +270,14 @@ func (c *Command) initCompleteCmd(args []string) { } } +// 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, []string, ShellCompDirective, error) { // The last argument, which is not completely typed by the user, // should not be part of the list of arguments @@ -399,10 +407,13 @@ 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") || - strings.HasPrefix(flag.Value.Type(), "stringTo") { + 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)...) diff --git a/completions_test.go b/completions_test.go index df153fc..a8f378e 100644 --- a/completions_test.go +++ b/completions_test.go @@ -671,6 +671,29 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { } } +// customMultiString is a custom Value type that accepts multiple values, +// but does not include "Slice" or "Array" in its "Type" string. +type customMultiString []string + +var _ SliceValue = (*customMultiString)(nil) + +func (s *customMultiString) String() string { + return fmt.Sprintf("%v", *s) +} + +func (s *customMultiString) Set(v string) error { + *s = append(*s, v) + return nil +} + +func (s *customMultiString) Type() string { + return "multi string" +} + +func (s *customMultiString) GetSlice() []string { + return *s +} + func TestFlagNameCompletionRepeat(t *testing.T) { rootCmd := &Command{ Use: "root", @@ -693,6 +716,8 @@ func TestFlagNameCompletionRepeat(t *testing.T) { sliceFlag := rootCmd.Flags().Lookup("slice") rootCmd.Flags().BoolSliceP("bslice", "b", nil, "bool slice flag") bsliceFlag := rootCmd.Flags().Lookup("bslice") + rootCmd.Flags().VarP(&customMultiString{}, "multi", "m", "multi string flag") + multiFlag := rootCmd.Flags().Lookup("multi") // Test that flag names are not repeated unless they are an array or slice output, err := executeCommand(rootCmd, ShellCompNoDescRequestCmd, "--first", "1", "--") @@ -706,6 +731,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--array", "--bslice", "--help", + "--multi", "--second", "--slice", ":4", @@ -728,6 +754,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--array", "--bslice", "--help", + "--multi", "--slice", ":4", "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") @@ -737,7 +764,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { } // Test that flag names are not repeated unless they are an array or slice - output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "--slice", "1", "--slice=2", "--array", "val", "--bslice", "true", "--") + output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "--slice", "1", "--slice=2", "--array", "val", "--bslice", "true", "--multi", "val", "--") if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -745,12 +772,14 @@ func TestFlagNameCompletionRepeat(t *testing.T) { sliceFlag.Changed = false arrayFlag.Changed = false bsliceFlag.Changed = false + multiFlag.Changed = false expected = strings.Join([]string{ "--array", "--bslice", "--first", "--help", + "--multi", "--second", "--slice", ":4", @@ -768,6 +797,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { // Reset the flag for the next command sliceFlag.Changed = false arrayFlag.Changed = false + multiFlag.Changed = false expected = strings.Join([]string{ "--array", @@ -778,6 +808,8 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "-f", "--help", "-h", + "--multi", + "-m", "--second", "-s", "--slice", @@ -797,6 +829,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { // Reset the flag for the next command sliceFlag.Changed = false arrayFlag.Changed = false + multiFlag.Changed = false expected = strings.Join([]string{ "-a", From 01ffff4eca5a08384ef2b85f39ec0dac192a5f7b Mon Sep 17 00:00:00 2001 From: ZhuHaiCheng Date: Sun, 12 Jan 2025 20:49:28 +0800 Subject: [PATCH 7/7] chore: fix function name in comment (#2216) Signed-off-by: zhuhaicity --- command_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command_test.go b/command_test.go index 9d5066c..837b6b3 100644 --- a/command_test.go +++ b/command_test.go @@ -390,7 +390,7 @@ func TestPlugin(t *testing.T) { checkStringContains(t, cmdHelp, "version for kubectl plugin") } -// TestPlugin checks usage as plugin with sub commands. +// TestPluginWithSubCommands checks usage as plugin with sub commands. func TestPluginWithSubCommands(t *testing.T) { rootCmd := &Command{ Use: "kubectl-plugin",