Skip to content

Commit

Permalink
feat(comp): Add descriptions for helm env vars
Browse files Browse the repository at this point in the history
When completing the helm env command, extra information will be shown
for shells that support completions (fish, zsh).  For example:

$ helm env HELM_RE<TAB>
HELM_REGISTRY_CONFIG    -- /me/Library/Preferences/helm/registry.json (Path to the registry configuration file)
HELM_REPOSITORY_CACHE   -- /me/Library/Caches/helm/repository (Path to the file containing cached repository indexes)
HELM_REPOSITORY_CONFIG  -- /me/Library/Preferences/helm/repositories.yaml (Path to the file containing repository names and URLs)

Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
  • Loading branch information
marckhouzam committed Feb 27, 2021
1 parent d91448f commit bd70e1a
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 31 deletions.
14 changes: 12 additions & 2 deletions cmd/helm/env.go
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"io"
"sort"
"strings"

"github.com/spf13/cobra"

Expand All @@ -38,8 +39,17 @@ func newEnvCmd(out io.Writer) *cobra.Command {
Args: require.MaximumNArgs(1),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 {
keys := getSortedEnvVarKeys()
return keys, cobra.ShellCompDirectiveNoFileComp
var vars []string
for _, v := range settings.EnvVarsWithDesc() {
if strings.HasPrefix(v.Name, toComplete) {
val := strings.TrimSpace(v.Value)
if val == "" {
val = `""`
}
vars = append(vars, fmt.Sprintf("%s\t%s (%s)", v.Name, val, v.Desc))
}
}
return vars, cobra.ShellCompDirectiveNoFileComp
}

return nil, cobra.ShellCompDirectiveNoFileComp
Expand Down
10 changes: 8 additions & 2 deletions cmd/helm/env_test.go
Expand Up @@ -22,9 +22,15 @@ import (

func TestEnv(t *testing.T) {
tests := []cmdTestCase{{
name: "completion for env",
cmd: "__complete env ''",
name: "completion for env",
// We disable descriptions by using __completeNoDesc because they would contain
// OS-specific paths which will change depending on where the tests are run
cmd: "__completeNoDesc env ''",
golden: "output/env-comp.txt",
}, {
name: "completion for env",
cmd: "__complete env HELM_K ",
golden: "output/env-desc-comp.txt",
}}
runTestCmd(t, tests)
}
Expand Down
16 changes: 8 additions & 8 deletions cmd/helm/testdata/output/env-comp.txt
Expand Up @@ -3,17 +3,17 @@ HELM_CACHE_HOME
HELM_CONFIG_HOME
HELM_DATA_HOME
HELM_DEBUG
HELM_KUBEAPISERVER
HELM_KUBEASGROUPS
HELM_KUBEASUSER
HELM_KUBECAFILE
HELM_KUBECONTEXT
HELM_KUBETOKEN
HELM_MAX_HISTORY
HELM_NAMESPACE
HELM_PLUGINS
HELM_REGISTRY_CONFIG
HELM_REPOSITORY_CACHE
HELM_REPOSITORY_CONFIG
HELM_NAMESPACE
HELM_MAX_HISTORY
HELM_KUBECONTEXT
HELM_KUBETOKEN
HELM_KUBEASUSER
HELM_KUBEASGROUPS
HELM_KUBEAPISERVER
HELM_KUBECAFILE
:4
Completion ended with directive: ShellCompDirectiveNoFileComp
8 changes: 8 additions & 0 deletions cmd/helm/testdata/output/env-desc-comp.txt
@@ -0,0 +1,8 @@
HELM_KUBECONTEXT "" (Kubernetes context to which this helm command applies)
HELM_KUBETOKEN "" (Path to the token file helm should use to contact the Kubernetes API server)
HELM_KUBEASUSER "" (Username to impersonate for the operation)
HELM_KUBEASGROUPS "" (Comma-separated list of groups to impersonate for the operation)
HELM_KUBEAPISERVER "" (<IP>:<port> helm should use to reach the Kubernetes API server)
HELM_KUBECAFILE "" (Path to the certificate authority file helm should use to contact the Kubernetes API server)
:4
Completion ended with directive: ShellCompDirectiveNoFileComp
56 changes: 37 additions & 19 deletions pkg/cli/environment.go
Expand Up @@ -144,28 +144,46 @@ func envCSV(name string) (ls []string) {
return
}

func (s *EnvSettings) EnvVars() map[string]string {
envvars := map[string]string{
"HELM_BIN": os.Args[0],
"HELM_CACHE_HOME": helmpath.CachePath(""),
"HELM_CONFIG_HOME": helmpath.ConfigPath(""),
"HELM_DATA_HOME": helmpath.DataPath(""),
"HELM_DEBUG": fmt.Sprint(s.Debug),
"HELM_PLUGINS": s.PluginsDirectory,
"HELM_REGISTRY_CONFIG": s.RegistryConfig,
"HELM_REPOSITORY_CACHE": s.RepositoryCache,
"HELM_REPOSITORY_CONFIG": s.RepositoryConfig,
"HELM_NAMESPACE": s.Namespace(),
"HELM_MAX_HISTORY": strconv.Itoa(s.MaxHistory),
// EnvironmentVariable represents information about helm env vars
type EnvironmentVariable struct {
Name string
Value string
Desc string
}

// EnvVarsWithDesc return an array of helm environment variables
func (s *EnvSettings) EnvVarsWithDesc() []EnvironmentVariable {
return []EnvironmentVariable{
{Name: "HELM_BIN", Value: os.Args[0], Desc: "Path of the helm binary"},
{Name: "HELM_CACHE_HOME", Value: helmpath.CachePath(""), Desc: "Path of helm's cache files"},
{Name: "HELM_CONFIG_HOME", Value: helmpath.ConfigPath(""), Desc: "Path of helm's configuration files"},
{Name: "HELM_DATA_HOME", Value: helmpath.DataPath(""), Desc: "Path of helm's data files"},
{Name: "HELM_DEBUG", Value: fmt.Sprint(s.Debug), Desc: "Indicates if debug statements should be printed (true/false)"},
{Name: "HELM_PLUGINS", Value: s.PluginsDirectory, Desc: "Path of helm's plugin files"},
{Name: "HELM_REGISTRY_CONFIG", Value: s.RegistryConfig, Desc: "Path to the registry configuration file"},
{Name: "HELM_REPOSITORY_CACHE", Value: s.RepositoryCache, Desc: "Path to the file containing cached repository indexes"},
{Name: "HELM_REPOSITORY_CONFIG", Value: s.RepositoryConfig, Desc: "Path to the file containing repository names and URLs"},
{Name: "HELM_NAMESPACE", Value: s.Namespace(), Desc: "Kubernetes namespace to which this helm command applies"},
{Name: "HELM_MAX_HISTORY", Value: strconv.Itoa(s.MaxHistory), Desc: "Maximum number of revisions to configure for release history"},

// broken, these are populated from helm flags and not kubeconfig.
"HELM_KUBECONTEXT": s.KubeContext,
"HELM_KUBETOKEN": s.KubeToken,
"HELM_KUBEASUSER": s.KubeAsUser,
"HELM_KUBEASGROUPS": strings.Join(s.KubeAsGroups, ","),
"HELM_KUBEAPISERVER": s.KubeAPIServer,
"HELM_KUBECAFILE": s.KubeCaFile,
{Name: "HELM_KUBECONTEXT", Value: s.KubeContext, Desc: "Kubernetes context to which this helm command applies"},
{Name: "HELM_KUBETOKEN", Value: s.KubeToken, Desc: "Path to the token file helm should use to contact the Kubernetes API server"},
{Name: "HELM_KUBEASUSER", Value: s.KubeAsUser, Desc: "Username to impersonate for the operation"},
{Name: "HELM_KUBEASGROUPS", Value: strings.Join(s.KubeAsGroups, ","), Desc: "Comma-separated list of groups to impersonate for the operation"},
{Name: "HELM_KUBEAPISERVER", Value: s.KubeAPIServer, Desc: "<IP>:<port> helm should use to reach the Kubernetes API server"},
{Name: "HELM_KUBECAFILE", Value: s.KubeCaFile, Desc: "Path to the certificate authority file helm should use to contact the Kubernetes API server"},
}
}

// EnvVars returns a map of env var with their current values
func (s *EnvSettings) EnvVars() map[string]string {
rawvars := s.EnvVarsWithDesc()
envvars := make(map[string]string, len(rawvars))
for _, v := range rawvars {
envvars[v.Name] = v.Value
}

if s.KubeConfig != "" {
envvars["KUBECONFIG"] = s.KubeConfig
}
Expand Down

0 comments on commit bd70e1a

Please sign in to comment.