docker-compose 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  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 are defined by a Dockerfile reference
  59. __docker_compose_services_from_build() {
  60. COMPREPLY=( $(compgen -W "$(__docker_compose_q ps --services --filter "source=build")" -- "$cur") )
  61. }
  62. # All services that are defined by an image
  63. __docker_compose_services_from_image() {
  64. COMPREPLY=( $(compgen -W "$(__docker_compose_q ps --services --filter "source=image")" -- "$cur") )
  65. }
  66. # The services for which at least one paused container exists
  67. __docker_compose_services_paused() {
  68. names=$(__docker_compose_q ps --services --filter "status=paused")
  69. COMPREPLY=( $(compgen -W "$names" -- "$cur") )
  70. }
  71. # The services for which at least one running container exists
  72. __docker_compose_services_running() {
  73. names=$(__docker_compose_q ps --services --filter "status=running")
  74. COMPREPLY=( $(compgen -W "$names" -- "$cur") )
  75. }
  76. # The services for which at least one stopped container exists
  77. __docker_compose_services_stopped() {
  78. names=$(__docker_compose_q ps --services --filter "status=stopped")
  79. COMPREPLY=( $(compgen -W "$names" -- "$cur") )
  80. }
  81. _docker_compose_build() {
  82. case "$prev" in
  83. --build-arg)
  84. COMPREPLY=( $( compgen -e -- "$cur" ) )
  85. __docker_compose_nospace
  86. return
  87. ;;
  88. esac
  89. case "$cur" in
  90. -*)
  91. COMPREPLY=( $( compgen -W "--build-arg --force-rm --help --memory --no-cache --pull" -- "$cur" ) )
  92. ;;
  93. *)
  94. __docker_compose_services_from_build
  95. ;;
  96. esac
  97. }
  98. _docker_compose_bundle() {
  99. case "$prev" in
  100. --output|-o)
  101. _filedir
  102. return
  103. ;;
  104. esac
  105. COMPREPLY=( $( compgen -W "--push-images --help --output -o" -- "$cur" ) )
  106. }
  107. _docker_compose_config() {
  108. COMPREPLY=( $( compgen -W "--help --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) )
  109. }
  110. _docker_compose_create() {
  111. case "$cur" in
  112. -*)
  113. COMPREPLY=( $( compgen -W "--build --force-recreate --help --no-build --no-recreate" -- "$cur" ) )
  114. ;;
  115. *)
  116. __docker_compose_services_all
  117. ;;
  118. esac
  119. }
  120. _docker_compose_docker_compose() {
  121. case "$prev" in
  122. --tlscacert|--tlscert|--tlskey)
  123. _filedir
  124. return
  125. ;;
  126. --file|-f)
  127. _filedir "y?(a)ml"
  128. return
  129. ;;
  130. --project-directory)
  131. _filedir -d
  132. return
  133. ;;
  134. $(__docker_compose_to_extglob "$top_level_options_with_args") )
  135. return
  136. ;;
  137. esac
  138. case "$cur" in
  139. -*)
  140. COMPREPLY=( $( compgen -W "$top_level_boolean_options $top_level_options_with_args --help -h --no-ansi --verbose --version -v" -- "$cur" ) )
  141. ;;
  142. *)
  143. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  144. ;;
  145. esac
  146. }
  147. _docker_compose_down() {
  148. case "$prev" in
  149. --rmi)
  150. COMPREPLY=( $( compgen -W "all local" -- "$cur" ) )
  151. return
  152. ;;
  153. --timeout|-t)
  154. return
  155. ;;
  156. esac
  157. case "$cur" in
  158. -*)
  159. COMPREPLY=( $( compgen -W "--help --rmi --timeout -t --volumes -v --remove-orphans" -- "$cur" ) )
  160. ;;
  161. esac
  162. }
  163. _docker_compose_events() {
  164. case "$prev" in
  165. --json)
  166. return
  167. ;;
  168. esac
  169. case "$cur" in
  170. -*)
  171. COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) )
  172. ;;
  173. *)
  174. __docker_compose_services_all
  175. ;;
  176. esac
  177. }
  178. _docker_compose_exec() {
  179. case "$prev" in
  180. --index|--user|-u)
  181. return
  182. ;;
  183. esac
  184. case "$cur" in
  185. -*)
  186. COMPREPLY=( $( compgen -W "-d --help --index --privileged -T --user -u" -- "$cur" ) )
  187. ;;
  188. *)
  189. __docker_compose_services_running
  190. ;;
  191. esac
  192. }
  193. _docker_compose_help() {
  194. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  195. }
  196. _docker_compose_images() {
  197. case "$cur" in
  198. -*)
  199. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  200. ;;
  201. *)
  202. __docker_compose_services_all
  203. ;;
  204. esac
  205. }
  206. _docker_compose_kill() {
  207. case "$prev" in
  208. -s)
  209. COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
  210. return
  211. ;;
  212. esac
  213. case "$cur" in
  214. -*)
  215. COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
  216. ;;
  217. *)
  218. __docker_compose_services_running
  219. ;;
  220. esac
  221. }
  222. _docker_compose_logs() {
  223. case "$prev" in
  224. --tail)
  225. return
  226. ;;
  227. esac
  228. case "$cur" in
  229. -*)
  230. COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) )
  231. ;;
  232. *)
  233. __docker_compose_services_all
  234. ;;
  235. esac
  236. }
  237. _docker_compose_pause() {
  238. case "$cur" in
  239. -*)
  240. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  241. ;;
  242. *)
  243. __docker_compose_services_running
  244. ;;
  245. esac
  246. }
  247. _docker_compose_port() {
  248. case "$prev" in
  249. --protocol)
  250. COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
  251. return;
  252. ;;
  253. --index)
  254. return;
  255. ;;
  256. esac
  257. case "$cur" in
  258. -*)
  259. COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
  260. ;;
  261. *)
  262. __docker_compose_services_all
  263. ;;
  264. esac
  265. }
  266. _docker_compose_ps() {
  267. case "$cur" in
  268. -*)
  269. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  270. ;;
  271. *)
  272. __docker_compose_services_all
  273. ;;
  274. esac
  275. }
  276. _docker_compose_pull() {
  277. case "$cur" in
  278. -*)
  279. COMPREPLY=( $( compgen -W "--help --ignore-pull-failures --parallel --quiet" -- "$cur" ) )
  280. ;;
  281. *)
  282. __docker_compose_services_from_image
  283. ;;
  284. esac
  285. }
  286. _docker_compose_push() {
  287. case "$cur" in
  288. -*)
  289. COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) )
  290. ;;
  291. *)
  292. __docker_compose_services_all
  293. ;;
  294. esac
  295. }
  296. _docker_compose_restart() {
  297. case "$prev" in
  298. --timeout|-t)
  299. return
  300. ;;
  301. esac
  302. case "$cur" in
  303. -*)
  304. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  305. ;;
  306. *)
  307. __docker_compose_services_running
  308. ;;
  309. esac
  310. }
  311. _docker_compose_rm() {
  312. case "$cur" in
  313. -*)
  314. COMPREPLY=( $( compgen -W "--force -f --help --stop -s -v" -- "$cur" ) )
  315. ;;
  316. *)
  317. if __docker_compose_has_option "--stop|-s" ; then
  318. __docker_compose_services_all
  319. else
  320. __docker_compose_services_stopped
  321. fi
  322. ;;
  323. esac
  324. }
  325. _docker_compose_run() {
  326. case "$prev" in
  327. -e)
  328. COMPREPLY=( $( compgen -e -- "$cur" ) )
  329. __docker_compose_nospace
  330. return
  331. ;;
  332. --entrypoint|--label|-l|--name|--user|-u|--volume|-v|--workdir|-w)
  333. return
  334. ;;
  335. esac
  336. case "$cur" in
  337. -*)
  338. 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" ) )
  339. ;;
  340. *)
  341. __docker_compose_services_all
  342. ;;
  343. esac
  344. }
  345. _docker_compose_scale() {
  346. case "$prev" in
  347. =)
  348. COMPREPLY=("$cur")
  349. return
  350. ;;
  351. --timeout|-t)
  352. return
  353. ;;
  354. esac
  355. case "$cur" in
  356. -*)
  357. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  358. ;;
  359. *)
  360. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  361. __docker_compose_nospace
  362. ;;
  363. esac
  364. }
  365. _docker_compose_start() {
  366. case "$cur" in
  367. -*)
  368. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  369. ;;
  370. *)
  371. __docker_compose_services_stopped
  372. ;;
  373. esac
  374. }
  375. _docker_compose_stop() {
  376. case "$prev" in
  377. --timeout|-t)
  378. return
  379. ;;
  380. esac
  381. case "$cur" in
  382. -*)
  383. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  384. ;;
  385. *)
  386. __docker_compose_services_running
  387. ;;
  388. esac
  389. }
  390. _docker_compose_top() {
  391. case "$cur" in
  392. -*)
  393. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  394. ;;
  395. *)
  396. __docker_compose_services_running
  397. ;;
  398. esac
  399. }
  400. _docker_compose_unpause() {
  401. case "$cur" in
  402. -*)
  403. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  404. ;;
  405. *)
  406. __docker_compose_services_paused
  407. ;;
  408. esac
  409. }
  410. _docker_compose_up() {
  411. case "$prev" in
  412. =)
  413. COMPREPLY=("$cur")
  414. return
  415. ;;
  416. --exit-code-from)
  417. __docker_compose_services_all
  418. return
  419. ;;
  420. --scale)
  421. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  422. __docker_compose_nospace
  423. return
  424. ;;
  425. --timeout|-t)
  426. return
  427. ;;
  428. esac
  429. case "$cur" in
  430. -*)
  431. COMPREPLY=( $( compgen -W "--abort-on-container-exit --build -d --exit-code-from --force-recreate --help --no-build --no-color --no-deps --no-recreate --no-start --remove-orphans --scale --timeout -t" -- "$cur" ) )
  432. ;;
  433. *)
  434. __docker_compose_services_all
  435. ;;
  436. esac
  437. }
  438. _docker_compose_version() {
  439. case "$cur" in
  440. -*)
  441. COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
  442. ;;
  443. esac
  444. }
  445. _docker_compose() {
  446. local previous_extglob_setting=$(shopt -p extglob)
  447. shopt -s extglob
  448. local commands=(
  449. build
  450. bundle
  451. config
  452. create
  453. down
  454. events
  455. exec
  456. help
  457. images
  458. kill
  459. logs
  460. pause
  461. port
  462. ps
  463. pull
  464. push
  465. restart
  466. rm
  467. run
  468. scale
  469. start
  470. stop
  471. top
  472. unpause
  473. up
  474. version
  475. )
  476. # Options for the docker daemon that have to be passed to secondary calls to
  477. # docker-compose executed by this script.
  478. # Other global otions that are not relevant for secondary calls are defined in
  479. # `_docker_compose_docker_compose`.
  480. local top_level_boolean_options="
  481. --skip-hostname-check
  482. --tls
  483. --tlsverify
  484. "
  485. local top_level_options_with_args="
  486. --file -f
  487. --host -H
  488. --project-directory
  489. --project-name -p
  490. --tlscacert
  491. --tlscert
  492. --tlskey
  493. "
  494. COMPREPLY=()
  495. local cur prev words cword
  496. _get_comp_words_by_ref -n : cur prev words cword
  497. # search subcommand and invoke its handler.
  498. # special treatment of some top-level options
  499. local command='docker_compose'
  500. local top_level_options=()
  501. local counter=1
  502. while [ $counter -lt $cword ]; do
  503. case "${words[$counter]}" in
  504. $(__docker_compose_to_extglob "$top_level_boolean_options") )
  505. local opt=${words[counter]}
  506. top_level_options+=($opt)
  507. ;;
  508. $(__docker_compose_to_extglob "$top_level_options_with_args") )
  509. local opt=${words[counter]}
  510. local arg=${words[++counter]}
  511. top_level_options+=($opt $arg)
  512. ;;
  513. -*)
  514. ;;
  515. *)
  516. command="${words[$counter]}"
  517. break
  518. ;;
  519. esac
  520. (( counter++ ))
  521. done
  522. local completions_func=_docker_compose_${command//-/_}
  523. declare -F $completions_func >/dev/null && $completions_func
  524. eval "$previous_extglob_setting"
  525. return 0
  526. }
  527. complete -F _docker_compose docker-compose docker-compose.exe