Browse code

zsh: update zsh completion for docker command

zsh completion is updated with the content of
felixr/docker-zsh-completion.

Docker-DCO-1.1-Signed-off-by: Vincent Bernat <vincent@bernat.im> (github: vincentbernat)

Vincent Bernat authored on 2014/07/18 02:50:50
Showing 1 changed files
... ...
@@ -1,58 +1,118 @@
1
-#compdef docker 
1
+#compdef docker
2 2
 #
3 3
 # zsh completion for docker (http://docker.com)
4 4
 #
5
-# version:  0.2.2
6
-# author:   Felix Riedel
7
-# license:  BSD License
5
+# version:  0.3.0
8 6
 # github:   https://github.com/felixr/docker-zsh-completion
9 7
 #
8
+# contributers:
9
+#   - Felix Riedel
10
+#   - Vincent Bernat
11
+#
12
+# license:
13
+#
14
+# Copyright (c) 2013, Felix Riedel
15
+# All rights reserved.
16
+#
17
+# Redistribution and use in source and binary forms, with or without
18
+# modification, are permitted provided that the following conditions are met:
19
+#     * Redistributions of source code must retain the above copyright
20
+#       notice, this list of conditions and the following disclaimer.
21
+#     * Redistributions in binary form must reproduce the above copyright
22
+#       notice, this list of conditions and the following disclaimer in the
23
+#       documentation and/or other materials provided with the distribution.
24
+#     * Neither the name of the <organization> nor the
25
+#       names of its contributors may be used to endorse or promote products
26
+#       derived from this software without specific prior written permission.
27
+#
28
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
29
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
32
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
+#
10 39
 
11 40
 __parse_docker_list() {
12
-    sed -e '/^ID/d' -e 's/[ ]\{2,\}/|/g' -e 's/ \([hdwm]\)\(inutes\|ays\|ours\|eeks\)/\1/' | awk ' BEGIN {FS="|"} { printf("%s:%7s, %s\n", $1, $4, $2)}'
41
+        awk '
42
+NR == 1 {
43
+    idx=1;i=0;f[i]=0
44
+    header=$0
45
+    while ( match(header, /  ([A-Z]+|[A-Z]+ [A-Z]+)/) ) {
46
+        idx += RSTART+1
47
+        f[++i]=idx
48
+        header = substr($0,idx)
49
+    }
50
+    f[++i]=999
51
+}
52
+
53
+NR > 1 '"$1"' {
54
+    for(j=0;j<i;j++) {
55
+        x[j] = substr($0, f[j], f[j+1]-f[j]-1)
56
+        gsub(/[ ]+$/, "", x[j])
57
+    }
58
+    printf("%s:%7s, %s\n", x[0], x[3], x[1])
59
+    if (x[6] != "") {
60
+       split(x[6], names, /,/)
61
+       for (name in names) printf("%s:%7s, %s\n", names[name], x[3], x[1])
62
+    }
63
+}
64
+'| sed -e 's/ \([hdwm]\)\(inutes\|ays\|ours\|eeks\)/\1/'
13 65
 }
14 66
 
15 67
 __docker_stoppedcontainers() {
16 68
     local expl
17
-    declare -a stoppedcontainers 
18
-    stoppedcontainers=(${(f)"$(docker ps -a | grep --color=never 'Exit' |  __parse_docker_list )"})
19
-    _describe -t containers-stopped "Stopped Containers" stoppedcontainers 
69
+    declare -a stoppedcontainers
70
+    stoppedcontainers=(${(f)"$(_call_program commands docker ps -a |  __parse_docker_list '&& / Exit/')"})
71
+    _describe -t containers-stopped "Stopped Containers" stoppedcontainers "$@"
20 72
 }
21 73
 
22 74
 __docker_runningcontainers() {
23 75
     local expl
24
-    declare -a containers 
76
+    declare -a containers
25 77
 
26
-    containers=(${(f)"$(docker ps | __parse_docker_list)"})
27
-    _describe -t containers-active "Running Containers" containers 
78
+    containers=(${(f)"$(_call_program commands docker ps | __parse_docker_list)"})
79
+    _describe -t containers-active "Running Containers" containers "$@"
28 80
 }
