Blame view
plugins/docker-compose/_docker-compose
17.7 KB
|
e4774f203
|
1 2 3 4 5 6 7 8 9 |
#compdef docker-compose # Description # ----------- # zsh completion for docker-compose # https://github.com/sdurrheimer/docker-compose-zsh-completion # ------------------------------------------------------------------------- # Version # ------- |
|
d9bebbb3c
|
10 |
# 1.5.0 |
|
e4774f203
|
11 12 13 14 15 16 17 18 19 20 |
# ------------------------------------------------------------------------- # Authors # ------- # * Steve Durrheimer <s.durrheimer@gmail.com> # ------------------------------------------------------------------------- # Inspiration # ----------- # * @albers docker-compose bash completion script # * @felixr docker zsh completion script : https://github.com/felixr/docker-zsh-completion # ------------------------------------------------------------------------- |
|
d9bebbb3c
|
21 22 |
__docker-compose_q() {
docker-compose 2>/dev/null $compose_options "$@"
|
|
e4774f203
|
23 |
} |
|
d9bebbb3c
|
24 25 |
# All services defined in docker-compose.yml
__docker-compose_all_services_in_compose_file() {
|
|
e4774f203
|
26 27 |
local already_selected
local -a services
|
|
d9bebbb3c
|
28 29 30 |
already_selected=$(echo $words | tr " " "|")
__docker-compose_q config --services \
| grep -Ev "^(${already_selected})$"
|
|
e4774f203
|
31 32 33 34 |
}
# All services, even those without an existing container
__docker-compose_services_all() {
|
|
d9bebbb3c
|
35 36 37 38 39 40 |
[[ $PREFIX = -* ]] && return 1
integer ret=1
services=$(__docker-compose_all_services_in_compose_file)
_alternative "args:services:($services)" && ret=0
return ret
|
|
e4774f203
|
41 42 43 |
} # All services that have an entry with the given key in their docker-compose.yml section |
|
d9bebbb3c
|
44 |
__docker-compose_services_with_key() {
|
|
e4774f203
|
45 46 |
local already_selected
local -a buildable
|
|
d9bebbb3c
|
47 |
already_selected=$(echo $words | tr " " "|") |
|
e4774f203
|
48 |
# flatten sections to one line, then filter lines containing the key and return section name. |
|
d9bebbb3c
|
49 50 51 52 53 54 55 56 |
__docker-compose_q config \
| sed -n -e '/^services:/,/^[^ ]/p' \
| sed -n 's/^ //p' \
| awk '/^[a-zA-Z0-9]/{printf "
"};{printf $0;next;}' \
| grep " \+$1:" \
| cut -d: -f1 \
| grep -Ev "^(${already_selected})$"
|
|
e4774f203
|
57 58 59 60 |
}
# All services that are defined by a Dockerfile reference
__docker-compose_services_from_build() {
|
|
d9bebbb3c
|
61 62 63 64 65 66 |
[[ $PREFIX = -* ]] && return 1
integer ret=1
buildable=$(__docker-compose_services_with_key build)
_alternative "args:buildable services:($buildable)" && ret=0
return ret
|
|
e4774f203
|
67 68 69 70 |
}
# All services that are defined by an image
__docker-compose_services_from_image() {
|
|
d9bebbb3c
|
71 72 73 74 75 76 |
[[ $PREFIX = -* ]] && return 1
integer ret=1
pullable=$(__docker-compose_services_with_key image)
_alternative "args:pullable services:($pullable)" && ret=0
return ret
|
|
e4774f203
|
77 78 79 |
}
__docker-compose_get_services() {
|
|
d9bebbb3c
|
80 81 82 83 |
[[ $PREFIX = -* ]] && return 1
integer ret=1
local kind
declare -a running paused stopped lines args services
|
|
e4774f203
|
84 85 86 87 88 89 90 91 92 |
docker_status=$(docker ps > /dev/null 2>&1)
if [ $? -ne 0 ]; then
_message "Error! Docker is not running."
return 1
fi
kind=$1
shift
|
|
d9bebbb3c
|
93 |
[[ $kind =~ (stopped|all) ]] && args=($args -a) |
|
e4774f203
|
94 |
|
|
d9bebbb3c
|
95 96 |
lines=(${(f)"$(_call_program commands docker $docker_options ps $args)"})
services=(${(f)"$(_call_program commands docker-compose 2>/dev/null $compose_options ps -q)"})
|
|
e4774f203
|
97 98 99 100 |
# Parse header line to find columns
local i=1 j=1 k header=${lines[1]}
declare -A begin end
|
|
d9bebbb3c
|
101 102 103 104 105 106 107 |
while (( j < ${#header} - 1 )); do
i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
j=$(( i + ${${header[$i,-1]}[(i) ]} - 1 ))
k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
begin[${header[$i,$((j-1))]}]=$i
end[${header[$i,$((j-1))]}]=$k
done
|
|
e4774f203
|
108 109 110 111 112 113 |
lines=(${lines[2,-1]})
# Container ID
local line s name
local -a names
for line in $lines; do
|
|
d9bebbb3c
|
114 |
if [[ ${services[@]} == *"${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}"* ]]; then
|
|
e4774f203
|
115 116 117 118 |
names=(${(ps:,:)${${line[${begin[NAMES]},-1]}%% *}})
for name in $names; do
s="${${name%_*}#*_}:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
s="$s, ${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}"
|
|
d9bebbb3c
|
119 |
s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
|
e4774f203
|
120 121 122 |
if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
stopped=($stopped $s)
else
|
|
d9bebbb3c
|
123 124 125 |
if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = *\(Paused\)* ]]; then
paused=($paused $s)
fi
|
|
e4774f203
|
126 127 128 129 130 |
running=($running $s)
fi
done
fi
done
|
|
d9bebbb3c
|
131 132 133 134 135 136 137 138 139 140 |
[[ $kind =~ (running|all) ]] && _describe -t services-running "running services" running "$@" && ret=0
[[ $kind =~ (paused|all) ]] && _describe -t services-paused "paused services" paused "$@" && ret=0
[[ $kind =~ (stopped|all) ]] && _describe -t services-stopped "stopped services" stopped "$@" && ret=0
return ret
}
__docker-compose_pausedservices() {
[[ $PREFIX = -* ]] && return 1
__docker-compose_get_services paused "$@"
|
|
e4774f203
|
141 142 143 |
}
__docker-compose_stoppedservices() {
|
|
d9bebbb3c
|
144 |
[[ $PREFIX = -* ]] && return 1 |
|
e4774f203
|
145 146 147 148 |
__docker-compose_get_services stopped "$@"
}
__docker-compose_runningservices() {
|
|
d9bebbb3c
|
149 |
[[ $PREFIX = -* ]] && return 1 |
|
e4774f203
|
150 151 |
__docker-compose_get_services running "$@" } |
|
d9bebbb3c
|
152 153 |
__docker-compose_services() {
[[ $PREFIX = -* ]] && return 1
|
|
e4774f203
|
154 155 156 157 |
__docker-compose_get_services all "$@"
}
__docker-compose_caching_policy() {
|
|
d9bebbb3c
|
158 |
oldp=( "$1"(Nmh+1) ) # 1 hour |
|
e4774f203
|
159 160 |
(( $#oldp )) } |
|
d9bebbb3c
|
161 |
__docker-compose_commands() {
|
|
e4774f203
|
162 163 164 165 166 167 168 169 170 171 172 173 174 |
local cache_policy
zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
if [[ -z "$cache_policy" ]]; then
zstyle ":completion:${curcontext}:" cache-policy __docker-compose_caching_policy
fi
if ( [[ ${+_docker_compose_subcommands} -eq 0 ]] || _cache_invalid docker_compose_subcommands) \
&& ! _retrieve_cache docker_compose_subcommands;
then
local -a lines
lines=(${(f)"$(_call_program commands docker-compose 2>&1)"})
_docker_compose_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I) *]}]}## #}/ ##/:})
|
|
d9bebbb3c
|
175 |
(( $#_docker_compose_subcommands > 0 )) && _store_cache docker_compose_subcommands _docker_compose_subcommands |
|
e4774f203
|
176 177 178 |
fi
_describe -t docker-compose-commands "docker-compose command" _docker_compose_subcommands
}
|
|
d9bebbb3c
|
179 180 181 182 183 184 185 186 187 188 189 |
__docker-compose_subcommand() {
local opts_help opts_force_recreate opts_no_recreate opts_no_build opts_remove_orphans opts_timeout opts_no_color opts_no_deps
opts_help='(: -)--help[Print usage]'
opts_force_recreate="(--no-recreate)--force-recreate[Recreate containers even if their configuration and image haven't changed. Incompatible with --no-recreate.]"
opts_no_recreate="(--force-recreate)--no-recreate[If containers already exist, don't recreate them. Incompatible with --force-recreate.]"
opts_no_build="(--build)--no-build[Don't build an image, even if it's missing.]"
opts_remove_orphans="--remove-orphans[Remove containers for services not defined in the Compose file]"
opts_timeout=('(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: ")
opts_no_color='--no-color[Produce monochrome output.]'
opts_no_deps="--no-deps[Don't start linked services.]"
|
|
e4774f203
|
190 |
integer ret=1 |
|
d9bebbb3c
|
191 |
|
|
e4774f203
|
192 193 194 |
case "$words[1]" in
(build)
_arguments \
|
|
d9bebbb3c
|
195 196 197 198 |
$opts_help \
'--force-rm[Always remove intermediate containers.]' \
'--no-cache[Do not use cache when building the image.]' \
'--pull[Always attempt to pull a newer version of the image.]' \
|
|
e4774f203
|
199 200 |
'*:services:__docker-compose_services_from_build' && ret=0
;;
|
|
d9bebbb3c
|
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
(bundle)
_arguments \
$opts_help \
'(--output -o)'{--output,-o}'[Path to write the bundle file to. Defaults to "<project name>.dab".]:file:_files' && ret=0
;;
(config)
_arguments \
$opts_help \
'(--quiet -q)'{--quiet,-q}"[Only validate the configuration, don't print anything.]" \
'--services[Print the service names, one per line.]' && ret=0
;;
(create)
_arguments \
$opts_help \
$opts_force_recreate \
$opts_no_recreate \
$opts_no_build \
"(--no-build)--build[Build images before creating containers.]" \
'*:services:__docker-compose_services_all' && ret=0
;;
(down)
_arguments \
$opts_help \
"--rmi[Remove images. Type must be one of: 'all': Remove all images used by any service. 'local': Remove only images that don't have a custom tag set by the \`image\` field.]:type:(all local)" \
'(-v --volumes)'{-v,--volumes}"[Remove named volumes declared in the \`volumes\` section of the Compose file and anonymous volumes attached to containers.]" \
$opts_remove_orphans && ret=0
;;
(events)
_arguments \
$opts_help \
'--json[Output events as a stream of json objects]' \
'*:services:__docker-compose_services_all' && ret=0
;;
(exec)
_arguments \
$opts_help \
'-d[Detached mode: Run command in the background.]' \
'--privileged[Give extended privileges to the process.]' \
'--user=[Run the command as this user.]:username:_users' \
'-T[Disable pseudo-tty allocation. By default `docker-compose exec` allocates a TTY.]' \
'--index=[Index of the container if there are multiple instances of a service \[default: 1\]]:index: ' \
'(-):running services:__docker-compose_runningservices' \
'(-):command: _command_names -e' \
'*::arguments: _normal' && ret=0
;;
|
|
e4774f203
|
246 247 248 249 250 |
(help)
_arguments ':subcommand:__docker-compose_commands' && ret=0
;;
(kill)
_arguments \
|
|
d9bebbb3c
|
251 |
$opts_help \ |
|
e4774f203
|
252 253 254 255 256 |
'-s[SIGNAL to send to the container. Default signal is SIGKILL.]:signal:_signals' \
'*:running services:__docker-compose_runningservices' && ret=0
;;
(logs)
_arguments \
|
|
d9bebbb3c
|
257 258 259 260 261 |
$opts_help \
'(-f --follow)'{-f,--follow}'[Follow log output]' \
$opts_no_color \
'--tail=[Number of lines to show from the end of the logs for each container.]:number of lines: ' \
'(-t --timestamps)'{-t,--timestamps}'[Show timestamps]' \
|
|
e4774f203
|
262 263 |
'*:services:__docker-compose_services_all' && ret=0
;;
|
|
d9bebbb3c
|
264 |
(pause) |
|
e4774f203
|
265 |
_arguments \ |
|
d9bebbb3c
|
266 267 |
$opts_help \
'*:running services:__docker-compose_runningservices' && ret=0
|
|
e4774f203
|
268 269 270 |
;;
(port)
_arguments \
|
|
d9bebbb3c
|
271 272 273 |
$opts_help \
'--protocol=[tcp or udp \[default: tcp\]]:protocol:(tcp udp)' \
'--index=[index of the container if there are multiple instances of a service \[default: 1\]]:index: ' \
|
|
e4774f203
|
274 275 276 277 278 |
'1:running services:__docker-compose_runningservices' \
'2:port:_ports' && ret=0
;;
(ps)
_arguments \
|
|
d9bebbb3c
|
279 |
$opts_help \ |
|
e4774f203
|
280 281 282 283 284 |
'-q[Only display IDs]' \
'*:services:__docker-compose_services_all' && ret=0
;;
(pull)
_arguments \
|
|
d9bebbb3c
|
285 286 |
$opts_help \
'--ignore-pull-failures[Pull what it can and ignores images with pull failures.]' \
|
|
e4774f203
|
287 288 |
'*:services:__docker-compose_services_from_image' && ret=0
;;
|
|
d9bebbb3c
|
289 290 291 292 293 294 |
(push)
_arguments \
$opts_help \
'--ignore-push-failures[Push what it can and ignores images with push failures.]' \
'*:services:__docker-compose_services' && ret=0
;;
|
|
e4774f203
|
295 296 |
(rm)
_arguments \
|
|
d9bebbb3c
|
297 |
$opts_help \ |
|
e4774f203
|
298 |
'(-f --force)'{-f,--force}"[Don't ask to confirm removal]" \
|
|
d9bebbb3c
|
299 |
'-v[Remove any anonymous volumes attached to containers]' \ |
|
e4774f203
|
300 301 302 303 |
'*:stopped services:__docker-compose_stoppedservices' && ret=0
;;
(run)
_arguments \
|
|
d9bebbb3c
|
304 |
$opts_help \ |
|
e4774f203
|
305 |
'-d[Detached mode: Run container in the background, print new container name.]' \ |
|
e4774f203
|
306 |
'*-e[KEY=VAL Set an environment variable (can be used multiple times)]:environment variable KEY=VAL: ' \ |
|
d9bebbb3c
|
307 308 309 310 |
'--entrypoint[Overwrite the entrypoint of the image.]:entry point: ' \
'--name=[Assign a name to the container]:name: ' \
$opts_no_deps \
'(-p --publish)'{-p,--publish=}"[Publish a container's port(s) to the host]" \
|
|
e4774f203
|
311 312 313 |
'--rm[Remove container after run. Ignored in detached mode.]' \
"--service-ports[Run command with the service's ports enabled and mapped to the host.]" \
'-T[Disable pseudo-tty allocation. By default `docker-compose run` allocates a TTY.]' \
|
|
d9bebbb3c
|
314 315 |
'(-u --user)'{-u,--user=}'[Run as specified username or uid]:username or uid:_users' \
'(-w --workdir)'{-w,--workdir=}'[Working directory inside the container]:workdir: ' \
|
|
e4774f203
|
316 317 318 319 320 |
'(-):services:__docker-compose_services' \
'(-):command: _command_names -e' \
'*::arguments: _normal' && ret=0
;;
(scale)
|
|
d9bebbb3c
|
321 322 323 324 |
_arguments \
$opts_help \
$opts_timeout \
'*:running services:__docker-compose_runningservices' && ret=0
|
|
e4774f203
|
325 326 |
;;
(start)
|
|
d9bebbb3c
|
327 328 329 |
_arguments \
$opts_help \
'*:stopped services:__docker-compose_stoppedservices' && ret=0
|
|
e4774f203
|
330 331 332 |
;;
(stop|restart)
_arguments \
|
|
d9bebbb3c
|
333 334 |
$opts_help \
$opts_timeout \
|
|
e4774f203
|
335 336 |
'*:running services:__docker-compose_runningservices' && ret=0
;;
|
|
d9bebbb3c
|
337 338 339 340 341 |
(unpause)
_arguments \
$opts_help \
'*:paused services:__docker-compose_pausedservices' && ret=0
;;
|
|
e4774f203
|
342 343 |
(up)
_arguments \
|
|
d9bebbb3c
|
344 345 346 347 348 349 350 351 352 353 354 |
$opts_help \
'(--abort-on-container-exit)-d[Detached mode: Run containers in the background, print new container names. Incompatible with --abort-on-container-exit.]' \
$opts_no_color \
$opts_no_deps \
$opts_force_recreate \
$opts_no_recreate \
$opts_no_build \
"(--no-build)--build[Build images before starting containers.]" \
"(-d)--abort-on-container-exit[Stops all containers if any container was stopped. Incompatible with -d.]" \
'(-t --timeout)'{-t,--timeout}"[Use this timeout in seconds for container shutdown when attached or when containers are already running. (default: 10)]:seconds: " \
$opts_remove_orphans \
|
|
e4774f203
|
355 356 357 358 |
'*:services:__docker-compose_services_all' && ret=0
;;
(version)
_arguments \
|
|
d9bebbb3c
|
359 |
$opts_help \ |
|
e4774f203
|
360 361 362 |
"--short[Shows only Compose's version number.]" && ret=0
;;
(*)
|
|
d9bebbb3c
|
363 364 |
_message 'Unknown sub command' && ret=1
;;
|
|
e4774f203
|
365 366 367 368 |
esac
return ret
}
|
|
d9bebbb3c
|
369 |
_docker-compose() {
|
|
e4774f203
|
370 371 372 373 374 375 |
# Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`.
# Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
if [[ $service != docker-compose ]]; then
_call_function - _$service
return
fi
|
|
d9bebbb3c
|
376 377 |
local curcontext="$curcontext" state line
integer ret=1
|
|
e4774f203
|
378 379 380 381 |
typeset -A opt_args
_arguments -C \
'(- :)'{-h,--help}'[Get help]' \
|
|
e4774f203
|
382 383 |
'(-f --file)'{-f,--file}'[Specify an alternate docker-compose file (default: docker-compose.yml)]:file:_files -g "*.yml"' \
'(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \
|
|
d9bebbb3c
|
384 385 386 387 388 389 390 391 392 |
'--verbose[Show more output]' \
'(- :)'{-v,--version}'[Print version and exit]' \
'(-H --host)'{-H,--host}'[Daemon socket to connect to]:host:' \
'--tls[Use TLS; implied by --tlsverify]' \
'--tlscacert=[Trust certs signed only by this CA]:ca path:' \
'--tlscert=[Path to TLS certificate file]:client cert path:' \
'--tlskey=[Path to TLS key file]:tls key path:' \
'--tlsverify[Use TLS and verify the remote]' \
"--skip-hostname-check[Don't check the daemon's hostname against the name specified in the client certificate (for example if your docker host is an IP address)]" \
|
|
e4774f203
|
393 394 |
'(-): :->command' \
'(-)*:: :->option-or-argument' && ret=0
|
|
d9bebbb3c
|
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
local -a relevant_compose_flags relevant_docker_flags compose_options docker_options
relevant_compose_flags=(
"--file" "-f"
"--host" "-H"
"--project-name" "-p"
"--tls"
"--tlscacert"
"--tlscert"
"--tlskey"
"--tlsverify"
"--skip-hostname-check"
)
relevant_docker_flags=(
"--host" "-H"
"--tls"
"--tlscacert"
"--tlscert"
"--tlskey"
"--tlsverify"
)
for k in "${(@k)opt_args}"; do
if [[ -n "${relevant_docker_flags[(r)$k]}" ]]; then
docker_options+=$k
if [[ -n "$opt_args[$k]" ]]; then
docker_options+=$opt_args[$k]
fi
fi
if [[ -n "${relevant_compose_flags[(r)$k]}" ]]; then
compose_options+=$k
if [[ -n "$opt_args[$k]" ]]; then
compose_options+=$opt_args[$k]
fi
fi
|
|
e4774f203
|
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
done
case $state in
(command)
__docker-compose_commands && ret=0
;;
(option-or-argument)
curcontext=${curcontext%:*:*}:docker-compose-$words[1]:
__docker-compose_subcommand && ret=0
;;
esac
return ret
}
_docker-compose "$@"
|