Fix completion of resource names

The output format is now used by the `Complete()` function, so it must
be set before invoking said function.

The commit also adds a unit tests for this scenario.

Signed-off-by: Marc Khouzam <marc.khouzam@gmail.com>

Kubernetes-commit: f3d278e75d1137f1c91dde7415bc577af3c3be82
This commit is contained in:
Marc Khouzam 2025-08-28 21:06:02 -07:00 committed by Kubernetes Publisher
parent 48317edcc3
commit 4dec168032
2 changed files with 97 additions and 2 deletions

View File

@ -319,14 +319,14 @@ func compGetResourceList(restClientGetter genericclioptions.RESTClientGetter, cm
streams := genericiooptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: io.Discard} streams := genericiooptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: io.Discard}
o := apiresources.NewAPIResourceOptions(streams) o := apiresources.NewAPIResourceOptions(streams)
o.Complete(restClientGetter, cmd, nil)
// Get the list of resources // Get the list of resources
o.PrintFlags.OutputFormat = ptr.To("name") o.PrintFlags.OutputFormat = ptr.To("name")
o.Cached = true o.Cached = true
o.Verbs = []string{"get"} o.Verbs = []string{"get"}
// TODO:Should set --request-timeout=5s // TODO:Should set --request-timeout=5s
o.Complete(restClientGetter, cmd, nil)
// Ignore errors as the output may still be valid // Ignore errors as the output may still be valid
o.RunAPIResources() o.RunAPIResources()

View File

@ -492,6 +492,101 @@ func TestResourceAndPortCompletionFunc(t *testing.T) {
} }
} }
func TestResourceTypeAndNameCompletionFuncResourceList(t *testing.T) {
// Set up a fake discovery client with some API resources
dc := cmdtesting.NewFakeCachedDiscoveryClient()
dc.PreferredResources = []*metav1.APIResourceList{
{
GroupVersion: "v1",
APIResources: []metav1.APIResource{
{
Name: "pods",
Namespaced: true,
Kind: "Pod",
Verbs: []string{"get", "list"},
},
{
Name: "services",
Namespaced: true,
Kind: "Service",
Verbs: []string{"get", "list"},
},
{
Name: "secrets",
Namespaced: true,
Kind: "Secret",
Verbs: []string{"get", "list"},
},
},
},
{
GroupVersion: "apps/v1",
APIResources: []metav1.APIResource{
{
Name: "deployments",
Namespaced: true,
Kind: "Deployment",
Verbs: []string{"get", "list"},
},
},
},
}
testCases := []struct {
name string
args []string
toComplete string
expectedComps []string
expectedDirective cobra.ShellCompDirective
}{
{
name: "complete resources starting with 's'",
args: []string{},
toComplete: "s",
expectedComps: []string{"secrets", "services"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "complete resources starting with 'p'",
args: []string{},
toComplete: "p",
expectedComps: []string{"pods"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "complete resources starting with 'd'",
args: []string{},
toComplete: "d",
expectedComps: []string{"deployments.apps"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "complete all resources with empty string",
args: []string{},
toComplete: "",
expectedComps: []string{"deployments.apps", "pods", "secrets", "services"},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
{
name: "no matches",
args: []string{},
toComplete: "xyz",
expectedComps: []string{},
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tf, cmd := prepareCompletionTest()
tf.WithDiscoveryClient(dc)
compFunc := ResourceTypeAndNameCompletionFunc(tf)
comps, directive := compFunc(cmd, tc.args, tc.toComplete)
checkCompletion(t, comps, tc.expectedComps, directive, tc.expectedDirective)
})
}
}
func setMockFactory(config api.Config) { func setMockFactory(config api.Config) {
clientConfig := clientcmd.NewDefaultClientConfig(config, nil) clientConfig := clientcmd.NewDefaultClientConfig(config, nil)
testFactory := cmdtesting.NewTestFactory().WithClientConfig(clientConfig) testFactory := cmdtesting.NewTestFactory().WithClientConfig(clientConfig)