cmd/get: Remove cmd argument from Run()
Removes the need to pass cmd as an argument to Run(). This change required reading the --sort-by flag in Complete() in a way similar to other flags. This change allows the cobra.Command not to need to be passed throughout the completion code, which I updated as part of this commit. It also is a step in the direction of the TODO comment requesting the removal of arguments passed to Run() and watch(). Kubernetes-commit: aa7a828f20b479a8a943d897224e8e76c3bb6cff
This commit is contained in:
parent
d3f76f431e
commit
a2ae001d8e
|
@ -538,7 +538,7 @@ func registerCompletionFuncForGlobalFlags(cmd *cobra.Command, f cmdutil.Factory)
|
|||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||
"namespace",
|
||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return utilcomp.CompGetResource(f, cmd, "namespace", toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||
return utilcomp.CompGetResource(f, "namespace", toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||
}))
|
||||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||
"context",
|
||||
|
|
|
@ -109,14 +109,14 @@ func NewCmdCp(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.C
|
|||
// complete <namespace>/<pod>
|
||||
namespace := toComplete[:idx]
|
||||
template := "{{ range .items }}{{ .metadata.namespace }}/{{ .metadata.name }}: {{ end }}"
|
||||
comps = completion.CompGetFromTemplate(&template, f, namespace, cmd, []string{"pod"}, toComplete)
|
||||
comps = completion.CompGetFromTemplate(&template, f, namespace, []string{"pod"}, toComplete)
|
||||
} else {
|
||||
// Complete namespaces followed by a /
|
||||
for _, ns := range completion.CompGetResource(f, cmd, "namespace", toComplete) {
|
||||
for _, ns := range completion.CompGetResource(f, "namespace", toComplete) {
|
||||
comps = append(comps, fmt.Sprintf("%s/", ns))
|
||||
}
|
||||
// Complete pod names followed by a :
|
||||
for _, pod := range completion.CompGetResource(f, cmd, "pod", toComplete) {
|
||||
for _, pod := range completion.CompGetResource(f, "pod", toComplete) {
|
||||
comps = append(comps, fmt.Sprintf("%s:", pod))
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptio
|
|||
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||
"clusterrole",
|
||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return completion.CompGetResource(f, cmd, "clusterrole", toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||
return completion.CompGetResource(f, "clusterrole", toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||
}))
|
||||
|
||||
return cmd
|
||||
|
|
|
@ -75,11 +75,11 @@ type GetOptions struct {
|
|||
Namespace string
|
||||
ExplicitNamespace bool
|
||||
Subresource string
|
||||
SortBy string
|
||||
|
||||
ServerPrint bool
|
||||
|
||||
NoHeaders bool
|
||||
Sort bool
|
||||
IgnoreNotFound bool
|
||||
|
||||
genericclioptions.IOStreams
|
||||
|
@ -168,7 +168,7 @@ func NewCmdGet(parent string, f cmdutil.Factory, streams genericclioptions.IOStr
|
|||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
cmdutil.CheckErr(o.Run(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Run(f, args))
|
||||
},
|
||||
SuggestFor: []string{"list", "ps"},
|
||||
}
|
||||
|
@ -208,11 +208,9 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
|
|||
o.ExplicitNamespace = false
|
||||
}
|
||||
|
||||
sortBy, err := cmd.Flags().GetString("sort-by")
|
||||
if err != nil {
|
||||
return err
|
||||
if o.PrintFlags.HumanReadableFlags.SortBy != nil {
|
||||
o.SortBy = *o.PrintFlags.HumanReadableFlags.SortBy
|
||||
}
|
||||
o.Sort = len(sortBy) > 0
|
||||
|
||||
o.NoHeaders = cmdutil.GetFlagBool(cmd, "no-headers")
|
||||
|
||||
|
@ -256,8 +254,8 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if o.Sort {
|
||||
printer = &SortingPrinter{Delegate: printer, SortField: sortBy}
|
||||
if len(o.SortBy) > 0 {
|
||||
printer = &SortingPrinter{Delegate: printer, SortField: o.SortBy}
|
||||
}
|
||||
if outputObjects != nil {
|
||||
printer = &skipPrinter{delegate: printer, output: outputObjects}
|
||||
|
@ -270,7 +268,7 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
|
|||
|
||||
switch {
|
||||
case o.Watch || o.WatchOnly:
|
||||
if o.Sort {
|
||||
if len(o.SortBy) > 0 {
|
||||
fmt.Fprintf(o.IOStreams.ErrOut, "warning: --watch or --watch-only requested, --sort-by will be ignored\n")
|
||||
}
|
||||
default:
|
||||
|
@ -431,14 +429,14 @@ func (o *GetOptions) transformRequests(req *rest.Request) {
|
|||
}, ","))
|
||||
|
||||
// if sorting, ensure we receive the full object in order to introspect its fields via jsonpath
|
||||
if o.Sort {
|
||||
if len(o.SortBy) > 0 {
|
||||
req.Param("includeObject", "Object")
|
||||
}
|
||||
}
|
||||
|
||||
// Run performs the get operation.
|
||||
// TODO: remove the need to pass these arguments, like other commands.
|
||||
func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
func (o *GetOptions) Run(f cmdutil.Factory, args []string) error {
|
||||
if len(o.Raw) > 0 {
|
||||
restClient, err := f.RESTClient()
|
||||
if err != nil {
|
||||
|
@ -447,11 +445,11 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
|
|||
return rawhttp.RawGet(restClient, o.IOStreams, o.Raw)
|
||||
}
|
||||
if o.Watch || o.WatchOnly {
|
||||
return o.watch(f, cmd, args)
|
||||
return o.watch(f, args)
|
||||
}
|
||||
|
||||
chunkSize := o.ChunkSize
|
||||
if o.Sort {
|
||||
if len(o.SortBy) > 0 {
|
||||
// TODO(juanvallejo): in the future, we could have the client use chunking
|
||||
// to gather all results, then sort them all at the end to reduce server load.
|
||||
chunkSize = 0
|
||||
|
@ -496,14 +494,9 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
|
|||
objs[ix] = infos[ix].Object
|
||||
}
|
||||
|
||||
sorting, err := cmd.Flags().GetString("sort-by")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var positioner OriginalPositioner
|
||||
if o.Sort {
|
||||
sorter := NewRuntimeSorter(objs, sorting)
|
||||
if len(o.SortBy) > 0 {
|
||||
sorter := NewRuntimeSorter(objs, o.SortBy)
|
||||
if err := sorter.Sort(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -608,7 +601,7 @@ func (s *separatorWriterWrapper) SetReady(state bool) {
|
|||
|
||||
// watch starts a client-side watch of one or more resources.
|
||||
// TODO: remove the need for arguments here.
|
||||
func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
func (o *GetOptions) watch(f cmdutil.Factory, args []string) error {
|
||||
r := f.NewBuilder().
|
||||
Unstructured().
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().AllNamespaces(o.AllNamespaces).
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/printers"
|
||||
|
@ -69,10 +70,10 @@ func SpecifiedResourceTypeAndNameNoRepeatCompletionFunc(f cmdutil.Factory, allow
|
|||
// that don't support that form. For commands that apply to pods and that support the <type>/<name>
|
||||
// form, please use PodResourceNameCompletionFunc()
|
||||
func ResourceNameCompletionFunc(f cmdutil.Factory, resourceType string) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
var comps []string
|
||||
if len(args) == 0 {
|
||||
comps = CompGetResource(f, cmd, resourceType, toComplete)
|
||||
comps = CompGetResource(f, resourceType, toComplete)
|
||||
}
|
||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
@ -82,11 +83,11 @@ func ResourceNameCompletionFunc(f cmdutil.Factory, resourceType string) func(*co
|
|||
// 1- pod names that match the toComplete prefix
|
||||
// 2- resource types containing pods which match the toComplete prefix
|
||||
func PodResourceNameCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
var comps []string
|
||||
directive := cobra.ShellCompDirectiveNoFileComp
|
||||
if len(args) == 0 {
|
||||
comps, directive = doPodResourceCompletion(f, cmd, toComplete)
|
||||
comps, directive = doPodResourceCompletion(f, toComplete)
|
||||
}
|
||||
return comps, directive
|
||||
}
|
||||
|
@ -97,14 +98,14 @@ func PodResourceNameCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []str
|
|||
// 2- resource types containing pods which match the toComplete prefix
|
||||
// and as a second argument the containers within the specified pod.
|
||||
func PodResourceNameAndContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
var comps []string
|
||||
directive := cobra.ShellCompDirectiveNoFileComp
|
||||
if len(args) == 0 {
|
||||
comps, directive = doPodResourceCompletion(f, cmd, toComplete)
|
||||
comps, directive = doPodResourceCompletion(f, toComplete)
|
||||
} else if len(args) == 1 {
|
||||
podName := convertResourceNameToPodName(f, args[0])
|
||||
comps = CompGetContainers(f, cmd, podName, toComplete)
|
||||
comps = CompGetContainers(f, podName, toComplete)
|
||||
}
|
||||
return comps, directive
|
||||
}
|
||||
|
@ -114,13 +115,13 @@ func PodResourceNameAndContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Co
|
|||
// pod specified by the first argument. The resource containing the pod can be specified in
|
||||
// the <type>/<name> form.
|
||||
func ContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
var comps []string
|
||||
// We need the pod name to be able to complete the container names, it must be in args[0].
|
||||
// That first argument can also be of the form <type>/<name> so we need to convert it.
|
||||
if len(args) > 0 {
|
||||
podName := convertResourceNameToPodName(f, args[0])
|
||||
comps = CompGetContainers(f, cmd, podName, toComplete)
|
||||
comps = CompGetContainers(f, podName, toComplete)
|
||||
}
|
||||
return comps, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
@ -128,7 +129,7 @@ func ContainerCompletionFunc(f cmdutil.Factory) func(*cobra.Command, []string, s
|
|||
|
||||
// ContextCompletionFunc is a completion function that completes as a first argument the
|
||||
// context names that match the toComplete prefix
|
||||
func ContextCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
func ContextCompletionFunc(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(args) == 0 {
|
||||
return ListContextsInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
@ -137,7 +138,7 @@ func ContextCompletionFunc(cmd *cobra.Command, args []string, toComplete string)
|
|||
|
||||
// ClusterCompletionFunc is a completion function that completes as a first argument the
|
||||
// cluster names that match the toComplete prefix
|
||||
func ClusterCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
func ClusterCompletionFunc(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(args) == 0 {
|
||||
return ListClustersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
@ -146,7 +147,7 @@ func ClusterCompletionFunc(cmd *cobra.Command, args []string, toComplete string)
|
|||
|
||||
// UserCompletionFunc is a completion function that completes as a first argument the
|
||||
// user names that match the toComplete prefix
|
||||
func UserCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
func UserCompletionFunc(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(args) == 0 {
|
||||
return ListUsersInConfig(toComplete), cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
@ -154,20 +155,20 @@ func UserCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([
|
|||
}
|
||||
|
||||
// CompGetResource gets the list of the resource specified which begin with `toComplete`.
|
||||
func CompGetResource(f cmdutil.Factory, cmd *cobra.Command, resourceName string, toComplete string) []string {
|
||||
func CompGetResource(f cmdutil.Factory, resourceName string, toComplete string) []string {
|
||||
template := "{{ range .items }}{{ .metadata.name }} {{ end }}"
|
||||
return CompGetFromTemplate(&template, f, "", cmd, []string{resourceName}, toComplete)
|
||||
return CompGetFromTemplate(&template, f, "", []string{resourceName}, toComplete)
|
||||
}
|
||||
|
||||
// CompGetContainers gets the list of containers of the specified pod which begin with `toComplete`.
|
||||
func CompGetContainers(f cmdutil.Factory, cmd *cobra.Command, podName string, toComplete string) []string {
|
||||
func CompGetContainers(f cmdutil.Factory, podName string, toComplete string) []string {
|
||||
template := "{{ range .spec.initContainers }}{{ .name }} {{end}}{{ range .spec.containers }}{{ .name }} {{ end }}"
|
||||
return CompGetFromTemplate(&template, f, "", cmd, []string{"pod", podName}, toComplete)
|
||||
return CompGetFromTemplate(&template, f, "", []string{"pod", podName}, toComplete)
|
||||
}
|
||||
|
||||
// CompGetFromTemplate executes a Get operation using the specified template and args and returns the results
|
||||
// which begin with `toComplete`.
|
||||
func CompGetFromTemplate(template *string, f cmdutil.Factory, namespace string, cmd *cobra.Command, args []string, toComplete string) []string {
|
||||
func CompGetFromTemplate(template *string, f cmdutil.Factory, namespace string, args []string, toComplete string) []string {
|
||||
buf := new(bytes.Buffer)
|
||||
streams := genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: io.Discard}
|
||||
o := get.NewGetOptions("kubectl", streams)
|
||||
|
@ -199,7 +200,7 @@ func CompGetFromTemplate(template *string, f cmdutil.Factory, namespace string,
|
|||
return printer.PrintObj, nil
|
||||
}
|
||||
|
||||
o.Run(f, cmd, args)
|
||||
o.Run(f, args)
|
||||
|
||||
var comps []string
|
||||
resources := strings.Split(buf.String(), " ")
|
||||
|
@ -304,7 +305,7 @@ func resourceTypeAndNameCompletionFunc(f cmdutil.Factory, allowedTypes []string,
|
|||
// The first argument is of the form <type> (e.g., pods)
|
||||
// All following arguments should be a resource name.
|
||||
if allowRepeat || len(args) == 1 {
|
||||
comps = CompGetResource(f, cmd, args[0], toComplete)
|
||||
comps = CompGetResource(f, args[0], toComplete)
|
||||
|
||||
// Remove choices already on the command-line
|
||||
if len(args) > 1 {
|
||||
|
@ -356,7 +357,7 @@ func resourceTypeAndNameCompletionFunc(f cmdutil.Factory, allowedTypes []string,
|
|||
if allowRepeat || len(args) == 0 {
|
||||
resourceType := toComplete[:slashIdx]
|
||||
toComplete = toComplete[slashIdx+1:]
|
||||
nameComps := CompGetResource(f, cmd, resourceType, toComplete)
|
||||
nameComps := CompGetResource(f, resourceType, toComplete)
|
||||
for _, c := range nameComps {
|
||||
comps = append(comps, fmt.Sprintf("%s/%s", resourceType, c))
|
||||
}
|
||||
|
@ -375,13 +376,13 @@ func resourceTypeAndNameCompletionFunc(f cmdutil.Factory, allowedTypes []string,
|
|||
// doPodResourceCompletion Returns completions of:
|
||||
// 1- pod names that match the toComplete prefix
|
||||
// 2- resource types containing pods which match the toComplete prefix
|
||||
func doPodResourceCompletion(f cmdutil.Factory, cmd *cobra.Command, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
func doPodResourceCompletion(f cmdutil.Factory, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
var comps []string
|
||||
directive := cobra.ShellCompDirectiveNoFileComp
|
||||
slashIdx := strings.Index(toComplete, "/")
|
||||
if slashIdx == -1 {
|
||||
// Standard case, complete pod names
|
||||
comps = CompGetResource(f, cmd, "pod", toComplete)
|
||||
comps = CompGetResource(f, "pod", toComplete)
|
||||
|
||||
// Also include resource choices for the <type>/<name> form,
|
||||
// but only for resources that contain pods
|
||||
|
@ -410,7 +411,7 @@ func doPodResourceCompletion(f cmdutil.Factory, cmd *cobra.Command, toComplete s
|
|||
// Dealing with the <type>/<name> form, use the specified resource type
|
||||
resourceType := toComplete[:slashIdx]
|
||||
toComplete = toComplete[slashIdx+1:]
|
||||
nameComps := CompGetResource(f, cmd, resourceType, toComplete)
|
||||
nameComps := CompGetResource(f, resourceType, toComplete)
|
||||
for _, c := range nameComps {
|
||||
comps = append(comps, fmt.Sprintf("%s/%s", resourceType, c))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue