docker-compose 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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. # suppress trailing whitespace
  19. __docker_compose_nospace() {
  20. # compopt is not available in ancient bash versions
  21. type compopt &>/dev/null && compopt -o nospace
  22. }
  23. # For compatibility reasons, Compose and therefore its completion supports several
  24. # stack compositon files as listed here, in descending priority.
  25. # Support for these filenames might be dropped in some future version.
  26. __docker_compose_compose_file() {
  27. local file
  28. for file in docker-compose.y{,a}ml ; do
  29. [ -e $file ] && {
  30. echo $file
  31. return
  32. }
  33. done
  34. echo docker-compose.yml
  35. }
  36. # Extracts all service names from the compose file.
  37. ___docker_compose_all_services_in_compose_file() {
  38. awk -F: '/^[a-zA-Z0-9]/{print $1}' "${compose_file:-$(__docker_compose_compose_file)}" 2>/dev/null
  39. }
  40. # All services, even those without an existing container
  41. __docker_compose_services_all() {
  42. COMPREPLY=( $(compgen -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  43. }
  44. # All services that have an entry with the given key in their compose_file section
  45. ___docker_compose_services_with_key() {
  46. # flatten sections to one line, then filter lines containing the key and return section name.
  47. awk '/^[a-zA-Z0-9]/{printf "\n"};{printf $0;next;}' "${compose_file:-$(__docker_compose_compose_file)}" 2>/dev/null | awk -F: -v key=": +$1:" '$0 ~ key {print $1}'
  48. }
  49. # All services that are defined by a Dockerfile reference
  50. __docker_compose_services_from_build() {
  51. COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key build)" -- "$cur") )
  52. }
  53. # All services that are defined by an image
  54. __docker_compose_services_from_image() {
  55. COMPREPLY=( $(compgen -W "$(___docker_compose_services_with_key image)" -- "$cur") )
  56. }
  57. # The services for which containers have been created, optionally filtered
  58. # by a boolean expression passed in as argument.
  59. __docker_compose_services_with() {
  60. local containers names
  61. containers="$(docker-compose 2>/dev/null ${compose_file:+-f $compose_file} ${compose_project:+-p $compose_project} ps -q)"
  62. names=( $(docker 2>/dev/null inspect --format "{{if ${1:-true}}} {{ .Name }} {{end}}" $containers) )
  63. names=( ${names[@]%_*} ) # strip trailing numbers
  64. names=( ${names[@]#*_} ) # strip project name
  65. COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") )
  66. }
  67. # The services for which at least one paused container exists
  68. __docker_compose_services_paused() {
  69. __docker_compose_services_with '.State.Paused'
  70. }
  71. # The services for which at least one running container exists
  72. __docker_compose_services_running() {
  73. __docker_compose_services_with '.State.Running'
  74. }
  75. # The services for which at least one stopped container exists
  76. __docker_compose_services_stopped() {
  77. __docker_compose_services_with 'not .State.Running'
  78. }
  79. _docker_compose_build() {
  80. case "$cur" in
  81. -*)
  82. COMPREPLY=( $( compgen -W "--force-rm --help --no-cache --pull" -- "$cur" ) )
  83. ;;
  84. *)
  85. __docker_compose_services_from_build
  86. ;;
  87. esac
  88. }
  89. _docker_compose_config() {
  90. COMPREPLY=( $( compgen -W "--help --quiet -q --services" -- "$cur" ) )
  91. }
  92. _docker_compose_docker_compose() {
  93. case "$prev" in
  94. --file|-f)
  95. _filedir "y?(a)ml"
  96. return
  97. ;;
  98. --project-name|-p)
  99. return
  100. ;;
  101. esac
  102. case "$cur" in
  103. -*)
  104. COMPREPLY=( $( compgen -W "--file -f --help -h --project-name -p --verbose --version -v" -- "$cur" ) )
  105. ;;
  106. *)
  107. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  108. ;;
  109. esac
  110. }
  111. _docker_compose_down() {
  112. case "$prev" in
  113. --rmi)
  114. COMPREPLY=( $( compgen -W "all local" -- "$cur" ) )
  115. return
  116. ;;
  117. esac
  118. case "$cur" in
  119. -*)
  120. COMPREPLY=( $( compgen -W "--help --rmi --volumes -v" -- "$cur" ) )
  121. ;;
  122. esac
  123. }
  124. _docker_compose_events() {
  125. case "$prev" in
  126. --json)
  127. return
  128. ;;
  129. esac
  130. case "$cur" in
  131. -*)
  132. COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) )
  133. ;;
  134. *)
  135. __docker_compose_services_all
  136. ;;
  137. esac
  138. }
  139. _docker_compose_help() {
  140. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  141. }
  142. _docker_compose_kill() {
  143. case "$prev" in
  144. -s)
  145. COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
  146. return
  147. ;;
  148. esac
  149. case "$cur" in
  150. -*)
  151. COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
  152. ;;
  153. *)
  154. __docker_compose_services_running
  155. ;;
  156. esac
  157. }
  158. _docker_compose_logs() {
  159. case "$cur" in
  160. -*)
  161. COMPREPLY=( $( compgen -W "--help --no-color" -- "$cur" ) )
  162. ;;
  163. *)
  164. __docker_compose_services_all
  165. ;;
  166. esac
  167. }
  168. _docker_compose_pause() {
  169. case "$cur" in
  170. -*)
  171. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  172. ;;
  173. *)
  174. __docker_compose_services_running
  175. ;;
  176. esac
  177. }
  178. _docker_compose_port() {
  179. case "$prev" in
  180. --protocol)
  181. COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
  182. return;
  183. ;;
  184. --index)
  185. return;
  186. ;;
  187. esac
  188. case "$cur" in
  189. -*)
  190. COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
  191. ;;
  192. *)
  193. __docker_compose_services_all
  194. ;;
  195. esac
  196. }
  197. _docker_compose_ps() {
  198. case "$cur" in
  199. -*)
  200. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  201. ;;
  202. *)
  203. __docker_compose_services_all
  204. ;;
  205. esac
  206. }
  207. _docker_compose_pull() {
  208. case "$cur" in
  209. -*)
  210. COMPREPLY=( $( compgen -W "--help --ignore-pull-failures" -- "$cur" ) )
  211. ;;
  212. *)
  213. __docker_compose_services_from_image
  214. ;;
  215. esac
  216. }
  217. _docker_compose_restart() {
  218. case "$prev" in
  219. --timeout|-t)
  220. return
  221. ;;
  222. esac
  223. case "$cur" in
  224. -*)
  225. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  226. ;;
  227. *)
  228. __docker_compose_services_running
  229. ;;
  230. esac
  231. }
  232. _docker_compose_rm() {
  233. case "$cur" in
  234. -*)
  235. COMPREPLY=( $( compgen -W "--force -f --help -v" -- "$cur" ) )
  236. ;;
  237. *)
  238. __docker_compose_services_stopped
  239. ;;
  240. esac
  241. }
  242. _docker_compose_run() {
  243. case "$prev" in
  244. -e)
  245. COMPREPLY=( $( compgen -e -- "$cur" ) )
  246. __docker_compose_nospace
  247. return
  248. ;;
  249. --entrypoint|--name|--user|-u)
  250. return
  251. ;;
  252. esac
  253. case "$cur" in
  254. -*)
  255. COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u" -- "$cur" ) )
  256. ;;
  257. *)
  258. __docker_compose_services_all
  259. ;;
  260. esac
  261. }
  262. _docker_compose_scale() {
  263. case "$prev" in
  264. =)
  265. COMPREPLY=("$cur")
  266. return
  267. ;;
  268. --timeout|-t)
  269. return
  270. ;;
  271. esac
  272. case "$cur" in
  273. -*)
  274. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  275. ;;
  276. *)
  277. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  278. __docker_compose_nospace
  279. ;;
  280. esac
  281. }
  282. _docker_compose_start() {
  283. case "$cur" in
  284. -*)
  285. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  286. ;;
  287. *)
  288. __docker_compose_services_stopped
  289. ;;
  290. esac
  291. }
  292. _docker_compose_stop() {
  293. case "$prev" in
  294. --timeout|-t)
  295. return
  296. ;;
  297. esac
  298. case "$cur" in
  299. -*)
  300. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  301. ;;
  302. *)
  303. __docker_compose_services_running
  304. ;;
  305. esac
  306. }
  307. _docker_compose_unpause() {
  308. case "$cur" in
  309. -*)
  310. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  311. ;;
  312. *)
  313. __docker_compose_services_paused
  314. ;;
  315. esac
  316. }
  317. _docker_compose_up() {
  318. case "$prev" in
  319. --timeout|-t)
  320. return
  321. ;;
  322. esac
  323. case "$cur" in
  324. -*)
  325. COMPREPLY=( $( compgen -W "--abort-on-container-exit -d --force-recreate --help --no-build --no-color --no-deps --no-recreate --timeout -t" -- "$cur" ) )
  326. ;;
  327. *)
  328. __docker_compose_services_all
  329. ;;
  330. esac
  331. }
  332. _docker_compose_version() {
  333. case "$cur" in
  334. -*)
  335. COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
  336. ;;
  337. esac
  338. }
  339. _docker_compose() {
  340. local previous_extglob_setting=$(shopt -p extglob)
  341. shopt -s extglob
  342. local commands=(
  343. build
  344. config
  345. down
  346. events
  347. help
  348. kill
  349. logs
  350. pause
  351. port
  352. ps
  353. pull
  354. restart
  355. rm
  356. run
  357. scale
  358. start
  359. stop
  360. unpause
  361. up
  362. version
  363. )
  364. COMPREPLY=()
  365. local cur prev words cword
  366. _get_comp_words_by_ref -n : cur prev words cword
  367. # search subcommand and invoke its handler.
  368. # special treatment of some top-level options
  369. local command='docker_compose'
  370. local counter=1
  371. local compose_file compose_project
  372. while [ $counter -lt $cword ]; do
  373. case "${words[$counter]}" in
  374. --file|-f)
  375. (( counter++ ))
  376. compose_file="${words[$counter]}"
  377. ;;
  378. --project-name|p)
  379. (( counter++ ))
  380. compose_project="${words[$counter]}"
  381. ;;
  382. -*)
  383. ;;
  384. *)
  385. command="${words[$counter]}"
  386. break
  387. ;;
  388. esac
  389. (( counter++ ))
  390. done
  391. local completions_func=_docker_compose_${command//-/_}
  392. declare -F $completions_func >/dev/null && $completions_func
  393. eval "$previous_extglob_setting"
  394. return 0
  395. }
  396. complete -F _docker_compose docker-compose