From f0715994710f0663d8a9981a099ca1072208f8f6 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 2 Oct 2014 15:13:37 -0600 Subject: [PATCH] Optimize the bash completion even further The biggest/bestest change here is cutting down on the number of calls to Docker in the filtering helpers (`__docker_containers_running`, etc), especially calls to the really heavy `docker images`. Signed-off-by: Andrew Page --- contrib/completion/bash/docker | 290 +++++++++++++-------------------- 1 file changed, 116 insertions(+), 174 deletions(-) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 40a85440..cc16d482 100755 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -25,79 +25,59 @@ __docker_q() { docker 2>/dev/null "$@" } -__docker_containers_all() -{ - local containers="$( __docker_q ps -a -q )" - local names="$( __docker_q inspect --format '{{.Name}}' $containers | sed 's,^/,,' )" - COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) ) +__docker_containers_all() { + local IFS=$'\n' + local containers=( $(__docker_q ps -aq --no-trunc) ) + if [ "$1" ]; then + containers=( $(__docker_q inspect --format "{{if $1}}{{.Id}}{{end}}" "${containers[@]}") ) + fi + local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) + names=( "${names[@]#/}" ) # trim off the leading "/" from the container names + unset IFS + COMPREPLY=( $(compgen -W "${names[*]} ${containers[*]}" -- "$cur") ) } -__docker_containers_running() -{ - local containers="$( __docker_q ps -q )" - local names="$( __docker_q inspect --format '{{.Name}}' $containers | sed 's,^/,,' )" - COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) ) +__docker_containers_running() { + __docker_containers_all '.State.Running' } -__docker_containers_stopped() -{ - local containers="$( { __docker_q ps -a -q; __docker_q ps -q; } | sort | uniq -u )" - local names="$( __docker_q inspect --format '{{.Name}}' $containers | sed 's,^/,,' )" - COMPREPLY=( $( compgen -W "$names $containers" -- "$cur" ) ) +__docker_containers_stopped() { + __docker_containers_all 'not .State.Running' } -__docker_containers_paused() -{ - local containers="$( __docker_q ps -q)" - local names="$( __docker_q inspect --format='{{.State.Paused}} {{.Name}}' $containers | sed 's/^false.*//' | sed 's,^true /,,' )" - local hostnames="$( __docker_q inspect --format='{{.State.Paused}} {{.Config.Hostname}}' $containers | sed 's/^false.*//' | sed 's,^true ,,' )" - COMPREPLY=( $( compgen -W "$names $hostnames" -- "$cur" ) ) +__docker_containers_pauseable() { + __docker_containers_all 'and .State.Running (not .State.Paused)' } -__docker_containers_not_paused() -{ - local containers="$( __docker_q ps -q)" - local names="$( __docker_q inspect --format='{{.State.Paused}} {{.Name}}' $containers | sed 's/^true.*//' | sed 's,^false /,,' )" - local hostnames="$( __docker_q inspect --format='{{.State.Paused}} {{.Config.Hostname}}' $containers | sed 's/^true.*//' | sed 's/^false //' )" - COMPREPLY=( $( compgen -W "$names $hostnames" -- "$cur" ) ) +__docker_containers_unpauseable() { + __docker_containers_all '.State.Paused' } -__docker_image_repos() -{ - local repos="$( __docker_q images | awk 'NR>1{print $1}' | grep -v '^$' )" - COMPREPLY=( $( compgen -W "$repos" -- "$cur" ) ) +__docker_image_repos() { + local repos="$(__docker_q images | awk 'NR>1 && $1 != "" { print $1 }')" + COMPREPLY=( $(compgen -W "$repos" -- "$cur") ) } -__docker_image_repos_and_tags() -{ - local repos="$( __docker_q images | awk 'NR>1{print $1}' | grep -v '^$' )" - local images="$( __docker_q images | awk 'NR>1{print $1":"$2}' | grep -v '^:' )" - COMPREPLY=( $( compgen -W "$repos $images" -- "$cur" ) ) +__docker_image_repos_and_tags() { + local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "" { print $1; print $1":"$2 }')" + COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") ) __ltrim_colon_completions "$cur" } -__docker_image_repos_and_tags_and_ids() -{ - local repos="$( __docker_q images | awk 'NR>1{print $1}' | grep -v '^$' )" - local images="$( __docker_q images | awk 'NR>1{print $1":"$2}' | grep -v '^:' )" - local ids="$( __docker_q images -a -q )" - COMPREPLY=( $( compgen -W "$repos $images $ids" -- "$cur" ) ) +__docker_image_repos_and_tags_and_ids() { + local images="$(__docker_q images -a --no-trunc | awk 'NR>1 { print $3; if ($1 != "") { print $1; print $1":"$2 } }')" + COMPREPLY=( $(compgen -W "$images" -- "$cur") ) __ltrim_colon_completions "$cur" } -__docker_containers_and_images() -{ - local containers="$( __docker_q ps -a -q )" - local names="$( __docker_q inspect --format '{{.Name}}' $containers | sed 's,^/,,' )" - local repos="$( __docker_q images | awk 'NR>1{print $1}' | grep -v '^$' )" - local images="$( __docker_q images | awk 'NR>1{print $1":"$2}' | grep -v '^:' )" - local ids="$( __docker_q images -a -q )" - COMPREPLY=( $( compgen -W "$containers $names $repos $images $ids" -- "$cur" ) ) - __ltrim_colon_completions "$cur" +__docker_containers_and_images() { + __docker_containers_all + local containers=( "${COMPREPLY[@]}" ) + __docker_image_repos_and_tags_and_ids + COMPREPLY+=( "${containers[@]}" ) } -__docker_pos_first_nonflag() -{ +__docker_pos_first_nonflag() { local argument_flags=$1 local counter=$cpos @@ -119,8 +99,7 @@ __docker_pos_first_nonflag() echo $counter } -_docker_docker() -{ +_docker_docker() { case "$prev" in -H) return @@ -134,13 +113,12 @@ _docker_docker() COMPREPLY=( $( compgen -W "-H" -- "$cur" ) ) ;; *) - COMPREPLY=( $( compgen -W "$commands help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) ;; esac } -_docker_attach() -{ +_docker_attach() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--no-stdin --sig-proxy" -- "$cur" ) ) @@ -154,8 +132,7 @@ _docker_attach() esac } -_docker_build() -{ +_docker_build() { case "$prev" in -t|--tag) __docker_image_repos_and_tags @@ -178,8 +155,7 @@ _docker_build() esac } -_docker_commit() -{ +_docker_commit() { case "$prev" in -m|--message|-a|--author|--run) return @@ -209,8 +185,7 @@ _docker_commit() esac } -_docker_cp() -{ +_docker_cp() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then case "$cur" in @@ -233,8 +208,7 @@ _docker_cp() fi } -_docker_create() -{ +_docker_create() { case "$prev" in -a|--attach) COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) @@ -302,16 +276,14 @@ _docker_create() esac } -_docker_diff() -{ +_docker_diff() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then __docker_containers_all fi } -_docker_events() -{ +_docker_events() { case "$prev" in --since) return @@ -329,8 +301,7 @@ _docker_events() esac } -_docker_exec() -{ +_docker_exec() { case "$cur" in -*) COMPREPLY=( $( compgen -W "-d --detach -i --interactive -t --tty" -- "$cur" ) ) @@ -341,24 +312,21 @@ _docker_exec() esac } -_docker_export() -{ +_docker_export() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then __docker_containers_all fi } -_docker_help() -{ +_docker_help() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then - COMPREPLY=( $( compgen -W "$commands" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) fi } -_docker_history() -{ +_docker_history() { case "$cur" in -*) COMPREPLY=( $( compgen -W "-q --quiet --no-trunc" -- "$cur" ) ) @@ -372,8 +340,7 @@ _docker_history() esac } -_docker_images() -{ +_docker_images() { case "$cur" in -*) COMPREPLY=( $( compgen -W "-q --quiet -a --all --no-trunc -v --viz -t --tree" -- "$cur" ) ) @@ -387,8 +354,7 @@ _docker_images() esac } -_docker_import() -{ +_docker_import() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then return @@ -401,13 +367,11 @@ _docker_import() fi } -_docker_info() -{ +_docker_info() { return } -_docker_inspect() -{ +_docker_inspect() { case "$prev" in -f|--format) return @@ -426,18 +390,15 @@ _docker_inspect() esac } -_docker_kill() -{ +_docker_kill() { __docker_containers_running } -_docker_load() -{ +_docker_load() { return } -_docker_login() -{ +_docker_login() { case "$prev" in -u|--username|-p|--password|-e|--email) return @@ -455,8 +416,7 @@ _docker_login() esac } -_docker_logs() -{ +_docker_logs() { case "$cur" in -*) COMPREPLY=( $( compgen -W "-f --follow" -- "$cur" ) ) @@ -469,24 +429,22 @@ _docker_logs() ;; esac } -_docker_pause() -{ + +_docker_pause() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then - __docker_containers_not_paused + __docker_containers_pauseable fi } -_docker_port() -{ +_docker_port() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then __docker_containers_all fi } -_docker_ps() -{ +_docker_ps() { case "$prev" in --since|--before) __docker_containers_all @@ -507,8 +465,7 @@ _docker_ps() esac } -_docker_pull() -{ +_docker_pull() { case "$prev" in -t|--tag) return @@ -530,16 +487,14 @@ _docker_pull() esac } -_docker_push() -{ +_docker_push() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then __docker_image_repos_and_tags fi } -_docker_restart() -{ +_docker_restart() { case "$prev" in -t|--time) return @@ -558,8 +513,7 @@ _docker_restart() esac } -_docker_rm() -{ +_docker_rm() { case "$cur" in -*) COMPREPLY=( $( compgen -W "-f --force -l --link -v --volumes" -- "$cur" ) ) @@ -581,13 +535,11 @@ _docker_rm() esac } -_docker_rmi() -{ +_docker_rmi() { __docker_image_repos_and_tags_and_ids } -_docker_run() -{ +_docker_run() { case "$prev" in -a|--attach) COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) @@ -656,16 +608,14 @@ _docker_run() esac } -_docker_save() -{ +_docker_save() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then __docker_image_repos_and_tags_and_ids fi } -_docker_search() -{ +_docker_search() { case "$prev" in -s|--stars) return @@ -683,8 +633,7 @@ _docker_search() esac } -_docker_start() -{ +_docker_start() { case "$cur" in -*) COMPREPLY=( $( compgen -W "-a --attach -i --interactive" -- "$cur" ) ) @@ -695,8 +644,7 @@ _docker_start() esac } -_docker_stop() -{ +_docker_stop() { case "$prev" in -t|--time) return @@ -715,8 +663,7 @@ _docker_stop() esac } -_docker_tag() -{ +_docker_tag() { case "$cur" in -*) COMPREPLY=( $( compgen -W "-f --force" -- "$cur" ) ) @@ -738,73 +685,68 @@ _docker_tag() esac } -_docker_unpause() -{ +_docker_unpause() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then - __docker_containers_paused + __docker_containers_unpauseable fi } -_docker_top() -{ +_docker_top() { local counter=$(__docker_pos_first_nonflag) if [ $cword -eq $counter ]; then __docker_containers_running fi } -_docker_version() -{ +_docker_version() { return } -_docker_wait() -{ +_docker_wait() { __docker_containers_all } -_docker() -{ - local commands=" - attach - build - commit - cp - create - diff - events - exec - export - history - images - import - info - insert - inspect - kill - load - login - logs - pause - port - ps - pull - push - restart - rm - rmi - run - save - search - start - stop - tag - top - unpause - version - wait - " +_docker() { + local commands=( + attach + build + commit + cp + create + diff + events + exec + export + history + images + import + info + insert + inspect + kill + load + login + logs + pause + port + ps + pull + push + restart + rm + rmi + run + save + search + start + stop + tag + top + unpause + version + wait + ) COMPREPLY=() local cur prev words cword