29 81
 
30 82
 __docker_containers () {
31
-    __docker_stoppedcontainers 
32
-    __docker_runningcontainers
83
+    __docker_stoppedcontainers "$@"
84
+    __docker_runningcontainers "$@"
33 85
 }
34 86
 
35 87
 __docker_images () {
36 88
     local expl
37 89
     declare -a images
38
-    images=(${(f)"$(docker images | awk '(NR > 1){printf("%s\\:%s\n", $1,$2)}')"})
39
-    images=($images ${(f)"$(docker images | awk '(NR > 1){printf("%s:%-15s in %s\n", $3,$2,$1)}')"})
90
+    images=(${(f)"$(_call_program commands docker images | awk '(NR > 1 && $1 != "<none>"){printf("%s", $1);if ($2 != "<none>") printf("\\:%s", $2); printf("\n")}')"})
91
+    images=($images ${(f)"$(_call_program commands docker images | awk '(NR > 1){printf("%s:%-15s in %s\n", $3,$2,$1)}')"})
40 92
     _describe -t docker-images "Images" images
41 93
 }
42 94
 
43 95
 __docker_tags() {
44 96
     local expl
45 97
     declare -a tags
46
-    tags=(${(f)"$(docker images | awk '(NR>1){print $2}'| sort | uniq)"})
98
+    tags=(${(f)"$(_call_program commands docker images | awk '(NR>1){print $2}'| sort | uniq)"})
47 99
     _describe -t docker-tags "tags" tags
48 100
 }
49 101
 
