Skip to content

Commit

Permalink
feat: Support autocompletion for helm subcommand
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Toh <tohjustin@hotmail.com>
  • Loading branch information
tohjustin committed Oct 21, 2021
1 parent d1317ca commit cb507e1
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
40 changes: 40 additions & 0 deletions pkg/cmd/helm/completion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package helm

import (
"fmt"

"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/action"
)

// Provide dynamic auto-completion for release names.
//
// Based off `compListReleases` from https://github.com/helm/helm/blob/v3.7.0/cmd/helm/list.go#L221-L243
func compGetHelmReleaseList(opts *CmdOptions, toComplete string) []string {
cobra.CompDebugln(fmt.Sprintf("completeHelm with \"%s\"", toComplete), false)
if err := opts.Complete(nil, nil); err != nil {
return nil
}
helmClient := action.NewList(opts.ActionConfig)
helmClient.All = true
helmClient.Limit = 0
helmClient.Filter = fmt.Sprintf("^%s", toComplete)
helmClient.SetStateMask()

var choices []string
releases, err := helmClient.Run()
if err != nil {
cobra.CompErrorln(fmt.Sprintf("Failed to list releases: %s", err))
return nil
}
for _, rel := range releases {
choices = append(choices,
fmt.Sprintf("%s\t%s-%s -> %s", rel.Name, rel.Chart.Metadata.Name, rel.Chart.Metadata.Version, rel.Info.Status.String()))
}
if len(choices) == 0 {
cobra.CompDebugln("No releases found", false)
return nil
}

return choices
}
21 changes: 14 additions & 7 deletions pkg/cmd/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/klog/v2"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util"
"k8s.io/kubectl/pkg/util/templates"

"github.com/tohjustin/kube-lineage/internal/client"
Expand Down Expand Up @@ -73,6 +74,9 @@ func NewCmd(streams genericclioptions.IOStreams, name, parentCmdPath string) *co
IOStreams: streams,
}

f := cmdutil.NewFactory(o.ClientFlags)
util.SetFactoryForCompletion(f)

if len(name) > 0 {
cmdName = name
}
Expand All @@ -95,6 +99,13 @@ func NewCmd(streams genericclioptions.IOStreams, name, parentCmdPath string) *co
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.Run())
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
var comp []string
if len(args) == 0 {
comp = compGetHelmReleaseList(o, toComplete)
}
return comp, cobra.ShellCompDirectiveNoFileComp
},
}

o.Flags.AddFlags(cmd.Flags())
Expand All @@ -108,11 +119,11 @@ func NewCmd(streams genericclioptions.IOStreams, name, parentCmdPath string) *co
// Complete completes all the required options for command.
func (o *CmdOptions) Complete(cmd *cobra.Command, args []string) error {
var err error

//nolint:gocritic
switch len(args) {
case 1:
o.RequestRelease = args[0]
default:
return fmt.Errorf("release name must be specified\nSee '%s -h' for help and examples", cmdPath)
}

// Setup client
Expand Down Expand Up @@ -143,11 +154,7 @@ func (o *CmdOptions) Complete(cmd *cobra.Command, args []string) error {
// Validate validates all the required options for the helm command.
func (o *CmdOptions) Validate() error {
if len(o.RequestRelease) == 0 {
return fmt.Errorf("release NAME must be specified")
}

if o.Client == nil {
return fmt.Errorf("client must be provided")
return fmt.Errorf("release name must be specified\nSee '%s -h' for help and examples", cmdPath)
}

klog.V(4).Infof("Namespace: %s", o.Namespace)
Expand Down

0 comments on commit cb507e1

Please sign in to comment.