1
0

docker-compose 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  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 ${compose_file:+-f $compose_file} ${compose_project:+-p $compose_project} "$@"
  20. }
  21. # suppress trailing whitespace
  22. __docker_compose_nospace() {
  23. # compopt is not available in ancient bash versions
  24. type compopt &>/dev/null && compopt -o nospace
  25. }
  26. # For compatibility reasons, Compose and therefore its completion supports several
  27. # stack compositon files as listed here, in descending priority.
  28. # Support for these filenames might be dropped in some future version.
  29. __docker_compose_compose_file() {
  30. local file
  31. for file in docker-compose.y{,a}ml ; do
  32. [ -e $file ] && {
  33. echo $file
  34. return
  35. }
  36. done
  37. echo docker-compose.yml
  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_config() {
  95. COMPREPLY=( $( compgen -W "--help --quiet -q --services" -- "$cur" ) )
  96. }
  97. _docker_compose_create() {
  98. case "$cur" in
  99. -*)
  100. COMPREPLY=( $( compgen -W "--force-recreate --help --no-build --no-recreate" -- "$cur" ) )
  101. ;;
  102. *)
  103. __docker_compose_services_all
  104. ;;
  105. esac
  106. }
  107. _docker_compose_docker_compose() {
  108. case "$prev" in
  109. --file|-f)
  110. _filedir "y?(a)ml"
  111. return
  112. ;;
  113. --project-name|-p)
  114. return
  115. ;;
  116. esac
  117. case "$cur" in
  118. -*)
  119. COMPREPLY=( $( compgen -W "--file -f --help -h --project-name -p --verbose --version -v" -- "$cur" ) )
  120. ;;
  121. *)
  122. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  123. ;;
  124. esac
  125. }
  126. _docker_compose_down() {
  127. case "$prev" in
  128. --rmi)
  129. COMPREPLY=( $( compgen -W "all local" -- "$cur" ) )
  130. return
  131. ;;
  132. esac
  133. case "$cur" in
  134. -*)
  135. COMPREPLY=( $( compgen -W "--help --rmi --volumes -v" -- "$cur" ) )
  136. ;;
  137. esac
  138. }
  139. _docker_compose_events() {
  140. case "$prev" in
  141. --json)
  142. return
  143. ;;
  144. esac
  145. case "$cur" in
  146. -*)
  147. COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) )
  148. ;;
  149. *)
  150. __docker_compose_services_all
  151. ;;
  152. esac
  153. }
  154. _docker_compose_help() {
  155. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  156. }
  157. _docker_compose_kill() {
  158. case "$prev" in
  159. -s)
  160. COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
  161. return
  162. ;;
  163. esac
  164. case "$cur" in
  165. -*)
  166. COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
  167. ;;
  168. *)
  169. __docker_compose_services_running
  170. ;;
  171. esac
  172. }
  173. _docker_compose_logs() {
  174. case "$cur" in
  175. -*)
  176. COMPREPLY=( $( compgen -W "--help --no-color" -- "$cur" ) )
  177. ;;
  178. *)
  179. __docker_compose_services_all
  180. ;;
  181. esac
  182. }
  183. _docker_compose_pause() {
  184. case "$cur" in
  185. -*)
  186. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  187. ;;
  188. *)
  189. __docker_compose_services_running
  190. ;;
  191. esac
  192. }
  193. _docker_compose_port() {
  194. case "$prev" in
  195. --protocol)
  196. COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
  197. return;
  198. ;;
  199. --index)
  200. return;
  201. ;;
  202. esac
  203. case "$cur" in
  204. -*)
  205. COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
  206. ;;
  207. *)
  208. __docker_compose_services_all
  209. ;;
  210. esac
  211. }
  212. _docker_compose_ps() {
  213. case "$cur" in
  214. -*)
  215. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  216. ;;
  217. *)
  218. __docker_compose_services_all
  219. ;;
  220. esac
  221. }
  222. _docker_compose_pull() {
  223. case "$cur" in
  224. -*)
  225. COMPREPLY=( $( compgen -W "--help --ignore-pull-failures" -- "$cur" ) )
  226. ;;
  227. *)
  228. __docker_compose_services_from_image
  229. ;;
  230. esac
  231. }
  232. _docker_compose_restart() {
  233. case "$prev" in
  234. --timeout|-t)
  235. return
  236. ;;
  237. esac
  238. case "$cur" in
  239. -*)
  240. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  241. ;;
  242. *)
  243. __docker_compose_services_running
  244. ;;
  245. esac
  246. }
  247. _docker_compose_rm() {
  248. case "$cur" in
  249. -*)
  250. COMPREPLY=( $( compgen -W "--force -f --help -v" -- "$cur" ) )
  251. ;;
  252. *)
  253. __docker_compose_services_stopped
  254. ;;
  255. esac
  256. }
  257. _docker_compose_run() {
  258. case "$prev" in
  259. -e)
  260. COMPREPLY=( $( compgen -e -- "$cur" ) )
  261. __docker_compose_nospace
  262. return
  263. ;;
  264. --entrypoint|--name|--user|-u)
  265. return
  266. ;;
  267. esac
  268. case "$cur" in
  269. -*)
  270. COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u" -- "$cur" ) )
  271. ;;
  272. *)
  273. __docker_compose_services_all
  274. ;;
  275. esac
  276. }
  277. _docker_compose_scale() {
  278. case "$prev" in
  279. =)
  280. COMPREPLY=("$cur")
  281. return
  282. ;;
  283. --timeout|-t)
  284. return
  285. ;;
  286. esac
  287. case "$cur" in
  288. -*)
  289. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  290. ;;
  291. *)
  292. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  293. __docker_compose_nospace
  294. ;;
  295. esac
  296. }
  297. _docker_compose_start() {
  298. case "$cur" in
  299. -*)
  300. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  301. ;;
  302. *)
  303. __docker_compose_services_stopped
  304. ;;
  305. esac
  306. }
  307. _docker_compose_stop() {
  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_unpause() {
  323. case "$cur" in
  324. -*)
  325. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  326. ;;
  327. *)
  328. __docker_compose_services_paused
  329. ;;
  330. esac
  331. }
  332. _docker_compose_up() {
  333. case "$prev" in
  334. --timeout|-t)
  335. return
  336. ;;
  337. esac
  338. case "$cur" in
  339. -*)
  340. COMPREPLY=( $( compgen -W "--abort-on-container-exit -d --force-recreate --help --no-build --no-color --no-deps --no-recreate --timeout -t" -- "$cur" ) )
  341. ;;
  342. *)
  343. __docker_compose_services_all
  344. ;;
  345. esac
  346. }
  347. _docker_compose_version() {
  348. case "$cur" in
  349. -*)
  350. COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
  351. ;;
  352. esac
  353. }
  354. _docker_compose() {
  355. local previous_extglob_setting=$(shopt -p extglob)
  356. shopt -s extglob
  357. local commands=(
  358. build
  359. config
  360. create
  361. down
  362. events
  363. help
  364. kill
  365. logs
  366. pause
  367. port
  368. ps
  369. pull
  370. restart
  371. rm
  372. run
  373. scale
  374. start
  375. stop
  376. unpause
  377. up
  378. version
  379. )
  380. COMPREPLY=()
  381. local cur prev words cword
  382. _get_comp_words_by_ref -n : cur prev words cword
  383. # search subcommand and invoke its handler.
  384. # special treatment of some top-level options
  385. local command='docker_compose'
  386. local counter=1
  387. local compose_file compose_project
  388. while [ $counter -lt $cword ]; do
  389. case "${words[$counter]}" in
  390. --file|-f)
  391. (( counter++ ))
  392. compose_file="${words[$counter]}"
  393. ;;
  394. --project-name|p)
  395. (( counter++ ))
  396. compose_project="${words[$counter]}"
  397. ;;
  398. -*)
  399. ;;
  400. *)
  401. command="${words[$counter]}"
  402. break
  403. ;;
  404. esac
  405. (( counter++ ))
  406. done
  407. local completions_func=_docker_compose_${command//-/_}
  408. declare -F $completions_func >/dev/null && $completions_func
  409. eval "$previous_extglob_setting"
  410. return 0
  411. }
  412. complete -F _docker_compose docker-compose