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 <admwiggin@gmail.com>
This commit is contained in:
Tianon Gravi 2014-10-02 15:13:37 -06:00
parent cbb81c30bd
commit 0597b6445d

View file

@ -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 '^<none>$' )"
COMPREPLY=( $( compgen -W "$repos" -- "$cur" ) )
__docker_image_repos() {
local repos="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1 }')"
COMPREPLY=( $(compgen -W "$repos" -- "$cur") )
}
__docker_image_repos_and_tags()
{
local repos="$( __docker_q images | awk 'NR>1{print $1}' | grep -v '^<none>$' )"
local images="$( __docker_q images | awk 'NR>1{print $1":"$2}' | grep -v '^<none>:' )"
COMPREPLY=( $( compgen -W "$repos $images" -- "$cur" ) )
__docker_image_repos_and_tags() {
local reposAndTags="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { 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 '^<none>$' )"
local images="$( __docker_q images | awk 'NR>1{print $1":"$2}' | grep -v '^<none>:' )"
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 != "<none>") { 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 '^<none>$' )"
local images="$( __docker_q images | awk 'NR>1{print $1":"$2}' | grep -v '^<none>:' )"
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" ) )
@ -655,16 +607,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
@ -682,8 +632,7 @@ _docker_search()
esac
}
_docker_start()
{
_docker_start() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "-a --attach -i --interactive" -- "$cur" ) )
@ -694,8 +643,7 @@ _docker_start()
esac
}
_docker_stop()
{
_docker_stop() {
case "$prev" in
-t|--time)
return
@ -714,8 +662,7 @@ _docker_stop()
esac
}
_docker_tag()
{
_docker_tag() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "-f --force" -- "$cur" ) )
@ -737,73 +684,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