|
| 1 | +package completion |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "strings" |
| 6 | + |
| 7 | + "github.com/spf13/cobra" |
| 8 | + |
| 9 | + cmdutil "k8s.io/kubectl/pkg/cmd/util" |
| 10 | + "k8s.io/kubectl/pkg/util/completion" |
| 11 | + |
| 12 | + "github.com/ray-project/kuberay/kubectl-plugin/pkg/util" |
| 13 | +) |
| 14 | + |
| 15 | +// RayResourceTypeCompletionFunc Returns a completion function that completes the Ray resource type. |
| 16 | +// That is, raycluster, rayjob, or rayservice. |
| 17 | +func RayResourceTypeCompletionFunc() func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) { |
| 18 | + return func(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) { |
| 19 | + var comps []string |
| 20 | + directive := cobra.ShellCompDirectiveNoFileComp |
| 21 | + resourceTypes := getAllRayResourceType() |
| 22 | + for _, resourceType := range resourceTypes { |
| 23 | + if strings.HasPrefix(resourceType, toComplete) { |
| 24 | + comps = append(comps, resourceType) |
| 25 | + } |
| 26 | + } |
| 27 | + return comps, directive |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +// RayClusterCompletionFunc Returns a completion function that completes RayCluster resource names. |
| 32 | +func RayClusterCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) { |
| 33 | + return completion.ResourceNameCompletionFunc(f, string(util.RayCluster)) |
| 34 | +} |
| 35 | + |
| 36 | +// RayJobCompletionFunc Returns a completion function that completes RayJob resource names. |
| 37 | +func RayJobCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) { |
| 38 | + return completion.ResourceNameCompletionFunc(f, string(util.RayJob)) |
| 39 | +} |
| 40 | + |
| 41 | +// RayServiceCompletionFunc Returns a completion function that completes RayService resource names. |
| 42 | +func RayServiceCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) { |
| 43 | + return completion.ResourceNameCompletionFunc(f, string(util.RayService)) |
| 44 | +} |
| 45 | + |
| 46 | +// RayClusterResourceNameCompletionFunc Returns completions of: |
| 47 | +// 1- RayCluster names that match the toComplete prefix |
| 48 | +// 2- Ray resource types which match the toComplete prefix |
| 49 | +func RayClusterResourceNameCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) { |
| 50 | + return func(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { |
| 51 | + var comps []string |
| 52 | + directive := cobra.ShellCompDirectiveNoFileComp |
| 53 | + if len(args) == 0 { |
| 54 | + comps, directive = doRayClusterCompletion(f, toComplete) |
| 55 | + } |
| 56 | + return comps, directive |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +func getAllRayResourceType() []string { |
| 61 | + return []string{ |
| 62 | + string(util.RayCluster), |
| 63 | + string(util.RayJob), |
| 64 | + string(util.RayService), |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +// doRayClusterCompletion Returns completions of: |
| 69 | +// 1- RayCluster names that match the toComplete prefix |
| 70 | +// 2- Ray resource types which match the toComplete prefix |
| 71 | +// Ref: https://github.com/kubernetes/kubectl/blob/262825a8a665c7cae467dfaa42b63be5a5b8e5a2/pkg/util/completion/completion.go#L434 |
| 72 | +func doRayClusterCompletion(f cmdutil.Factory, toComplete string) ([]string, cobra.ShellCompDirective) { |
| 73 | + var comps []string |
| 74 | + directive := cobra.ShellCompDirectiveNoFileComp |
| 75 | + slashIdx := strings.Index(toComplete, "/") |
| 76 | + if slashIdx == -1 { |
| 77 | + // Standard case, complete RayCluster names |
| 78 | + comps = completion.CompGetResource(f, string(util.RayCluster), toComplete) |
| 79 | + |
| 80 | + // Also include resource choices for the <type>/<name> form |
| 81 | + resourceTypes := getAllRayResourceType() |
| 82 | + |
| 83 | + if len(comps) == 0 { |
| 84 | + // If there are no RayCluster to complete, we will only be completing |
| 85 | + // <type>/. We should disable adding a space after the /. |
| 86 | + directive |= cobra.ShellCompDirectiveNoSpace |
| 87 | + } |
| 88 | + |
| 89 | + for _, resource := range resourceTypes { |
| 90 | + if strings.HasPrefix(resource, toComplete) { |
| 91 | + comps = append(comps, fmt.Sprintf("%s/", resource)) |
| 92 | + } |
| 93 | + } |
| 94 | + } else { |
| 95 | + // Dealing with the <type>/<name> form, use the specified resource type |
| 96 | + resourceType := toComplete[:slashIdx] |
| 97 | + toComplete = toComplete[slashIdx+1:] |
| 98 | + nameComps := completion.CompGetResource(f, resourceType, toComplete) |
| 99 | + for _, c := range nameComps { |
| 100 | + comps = append(comps, fmt.Sprintf("%s/%s", resourceType, c)) |
| 101 | + } |
| 102 | + } |
| 103 | + return comps, directive |
| 104 | +} |
0 commit comments