| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- #!/bin/bash
- #
- # bash completion for docker-compose
- #
- # This work is based on the completion for the docker command.
- #
- # This script provides completion of:
- # - commands and their options
- # - service names
- # - filepaths
- #
- # To enable the completions either:
- # - place this file in /etc/bash_completion.d
- # or
- # - copy this file to e.g. ~/.docker-compose-completion.sh and add the line
- # below to your .bashrc after bash completion features are loaded
- # . ~/.docker-compose-completion.sh
- __docker_compose_q() {
- docker-compose 2>/dev/null "${top_level_options[@]}" "$@"
- }
- # Transforms a multiline list of strings into a single line string
- # with the words separated by "|".
- __docker_compose_to_alternatives() {
- local parts=( $1 )
- local IFS='|'
- echo "${parts[*]}"
- }
- # Transforms a multiline list of options into an extglob pattern
- # suitable for use in case statements.
- __docker_compose_to_extglob() {
- local extglob=$( __docker_compose_to_alternatives "$1" )
- echo "@($extglob)"
- }
- # Determines whether the option passed as the first argument exist on
- # the commandline. The option may be a pattern, e.g. `--force|-f`.
- __docker_compose_has_option() {
- local pattern="$1"
- for (( i=2; i < $cword; ++i)); do
- if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then
- return 0
- fi
- done
- return 1
- }
- # Returns `key` if we are currently completing the value of a map option (`key=value`)
- # which matches the extglob passed in as an argument.
- # This function is needed for key-specific completions.
- __docker_compose_map_key_of_current_option() {
- local glob="$1"
- local key glob_pos
- if [ "$cur" = "=" ] ; then # key= case
- key="$prev"
- glob_pos=$((cword - 2))
- elif [[ $cur == *=* ]] ; then # key=value case (OSX)
- key=${cur%=*}
- glob_pos=$((cword - 1))
- elif [ "$prev" = "=" ] ; then
- key=${words[$cword - 2]} # key=value case
- glob_pos=$((cword - 3))
- else
- return
- fi
- [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax
- [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key"
- }
- # suppress trailing whitespace
- __docker_compose_nospace() {
- # compopt is not available in ancient bash versions
- type compopt &>/dev/null && compopt -o nospace
- }
- # Extracts all service names from the compose file.
- ___docker_compose_all_services_in_compose_file() {
- __docker_compose_q config --services
- }
- # All services, even those without an existing container
- __docker_compose_services_all() {
- COMPREPLY=( $(compgen -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
- }
- # All services that are defined by a Dockerfile reference
- __docker_compose_services_from_build() {
- COMPREPLY=( $(compgen -W "$(__docker_compose_q ps --services --filter "source=build")" -- "$cur") )
- }
- # All services that are defined by an image
- __docker_compose_services_from_image() {
- COMPREPLY=( $(compgen -W "$(__docker_compose_q ps --services --filter "source=image")" -- "$cur") )
- }
- # The services for which at least one paused container exists
- __docker_compose_services_paused() {
- names=$(__docker_compose_q ps --services --filter "status=paused")
- COMPREPLY=( $(compgen -W "$names" -- "$cur") )
- }
- # The services for which at least one running container exists
- __docker_compose_services_running() {
- names=$(__docker_compose_q ps --services --filter "status=running")
- COMPREPLY=( $(compgen -W "$names" -- "$cur") )
- }
- # The services for which at least one stopped container exists
- __docker_compose_services_stopped() {
- names=$(__docker_compose_q ps --services --filter "status=stopped")
- COMPREPLY=( $(compgen -W "$names" -- "$cur") )
- }
- _docker_compose_build() {
- case "$prev" in
- --build-arg)
- COMPREPLY=( $( compgen -e -- "$cur" ) )
- __docker_compose_nospace
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--build-arg --force-rm --help --memory --no-cache --pull" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_from_build
- ;;
- esac
- }
- _docker_compose_bundle() {
- case "$prev" in
- --output|-o)
- _filedir
- return
- ;;
- esac
- COMPREPLY=( $( compgen -W "--push-images --help --output -o" -- "$cur" ) )
- }
- _docker_compose_config() {
- COMPREPLY=( $( compgen -W "--help --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) )
- }
- _docker_compose_create() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--build --force-recreate --help --no-build --no-recreate" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_docker_compose() {
- case "$prev" in
- --tlscacert|--tlscert|--tlskey)
- _filedir
- return
- ;;
- --file|-f)
- _filedir "y?(a)ml"
- return
- ;;
- --project-directory)
- _filedir -d
- return
- ;;
- $(__docker_compose_to_extglob "$top_level_options_with_args") )
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "$top_level_boolean_options $top_level_options_with_args --help -h --no-ansi --verbose --version -v" -- "$cur" ) )
- ;;
- *)
- COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
- ;;
- esac
- }
- _docker_compose_down() {
- case "$prev" in
- --rmi)
- COMPREPLY=( $( compgen -W "all local" -- "$cur" ) )
- return
- ;;
- --timeout|-t)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --rmi --timeout -t --volumes -v --remove-orphans" -- "$cur" ) )
- ;;
- esac
- }
- _docker_compose_events() {
- case "$prev" in
- --json)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_exec() {
- case "$prev" in
- --index|--user|-u)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "-d --help --index --privileged -T --user -u" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_running
- ;;
- esac
- }
- _docker_compose_help() {
- COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
- }
- _docker_compose_images() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --quiet -q" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_kill() {
- case "$prev" in
- -s)
- COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_running
- ;;
- esac
- }
- _docker_compose_logs() {
- case "$prev" in
- --tail)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_pause() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_running
- ;;
- esac
- }
- _docker_compose_port() {
- case "$prev" in
- --protocol)
- COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
- return;
- ;;
- --index)
- return;
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_ps() {
- local key=$(__docker_compose_map_key_of_current_option '--filter')
- case "$key" in
- source)
- COMPREPLY=( $( compgen -W "build image" -- "${cur##*=}" ) )
- return
- ;;
- status)
- COMPREPLY=( $( compgen -W "paused restarting running stopped" -- "${cur##*=}" ) )
- return
- ;;
- esac
- case "$prev" in
- --filter)
- COMPREPLY=( $( compgen -W "source status" -S "=" -- "$cur" ) )
- __docker_compose_nospace
- return;
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --quiet -q --services --filter" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_pull() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --ignore-pull-failures --parallel --quiet -q" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_from_image
- ;;
- esac
- }
- _docker_compose_push() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_restart() {
- case "$prev" in
- --timeout|-t)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_running
- ;;
- esac
- }
- _docker_compose_rm() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--force -f --help --stop -s -v" -- "$cur" ) )
- ;;
- *)
- if __docker_compose_has_option "--stop|-s" ; then
- __docker_compose_services_all
- else
- __docker_compose_services_stopped
- fi
- ;;
- esac
- }
- _docker_compose_run() {
- case "$prev" in
- -e)
- COMPREPLY=( $( compgen -e -- "$cur" ) )
- __docker_compose_nospace
- return
- ;;
- --entrypoint|--label|-l|--name|--user|-u|--volume|-v|--workdir|-w)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --label -l --name --no-deps --publish -p --rm --service-ports -T --user -u --volume -v --workdir -w" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_scale() {
- case "$prev" in
- =)
- COMPREPLY=("$cur")
- return
- ;;
- --timeout|-t)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
- ;;
- *)
- COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
- __docker_compose_nospace
- ;;
- esac
- }
- _docker_compose_start() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_stopped
- ;;
- esac
- }
- _docker_compose_stop() {
- case "$prev" in
- --timeout|-t)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_running
- ;;
- esac
- }
- _docker_compose_top() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_running
- ;;
- esac
- }
- _docker_compose_unpause() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_paused
- ;;
- esac
- }
- _docker_compose_up() {
- case "$prev" in
- =)
- COMPREPLY=("$cur")
- return
- ;;
- --exit-code-from)
- __docker_compose_services_all
- return
- ;;
- --scale)
- COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
- __docker_compose_nospace
- return
- ;;
- --timeout|-t)
- return
- ;;
- esac
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--abort-on-container-exit --always-recreate-deps --build -d --exit-code-from --force-recreate --help --no-build --no-color --no-deps --no-recreate --no-start --renew-anon-volumes -V --remove-orphans --scale --timeout -t" -- "$cur" ) )
- ;;
- *)
- __docker_compose_services_all
- ;;
- esac
- }
- _docker_compose_version() {
- case "$cur" in
- -*)
- COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
- ;;
- esac
- }
- _docker_compose() {
- local previous_extglob_setting=$(shopt -p extglob)
- shopt -s extglob
- local commands=(
- build
- bundle
- config
- create
- down
- events
- exec
- help
- images
- kill
- logs
- pause
- port
- ps
- pull
- push
- restart
- rm
- run
- scale
- start
- stop
- top
- unpause
- up
- version
- )
- # Options for the docker daemon that have to be passed to secondary calls to
- # docker-compose executed by this script.
- # Other global otions that are not relevant for secondary calls are defined in
- # `_docker_compose_docker_compose`.
- local top_level_boolean_options="
- --skip-hostname-check
- --tls
- --tlsverify
- "
- local top_level_options_with_args="
- --file -f
- --host -H
- --project-directory
- --project-name -p
- --tlscacert
- --tlscert
- --tlskey
- "
- COMPREPLY=()
- local cur prev words cword
- _get_comp_words_by_ref -n : cur prev words cword
- # search subcommand and invoke its handler.
- # special treatment of some top-level options
- local command='docker_compose'
- local top_level_options=()
- local counter=1
- while [ $counter -lt $cword ]; do
- case "${words[$counter]}" in
- $(__docker_compose_to_extglob "$top_level_boolean_options") )
- local opt=${words[counter]}
- top_level_options+=($opt)
- ;;
- $(__docker_compose_to_extglob "$top_level_options_with_args") )
- local opt=${words[counter]}
- local arg=${words[++counter]}
- top_level_options+=($opt $arg)
- ;;
- -*)
- ;;
- *)
- command="${words[$counter]}"
- break
- ;;
- esac
- (( counter++ ))
- done
- local completions_func=_docker_compose_${command//-/_}
- declare -F $completions_func >/dev/null && $completions_func
- eval "$previous_extglob_setting"
- return 0
- }
- complete -F _docker_compose docker-compose docker-compose.exe
|