docker-compose 11 KB

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