github.com/argoproj/argo-cd/v3@v3.2.1/cmd/argocd/commands/completion.go (about) 1 package commands 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 8 log "github.com/sirupsen/logrus" 9 "github.com/spf13/cobra" 10 ) 11 12 const ( 13 bashCompletionFunc = ` 14 __argocd_list_apps() { 15 local -a argocd_out 16 if argocd_out=($(argocd app list --output name 2>/dev/null)); then 17 COMPREPLY+=( $( compgen -W "${argocd_out[*]}" -- "$cur" ) ) 18 fi 19 } 20 21 __argocd_list_app_history() { 22 local app=$1 23 local -a argocd_out 24 if argocd_out=($(argocd app history $app --output id 2>/dev/null)); then 25 COMPREPLY+=( $( compgen -W "${argocd_out[*]}" -- "$cur" ) ) 26 fi 27 } 28 29 __argocd_app_rollback() { 30 local -a command 31 for comp_word in "${COMP_WORDS[@]}"; do 32 if [[ $comp_word =~ ^-.*$ ]]; then 33 continue 34 fi 35 command+=($comp_word) 36 done 37 38 # fourth arg is app (if present): e.g.- argocd app rollback guestbook 39 local app=${command[3]} 40 local id=${command[4]} 41 if [[ -z $app || $app == $cur ]]; then 42 __argocd_list_apps 43 elif [[ -z $id || $id == $cur ]]; then 44 __argocd_list_app_history $app 45 fi 46 } 47 48 __argocd_list_servers() { 49 local -a argocd_out 50 if argocd_out=($(argocd cluster list --output server 2>/dev/null)); then 51 COMPREPLY+=( $( compgen -W "${argocd_out[*]}" -- "$cur" ) ) 52 fi 53 } 54 55 __argocd_list_repos() { 56 local -a argocd_out 57 if argocd_out=($(argocd repo list --output url 2>/dev/null)); then 58 COMPREPLY+=( $( compgen -W "${argocd_out[*]}" -- "$cur" ) ) 59 fi 60 } 61 62 __argocd_list_projects() { 63 local -a argocd_out 64 if argocd_out=($(argocd proj list --output name 2>/dev/null)); then 65 COMPREPLY+=( $( compgen -W "${argocd_out[*]}" -- "$cur" ) ) 66 fi 67 } 68 69 __argocd_list_namespaces() { 70 local -a argocd_out 71 if argocd_out=($(kubectl get namespaces --no-headers 2>/dev/null | cut -f1 -d' ' 2>/dev/null)); then 72 COMPREPLY+=( $( compgen -W "${argocd_out[*]}" -- "$cur" ) ) 73 fi 74 } 75 76 __argocd_proj_server_namespace() { 77 local -a command 78 for comp_word in "${COMP_WORDS[@]}"; do 79 if [[ $comp_word =~ ^-.*$ ]]; then 80 continue 81 fi 82 command+=($comp_word) 83 done 84 85 # expect something like this: argocd proj add-destination PROJECT SERVER NAMESPACE 86 local project=${command[3]} 87 local server=${command[4]} 88 local namespace=${command[5]} 89 if [[ -z $project || $project == $cur ]]; then 90 __argocd_list_projects 91 elif [[ -z $server || $server == $cur ]]; then 92 __argocd_list_servers 93 elif [[ -z $namespace || $namespace == $cur ]]; then 94 __argocd_list_namespaces 95 fi 96 } 97 98 __argocd_list_project_role() { 99 local project="$1" 100 local -a argocd_out 101 if argocd_out=($(argocd proj role list "$project" --output=name 2>/dev/null)); then 102 COMPREPLY+=( $( compgen -W "${argocd_out[*]}" -- "$cur" ) ) 103 fi 104 } 105 106 __argocd_proj_role(){ 107 local -a command 108 for comp_word in "${COMP_WORDS[@]}"; do 109 if [[ $comp_word =~ ^-.*$ ]]; then 110 continue 111 fi 112 command+=($comp_word) 113 done 114 115 # expect something like this: argocd proj role add-policy PROJECT ROLE-NAME 116 local project=${command[4]} 117 local role=${command[5]} 118 if [[ -z $project || $project == $cur ]]; then 119 __argocd_list_projects 120 elif [[ -z $role || $role == $cur ]]; then 121 __argocd_list_project_role $project 122 fi 123 } 124 125 __argocd_custom_func() { 126 case ${last_command} in 127 argocd_app_delete | \ 128 argocd_app_diff | \ 129 argocd_app_edit | \ 130 argocd_app_get | \ 131 argocd_app_history | \ 132 argocd_app_manifests | \ 133 argocd_app_patch-resource | \ 134 argocd_app_set | \ 135 argocd_app_sync | \ 136 argocd_app_terminate-op | \ 137 argocd_app_unset | \ 138 argocd_app_wait | \ 139 argocd_app_create) 140 __argocd_list_apps 141 return 142 ;; 143 argocd_app_rollback) 144 __argocd_app_rollback 145 return 146 ;; 147 argocd_cluster_get | \ 148 argocd_cluster_rm | \ 149 argocd_cluster_set | \ 150 argocd_login | \ 151 argocd_cluster_add) 152 __argocd_list_servers 153 return 154 ;; 155 argocd_repo_rm | \ 156 argocd_repo_add) 157 __argocd_list_repos 158 return 159 ;; 160 argocd_proj_add-destination | \ 161 argocd_proj_remove-destination) 162 __argocd_proj_server_namespace 163 return 164 ;; 165 argocd_proj_add-source | \ 166 argocd_proj_remove-source | \ 167 argocd_proj_allow-cluster-resource | \ 168 argocd_proj_allow-namespace-resource | \ 169 argocd_proj_deny-cluster-resource | \ 170 argocd_proj_deny-namespace-resource | \ 171 argocd_proj_delete | \ 172 argocd_proj_edit | \ 173 argocd_proj_get | \ 174 argocd_proj_set | \ 175 argocd_proj_role_list) 176 __argocd_list_projects 177 return 178 ;; 179 argocd_proj_role_remove-policy | \ 180 argocd_proj_role_add-policy | \ 181 argocd_proj_role_create | \ 182 argocd_proj_role_delete | \ 183 argocd_proj_role_get | \ 184 argocd_proj_role_create-token | \ 185 argocd_proj_role_delete-token) 186 __argocd_proj_role 187 return 188 ;; 189 *) 190 ;; 191 esac 192 } 193 ` 194 ) 195 196 func NewCompletionCommand() *cobra.Command { 197 command := &cobra.Command{ 198 Use: "completion SHELL", 199 Short: "output shell completion code for the specified shell (bash, zsh or fish)", 200 Long: `Write bash, zsh or fish shell completion code to standard output. 201 202 For bash, ensure you have bash completions installed and enabled. 203 To access completions in your current shell, run 204 $ source <(argocd completion bash) 205 Alternatively, write it to a file and source in .bash_profile 206 207 For zsh, add the following to your ~/.zshrc file: 208 source <(argocd completion zsh) 209 compdef _argocd argocd 210 211 Optionally, also add the following, in case you are getting errors involving compdef & compinit such as command not found: compdef: 212 autoload -Uz compinit 213 compinit 214 `, 215 Example: `# For bash 216 $ source <(argocd completion bash) 217 218 # For zsh 219 $ argocd completion zsh > _argocd 220 $ source _argocd 221 222 # For fish 223 $ argocd completion fish > ~/.config/fish/completions/argocd.fish 224 $ source ~/.config/fish/completions/argocd.fish 225 226 `, 227 Run: func(cmd *cobra.Command, args []string) { 228 if len(args) != 1 { 229 cmd.HelpFunc()(cmd, args) 230 os.Exit(1) 231 } 232 shell := args[0] 233 rootCommand := NewCommand() 234 rootCommand.BashCompletionFunction = bashCompletionFunc 235 availableCompletions := map[string]func(out io.Writer, cmd *cobra.Command) error{ 236 "bash": runCompletionBash, 237 "zsh": runCompletionZsh, 238 "fish": runCompletionFish, 239 } 240 completion, ok := availableCompletions[shell] 241 if !ok { 242 fmt.Printf("Invalid shell '%s'. The supported shells are bash, zsh and fish.\n", shell) 243 os.Exit(1) 244 } 245 if err := completion(os.Stdout, rootCommand); err != nil { 246 log.Fatal(err) 247 } 248 }, 249 } 250 251 return command 252 } 253 254 func runCompletionBash(out io.Writer, cmd *cobra.Command) error { 255 return cmd.GenBashCompletion(out) 256 } 257 258 func runCompletionZsh(out io.Writer, cmd *cobra.Command) error { 259 return cmd.GenZshCompletion(out) 260 } 261 262 func runCompletionFish(out io.Writer, cmd *cobra.Command) error { 263 return cmd.GenFishCompletion(out, true) 264 }