Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 98 additions & 79 deletions contrib/completion/bash/docker
Original file line number Diff line number Diff line change
Expand Up @@ -178,52 +178,78 @@ __docker_complete_container_ids() {
COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") )
}

# __docker_images returns a list of images. For each image, up to three representations
# can be generated: the repository (e.g. busybox), repository:tag (e.g. busybox:latest)
# and the ID (e.g. sha256:ee22cbbd4ea3dff63c86ba60c7691287c321e93adfc1009604eb1dde7ec88645).
#
# The optional arguments `--repo`, `--tag` and `--id` select the representations that
# may be returned. Whether or not a particular representation is actually returned
# depends on the user's customization through several environment variables:
# - image IDs are only shown if DOCKER_COMPLETION_SHOW_IMAGE_IDS=all|non-intermediate.
# - tags can be excluded by setting DOCKER_COMPLETION_SHOW_TAGS=no.
# - repositories are always shown.
#
# In cases where an exact image specification is needed, `--force-tag` can be used.
# It ignores DOCKER_COMPLETION_SHOW_TAGS and only lists valid repository:tag combinations,
# avoiding repository names that would default to a potentially missing default tag.
#
# Additional arguments to `docker image ls` may be specified in order to filter the list,
# e.g. `__docker_images --filter dangling=true`.
#
__docker_images() {
local images_args=""

case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
all)
images_args="--no-trunc -a"
;;
non-intermediate)
images_args="--no-trunc"
;;
esac
local repo_format='{{.Repository}}'
local tag_format='{{.Repository}}:{{.Tag}}'
local id_format='{{.ID}}'
local all
local format

local repo_print_command
if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then
repo_print_command='print $1; print $1":"$2'
else
repo_print_command='print $1'
if [ "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" = "all" ] ; then
all='--all'
fi

local awk_script
case "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" in
all|non-intermediate)
awk_script='NR>1 { print $3; if ($1 != "<none>") { '"$repo_print_command"' } }'
;;
none|*)
awk_script='NR>1 && $1 != "<none>" { '"$repo_print_command"' }'
;;
esac
while true ; do
case "$1" in
--repo)
format+="$repo_format\n"
shift
;;
--tag)
if [ "${DOCKER_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then
format+="$tag_format\n"
fi
shift
;;
--id)
if [[ $DOCKER_COMPLETION_SHOW_IMAGE_IDS =~ ^(all|non-intermediate)$ ]] ; then
format+="$id_format\n"
fi
shift
;;
--force-tag)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it should be additive with --tag, like --tag --force or something like that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work because it is not clear what should be forced. My intent is to use --repo, --tag and --id to express that a representation can be completed (if permitted by environment settings) and to use --force-repo, --force-tag and --force-id when a representation has to be added, regardless of environment settings. Of the latter, currently only --force-tag is used, so the other options from this set are not yet implemented.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also want to keep this function very simple. That's why it doesn't care about the order of the arguments. Thus, a --force is not deterministic. And I want the invocations to fit on one line, so I opted for the short names like --tag instead of something more exact like --try-tag or --allow-tag.
I think this simplicity is appropriate for this function because it is only used internally in the bash completion script.

# like `--tag` but ignores environment setting
format+="$tag_format\n"
shift
;;
*)
break
;;
esac
done

__docker_q images $images_args | awk "$awk_script" | grep -v '<none>$'
__docker_q image ls --no-trunc --format "${format%\\n}" $all "$@" | grep -v '<none>$'
}

# __docker_complete_images applies completion of images based on the current value of `$cur` or
# the value of the optional first option `--cur`, if given.
# See __docker_images for customization of the returned items.
__docker_complete_images() {
COMPREPLY=( $(compgen -W "$(__docker_images)" -- "$cur") )
__ltrim_colon_completions "$cur"
}

__docker_complete_image_repos() {
local repos="$(__docker_q images | awk 'NR>1 && $1 != "<none>" { print $1 }')"
COMPREPLY=( $(compgen -W "$repos" -- "$cur") )
}

__docker_complete_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"
local current="$cur"
if [ "$1" = "--cur" ] ; then
current="$2"
shift 2
fi
COMPREPLY=( $(compgen -W "$(__docker_images "$@")" -- "$current") )
__ltrim_colon_completions "$current"
}