102
+__docker_repositories_with_tags() {
103
+    if compset -P '*:'; then
104
+        __docker_tags
105
+    else
106
+        __docker_repositories -qS ":"
107
+    fi
108
+}
109
+
50 110
 __docker_search() {
51 111
     # declare -a dockersearch
52 112
     local cache_policy
53 113
     zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
54 114
     if [[ -z "$cache_policy" ]]; then
55
-        zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy 
115
+        zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
56 116
     fi
57 117
 
58 118
     local searchterm cachename
... ...
@@ -60,14 +120,14 @@ __docker_search() {
60 60
     cachename=_docker-search-$searchterm
61 61
 
62 62
     local expl
63
-    local -a result 
63
+    local -a result
64 64
     if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
65 65
         && ! _retrieve_cache ${cachename#_}; then
66 66
         _message "Searching for ${searchterm}..."
67
-        result=(${(f)"$(docker search ${searchterm} | awk '(NR>2){print $1}')"})
67
+        result=(${(f)"$(_call_program commands docker search ${searchterm} | awk '(NR>2){print $1}')"})
68 68
         _store_cache ${cachename#_} result
69
-    fi 
70
-    _wanted dockersearch expl 'Available images' compadd -a result 
69
+    fi
70
+    _wanted dockersearch expl 'Available images' compadd -a result
71 71
 }
72 72
 
73 73
 __docker_caching_policy()
... ...
@@ -81,8 +141,8 @@ __docker_caching_policy()
81 81
 __docker_repositories () {
82 82
     local expl
83 83
     declare -a repos
84
-    repos=(${(f)"$(docker images | sed -e '1d' -e 's/[ ].*//' | sort | uniq)"})
85
-    _describe -t docker-repos "Repositories" repos
84
+    repos=(${(f)"$(_call_program commands docker images | sed -e '1d' -e 's/[ ].*//' | sort | uniq)"})
85
+    _describe -t docker-repos "Repositories" repos "$@"
86 86
 }
87 87
 
88 88
 __docker_commands () {
... ...
@@ -91,15 +151,15 @@ __docker_commands () {
91 91
 
92 92
     zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
93 93
     if [[ -z "$cache_policy" ]]; then
94
-        zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy 
94
+        zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
95 95
     fi
96 96
 
97 97
     if ( [[ ${+_docker_subcommands} -eq 0 ]] || _cache_invalid docker_subcommands) \
98
-        && ! _retrieve_cache docker_subcommands; 
98
+        && ! _retrieve_cache docker_subcommands;
99 99
     then
100
-        _docker_subcommands=(${${(f)"$(_call_program commands 
100
+        _docker_subcommands=(${${(f)"$(_call_program commands
101 101
         docker 2>&1 | sed -e '1,6d' -e '/^[ ]*$/d' -e 's/[ ]*\([^ ]\+\)\s*\([^ ].*\)/\1:\2/' )"}})
102
-        _docker_subcommands=($_docker_subcommands 'help:Show help for a command') 
102
+        _docker_subcommands=($_docker_subcommands 'help:Show help for a command')
103 103
         _store_cache docker_subcommands _docker_subcommands
104 104
     fi
105 105
     _describe -t docker-commands "docker command" _docker_subcommands
... ...
@@ -108,100 +168,206 @@ __docker_commands () {
108 108
 __docker_subcommand () {
109 109
     local -a _command_args
110 110
     case "$words[1]" in
111
-        (attach|wait)
112
-            _arguments ':containers:__docker_runningcontainers'
111
+        (attach)
112
+            _arguments \
113
+                '--no-stdin[Do not attach stdin]' \
114
+                '--sig-proxy[Proxify all received signal]' \
115
+                ':containers:__docker_runningcontainers'
113 116
             ;;
114 117
         (build)
115 118
             _arguments \
116
-                '-t=-:repository:__docker_repositories' \
119
+                '--no-cache[Do not use cache when building the image]' \
120
+                '-q[Suppress verbose build output]' \
121
+                '--rm[Remove intermediate containers after a successful build]' \
122
+                '-t=-:repository:__docker_repositories_with_tags' \
117 123
                 ':path or URL:_directories'
118 124
             ;;
119 125
         (commit)
120 126
             _arguments \
127
+                '--author=-[Author]:author: ' \
128
+                '-m=-[Commit message]:message: ' \
129
+                '--run=-[Configuration automatically applied when the image is run]:configuration: ' \
121 130
                 ':container:__docker_containers' \
122
-                ':repository:__docker_repositories' \
123
-                ':tag: '
131
+                ':repository:__docker_repositories_with_tags'
132
+            ;;
133
+        (cp)
134
+            _arguments \
135
+                ':container:->container' \
136
+                ':hostpath:_files'
137
+            case $state in
138
+                (container)
139
+                    if compset -P '*:'; then
140
+                        _files
141
+                    else
142
+                        __docker_containers -qS ":"
143
+                    fi
144
+                    ;;
145
+            esac
124 146
             ;;
125
-        (diff|export|logs)
147
+        (diff|export)
126 148
             _arguments '*:containers:__docker_containers'
127 149
             ;;
128 150
         (history)
129
-            _arguments '*:images:__docker_images'
151
+            _arguments \
152
+                '--no-trunc[Do not truncate output]' \
153
+                '-q[Only show numeric IDs]' \
154
+                '*:images:__docker_images'
130 155
             ;;
131 156
         (images)
132 157
             _arguments \
133 158
                 '-a[Show all images]' \
159
+                '--no-trunc[Do not truncate output]' \
160
+                '-q[Only show numeric IDs]' \
161
+                '--tree[Output graph in tree format]' \
162
+                '--viz[Output graph in graphviz format]' \
134 163
                 ':repository:__docker_repositories'
135 164
             ;;
136 165
         (inspect)
137
-            _arguments '*:containers:__docker_containers'
166
+            _arguments \
167
+                '--format=-[Format the output using the given go template]:template: ' \
168
+                '*:containers:__docker_containers'
138 169
             ;;
139
-        (history)
140
-            _arguments ':images:__docker_images'
170
+        (import)
171
+            _arguments \
172
+                ':URL:(- http:// file://)' \
173
+                ':repository:__docker_repositories_with_tags'
174
+            ;;
175
+        (info)
176
+            ;;
177
+        (import)
178
+            _arguments \
179
+                ':URL:(- http:// file://)' \
180
+                ':repository:__docker_repositories_with_tags'
181
+            ;;
182
+        (insert)
183
+            _arguments '1:containers:__docker_containers' \
184
+                       '2:URL:(http:// file://)' \
185
+                       '3:file:_files'
141 186
             ;;
142 187
         (kill)
143 188
             _arguments '*:containers:__docker_runningcontainers'
144 189
             ;;
190
+        (load)
191
+            ;;
192
+        (login)
193
+            _arguments \
194
+                '-e=-[Email]:email: ' \
195
+                '-p=-[Password]:password: ' \
196
+                '-u=-[Username]:username: ' \
197
+                ':server: '
198
+            ;;
199
+        (logs)
200
+            _arguments \
201
+                '-f[Follow log output]' \
202
+                '*:containers:__docker_containers'
203
+            ;;
145 204
         (port)
146
-            _arguments '1:containers:__docker_runningcontainers'
205
+            _arguments \
206
+                '1:containers:__docker_runningcontainers' \
207
+                '2:port:_ports'
147 208
             ;;
148 209
         (start)
149
-            _arguments '*:containers:__docker_stoppedcontainers'
210
+            _arguments \
211
+                '-a[Attach container'"'"'s stdout/stderr and forward all signals]' \
212
+                '-i[Attach container'"'"'s stding]' \
213
+                '*:containers:__docker_stoppedcontainers'
150 214
             ;;
151 215
         (rm)
152
-            _arguments '-v[Remove the volumes associated to the container]' \
216
+            _arguments \
217
+                '--link[Remove the specified link and not the underlying container]' \
218
+                '-v[Remove the volumes associated to the container]' \
153 219
                 '*:containers:__docker_stoppedcontainers'
154 220
             ;;
155 221
         (rmi)
156
-            _arguments '-v[Remove the volumes associated to the container]' \
222
+            _arguments \
157 223
                 '*:images:__docker_images'
158 224
             ;;
159
-        (top)
160
-            _arguments '1:containers:__docker_runningcontainers'
161
-            ;;
162 225
         (restart|stop)
163 226
             _arguments '-t=-[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)' \
164 227
                 '*:containers:__docker_runningcontainers'
165 228
             ;;
166 229
         (top)
167
-            _arguments ':containers:__docker_runningcontainers'
230
+            _arguments \
231
+                '1:containers:__docker_runningcontainers' \
232
+                '(-)*:: :->ps-arguments'
233
+            case $state in
234
+                (ps-arguments)
235
+                    _ps
236
+                    ;;
237
+            esac
238
+
168 239
             ;;
169 240
         (ps)
170
-            _arguments '-a[Show all containers. Only running containers are shown by default]' \
171
-                '-h[Show help]' \
172
-                '--before-id=-[Show only container created before Id, include non-running one]:containers:__docker_containers' \
173
-            '-n=-[Show n last created containers, include non-running one]:n:(1 5 10 25 50)'
241
+            _arguments \
242
+                '-a[Show all containers]' \
243
+                '--before=-[Show only container created before...]:containers:__docker_containers' \
244
+                '-l[Show only the latest created container]' \
245
+                '-n=-[Show n last created containers, include non-running one]:n:(1 5 10 25 50)' \
246
+                '--no-trunc[Do not truncate output]' \
247
+                '-q[Only show numeric IDs]' \
248
+                '-s[Display sizes]' \
249
+                '--since=-[Show only containers created since...]:containers:__docker_containers'
174 250
             ;;
175 251
         (tag)
176 252
             _arguments \
177 253
                 '-f[force]'\
178 254
                 ':image:__docker_images'\
179
-                ':repository:__docker_repositories' \
180
-                ':tag:__docker_tags'
255
+                ':repository:__docker_repositories_with_tags'
181 256
             ;;
182 257
         (run)
183 258
             _arguments \
184
-                '-a=-[Attach to stdin, stdout or stderr]:toggle:(true false)' \
185
-                '-c=-[CPU shares (relative weight)]:CPU shares: ' \
259
+                '-P[Publish all exposed ports to the host]' \
260
+                '-a[Attach to stdin, stdout or stderr]' \
261
+                '-c=-[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)' \
262
+                '--cidfile=-[Write the container ID to the file]:CID file:_files' \
186 263
                 '-d[Detached mode: leave the container running in the background]' \
187
-                '*--dns=[Set custom dns servers]:dns server: ' \
188
-                '*-e=[Set environment variables]:environment variable: ' \
264
+                '*--dns=-[Set custom dns servers]:dns server: ' \
265
+                '*-e=-[Set environment variables]:environment variable: ' \
189 266
                 '--entrypoint=-[Overwrite the default entrypoint of the image]:entry point: ' \
267
+                '*--expose=-[Expose a port from the container without publishing it]: ' \
190 268
                 '-h=-[Container host name]:hostname:_hosts' \
191 269
                 '-i[Keep stdin open even if not attached]' \
270
+                '--link=-[Add link to another container]:link:->link' \
271
+                '--lxc-conf=-[Add custom lxc options]:lxc options: ' \
192 272
                 '-m=-[Memory limit (in bytes)]:limit: ' \
193
-                '*-p=-[Expose a container''s port to the host]:port:_ports' \
194
-                '-t=-[Allocate a pseudo-tty]:toggle:(true false)' \
273
+                '--name=-[Container name]:name: ' \
274
+                '*-p=-[Expose a container'"'"'s port to the host]:port:_ports' \
275
+                '--privileged[Give extended privileges to this container]' \
276
+                '--rm[Remove intermediate containers when it exits]' \
277
+                '--sig-proxy[Proxify all received signal]' \
278
+                '-t[Allocate a pseudo-tty]' \
195 279
                 '-u=-[Username or UID]:user:_users' \
196 280
                 '*-v=-[Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)]:volume: '\
197 281
                 '--volumes-from=-[Mount volumes from the specified container]:volume: ' \
282
+                '-w=-[Working directory inside the container]:directory:_directories' \
198 283
                 '(-):images:__docker_images' \
199 284
                 '(-):command: _command_names -e' \
200 285
                 '*::arguments: _normal'
201
-                ;;
286
+
287
+            case $state in
288
+                (link)
289
+                    if compset -P '*:'; then
290
+                        _wanted alias expl 'Alias' compadd -E ""
291
+                    else
292
+                        __docker_runningcontainers -qS ":"
293
+                    fi
294
+                    ;;
295
+            esac
296
+
297
+            ;;
202 298
         (pull|search)
203 299
             _arguments ':name:__docker_search'
204 300
             ;;
301
+        (push)
302
+            _arguments ':repository:__docker_repositories_with_tags'
303
+            ;;
304
+        (save)
305
+            _arguments \
306
+                ':images:__docker_images'
307
+            ;;
308
+        (wait)
309
+            _arguments ':containers:__docker_runningcontainers'
310
+            ;;
205 311
         (help)
206 312
             _arguments ':subcommand:__docker_commands'
207 313
             ;;
... ...
@@ -212,24 +378,31 @@ __docker_subcommand () {
212 212
 }
213 213
 
214 214
 _docker () {
215
+    # Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`.
216
+    # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
217
+    if [[ $service != docker ]]; then
218
+        _call_function - _$service
219
+        return
220
+    fi
221
+
215 222
     local curcontext="$curcontext" state line
216 223
     typeset -A opt_args
217 224
 
218 225
     _arguments -C \
219 226
       '-H=-[tcp://host:port to bind/connect to]:socket: ' \
220 227
          '(-): :->command' \
221
-         '(-)*:: :->option-or-argument' 
228
+         '(-)*:: :->option-or-argument'
222 229
 
223 230
     if (( CURRENT == 1 )); then
224 231
 
225 232
     fi
226
-    case $state in 
233
+    case $state in
227 234
         (command)
228 235
             __docker_commands
229 236
             ;;
230 237
         (option-or-argument)
231 238
             curcontext=${curcontext%:*:*}:docker-$words[1]:
232
-            __docker_subcommand 
239
+            __docker_subcommand
233 240
             ;;
234 241
     esac
235 242
 }