docker-compose 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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 fig.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 "--help --no-cache --pull" -- "$cur" ) )
  83. ;;
  84. *)
  85. __docker_compose_services_from_build
  86. ;;
  87. esac
  88. }
  89. _docker_compose_docker_compose() {
  90. case "$prev" in
  91. --file|-f)
  92. _filedir "y?(a)ml"
  93. return
  94. ;;
  95. --project-name|-p)
  96. return
  97. ;;
  98. --x-network-driver)
  99. COMPREPLY=( $( compgen -W "bridge host none overlay" -- "$cur" ) )
  100. return
  101. ;;
  102. esac
  103. case "$cur" in
  104. -*)
  105. COMPREPLY=( $( compgen -W "--file -f --help -h --project-name -p --verbose --version -v --x-networking --x-network-driver" -- "$cur" ) )
  106. ;;
  107. *)
  108. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  109. ;;
  110. esac
  111. }
  112. _docker_compose_help() {
  113. COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
  114. }
  115. _docker_compose_kill() {
  116. case "$prev" in
  117. -s)
  118. COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
  119. return
  120. ;;
  121. esac
  122. case "$cur" in
  123. -*)
  124. COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
  125. ;;
  126. *)
  127. __docker_compose_services_running
  128. ;;
  129. esac
  130. }
  131. _docker_compose_logs() {
  132. case "$cur" in
  133. -*)
  134. COMPREPLY=( $( compgen -W "--help --no-color" -- "$cur" ) )
  135. ;;
  136. *)
  137. __docker_compose_services_all
  138. ;;
  139. esac
  140. }
  141. _docker_compose_migrate_to_labels() {
  142. case "$cur" in
  143. -*)
  144. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  145. ;;
  146. esac
  147. }
  148. _docker_compose_pause() {
  149. case "$cur" in
  150. -*)
  151. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  152. ;;
  153. *)
  154. __docker_compose_services_running
  155. ;;
  156. esac
  157. }
  158. _docker_compose_port() {
  159. case "$prev" in
  160. --protocol)
  161. COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
  162. return;
  163. ;;
  164. --index)
  165. return;
  166. ;;
  167. esac
  168. case "$cur" in
  169. -*)
  170. COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
  171. ;;
  172. *)
  173. __docker_compose_services_all
  174. ;;
  175. esac
  176. }
  177. _docker_compose_ps() {
  178. case "$cur" in
  179. -*)
  180. COMPREPLY=( $( compgen -W "--help -q" -- "$cur" ) )
  181. ;;
  182. *)
  183. __docker_compose_services_all
  184. ;;
  185. esac
  186. }
  187. _docker_compose_pull() {
  188. case "$cur" in
  189. -*)
  190. COMPREPLY=( $( compgen -W "--help --ignore-pull-failures" -- "$cur" ) )
  191. ;;
  192. *)
  193. __docker_compose_services_from_image
  194. ;;
  195. esac
  196. }
  197. _docker_compose_restart() {
  198. case "$prev" in
  199. --timeout|-t)
  200. return
  201. ;;
  202. esac
  203. case "$cur" in
  204. -*)
  205. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  206. ;;
  207. *)
  208. __docker_compose_services_running
  209. ;;
  210. esac
  211. }
  212. _docker_compose_rm() {
  213. case "$cur" in
  214. -*)
  215. COMPREPLY=( $( compgen -W "--force -f --help -v" -- "$cur" ) )
  216. ;;
  217. *)
  218. __docker_compose_services_stopped
  219. ;;
  220. esac
  221. }
  222. _docker_compose_run() {
  223. case "$prev" in
  224. -e)
  225. COMPREPLY=( $( compgen -e -- "$cur" ) )
  226. __docker_compose_nospace
  227. return
  228. ;;
  229. --entrypoint|--name|--user|-u)
  230. return
  231. ;;
  232. esac
  233. case "$cur" in
  234. -*)
  235. COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --name --no-deps --publish -p --rm --service-ports -T --user -u" -- "$cur" ) )
  236. ;;
  237. *)
  238. __docker_compose_services_all
  239. ;;
  240. esac
  241. }
  242. _docker_compose_scale() {
  243. case "$prev" in
  244. =)
  245. COMPREPLY=("$cur")
  246. return
  247. ;;
  248. --timeout|-t)
  249. return
  250. ;;
  251. esac
  252. case "$cur" in
  253. -*)
  254. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  255. ;;
  256. *)
  257. COMPREPLY=( $(compgen -S "=" -W "$(___docker_compose_all_services_in_compose_file)" -- "$cur") )
  258. __docker_compose_nospace
  259. ;;
  260. esac
  261. }
  262. _docker_compose_start() {
  263. case "$cur" in
  264. -*)
  265. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  266. ;;
  267. *)
  268. __docker_compose_services_stopped
  269. ;;
  270. esac
  271. }
  272. _docker_compose_stop() {
  273. case "$prev" in
  274. --timeout|-t)
  275. return
  276. ;;
  277. esac
  278. case "$cur" in
  279. -*)
  280. COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
  281. ;;
  282. *)
  283. __docker_compose_services_running
  284. ;;
  285. esac
  286. }
  287. _docker_compose_unpause() {
  288. case "$cur" in
  289. -*)
  290. COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
  291. ;;
  292. *)
  293. __docker_compose_services_paused
  294. ;;
  295. esac
  296. }
  297. _docker_compose_up() {
  298. case "$prev" in
  299. --timeout|-t)
  300. return
  301. ;;
  302. esac
  303. case "$cur" in
  304. -*)
  305. COMPREPLY=( $( compgen -W "-d --help --no-build --no-color --no-deps --no-recreate --force-recreate --timeout -t" -- "$cur" ) )
  306. ;;
  307. *)
  308. __docker_compose_services_all
  309. ;;
  310. esac
  311. }
  312. _docker_compose_version() {
  313. case "$cur" in
  314. -*)
  315. COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
  316. ;;
  317. esac
  318. }
  319. _docker_compose() {
  320. local previous_extglob_setting=$(shopt -p extglob)
  321. shopt -s extglob
  322. local commands=(
  323. build
  324. help
  325. kill
  326. logs
  327. migrate-to-labels
  328. pause
  329. port
  330. ps
  331. pull
  332. restart
  333. rm
  334. run
  335. scale
  336. start
  337. stop
  338. unpause
  339. up
  340. version
  341. )
  342. COMPREPLY=()
  343. local cur prev words cword
  344. _get_comp_words_by_ref -n : cur prev words cword
  345. # search subcommand and invoke its handler.
  346. # special treatment of some top-level options
  347. local command='docker_compose'
  348. local counter=1
  349. local compose_file compose_project
  350. while [ $counter -lt $cword ]; do
  351. case "${words[$counter]}" in
  352. --file|-f)
  353. (( counter++ ))
  354. compose_file="${words[$counter]}"
  355. ;;
  356. --project-name|p)
  357. (( counter++ ))
  358. compose_project="${words[$counter]}"
  359. ;;
  360. --x-network-driver)
  361. (( counter++ ))
  362. ;;
  363. -*)
  364. ;;
  365. *)
  366. command="${words[$counter]}"
  367. break
  368. ;;
  369. esac
  370. (( counter++ ))
  371. done
  372. local completions_func=_docker_compose_${command//-/_}
  373. declare -F $completions_func >/dev/null && $completions_func
  374. eval "$previous_extglob_setting"
  375. return 0
  376. }
  377. complete -F _docker_compose docker-compose