Commit e4774f20335241b0d8c3f4291e654e5946aa4f1e
1 parent
ab0f2f9d57
Exists in
master
and in
2 other branches
Squashed 'repos/robbyrussell/oh-my-zsh/' changes from 3ea3384..a207a38
a207a38 Merge pull request #4099 from moncho/master 0950f9c Plugin now uses completion script from docker-compose repo. git-subtree-dir: repos/robbyrussell/oh-my-zsh git-subtree-split: a207a38d634cc10441636bc4359cd8a18c502dea
Showing 3 changed files with 312 additions and 14 deletions Side-by-side Diff
plugins/docker-compose/README.md
plugins/docker-compose/_docker-compose
| ... | ... | @@ -0,0 +1,308 @@ |
| 1 | +#compdef docker-compose | |
| 2 | + | |
| 3 | +# Description | |
| 4 | +# ----------- | |
| 5 | +# zsh completion for docker-compose | |
| 6 | +# https://github.com/sdurrheimer/docker-compose-zsh-completion | |
| 7 | +# ------------------------------------------------------------------------- | |
| 8 | +# Version | |
| 9 | +# ------- | |
| 10 | +# 0.1.0 | |
| 11 | +# ------------------------------------------------------------------------- | |
| 12 | +# Authors | |
| 13 | +# ------- | |
| 14 | +# * Steve Durrheimer <s.durrheimer@gmail.com> | |
| 15 | +# ------------------------------------------------------------------------- | |
| 16 | +# Inspiration | |
| 17 | +# ----------- | |
| 18 | +# * @albers docker-compose bash completion script | |
| 19 | +# * @felixr docker zsh completion script : https://github.com/felixr/docker-zsh-completion | |
| 20 | +# ------------------------------------------------------------------------- | |
| 21 | + | |
| 22 | +# For compatibility reasons, Compose and therefore its completion supports several | |
| 23 | +# stack compositon files as listed here, in descending priority. | |
| 24 | +# Support for these filenames might be dropped in some future version. | |
| 25 | +__docker-compose_compose_file() { | |
| 26 | + local file | |
| 27 | + for file in docker-compose.y{,a}ml fig.y{,a}ml ; do | |
| 28 | + [ -e $file ] && { | |
| 29 | + echo $file | |
| 30 | + return | |
| 31 | + } | |
| 32 | + done | |
| 33 | + echo docker-compose.yml | |
| 34 | +} | |
| 35 | + | |
| 36 | +# Extracts all service names from docker-compose.yml. | |
| 37 | +___docker-compose_all_services_in_compose_file() { | |
| 38 | + local already_selected | |
| 39 | + local -a services | |
| 40 | + already_selected=$(echo ${words[@]} | tr " " "|") | |
| 41 | + awk -F: '/^[a-zA-Z0-9]/{print $1}' "${compose_file:-$(__docker-compose_compose_file)}" 2>/dev/null | grep -Ev "$already_selected" | |
| 42 | +} | |
| 43 | + | |
| 44 | +# All services, even those without an existing container | |
| 45 | +__docker-compose_services_all() { | |
| 46 | + services=$(___docker-compose_all_services_in_compose_file) | |
| 47 | + _alternative "args:services:($services)" | |
| 48 | +} | |
| 49 | + | |
| 50 | +# All services that have an entry with the given key in their docker-compose.yml section | |
| 51 | +___docker-compose_services_with_key() { | |
| 52 | + local already_selected | |
| 53 | + local -a buildable | |
| 54 | + already_selected=$(echo ${words[@]} | tr " " "|") | |
| 55 | + # flatten sections to one line, then filter lines containing the key and return section name. | |
| 56 | + 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}' 2>/dev/null | grep -Ev "$already_selected" | |
| 57 | +} | |
| 58 | + | |
| 59 | +# All services that are defined by a Dockerfile reference | |
| 60 | +__docker-compose_services_from_build() { | |
| 61 | + buildable=$(___docker-compose_services_with_key build) | |
| 62 | + _alternative "args:buildable services:($buildable)" | |
| 63 | +} | |
| 64 | + | |
| 65 | +# All services that are defined by an image | |
| 66 | +__docker-compose_services_from_image() { | |
| 67 | + pullable=$(___docker-compose_services_with_key image) | |
| 68 | + _alternative "args:pullable services:($pullable)" | |
| 69 | +} | |
| 70 | + | |
| 71 | +__docker-compose_get_services() { | |
| 72 | + local kind expl | |
| 73 | + declare -a running stopped lines args services | |
| 74 | + | |
| 75 | + docker_status=$(docker ps > /dev/null 2>&1) | |
| 76 | + if [ $? -ne 0 ]; then | |
| 77 | + _message "Error! Docker is not running." | |
| 78 | + return 1 | |
| 79 | + fi | |
| 80 | + | |
| 81 | + kind=$1 | |
| 82 | + shift | |
| 83 | + [[ $kind = (stopped|all) ]] && args=($args -a) | |
| 84 | + | |
| 85 | + lines=(${(f)"$(_call_program commands docker ps ${args})"}) | |
| 86 | + services=(${(f)"$(_call_program commands docker-compose 2>/dev/null ${compose_file:+-f $compose_file} ${compose_project:+-p $compose_project} ps -q)"}) | |
| 87 | + | |
| 88 | + # Parse header line to find columns | |
| 89 | + local i=1 j=1 k header=${lines[1]} | |
| 90 | + declare -A begin end | |
| 91 | + while (( $j < ${#header} - 1 )) { | |
| 92 | + i=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 1)) | |
| 93 | + j=$(( $i + ${${header[$i,-1]}[(i) ]} - 1)) | |
| 94 | + k=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 2)) | |
| 95 | + begin[${header[$i,$(($j-1))]}]=$i | |
| 96 | + end[${header[$i,$(($j-1))]}]=$k | |
| 97 | + } | |
| 98 | + lines=(${lines[2,-1]}) | |
| 99 | + | |
| 100 | + # Container ID | |
| 101 | + local line s name | |
| 102 | + local -a names | |
| 103 | + for line in $lines; do | |
| 104 | + if [[ $services == *"${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}"* ]]; then | |
| 105 | + names=(${(ps:,:)${${line[${begin[NAMES]},-1]}%% *}}) | |
| 106 | + for name in $names; do | |
| 107 | + s="${${name%_*}#*_}:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}" | |
| 108 | + s="$s, ${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}" | |
| 109 | + s="$s, ${${${line[$begin[IMAGE],$end[IMAGE]]}/:/\\:}%% ##}" | |
| 110 | + if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then | |
| 111 | + stopped=($stopped $s) | |
| 112 | + else | |
| 113 | + running=($running $s) | |
| 114 | + fi | |
| 115 | + done | |
| 116 | + fi | |
| 117 | + done | |
| 118 | + | |
| 119 | + [[ $kind = (running|all) ]] && _describe -t services-running "running services" running | |
| 120 | + [[ $kind = (stopped|all) ]] && _describe -t services-stopped "stopped services" stopped | |
| 121 | +} | |
| 122 | + | |
| 123 | +__docker-compose_stoppedservices() { | |
| 124 | + __docker-compose_get_services stopped "$@" | |
| 125 | +} | |
| 126 | + | |
| 127 | +__docker-compose_runningservices() { | |
| 128 | + __docker-compose_get_services running "$@" | |
| 129 | +} | |
| 130 | + | |
| 131 | +__docker-compose_services () { | |
| 132 | + __docker-compose_get_services all "$@" | |
| 133 | +} | |
| 134 | + | |
| 135 | +__docker-compose_caching_policy() { | |
| 136 | + oldp=( "$1"(Nmh+1) ) # 1 hour | |
| 137 | + (( $#oldp )) | |
| 138 | +} | |
| 139 | + | |
| 140 | +__docker-compose_commands () { | |
| 141 | + local cache_policy | |
| 142 | + | |
| 143 | + zstyle -s ":completion:${curcontext}:" cache-policy cache_policy | |
| 144 | + if [[ -z "$cache_policy" ]]; then | |
| 145 | + zstyle ":completion:${curcontext}:" cache-policy __docker-compose_caching_policy | |
| 146 | + fi | |
| 147 | + | |
| 148 | + if ( [[ ${+_docker_compose_subcommands} -eq 0 ]] || _cache_invalid docker_compose_subcommands) \ | |
| 149 | + && ! _retrieve_cache docker_compose_subcommands; | |
| 150 | + then | |
| 151 | + local -a lines | |
| 152 | + lines=(${(f)"$(_call_program commands docker-compose 2>&1)"}) | |
| 153 | + _docker_compose_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I) *]}]}## #}/ ##/:}) | |
| 154 | + _store_cache docker_compose_subcommands _docker_compose_subcommands | |
| 155 | + fi | |
| 156 | + _describe -t docker-compose-commands "docker-compose command" _docker_compose_subcommands | |
| 157 | +} | |
| 158 | + | |
| 159 | +__docker-compose_subcommand () { | |
| 160 | + local -a _command_args | |
| 161 | + integer ret=1 | |
| 162 | + case "$words[1]" in | |
| 163 | + (build) | |
| 164 | + _arguments \ | |
| 165 | + '--no-cache[Do not use cache when building the image]' \ | |
| 166 | + '*:services:__docker-compose_services_from_build' && ret=0 | |
| 167 | + ;; | |
| 168 | + (help) | |
| 169 | + _arguments ':subcommand:__docker-compose_commands' && ret=0 | |
| 170 | + ;; | |
| 171 | + (kill) | |
| 172 | + _arguments \ | |
| 173 | + '-s[SIGNAL to send to the container. Default signal is SIGKILL.]:signal:_signals' \ | |
| 174 | + '*:running services:__docker-compose_runningservices' && ret=0 | |
| 175 | + ;; | |
| 176 | + (logs) | |
| 177 | + _arguments \ | |
| 178 | + '--no-color[Produce monochrome output.]' \ | |
| 179 | + '*:services:__docker-compose_services_all' && ret=0 | |
| 180 | + ;; | |
| 181 | + (migrate-to-labels) | |
| 182 | + _arguments \ | |
| 183 | + '(-):Recreate containers to add labels' && ret=0 | |
| 184 | + ;; | |
| 185 | + (port) | |
| 186 | + _arguments \ | |
| 187 | + '--protocol=-[tcp or udap (defaults to tcp)]:protocol:(tcp udp)' \ | |
| 188 | + '--index=-[index of the container if there are mutiple instances of a service (defaults to 1)]:index: ' \ | |
| 189 | + '1:running services:__docker-compose_runningservices' \ | |
| 190 | + '2:port:_ports' && ret=0 | |
| 191 | + ;; | |
| 192 | + (ps) | |
| 193 | + _arguments \ | |
| 194 | + '-q[Only display IDs]' \ | |
| 195 | + '*:services:__docker-compose_services_all' && ret=0 | |
| 196 | + ;; | |
| 197 | + (pull) | |
| 198 | + _arguments \ | |
| 199 | + '--allow-insecure-ssl[Allow insecure connections to the docker registry]' \ | |
| 200 | + '*:services:__docker-compose_services_from_image' && ret=0 | |
| 201 | + ;; | |
| 202 | + (rm) | |
| 203 | + _arguments \ | |
| 204 | + '(-f --force)'{-f,--force}"[Don't ask to confirm removal]" \ | |
| 205 | + '-v[Remove volumes associated with containers]' \ | |
| 206 | + '*:stopped services:__docker-compose_stoppedservices' && ret=0 | |
| 207 | + ;; | |
| 208 | + (run) | |
| 209 | + _arguments \ | |
| 210 | + '--allow-insecure-ssl[Allow insecure connections to the docker registry]' \ | |
| 211 | + '-d[Detached mode: Run container in the background, print new container name.]' \ | |
| 212 | + '--entrypoint[Overwrite the entrypoint of the image.]:entry point: ' \ | |
| 213 | + '*-e[KEY=VAL Set an environment variable (can be used multiple times)]:environment variable KEY=VAL: ' \ | |
| 214 | + '(-u --user)'{-u,--user=-}'[Run as specified username or uid]:username or uid:_users' \ | |
| 215 | + "--no-deps[Don't start linked services.]" \ | |
| 216 | + '--rm[Remove container after run. Ignored in detached mode.]' \ | |
| 217 | + "--service-ports[Run command with the service's ports enabled and mapped to the host.]" \ | |
| 218 | + '-T[Disable pseudo-tty allocation. By default `docker-compose run` allocates a TTY.]' \ | |
| 219 | + '(-):services:__docker-compose_services' \ | |
| 220 | + '(-):command: _command_names -e' \ | |
| 221 | + '*::arguments: _normal' && ret=0 | |
| 222 | + ;; | |
| 223 | + (scale) | |
| 224 | + _arguments '*:running services:__docker-compose_runningservices' && ret=0 | |
| 225 | + ;; | |
| 226 | + (start) | |
| 227 | + _arguments '*:stopped services:__docker-compose_stoppedservices' && ret=0 | |
| 228 | + ;; | |
| 229 | + (stop|restart) | |
| 230 | + _arguments \ | |
| 231 | + '(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: " \ | |
| 232 | + '*:running services:__docker-compose_runningservices' && ret=0 | |
| 233 | + ;; | |
| 234 | + (up) | |
| 235 | + _arguments \ | |
| 236 | + '--allow-insecure-ssl[Allow insecure connections to the docker registry]' \ | |
| 237 | + '-d[Detached mode: Run containers in the background, print new container names.]' \ | |
| 238 | + '--no-color[Produce monochrome output.]' \ | |
| 239 | + "--no-deps[Don't start linked services.]" \ | |
| 240 | + "--no-recreate[If containers already exist, don't recreate them.]" \ | |
| 241 | + "--no-build[Don't build an image, even if it's missing]" \ | |
| 242 | + '(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: " \ | |
| 243 | + "--x-smart-recreate[Only recreate containers whose configuration or image needs to be updated. (EXPERIMENTAL)]" \ | |
| 244 | + '*:services:__docker-compose_services_all' && ret=0 | |
| 245 | + ;; | |
| 246 | + (version) | |
| 247 | + _arguments \ | |
| 248 | + "--short[Shows only Compose's version number.]" && ret=0 | |
| 249 | + ;; | |
| 250 | + (*) | |
| 251 | + _message 'Unknown sub command' | |
| 252 | + esac | |
| 253 | + | |
| 254 | + return ret | |
| 255 | +} | |
| 256 | + | |
| 257 | +_docker-compose () { | |
| 258 | + # Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`. | |
| 259 | + # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`. | |
| 260 | + if [[ $service != docker-compose ]]; then | |
| 261 | + _call_function - _$service | |
| 262 | + return | |
| 263 | + fi | |
| 264 | + | |
| 265 | + local curcontext="$curcontext" state line ret=1 | |
| 266 | + typeset -A opt_args | |
| 267 | + | |
| 268 | + _arguments -C \ | |
| 269 | + '(- :)'{-h,--help}'[Get help]' \ | |
| 270 | + '--verbose[Show more output]' \ | |
| 271 | + '(- :)'{-v,--version}'[Print version and exit]' \ | |
| 272 | + '(-f --file)'{-f,--file}'[Specify an alternate docker-compose file (default: docker-compose.yml)]:file:_files -g "*.yml"' \ | |
| 273 | + '(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \ | |
| 274 | + '(-): :->command' \ | |
| 275 | + '(-)*:: :->option-or-argument' && ret=0 | |
| 276 | + | |
| 277 | + local counter=1 | |
| 278 | + #local compose_file compose_project | |
| 279 | + while [ $counter -lt ${#words[@]} ]; do | |
| 280 | + case "${words[$counter]}" in | |
| 281 | + -f|--file) | |
| 282 | + (( counter++ )) | |
| 283 | + compose_file="${words[$counter]}" | |
| 284 | + ;; | |
| 285 | + -p|--project-name) | |
| 286 | + (( counter++ )) | |
| 287 | + compose_project="${words[$counter]}" | |
| 288 | + ;; | |
| 289 | + *) | |
| 290 | + ;; | |
| 291 | + esac | |
| 292 | + (( counter++ )) | |
| 293 | + done | |
| 294 | + | |
| 295 | + case $state in | |
| 296 | + (command) | |
| 297 | + __docker-compose_commands && ret=0 | |
| 298 | + ;; | |
| 299 | + (option-or-argument) | |
| 300 | + curcontext=${curcontext%:*:*}:docker-compose-$words[1]: | |
| 301 | + __docker-compose_subcommand && ret=0 | |
| 302 | + ;; | |
| 303 | + esac | |
| 304 | + | |
| 305 | + return ret | |
| 306 | +} | |
| 307 | + | |
| 308 | +_docker-compose "$@" |
plugins/docker-compose/docker-compose.plugin.zsh
| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | -# Authors: | |
| 2 | -# https://github.com/tristola | |
| 3 | -# | |
| 4 | -# Docker-compose related zsh aliases | |
| 5 | - | |
| 6 | -# Aliases ################################################################### | |
| 7 | - | |
| 8 | -alias dcup='docker-compose up' | |
| 9 | -alias dcb='docker-compose build' | |
| 10 | -alias dcrm='docker-compose rm' | |
| 11 | -alias dcps='docker-compose ps' | |
| 12 | -alias dcstop='docker-compose stop' | |
| 13 | -alias dcrestart='docker-compose restart' | |
| 14 | - |