docker-compose 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. #!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_kill() {
  186. case "$prev" in
  187. -s)
  188. COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
  189. return
  190. ;;
  191. esac
  192. case "$cur" in
  193. -*)
  194. COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
  195. ;;
  196. *)
  197. __docker_compose_services_running
  198. ;;
  199. esac
  200. }
  201. _docker_compose_logs() {
  202. case "$prev" in
  203. --tail)
  204. return
  205. ;;
  206. esac
  207. case "$cur" in
  208. -*)
  209. COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) )
  210. ;;
  211. *)
  212. __docker_compose_services_all
  213. ;;
  214. esac
  215. }
  216. _docker_compose_pause() {
  217. case "$cur" in
  218. -*)
  219. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  220. ;;
  221. *)
  222. __docker_compose_services_running
  223. ;;
  224. esac
  225. }
  226. _docker_compose_port() {
  227. case "$prev" in
  228. --protocol)
  229. COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
  230. return;
  231. ;;
  232. --index)
  233. return;
  234. ;;
  235. esac
  236. case "$cur" in
  237. -*)
  238. COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
  239. ;;
  240. *)
  241. __docker_compose_services_all
  242. ;;
  243. esac
  244. }
  245. _docker_compose_ps() {
  246. case "$cur" in
  247. -*)
  248. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  249. ;;
  250. *)
  251. __docker_compose_services_all
  252. ;;
  253. esac
  254. }
  255. _docker_compose_pull() {
  256. case "$cur" in
  257. -*)
  258. COMPREPLY=( $( compgen -W "--help --ignore-pull-failures" -- "$cur" ) )
  259. ;;
  260. *)
  261. __docker_compose_services_from_image
  262. ;;
  263. esac
  264. }
  265. _docker_compose_push() {
  266. case "$cur" in
  267. -*)
  268. COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) )
  269. ;;
  270. *)
  271. __docker_compose_services_all
  272. ;;
  273. esac
  274. }
  275. _docker_compose_restart() {
  276. case "$prev" in
  277. --timeout|-t)
  278. return
  279. ;;
  280. esac
  281. case "$cur" in
  282. -*)
  283. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  284. ;;
  285. *)
  286. __docker_compose_services_running
  287. ;;
  288. esac
  289. }
  290. _docker_compose_rm() {
  291. case "$cur" in
  292. -*)
  293. COMPREPLY=( $( compgen -W "--force -f --help -v" -- "$cur" ) )
  294. ;;
  295. *)
  296. __docker_compose_services_stopped
  297. ;;
  298. esac
  299. }
  300. _docker_compose_run() {
  301. case "$prev" in
  302. -e)
  303. COMPREPLY=( $( compgen -e -- "$cur" ) )
  304. __docker_compose_nospace
  305. return
  306. ;;
  307. --entrypoint|--name|--user|-u|--workdir|-w)
  308. return
  309. ;;
  310. esac
  311. case "$cur" in
  312. -*)
  313. COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u --workdir -w" -- "$cur" ) )
  314. ;;
  315. *)
  316. __docker_compose_services_all
  317. ;;
  318. esac
  319. }
  320. _docker_compose_scale() {
  321. case "$prev" in
  322. =)
  323. COMPREPLY=("$cur")
  324. return
  325. ;;
  326. --timeout|-t)
  327. return
  328. ;;
  329. esac
  330. case "$cur" in
  331. -*)
  332. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  333. ;;
  334. *)
  335. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  336. __docker_compose_nospace
  337. ;;
  338. esac
  339. }
  340. _docker_compose_start() {
  341. case "$cur" in
  342. -*)
  343. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  344. ;;
  345. *)
  346. __docker_compose_services_stopped
  347. ;;
  348. esac
  349. }
  350. _docker_compose_stop() {
  351. case "$prev" in
  352. --timeout|-t)
  353. return
  354. ;;
  355. esac
  356. case "$cur" in
  357. -*)
  358. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  359. ;;
  360. *)
  361. __docker_compose_services_running
  362. ;;
  363. esac
  364. }
  365. _docker_compose_unpause() {
  366. case "$cur" in
  367. -*)
  368. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  369. ;;
  370. *)
  371. __docker_compose_services_paused
  372. ;;
  373. esac
  374. }
  375. _docker_compose_up() {
  376. case "$prev" in
  377. --timeout|-t)
  378. return
  379. ;;
  380. esac
  381. case "$cur" in
  382. -*)
  383. COMPREPLY=( $( compgen -W "--abort-on-container-exit --build -d --force-recreate --help --no-build --no-color --no-deps --no-recreate --timeout -t --remove-orphans" -- "$cur" ) )
  384. ;;
  385. *)
  386. __docker_compose_services_all
  387. ;;
  388. esac
  389. }
  390. _docker_compose_version() {
  391. case "$cur" in
  392. -*)
  393. COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
  394. ;;
  395. esac
  396. }
  397. _docker_compose() {
  398. local previous_extglob_setting=$(shopt -p extglob)
  399. shopt -s extglob
  400. local commands=(
  401. build
  402. bundle
  403. config
  404. create
  405. down
  406. events
  407. exec
  408. help
  409. kill
  410. logs
  411. pause
  412. port
  413. ps
  414. pull
  415. push
  416. restart
  417. rm
  418. run
  419. scale
  420. start
  421. stop
  422. unpause
  423. up
  424. version
  425. )
  426. # options for the docker daemon that have to be passed to secondary calls to
  427. # docker-compose executed by this script
  428. local daemon_boolean_options="
  429. --skip-hostname-check
  430. --tls
  431. --tlsverify
  432. "
  433. local daemon_options_with_args="
  434. --file -f
  435. --host -H
  436. --project-name -p
  437. --tlscacert
  438. --tlscert
  439. --tlskey
  440. "
  441. COMPREPLY=()
  442. local cur prev words cword
  443. _get_comp_words_by_ref -n : cur prev words cword
  444. # search subcommand and invoke its handler.
  445. # special treatment of some top-level options
  446. local command='docker_compose'
  447. local daemon_options=()
  448. local counter=1
  449. while [ $counter -lt $cword ]; do
  450. case "${words[$counter]}" in
  451. $(__docker_compose_to_extglob "$daemon_boolean_options") )
  452. local opt=${words[counter]}
  453. daemon_options+=($opt)
  454. ;;
  455. $(__docker_compose_to_extglob "$daemon_options_with_args") )
  456. local opt=${words[counter]}
  457. local arg=${words[++counter]}
  458. daemon_options+=($opt $arg)
  459. ;;
  460. -*)
  461. ;;
  462. *)
  463. command="${words[$counter]}"
  464. break
  465. ;;
  466. esac
  467. (( counter++ ))
  468. done
  469. local completions_func=_docker_compose_${command//-/_}
  470. declare -F $completions_func >/dev/null && $completions_func
  471. eval "$previous_extglob_setting"
  472. return 0
  473. }
  474. complete -F _docker_compose docker-compose