github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/cmd/helm/completion.go (about) 1 /* 2 Copyright The Helm Authors. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package main 17 18 import ( 19 "fmt" 20 "io" 21 "os" 22 "path/filepath" 23 24 "github.com/spf13/cobra" 25 26 "github.com/stefanmcshane/helm/cmd/helm/require" 27 ) 28 29 const completionDesc = ` 30 Generate autocompletion scripts for Helm for the specified shell. 31 ` 32 const bashCompDesc = ` 33 Generate the autocompletion script for Helm for the bash shell. 34 35 To load completions in your current shell session: 36 37 source <(helm completion bash) 38 39 To load completions for every new session, execute once: 40 - Linux: 41 42 helm completion bash > /etc/bash_completion.d/helm 43 44 - MacOS: 45 46 helm completion bash > /usr/local/etc/bash_completion.d/helm 47 ` 48 49 const zshCompDesc = ` 50 Generate the autocompletion script for Helm for the zsh shell. 51 52 To load completions in your current shell session: 53 54 source <(helm completion zsh) 55 56 To load completions for every new session, execute once: 57 58 helm completion zsh > "${fpath[1]}/_helm" 59 ` 60 61 const fishCompDesc = ` 62 Generate the autocompletion script for Helm for the fish shell. 63 64 To load completions in your current shell session: 65 66 helm completion fish | source 67 68 To load completions for every new session, execute once: 69 70 helm completion fish > ~/.config/fish/completions/helm.fish 71 72 You will need to start a new shell for this setup to take effect. 73 ` 74 75 const powershellCompDesc = ` 76 Generate the autocompletion script for powershell. 77 78 To load completions in your current shell session: 79 PS C:\> helm completion powershell | Out-String | Invoke-Expression 80 81 To load completions for every new session, add the output of the above command 82 to your powershell profile. 83 ` 84 85 const ( 86 noDescFlagName = "no-descriptions" 87 noDescFlagText = "disable completion descriptions" 88 ) 89 90 var disableCompDescriptions bool 91 92 func newCompletionCmd(out io.Writer) *cobra.Command { 93 cmd := &cobra.Command{ 94 Use: "completion", 95 Short: "generate autocompletion scripts for the specified shell", 96 Long: completionDesc, 97 Args: require.NoArgs, 98 } 99 100 bash := &cobra.Command{ 101 Use: "bash", 102 Short: "generate autocompletion script for bash", 103 Long: bashCompDesc, 104 Args: require.NoArgs, 105 ValidArgsFunction: noCompletions, 106 RunE: func(cmd *cobra.Command, args []string) error { 107 return runCompletionBash(out, cmd) 108 }, 109 } 110 bash.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText) 111 112 zsh := &cobra.Command{ 113 Use: "zsh", 114 Short: "generate autocompletion script for zsh", 115 Long: zshCompDesc, 116 Args: require.NoArgs, 117 ValidArgsFunction: noCompletions, 118 RunE: func(cmd *cobra.Command, args []string) error { 119 return runCompletionZsh(out, cmd) 120 }, 121 } 122 zsh.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText) 123 124 fish := &cobra.Command{ 125 Use: "fish", 126 Short: "generate autocompletion script for fish", 127 Long: fishCompDesc, 128 Args: require.NoArgs, 129 ValidArgsFunction: noCompletions, 130 RunE: func(cmd *cobra.Command, args []string) error { 131 return runCompletionFish(out, cmd) 132 }, 133 } 134 fish.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText) 135 136 powershell := &cobra.Command{ 137 Use: "powershell", 138 Short: "generate autocompletion script for powershell", 139 Long: powershellCompDesc, 140 Args: require.NoArgs, 141 ValidArgsFunction: noCompletions, 142 RunE: func(cmd *cobra.Command, args []string) error { 143 return runCompletionPowershell(out, cmd) 144 }, 145 } 146 powershell.Flags().BoolVar(&disableCompDescriptions, noDescFlagName, false, noDescFlagText) 147 148 cmd.AddCommand(bash, zsh, fish, powershell) 149 150 return cmd 151 } 152 153 func runCompletionBash(out io.Writer, cmd *cobra.Command) error { 154 err := cmd.Root().GenBashCompletionV2(out, !disableCompDescriptions) 155 156 // In case the user renamed the helm binary (e.g., to be able to run 157 // both helm2 and helm3), we hook the new binary name to the completion function 158 if binary := filepath.Base(os.Args[0]); binary != "helm" { 159 renamedBinaryHook := ` 160 # Hook the command used to generate the completion script 161 # to the helm completion function to handle the case where 162 # the user renamed the helm binary 163 if [[ $(type -t compopt) = "builtin" ]]; then 164 complete -o default -F __start_helm %[1]s 165 else 166 complete -o default -o nospace -F __start_helm %[1]s 167 fi 168 ` 169 fmt.Fprintf(out, renamedBinaryHook, binary) 170 } 171 172 return err 173 } 174 175 func runCompletionZsh(out io.Writer, cmd *cobra.Command) error { 176 var err error 177 if disableCompDescriptions { 178 err = cmd.Root().GenZshCompletionNoDesc(out) 179 } else { 180 err = cmd.Root().GenZshCompletion(out) 181 } 182 183 // In case the user renamed the helm binary (e.g., to be able to run 184 // both helm2 and helm3), we hook the new binary name to the completion function 185 if binary := filepath.Base(os.Args[0]); binary != "helm" { 186 renamedBinaryHook := ` 187 # Hook the command used to generate the completion script 188 # to the helm completion function to handle the case where 189 # the user renamed the helm binary 190 compdef _helm %[1]s 191 ` 192 fmt.Fprintf(out, renamedBinaryHook, binary) 193 } 194 195 // Cobra doesn't source zsh completion file, explicitly doing it here 196 fmt.Fprintf(out, "compdef _helm helm") 197 198 return err 199 } 200 201 func runCompletionFish(out io.Writer, cmd *cobra.Command) error { 202 return cmd.Root().GenFishCompletion(out, !disableCompDescriptions) 203 } 204 205 func runCompletionPowershell(out io.Writer, cmd *cobra.Command) error { 206 if disableCompDescriptions { 207 return cmd.Root().GenPowerShellCompletion(out) 208 } 209 return cmd.Root().GenPowerShellCompletionWithDesc(out) 210 } 211 212 // Function to disable file completion 213 func noCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 214 return nil, cobra.ShellCompDirectiveNoFileComp 215 }