# __docker_networks returns a list of all networks. Additional options to
Expand Down Expand Up @@ -1346,11 +1372,8 @@ _docker_container_commit() {
if [ "$cword" -eq "$counter" ]; then
__docker_complete_containers_all
return
fi
(( counter++ ))

if [ "$cword" -eq "$counter" ]; then
__docker_complete_image_repos_and_tags
elif [ "$cword" -eq "$((counter + 1))" ]; then
__docker_complete_images --repo --tag
return
fi
;;
Expand Down Expand Up @@ -1518,8 +1541,7 @@ _docker_container_ls() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
ancestor)
cur="${cur##*=}"
__docker_complete_images
__docker_complete_images --cur "${cur##*=}" --repo --tag --id
return
;;
before)
Expand Down Expand Up @@ -1984,7 +2006,7 @@ _docker_container_run_and_create() {
*)
local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" )
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
__docker_complete_images --repo --tag --id
fi
;;
esac
Expand Down Expand Up @@ -2494,7 +2516,7 @@ _docker_image_build() {
return
;;
--cache-from)
__docker_complete_image_repos_and_tags
__docker_complete_images --repo --tag --id
return
;;
--file|-f|--iidfile)
Expand Down Expand Up @@ -2522,7 +2544,7 @@ _docker_image_build() {
return
;;
--tag|-t)
__docker_complete_image_repos_and_tags
__docker_complete_images --repo --tag
return
;;
--target)
Expand Down Expand Up @@ -2568,9 +2590,9 @@ _docker_image_history() {
COMPREPLY=( $( compgen -W "--format --help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
local counter=$(__docker_pos_first_nonflag '--format')
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
__docker_complete_images --force-tag --id
fi
;;
esac
Expand All @@ -2594,12 +2616,10 @@ _docker_image_import() {
*)
local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m')
if [ "$cword" -eq "$counter" ]; then
_filedir
return
fi
(( counter++ ))

if [ "$cword" -eq "$counter" ]; then
__docker_complete_image_repos_and_tags
elif [ "$cword" -eq "$((counter + 1))" ]; then
__docker_complete_images --repo --tag
return
fi
;;
Expand Down Expand Up @@ -2632,9 +2652,8 @@ _docker_image_list() {
_docker_image_ls() {
local key=$(__docker_map_key_of_current_option '--filter|-f')
case "$key" in
before|since|reference)
cur="${cur##*=}"
__docker_complete_images
before|since)
__docker_complete_images --cur "${cur##*=}" --force-tag --id
return
;;
dangling)
Expand All @@ -2644,6 +2663,10 @@ _docker_image_ls() {
label)
return
;;
reference)
__docker_complete_images --cur "${cur##*=}" --repo --tag
return
;;
esac

case "$prev" in
Expand All @@ -2665,7 +2688,7 @@ _docker_image_ls() {
return
;;
*)
__docker_complete_image_repos
__docker_complete_images --repo --tag
;;
esac
}
Expand Down Expand Up @@ -2697,12 +2720,12 @@ _docker_image_pull() {
for arg in "${COMP_WORDS[@]}"; do
case "$arg" in
--all-tags|-a)
__docker_complete_image_repos
__docker_complete_images --repo
return
;;
esac
done
__docker_complete_image_repos_and_tags
__docker_complete_images --repo --tag
fi
;;
esac
Expand All @@ -2716,7 +2739,7 @@ _docker_image_push() {
*)
local counter=$(__docker_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
__docker_complete_image_repos_and_tags
__docker_complete_images --repo --tag
fi
;;
esac
Expand All @@ -2732,7 +2755,7 @@ _docker_image_rm() {
COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) )
;;
*)
__docker_complete_images
__docker_complete_images --force-tag --id
;;
esac
}
Expand All @@ -2754,7 +2777,7 @@ _docker_image_save() {
COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) )
;;
*)
__docker_complete_images
__docker_complete_images --repo --tag --id
;;
esac
}
Expand All @@ -2768,13 +2791,10 @@ _docker_image_tag() {
local counter=$(__docker_pos_first_nonflag)

if [ "$cword" -eq "$counter" ]; then
__docker_complete_image_repos_and_tags
__docker_complete_images --force-tag --id
return
fi
(( counter++ ))

if [ "$cword" -eq "$counter" ]; then
__docker_complete_image_repos_and_tags
elif [ "$cword" -eq "$((counter + 1))" ]; then
__docker_complete_images --repo --tag
return
fi
;;
Expand Down Expand Up @@ -2830,7 +2850,7 @@ _docker_inspect() {
'')
COMPREPLY=( $( compgen -W "
$(__docker_containers --all)
$(__docker_images)
$(__docker_images --force-tag --id)
$(__docker_networks)
$(__docker_nodes)
$(__docker_plugins_installed)
Expand All @@ -2843,7 +2863,7 @@ _docker_inspect() {
__docker_complete_containers_all
;;
image)
__docker_complete_images
__docker_complete_images --force-tag --id
;;
network)
__docker_complete_networks
Expand Down Expand Up @@ -3463,7 +3483,7 @@ _docker_service_update_and_create() {
esac
;;
--image)
__docker_complete_image_repos_and_tags
__docker_complete_images --repo --tag --id
return
;;
--network-add|--network-rm)
Expand Down Expand Up @@ -3559,7 +3579,7 @@ _docker_service_update_and_create() {
fi
else
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
__docker_complete_images --repo --tag --id
fi
fi
;;
Expand Down Expand Up @@ -4607,8 +4627,7 @@ _docker_system_events() {
return
;;
image)
cur="${cur##*=}"
__docker_complete_images
__docker_complete_images --cur "${cur##*=}" --repo --tag
return
;;
network)
Expand Down Expand Up @@ -4705,7 +4724,7 @@ _docker_trust_revoke() {
*)
local counter=$(__docker_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
__docker_complete_images --repo --tag
fi
;;
esac
Expand All @@ -4719,7 +4738,7 @@ _docker_trust_sign() {
*)
local counter=$(__docker_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
__docker_complete_images --force-tag --id
fi
;;
esac
Expand All @@ -4733,7 +4752,7 @@ _docker_trust_view() {
*)
local counter=$(__docker_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
__docker_complete_images --repo --tag
fi
;;
esac
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/commandline/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ The currently supported filters are:
* container (`container=<name or id>`)
* daemon (`daemon=<name or id>`)
* event (`event=<event action>`)
* image (`image=<tag or id>`)
* image (`image=<repository or tag>`)
* label (`label=<key>` or `label=<key>=<value>`)
* network (`network=<name or id>`)
* node (`node=<id>`)
Expand Down