# bash completion for composer-cli __composer_cli_flags="-h --help -j --json -s --socket --log -a --api --test -V" declare -A __composer_cli_cmds=( [compose]="list start types status log cancel delete info metadata logs results image" [blueprints]="list show changes diff save delete depsolve push freeze tag undo workspace" [modules]="list" [projects]="list info" [sources]="list info add change delete" [help]="" ) __composer_socket_ok() { [ -w "${COMPOSER_SOCKET:-/run/weldr/api.socket}" ] } __composer_blueprints() { __composer_socket_ok && composer-cli blueprints list } __composer_sources() { __composer_socket_ok && composer-cli sources list } __composer_compose_types() { __composer_socket_ok && composer-cli compose types } __composer_composes() { __composer_socket_ok && composer-cli compose list $@ | while read id rest; do echo $id; done } __word_in_list() { local w word=$1; shift for w in "$@"; do [ "$w" == "$word" ] && return 0 done return 1 } _composer_cli() { local cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" local w="" wi=0 cmd="__NONE__" subcmd="__NONE__" cmd_cword=0 # find the command and its subcommand for (( wi=0; wi < ${#COMP_WORDS[*]}; wi++ )); do if __word_in_list "${COMP_WORDS[wi]}" "${!__composer_cli_cmds[@]}"; then cmd="${COMP_WORDS[wi]}" subcmd="${COMP_WORDS[wi+1]}" cmd_cword=$((COMP_CWORD-wi)) break fi done COMPREPLY=() if [ "$cmd_cword" -le 0 ]; then # No command yet, complete flags or commands case "$prev" in -s|--socket|--log) # If it's a flag that takes a filename, suggest filenames compopt -o filenames COMPREPLY=($(compgen -f -- "${cur}")) ;; -a|--api|--test) # If it's a flag that takes an arg we can't guess, don't suggest anything COMPREPLY=() ;; *) if [ "${cur:0:1}" == "-" ]; then # Suggest flags if cur starts with '-' COMPREPLY=($(compgen -W "${__composer_cli_flags}" -- "${cur}")) else # Suggest commands if there isn't one already COMPREPLY=($(compgen -W "${!__composer_cli_cmds[*]}" -- "${cur}")) fi ;; esac elif [ $cmd_cword == 1 ]; then # Complete the word after the command COMPREPLY=($(compgen -W "${__composer_cli_cmds[$cmd]} help" -- "${cur}")) elif [ $cmd_cword == 2 ]; then # Complete word(s) after subcommand case "$cmd:$subcmd" in compose:list) COMPREPLY=($(compgen -W "waiting running finish failed" -- "${cur}")) ;; *:list|*:help|compose:types) COMPREPLY=() ;; sources:info|sources:delete) COMPREPLY=($(compgen -W "$(__composer_sources)" -- "${cur}")) ;; sources:add|sources:change|blueprints:workspace|blueprints:push) compopt -o filenames COMPREPLY=($(compgen -f -- "${cur}")) ;; blueprints:freeze) COMPREPLY=($(compgen -W "$(__composer_blueprints) show save" -- "${cur}")) ;; compose:start|blueprints:*) COMPREPLY=($(compgen -W "$(__composer_blueprints)" -- "${cur}")) ;; compose:cancel) COMPREPLY=($(compgen -W "$(__composer_composes running waiting)" -- "${cur}")) ;; compose:delete|compose:results|compose:metadata) COMPREPLY=($(compgen -W "$(__composer_composes finished failed)" -- "${cur}")) ;; compose:log*) COMPREPLY=($(compgen -W "$(__composer_composes running finished failed)" -- "${cur}")) ;; compose:image) COMPREPLY=($(compgen -W "$(__composer_composes finished)" -- "${cur}")) ;; compose:*) COMPREPLY=($(compgen -W "$(__composer_composes)" -- "${cur}")) ;; esac else # Complete words past the subcommand's argument (if appropriate) case "$cmd:$subcmd" in compose:delete) COMPREPLY=($(compgen -W "$(__composer_composes finished failed)" -- "${cur}")) ;; compose:start) if [ "$cmd_cword" == 3 ]; then COMPREPLY=($(compgen -W "$(__composer_compose_types)" -- "${cur}")) fi ;; # TODO: blueprints:diff and blueprints:undo want commits blueprints:freeze|blueprints:save|blueprints:depsolve|blueprints:changes|blueprints:show) COMPREPLY=($(compgen -W "$(__composer_blueprints)" -- "${cur}")) ;; sources:info) COMPREPLY=($(compgen -W "$(__composer_sources)" -- "${cur}")) ;; esac fi } complete -F _composer_cli composer-cli