docker-compose 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. #!/bin/bash
  2. #
  3. # bash completion for docker-compose
  4. #
  5. # This work is based on the completion for the docker command.
  6. #
  7. # This script provides completion of:
  8. # - commands and their options
  9. # - service names
  10. # - filepaths
  11. #
  12. # To enable the completions either:
  13. # - place this file in /etc/bash_completion.d
  14. # or
  15. # - copy this file to e.g. ~/.docker-compose-completion.sh and add the line
  16. # below to your .bashrc after bash completion features are loaded
  17. # . ~/.docker-compose-completion.sh
  18. __docker_compose_q() {
  19. docker-compose 2>/dev/null "${top_level_options[@]}" "$@"
  20. }
  21. # Transforms a multiline list of strings into a single line string
  22. # with the words separated by "|".
  23. __docker_compose_to_alternatives() {
  24. local parts=( $1 )
  25. local IFS='|'
  26. echo "${parts[*]}"
  27. }
  28. # Transforms a multiline list of options into an extglob pattern
  29. # suitable for use in case statements.
  30. __docker_compose_to_extglob() {
  31. local extglob=$( __docker_compose_to_alternatives "$1" )
  32. echo "@($extglob)"
  33. }
  34. # Determines whether the option passed as the first argument exist on
  35. # the commandline. The option may be a pattern, e.g. `--force|-f`.
  36. __docker_compose_has_option() {
  37. local pattern="$1"
  38. for (( i=2; i < $cword; ++i)); do
  39. if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then
  40. return 0
  41. fi
  42. done
  43. return 1
  44. }
  45. # suppress trailing whitespace
  46. __docker_compose_nospace() {
  47. # compopt is not available in ancient bash versions
  48. type compopt &>/dev/null && compopt -o nospace
  49. }
  50. # Extracts all service names from the compose file.
  51. ___docker_compose_all_services_in_compose_file() {
  52. __docker_compose_q config --services
  53. }
  54. # All services, even those without an existing container
  55. __docker_compose_services_all() {
  56. COMPREPLY=( $(compgen -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  57. }
  58. # All services that have an entry with the given key in their compose_file section
  59. ___docker_compose_services_with_key() {
  60. # flatten sections under "services" to one line, then filter lines containing the key and return section name
  61. __docker_compose_q config \
  62. | sed -n -e '/^services:/,/^[^ ]/p' \
  63. | sed -n 's/^ //p' \
  64. | awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' \
  65. | awk -F: -v key=": +$1:" '$0 ~ key {print $1}'
  66. }
  67. # All services that are defined by a Dockerfile reference
  68. __docker_compose_services_from_build() {
  69. COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key build)" -- "$cur") )
  70. }
  71. # All services that are defined by an image
  72. __docker_compose_services_from_image() {
  73. COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key image)" -- "$cur") )
  74. }
  75. # The services for which containers have been created, optionally filtered
  76. # by a boolean expression passed in as argument.
  77. __docker_compose_services_with() {
  78. local containers names
  79. containers="$(__docker_compose_q ps -q)"
  80. names=$(docker 2>/dev/null inspect -f "{{if ${1:-true}}}{{range \$k, \$v := .Config.Labels}}{{if eq \$k \"com.docker.compose.service\"}}{{\$v}}{{end}}{{end}}{{end}}" $containers)
  81. COMPREPLY=( $(compgen -W "$names" -- "$cur") )
  82. }
  83. # The services for which at least one paused container exists
  84. __docker_compose_services_paused() {
  85. __docker_compose_services_with '.State.Paused'
  86. }
  87. # The services for which at least one running container exists
  88. __docker_compose_services_running() {
  89. __docker_compose_services_with '.State.Running'
  90. }
  91. # The services for which at least one stopped container exists
  92. __docker_compose_services_stopped() {
  93. __docker_compose_services_with 'not .State.Running'
  94. }
  95. _docker_compose_build() {
  96. case "$prev" in
  97. --build-arg)
  98. COMPREPLY=( $( compgen -e -- "$cur" ) )
  99. __docker_compose_nospace
  100. return
  101. ;;
  102. esac
  103. case "$cur" in
  104. -*)
  105. COMPREPLY=( $( compgen -W "--build-arg --force-rm --help --no-cache --pull" -- "$cur" ) )
  106. ;;
  107. *)
  108. __docker_compose_services_from_build
  109. ;;
  110. esac
  111. }
  112. _docker_compose_bundle() {
  113. case "$prev" in
  114. --output|-o)
  115. _filedir
  116. return
  117. ;;
  118. esac
  119. COMPREPLY=( $( compgen -W "--push-images --help --output -o" -- "$cur" ) )
  120. }
  121. _docker_compose_config() {
  122. COMPREPLY=( $( compgen -W "--help --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) )
  123. }
  124. _docker_compose_create() {
  125. case "$cur" in
  126. -*)
  127. COMPREPLY=( $( compgen -W "--build --force-recreate --help --no-build --no-recreate" -- "$cur" ) )
  128. ;;
  129. *)
  130. __docker_compose_services_all
  131. ;;
  132. esac
  133. }
  134. _docker_compose_docker_compose() {
  135. case "$prev" in
  136. --tlscacert|--tlscert|--tlskey)
  137. _filedir
  138. return
  139. ;;
  140. --file|-f)
  141. _filedir "y?(a)ml"
  142. return
  143. ;;
  144. --project-directory)
  145. _filedir -d
  146. return
  147. ;;
  148. $(__docker_compose_to_extglob "$top_level_options_with_args") )
  149. return
  150. ;;
  151. esac
  152. case "$cur" in
  153. -*)
  154. COMPREPLY=( $( compgen -W "$top_level_boolean_options $top_level_options_with_args --help -h --no-ansi --verbose --version -v" -- "$cur" ) )
  155. ;;
  156. *)
  157. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  158. ;;
  159. esac
  160. }
  161. _docker_compose_down() {
  162. case "$prev" in
  163. --rmi)
  164. COMPREPLY=( $( compgen -W "all local" -- "$cur" ) )
  165. return
  166. ;;
  167. esac
  168. case "$cur" in
  169. -*)
  170. COMPREPLY=( $( compgen -W "--help --rmi --volumes -v --remove-orphans" -- "$cur" ) )
  171. ;;
  172. esac
  173. }
  174. _docker_compose_events() {
  175. case "$prev" in
  176. --json)
  177. return
  178. ;;
  179. esac
  180. case "$cur" in
  181. -*)
  182. COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) )
  183. ;;
  184. *)
  185. __docker_compose_services_all
  186. ;;
  187. esac
  188. }
  189. _docker_compose_exec() {
  190. case "$prev" in
  191. --index|--user|-u)
  192. return
  193. ;;
  194. esac
  195. case "$cur" in
  196. -*)
  197. COMPREPLY=( $( compgen -W "-d --help --index --privileged -T --user -u" -- "$cur" ) )
  198. ;;
  199. *)
  200. __docker_compose_services_running
  201. ;;
  202. esac
  203. }
  204. _docker_compose_help() {
  205. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  206. }
  207. _docker_compose_images() {
  208. case "$cur" in
  209. -*)
  210. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  211. ;;
  212. *)
  213. __docker_compose_services_all
  214. ;;
  215. esac
  216. }
  217. _docker_compose_kill() {
  218. case "$prev" in
  219. -s)
  220. COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
  221. return
  222. ;;
  223. esac
  224. case "$cur" in
  225. -*)
  226. COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
  227. ;;
  228. *)
  229. __docker_compose_services_running
  230. ;;
  231. esac
  232. }
  233. _docker_compose_logs() {
  234. case "$prev" in
  235. --tail)
  236. return
  237. ;;
  238. esac
  239. case "$cur" in
  240. -*)
  241. COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) )
  242. ;;
  243. *)
  244. __docker_compose_services_all
  245. ;;
  246. esac
  247. }
  248. _docker_compose_pause() {
  249. case "$cur" in
  250. -*)
  251. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  252. ;;
  253. *)
  254. __docker_compose_services_running
  255. ;;
  256. esac
  257. }
  258. _docker_compose_port() {
  259. case "$prev" in
  260. --protocol)
  261. COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
  262. return;
  263. ;;
  264. --index)
  265. return;
  266. ;;
  267. esac
  268. case "$cur" in
  269. -*)
  270. COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
  271. ;;
  272. *)
  273. __docker_compose_services_all
  274. ;;
  275. esac
  276. }
  277. _docker_compose_ps() {
  278. case "$cur" in
  279. -*)
  280. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  281. ;;
  282. *)
  283. __docker_compose_services_all
  284. ;;
  285. esac
  286. }
  287. _docker_compose_pull() {
  288. case "$cur" in
  289. -*)
  290. COMPREPLY=( $( compgen -W "--help --ignore-pull-failures --parallel --quiet" -- "$cur" ) )
  291. ;;
  292. *)
  293. __docker_compose_services_from_image
  294. ;;
  295. esac
  296. }
  297. _docker_compose_push() {
  298. case "$cur" in
  299. -*)
  300. COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) )
  301. ;;
  302. *)
  303. __docker_compose_services_all
  304. ;;
  305. esac
  306. }
  307. _docker_compose_restart() {
  308. case "$prev" in
  309. --timeout|-t)
  310. return
  311. ;;
  312. esac
  313. case "$cur" in
  314. -*)
  315. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  316. ;;
  317. *)
  318. __docker_compose_services_running
  319. ;;
  320. esac
  321. }
  322. _docker_compose_rm() {
  323. case "$cur" in
  324. -*)
  325. COMPREPLY=( $( compgen -W "--force -f --help --stop -s -v" -- "$cur" ) )
  326. ;;
  327. *)
  328. if __docker_compose_has_option "--stop|-s" ; then
  329. __docker_compose_services_all
  330. else
  331. __docker_compose_services_stopped
  332. fi
  333. ;;
  334. esac
  335. }
  336. _docker_compose_run() {
  337. case "$prev" in
  338. -e)
  339. COMPREPLY=( $( compgen -e -- "$cur" ) )
  340. __docker_compose_nospace
  341. return
  342. ;;
  343. --entrypoint|--name|--user|-u|--volume|-v|--workdir|-w)
  344. return
  345. ;;
  346. esac
  347. case "$cur" in
  348. -*)
  349. COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u --volume -v --workdir -w" -- "$cur" ) )
  350. ;;
  351. *)
  352. __docker_compose_services_all
  353. ;;
  354. esac
  355. }
  356. _docker_compose_scale() {
  357. case "$prev" in
  358. =)
  359. COMPREPLY=("$cur")
  360. return
  361. ;;
  362. --timeout|-t)
  363. return
  364. ;;
  365. esac
  366. case "$cur" in
  367. -*)
  368. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  369. ;;
  370. *)
  371. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  372. __docker_compose_nospace
  373. ;;
  374. esac
  375. }
  376. _docker_compose_start() {
  377. case "$cur" in
  378. -*)
  379. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  380. ;;
  381. *)
  382. __docker_compose_services_stopped
  383. ;;
  384. esac
  385. }
  386. _docker_compose_stop() {
  387. case "$prev" in
  388. --timeout|-t)
  389. return
  390. ;;
  391. esac
  392. case "$cur" in
  393. -*)
  394. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  395. ;;
  396. *)
  397. __docker_compose_services_running
  398. ;;
  399. esac
  400. }
  401. _docker_compose_top() {
  402. case "$cur" in
  403. -*)
  404. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  405. ;;
  406. *)
  407. __docker_compose_services_running
  408. ;;
  409. esac
  410. }
  411. _docker_compose_unpause() {
  412. case "$cur" in
  413. -*)
  414. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  415. ;;
  416. *)
  417. __docker_compose_services_paused
  418. ;;
  419. esac
  420. }
  421. _docker_compose_up() {
  422. case "$prev" in
  423. =)
  424. COMPREPLY=("$cur")
  425. return
  426. ;;
  427. --exit-code-from)
  428. __docker_compose_services_all
  429. return
  430. ;;
  431. --scale)
  432. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  433. __docker_compose_nospace
  434. return
  435. ;;
  436. --timeout|-t)
  437. return
  438. ;;
  439. esac
  440. case "$cur" in
  441. -*)
  442. COMPREPLY=( $( compgen -W "--abort-on-container-exit --build -d --exit-code-from --force-recreate --help --no-build --no-color --no-deps --no-recreate --remove-orphans --scale --timeout -t" -- "$cur" ) )
  443. ;;
  444. *)
  445. __docker_compose_services_all
  446. ;;
  447. esac
  448. }
  449. _docker_compose_version() {
  450. case "$cur" in
  451. -*)
  452. COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
  453. ;;
  454. esac
  455. }
  456. _docker_compose() {
  457. local previous_extglob_setting=$(shopt -p extglob)
  458. shopt -s extglob
  459. local commands=(
  460. build
  461. bundle
  462. config
  463. create
  464. down
  465. events
  466. exec
  467. help
  468. images
  469. kill
  470. logs
  471. pause
  472. port
  473. ps
  474. pull
  475. push
  476. restart
  477. rm
  478. run
  479. scale
  480. start
  481. stop
  482. top
  483. unpause
  484. up
  485. version
  486. )
  487. # Options for the docker daemon that have to be passed to secondary calls to
  488. # docker-compose executed by this script.
  489. # Other global otions that are not relevant for secondary calls are defined in
  490. # `_docker_compose_docker_compose`.
  491. local top_level_boolean_options="
  492. --skip-hostname-check
  493. --tls
  494. --tlsverify
  495. "
  496. local top_level_options_with_args="
  497. --file -f
  498. --host -H
  499. --project-directory
  500. --project-name -p
  501. --tlscacert
  502. --tlscert
  503. --tlskey
  504. "
  505. COMPREPLY=()
  506. local cur prev words cword
  507. _get_comp_words_by_ref -n : cur prev words cword
  508. # search subcommand and invoke its handler.
  509. # special treatment of some top-level options
  510. local command='docker_compose'
  511. local top_level_options=()
  512. local counter=1
  513. while [ $counter -lt $cword ]; do
  514. case "${words[$counter]}" in
  515. $(__docker_compose_to_extglob "$top_level_boolean_options") )
  516. local opt=${words[counter]}
  517. top_level_options+=($opt)
  518. ;;
  519. $(__docker_compose_to_extglob "$top_level_options_with_args") )
  520. local opt=${words[counter]}
  521. local arg=${words[++counter]}
  522. top_level_options+=($opt $arg)
  523. ;;
  524. -*)
  525. ;;
  526. *)
  527. command="${words[$counter]}"
  528. break
  529. ;;
  530. esac
  531. (( counter++ ))
  532. done
  533. local completions_func=_docker_compose_${command//-/_}
  534. declare -F $completions_func >/dev/null && $completions_func
  535. eval "$previous_extglob_setting"
  536. return 0
  537. }
  538. complete -F _docker_compose docker-compose docker-compose.exe