diff --git a/.editorconfig b/.editorconfig index 6deb6378..e302645a 100755 --- a/.editorconfig +++ b/.editorconfig @@ -1,32 +1,15 @@ # EditorConfig is awesome: http://EditorConfig.org [*] -indent_style = tab -indent_size = 4 - -shell_variant = bash -binary_next_line = true # like -bn -switch_case_indent = true # like -ci -space_redirects = true # like -sr -keep_padding = true # like -kp -end_of_line = lf -charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false -[*.*sh] +[.git*] indent_style = tab -indent_size = 4 - -shell_variant = bash -binary_next_line = true # like -bn -switch_case_indent = true # like -ci -space_redirects = true # like -sr -keep_padding = true # like -kp -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/.gitmodules b/.gitmodules index 095a6a5e..57b46adc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,16 @@ [submodule "test_lib/bats-core"] path = test_lib/bats-core url = https://github.com/bats-core/bats-core + branch = tags/v1.2.0 [submodule "test_lib/bats-support"] path = test_lib/bats-support - url = https://github.com/ztombol/bats-support + url = https://github.com/bats-core/bats-support + branch = tags/v0.3.0 [submodule "test_lib/bats-assert"] path = test_lib/bats-assert - url = https://github.com/ztombol/bats-assert + url = https://github.com/bats-core/bats-assert + branch = tags/v2.0.0 [submodule "test_lib/bats-file"] path = test_lib/bats-file - url = https://github.com/ztombol/bats-file + url = https://github.com/bats-core/bats-file + branch = tags/v0.3.0 diff --git a/.travis.yml b/.travis.yml index b3fa2728..17e04a6b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,31 @@ -sudo: false -script: test/run -language: c -os: - - linux - - osx +# YAML anchors need to appear first. +# Keys starting with an underscore are the custom ones, refer to +# https://docs.travis-ci.com/user/build-config-yaml#private-keys-as-yaml-anchors-and-aliases-and-external-tooling + +_native_job: &native_job + script: | + test/run + +language: shell + +os: linux + +dist: xenial + +jobs: + - <<: *native_job + name: Ubuntu 16.04 + + - <<: *native_job + name: Ubuntu 18.04 + dist: bionic + + - <<: *native_job + name: MacOS xcode9.4 + os: osx + osx_image: xcode9.4 # Default xcode on Travis. + + - <<: *native_job + name: MacOS xcode11.5 + os: osx + osx_image: xcode11.5 # Latest xcode on Travis. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index bb03ab49..2f7941cb 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,6 +2,22 @@ This page summarizes a couple of rules to keep in mind when developing features or making changes in Bash-it. +## Debugging and Logging + +### General Logging + +While developing feature or making changes in general, you can log error/warning/debug +using `_log_error` `_log_warning` and `_log_debug`. This will help you solve problems quicker +and also propagate important notes to other users of Bash-it. +You can see the logs by using `bash-it doctor` command to reload and see the logs. +Alternatively, you can set `BASH_IT_LOG_LEVEL` to `BASH_IT_LOG_LEVEL_ERROR`, `BASH_IT_LOG_LEVEL_WARNING` or `BASH_IT_LOG_LEVEL_ALL`. + +### Log Prefix/Context + +You can define `BASH_IT_LOG_PREFIX` in your files in order to a have a constant prefix before your logs. +Note that we prefer to uses "tags" based logging, i.e `plugins: git: DEBUG: Loading git plugin`. + + ## Load Order ### General Load Order @@ -44,6 +60,11 @@ Having the order based on a numeric priority in a common directory allows for mo These items are subject to change. When making changes to the internal functionality, this page needs to be updated as well. +## Plugin Disable Callbacks + +Plugins can define a function that will be called when the plugin is being disabled. +The callback name should be `{PLUGIN_NAME}_on_disable`, you can see `gitstatus` for usage example. + ## Using the pre-commit hook Note the file .pre-commit-config.yaml at the top of the repo. diff --git a/README.md b/README.md index ccaa7946..1da1f7eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Bash-it -[![Build Status](https://travis-ci.org/Bash-it/bash-it.svg?branch=master)](https://travis-ci.org/Bash-it/bash-it) [![Join the chat at https://gitter.im/Bash-it/bash-it](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Bash-it/bash-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://travis-ci.com/Bash-it/bash-it.svg?branch=master)](https://travis-ci.com/Bash-it/bash-it) +[![Join the chat at https://gitter.im/Bash-it/bash-it](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Bash-it/bash-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) **Bash-it** is a collection of community Bash commands and scripts for Bash 3.2+. (And a shameless ripoff of [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) :smiley:) @@ -86,13 +87,24 @@ Have a look at our [bash-it-docker repository](https://github.com/Bash-it/bash-i ### Updating -To update Bash-it to the latest version, simply run: +To update Bash-it to the latest stable version, simply run: ```bash -bash-it update +bash-it update stable ``` -that's all. +If you want to update to the latest dev version (directly from master), run: + +```bash +bash-it update dev +``` + +If you want to update automatically and unattended, you can add the optional +`-s/--silent` flag, for example: + +```bash +bash-it update dev --silent +``` If you are using an older version of Bash-it, it's possible that some functionality has changed, or that the internal structure of how Bash-it organizes its functionality has been updated. For these cases, we provide a `migrate` command: @@ -394,6 +406,13 @@ $ git config --global --add bash-it.hide-status 1 Setting this flag globally has the same effect as `SCM_CHECK=true`, but only for Git repos. +### Speed up git status calculations + +As an alternative to ignoring repo status entirely, you can try out the `gitstatus` plugin. +This plugin speeds up all `git status` calculations by up to 10x times! + +**NOTE**: You will need to clone `gitstatus` repo from [here](https://github.com/romkatv/gitstatus). + ### Pass function renamed to passgen The Bash-it `pass` function has been renamed to `passgen` in order to avoid a naming conflict with the [pass password manager](https://www.passwordstore.org/). @@ -409,6 +428,20 @@ Unset `BASH_IT_LEGACY_PASS` to have Bash-it **return to default behavior**: * `unset BASH_IT_LEGACY_PASS` +### Debugging + +If you encounter problems with any part of Bash-it, run the following command: +```bash +bash-it doctor +``` +This will reload your bash profile and print out logs of various parts in Bash-it. +Note that this command at default will print all logs, including debug logs. +You can call it like this: +```bash +bash-it doctor [errors/warnings/all] +``` +In order to get wanted verbosity. + ### Proxy Support If you are working in a corporate environment where you have to go through a proxy server for internet access, diff --git a/aliases/available/bash-it.aliases.bash b/aliases/available/bash-it.aliases.bash new file mode 100644 index 00000000..d2975667 --- /dev/null +++ b/aliases/available/bash-it.aliases.bash @@ -0,0 +1,23 @@ +cite about-alias +about-alias 'Aliases for the bash-it command (these aliases are automatically included with the "general" aliases)' + +# Common misspellings of bash-it +alias shit='bash-it' +alias batshit='bash-it' +alias bashit='bash-it' +alias batbsh='bash-it' +alias babsh='bash-it' +alias bash_it='bash-it' +alias bash_ti='bash-it' + +# Additional bash-it aliases for help/show +alias bshsa='bash-it show aliases' +alias bshsc='bash-it show completions' +alias bshsp='bash-it show plugins' +alias bshha='bash-it help aliases' +alias bshhc='bash-it help completions' +alias bshhp='bash-it help plugins' +alias bshsch="bash-it search" +alias bshenp="bash-it enable plugin" +alias bshena="bash-it enable alias" +alias bshenc="bash-it enable completion" diff --git a/aliases/available/general.aliases.bash b/aliases/available/general.aliases.bash index 542b76cd..0c7bcd9d 100644 --- a/aliases/available/general.aliases.bash +++ b/aliases/available/general.aliases.bash @@ -28,7 +28,6 @@ alias vbpf="vim ~/.bash_profile" if grep --color=auto "a" "${BASH_IT}/"*.md &> /dev/null then alias grep='grep --color=auto' - export GREP_COLOR='1;33' fi if which gshuf &> /dev/null @@ -75,27 +74,6 @@ fi alias md='mkdir -p' alias rd='rmdir' -# Common misspellings of bash-it -alias shit='bash-it' -alias batshit='bash-it' -alias bashit='bash-it' -alias batbsh='bash-it' -alias babsh='bash-it' -alias bash_it='bash-it' -alias bash_ti='bash-it' - -# Additional bash-it aliases for help/show -alias bshsa='bash-it show aliases' -alias bshsc='bash-it show completions' -alias bshsp='bash-it show plugins' -alias bshha='bash-it help aliases' -alias bshhc='bash-it help completions' -alias bshhp='bash-it help plugins' -alias bshsch="bash-it search" -alias bshenp="bash-it enable plugin" -alias bshena="bash-it enable alias" -alias bshenc="bash-it enable completion" - # Shorten extract alias xt="extract" @@ -113,3 +91,12 @@ catt() { fi done } + +# The Bash-it aliases were moved to the `bash-it.aliases.bash` file. The intent of this +# is to keep the script readable and less bloated. If you don't need to use +# the `general` aliases, but you want the Bash-it aliases, you can disable the `general` +# aliases and enable just the ones for Bash-it explicitly: +# bash-it disable alias general +# bash-it enable alias bash-it +# shellcheck source=./bash-it.aliases.bash +source "$BASH_IT/aliases/available/bash-it.aliases.bash" diff --git a/aliases/available/git.aliases.bash b/aliases/available/git.aliases.bash index e784dade..be8d7330 100644 --- a/aliases/available/git.aliases.bash +++ b/aliases/available/git.aliases.bash @@ -22,6 +22,7 @@ alias gs='git status' alias gss='git status -s' alias gsu='git submodule update --init --recursive' alias gl='git pull' +alias gpl='git pull' alias glum='git pull upstream master' alias gpr='git pull --rebase' alias gpp='git pull && git push' @@ -35,8 +36,12 @@ alias gpom='git push origin master' alias gr='git remote' alias grv='git remote -v' alias gra='git remote add' +alias grb='git rebase' +alias grm='git rebase master' +alias grmi='git rebase master -i' alias gd='git diff' alias gds='git diff --staged' +alias gdt='git difftool' alias gdv='git diff -w "$@" | vim -R -' alias gc='git commit -v' alias gca='git commit -v -a' @@ -46,6 +51,8 @@ alias gci='git commit --interactive' alias gcamd='git commit --amend' alias gb='git branch' alias gba='git branch -a' +# FROM https://stackoverflow.com/a/58623139/10362396 +alias gbc='git for-each-ref --format="%(authorname) %09 %(if)%(HEAD)%(then)*%(else)%(refname:short)%(end) %09 %(creatordate)" refs/remotes/ --sort=authorname DESC' alias gbt='git branch --track' alias gbm='git branch -m' alias gbd='git branch -d' @@ -64,7 +71,9 @@ alias gdel='git branch -D' alias gmu='git fetch origin -v; git fetch upstream -v; git merge upstream/master' alias gll='git log --graph --pretty=oneline --abbrev-commit' alias gg="git log --graph --pretty=format:'%C(bold)%h%Creset%C(magenta)%d%Creset %s %C(yellow)<%an> %C(cyan)(%cr)%Creset' --abbrev-commit --date=relative" +alias ggf="git log --graph --date=short --pretty=format:'%C(auto)%h %Cgreen%an%Creset %Cblue%cd%Creset %C(auto)%d %s'" alias ggs="gg --stat" +alias gsh="git show" alias gsl="git shortlog -sn" alias gwc="git whatchanged" alias gt="git tag" @@ -79,15 +88,36 @@ alias gnew="git log HEAD@{1}..HEAD@{0}" alias gcaa="git commit -a --amend -C HEAD" # Rebase with latest remote master alias gprom="git fetch origin master && git rebase origin/master && git update-ref refs/heads/master origin/master" +alias gpf="git push --force" alias gpunch="git push --force-with-lease" alias ggui="git gui" alias gcsam="git commit -S -am" +# Stash aliases alias gst="git stash" alias gstb="git stash branch" alias gstd="git stash drop" alias gstl="git stash list" +# Push introduced in git v2.13.2 +alias gstpu="git stash push" +alias gstpum="git stash push -m" +# Save deprecated since git v2.16.0 +# - aliases now resolve to push +alias gsts="git stash push" +alias gstsm="git stash push -m" +# Alias gstpo added for symmetry with gstpu (push) +# - gstp remains as alias for pop due to long-standing usage +alias gstpo="git stash pop" alias gstp="git stash pop" -alias gh='cd "$(git rev-parse --show-toplevel)"' +# Switch aliases - Requires git v2.23+ +alias gsw="git switch" +alias gswm="git switch master" +alias gswc="git switch --create" +alias gswt="git switch --track" +# Git home +alias ghm='cd "$(git rev-parse --show-toplevel)"' +if ! _command_exists gh; then + alias gh='ghm' +fi # Show untracked files alias gu='git ls-files . --exclude-standard --others' diff --git a/aliases/available/kubectl.aliases.bash b/aliases/available/kubectl.aliases.bash index 0322c931..9ce923a0 100644 --- a/aliases/available/kubectl.aliases.bash +++ b/aliases/available/kubectl.aliases.bash @@ -5,12 +5,11 @@ cite 'about-alias' about-alias 'kubectl aliases' -# set apt aliases function _set_pkg_aliases() { - if [ -x $(which kubectl) ]; then - alias kc='kubectl' - alias kcgp='kubectl get pods' + if _command_exists kubectl; then + alias kc='kubectl' + alias kcgp='kubectl get pods' alias kcgd='kubectl get deployments' alias kcgn='kubectl get nodes' alias kcdp='kubectl describe pod' @@ -18,8 +17,9 @@ function _set_pkg_aliases() alias kcdn='kubectl describe node' alias kcgpan='kubectl get pods --all-namespaces' alias kcgdan='kubectl get deployments --all-namespaces' - alias kcnetshoot='kubectl run --generator=run-pod/v1 netshoot-$(uuidgen | tr A-Z a-z | sed 's/-//g') --rm -i --tty --image nicolaka/netshoot -- /bin/bash' - fi + # launches a disposable netshoot pod in the k8s cluster + alias kcnetshoot='kubectl run --generator=run-pod/v1 netshoot-$(date +%s) --rm -i --tty --image nicolaka/netshoot -- /bin/bash' + fi } _set_pkg_aliases diff --git a/aliases/available/terraform.aliases.bash b/aliases/available/terraform.aliases.bash new file mode 100644 index 00000000..d62a8c2c --- /dev/null +++ b/aliases/available/terraform.aliases.bash @@ -0,0 +1,10 @@ +# Aliases for Terraform and Terragrunt + +cite 'about-alias' +about-alias 'Terraform abbreviations' + +alias tf='terraform' +alias tfv='terraform validate' +alias tfp='terraform plan' +alias tfa='terraform apply' +alias tfd='terraform destory' diff --git a/aliases/available/terragrunt.aliases.bash b/aliases/available/terragrunt.aliases.bash new file mode 100644 index 00000000..9395b351 --- /dev/null +++ b/aliases/available/terragrunt.aliases.bash @@ -0,0 +1,15 @@ +# Aliases for Terraform and Terragrunt + +cite 'about-alias' +about-alias 'Terragrunt abbreviations' + +alias tg='terragrunt' +alias tgv='terragrunt validate' +alias tgp='terragrunt plan' +alias tga='terragrunt apply' +alias tgd='terragrunt destroy' + +alias tgva='terragrunt validate-all' +alias tgpa='terragrunt plan-all' +alias tgaa='terragrunt apply-all' +alias tgda='terragrunt destroy-all' diff --git a/aliases/available/uuidgen.aliases.bash b/aliases/available/uuidgen.aliases.bash index fec5a2b8..aada05fb 100644 --- a/aliases/available/uuidgen.aliases.bash +++ b/aliases/available/uuidgen.aliases.bash @@ -1,6 +1,11 @@ cite 'uuid-alias' about-alias 'uuidgen aliases' -alias uuidu="uuidgen" -alias uuidl="uuidgen | tr '[:upper:]' '[:lower:]'" -alias uuid=uuidl # because upper case is like YELLING +if _command_exists uuid; then # Linux + alias uuidu="uuid | tr '[:lower:]' '[:upper:]'" + alias uuidl=uuid +elif _command_exists uuidgen; then # macOS/BSD + alias uuidu="uuidgen" + alias uuid="uuidgen | tr '[:upper:]' '[:lower:]'" # because upper case is like YELLING + alias uuidl=uuid +fi diff --git a/bash_it.sh b/bash_it.sh index ab911019..310aae42 100755 --- a/bash_it.sh +++ b/bash_it.sh @@ -1,37 +1,49 @@ #!/usr/bin/env bash # Initialize Bash It +BASH_IT_LOG_PREFIX="core: main: " # Only set $BASH_IT if it's not already set if [ -z "$BASH_IT" ]; then # Setting $BASH to maintain backwards compatibility - # TODO: warn users that they should upgrade their .bash_profile export BASH_IT=$BASH BASH="$(bash -c 'echo $BASH')" export BASH -fi - -# For backwards compatibility, look in old BASH_THEME location -if [ -z "$BASH_IT_THEME" ]; -then - # TODO: warn users that they should upgrade their .bash_profile - export BASH_IT_THEME="$BASH_THEME"; - unset BASH_THEME; + BASH_IT_OLD_BASH_SETUP=true fi # Load composure first, so we support function metadata # shellcheck source=./lib/composure.bash source "${BASH_IT}/lib/composure.bash" +# We need to load logging module first as well in order to be able to log +# shellcheck source=./lib/log.bash +source "${BASH_IT}/lib/log.bash" + +# We can only log it now +[ -z "$BASH_IT_OLD_BASH_SETUP" ] || _log_warning "BASH_IT variable not initialized, please upgrade your bash-it version and reinstall it!" + +# For backwards compatibility, look in old BASH_THEME location +if [ -z "$BASH_IT_THEME" ]; +then + _log_warning "BASH_IT_THEME variable not initialized, please upgrade your bash-it version and reinstall it!" + export BASH_IT_THEME="$BASH_THEME"; + unset BASH_THEME; +fi # support 'plumbing' metadata cite _about _param _example _group _author _version # libraries, but skip appearance (themes) for now +_log_debug "Loading libraries(except appearance)..." LIB="${BASH_IT}/lib/*.bash" APPEARANCE_LIB="${BASH_IT}/lib/appearance.bash" for _bash_it_config_file in $LIB do if [ "$_bash_it_config_file" != "$APPEARANCE_LIB" ]; then + filename=${_bash_it_config_file##*/} + filename=${filename%.bash} + BASH_IT_LOG_PREFIX="lib: ${filename}: " + _log_debug "Loading library file..." # shellcheck disable=SC1090 source "$_bash_it_config_file" fi @@ -51,36 +63,51 @@ done # Load theme, if a theme was set if [[ ! -z "${BASH_IT_THEME}" ]]; then + _log_debug "Loading \"${BASH_IT_THEME}\" theme..." # Load colors and helpers first so they can be used in base theme + BASH_IT_LOG_PREFIX="themes: colors: " # shellcheck source=./themes/colors.theme.bash source "${BASH_IT}/themes/colors.theme.bash" + BASH_IT_LOG_PREFIX="themes: githelpers: " # shellcheck source=./themes/githelpers.theme.bash source "${BASH_IT}/themes/githelpers.theme.bash" + BASH_IT_LOG_PREFIX="themes: p4helpers: " # shellcheck source=./themes/p4helpers.theme.bash source "${BASH_IT}/themes/p4helpers.theme.bash" + BASH_IT_LOG_PREFIX="themes: base: " # shellcheck source=./themes/base.theme.bash source "${BASH_IT}/themes/base.theme.bash" + BASH_IT_LOG_PREFIX="lib: appearance: " # appearance (themes) now, after all dependencies # shellcheck source=./lib/appearance.bash source "$APPEARANCE_LIB" fi -# Load custom aliases, completion, plugins +BASH_IT_LOG_PREFIX="core: main: " +_log_debug "Loading custom aliases, completion, plugins..." for file_type in "aliases" "completion" "plugins" do if [ -e "${BASH_IT}/${file_type}/custom.${file_type}.bash" ] then + BASH_IT_LOG_PREFIX="${file_type}: custom: " + _log_debug "Loading component..." # shellcheck disable=SC1090 source "${BASH_IT}/${file_type}/custom.${file_type}.bash" fi done # Custom +BASH_IT_LOG_PREFIX="core: main: " +_log_debug "Loading general custom files..." CUSTOM="${BASH_IT_CUSTOM:=${BASH_IT}/custom}/*.bash ${BASH_IT_CUSTOM:=${BASH_IT}/custom}/**/*.bash" for _bash_it_config_file in $CUSTOM do if [ -e "${_bash_it_config_file}" ]; then + filename=$(basename "${_bash_it_config_file}") + filename=${filename%*.bash} + BASH_IT_LOG_PREFIX="custom: $filename: " + _log_debug "Loading custom file..." # shellcheck disable=SC1090 source "$_bash_it_config_file" fi diff --git a/completion/available/bash-it.completion.bash b/completion/available/bash-it.completion.bash index 71ec8418..4fdd72d6 100644 --- a/completion/available/bash-it.completion.bash +++ b/completion/available/bash-it.completion.bash @@ -65,7 +65,7 @@ _bash-it-comp() prev="${COMP_WORDS[COMP_CWORD-1]}" chose_opt="${COMP_WORDS[1]}" file_type="${COMP_WORDS[2]}" - opts="disable enable help migrate reload search show update version" + opts="disable enable help migrate reload restart doctor search show update version" case "${chose_opt}" in show) local show_args="aliases completions plugins" @@ -82,7 +82,21 @@ _bash-it-comp() return 0 fi ;; - migrate | reload | search | update | version) + doctor) + local doctor_args="errors warnings all" + COMPREPLY=( $(compgen -W "${doctor_args}" -- ${cur}) ) + return 0 + ;; + update) + if [[ ${cur} == -* ]];then + local update_args="-s --silent" + else + local update_args="stable dev" + fi + COMPREPLY=( $(compgen -W "${update_args}" -- ${cur}) ) + return 0 + ;; + migrate | reload | search | version) return 0 ;; enable | disable) diff --git a/completion/available/brew.completion.bash b/completion/available/brew.completion.bash index fb1176e5..54268035 100644 --- a/completion/available/brew.completion.bash +++ b/completion/available/brew.completion.bash @@ -1,13 +1,27 @@ -if which brew >/dev/null 2>&1; then - BREW_PREFIX=$(brew --prefix) - if [ -f "$BREW_PREFIX"/etc/bash_completion.d/brew ]; then - . "$BREW_PREFIX"/etc/bash_completion.d/brew - elif [ -f "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh ]; then - . "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh - elif [ -f "$BREW_PREFIX"/completions/bash/brew ]; then - # For the git-clone based installation, see here for more info: - # https://github.com/Bash-it/bash-it/issues/1458 - # https://docs.brew.sh/Shell-Completion - . "$BREW_PREFIX"/completions/bash/brew - fi +#!/usr/bin/env bash + +# Load late to make sure `system` completion loads first +# BASH_IT_LOAD_PRIORITY: 375 + +if [[ "$(uname -s)" != 'Darwin' ]]; then + _log_warning "unsupported operating system - only 'Darwin' is supported" + return 0 +fi + +# Make sure brew is installed +_command_exists brew || return 0 + +BREW_PREFIX=${BREW_PREFIX:-$(brew --prefix)} + +if [[ -r "$BREW_PREFIX"/etc/bash_completion.d/brew ]]; then + source "$BREW_PREFIX"/etc/bash_completion.d/brew + +elif [[ -r "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh ]]; then + source "$BREW_PREFIX"/Library/Contributions/brew_bash_completion.sh + +elif [[ -f "$BREW_PREFIX"/completions/bash/brew ]]; then + # For the git-clone based installation, see here for more info: + # https://github.com/Bash-it/bash-it/issues/1458 + # https://docs.brew.sh/Shell-Completion + source "$BREW_PREFIX"/completions/bash/brew fi diff --git a/completion/available/crystal.completion.bash b/completion/available/crystal.completion.bash index cbc891d7..7644ffd4 100644 --- a/completion/available/crystal.completion.bash +++ b/completion/available/crystal.completion.bash @@ -1,11 +1 @@ -if which crystal >/dev/null 2>&1; then - - if which brew >/dev/null 2>&1; then - BREW_PREFIX=$(brew --prefix) - - if [ -f "$BREW_PREFIX"/etc/bash_completion.d/crystal ]; then - . "$BREW_PREFIX"/etc/bash_completion.d/crystal - fi - fi - -fi +_log_warning 'Bash completion for "crystal" is now covered by "system". This completion can be disabled.' diff --git a/completion/available/docker.completion.bash b/completion/available/docker.completion.bash index 11b988f3..125ac0f8 100644 --- a/completion/available/docker.completion.bash +++ b/completion/available/docker.completion.bash @@ -1,5617 +1,21 @@ #!/usr/bin/env bash -# shellcheck disable=SC2016,SC2119,SC2155,SC2206,SC2207 -# -# Shellcheck ignore list: -# - SC2016: Expressions don't expand in single quotes, use double quotes for that. -# - SC2119: Use foo "$@" if function's $1 should mean script's $1. -# - SC2155: Declare and assign separately to avoid masking return values. -# - SC2206: Quote to prevent word splitting, or split robustly with mapfile or read -a. -# - SC2207: Prefer mapfile or read -a to split command output (or quote to avoid splitting). -# -# You can find more details for each warning at the following page: -# https://github.com/koalaman/shellcheck/wiki/ -# -# bash completion file for core docker commands -# -# This script provides completion of: -# - commands and their options -# - container ids and names -# - image repos and tags -# - filepaths -# -# To enable the completions either: -# - place this file in /etc/bash_completion.d -# or -# - copy this file to e.g. ~/.docker-completion.sh and add the line -# below to your .bashrc after bash completion features are loaded -# . ~/.docker-completion.sh -# -# Configuration: -# -# For several commands, the amount of completions can be configured by -# setting environment variables. -# -# DOCKER_COMPLETION_SHOW_CONFIG_IDS -# DOCKER_COMPLETION_SHOW_CONTAINER_IDS -# DOCKER_COMPLETION_SHOW_NETWORK_IDS -# DOCKER_COMPLETION_SHOW_NODE_IDS -# DOCKER_COMPLETION_SHOW_PLUGIN_IDS -# DOCKER_COMPLETION_SHOW_SECRET_IDS -# DOCKER_COMPLETION_SHOW_SERVICE_IDS -# "no" - Show names only (default) -# "yes" - Show names and ids -# -# You can tailor completion for the "events", "history", "inspect", "run", -# "rmi" and "save" commands by settings the following environment -# variables: -# -# DOCKER_COMPLETION_SHOW_IMAGE_IDS -# "none" - Show names only (default) -# "non-intermediate" - Show names and ids, but omit intermediate image IDs -# "all" - Show names and ids, including intermediate image IDs -# -# DOCKER_COMPLETION_SHOW_TAGS -# "yes" - include tags in completion options (default) -# "no" - don't include tags in completion options -# -# Note: -# Currently, the completions will not work if the docker daemon is not -# bound to the default communication port/socket -# If the docker daemon is using a unix socket for communication your user -# must have access to the socket for the completions to function correctly -# -# Note for developers: -# Please arrange options sorted alphabetically by long name with the short -# options immediately following their corresponding long form. -# This order should be applied to lists, alternatives and code blocks. - -__docker_previous_extglob_setting=$(shopt -p extglob) -shopt -s extglob - -__docker_q() { - docker ${host:+--host "$host"} ${config:+--config "$config"} ${context:+--context "$context"} 2>/dev/null "$@" -} - -# __docker_configs returns a list of configs. Additional options to -# `docker config ls` may be specified in order to filter the list, e.g. -# `__docker_configs --filter label=stage=production`. -# By default, only names are returned. -# Set DOCKER_COMPLETION_SHOW_CONFIG_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__docker_configs() { - local format - if [ "$1" = "--id" ] ; then - format='{{.ID}}' - shift - elif [ "$1" = "--name" ] ; then - format='{{.Name}}' - shift - elif [ "$DOCKER_COMPLETION_SHOW_CONFIG_IDS" = yes ] ; then - format='{{.ID}} {{.Name}}' - else - format='{{.Name}}' - fi - - __docker_q config ls --format "$format" "$@" -} - -# __docker_complete_configs applies completion of configs based on the current value -# of `$cur` or the value of the optional first option `--cur`, if given. -__docker_complete_configs() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_configs "$@")" -- "$current") ) -} - -# __docker_containers returns a list of containers. Additional options to -# `docker ps` may be specified in order to filter the list, e.g. -# `__docker_containers --filter status=running` -# By default, only names are returned. -# Set DOCKER_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__docker_containers() { - local format - if [ "$1" = "--id" ] ; then - format='{{.ID}}' - shift - elif [ "$1" = "--name" ] ; then - format='{{.Names}}' - shift - elif [ "${DOCKER_COMPLETION_SHOW_CONTAINER_IDS}" = yes ] ; then - format='{{.ID}} {{.Names}}' - else - format='{{.Names}}' - fi - __docker_q ps --format "$format" "$@" -} - -# __docker_complete_containers applies completion of containers based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__docker_containers`. -__docker_complete_containers() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_containers "$@")" -- "$current") ) -} - -__docker_complete_containers_all() { - __docker_complete_containers "$@" --all -} - -# shellcheck disable=SC2120 -__docker_complete_containers_removable() { - __docker_complete_containers "$@" --filter status=created --filter status=exited -} - -__docker_complete_containers_running() { - __docker_complete_containers "$@" --filter status=running -} - -# shellcheck disable=SC2120 -__docker_complete_containers_stoppable() { - __docker_complete_containers "$@" --filter status=running --filter status=paused -} - -# shellcheck disable=SC2120 -__docker_complete_containers_stopped() { - __docker_complete_containers "$@" --filter status=exited -} - -# shellcheck disable=SC2120 -__docker_complete_containers_unpauseable() { - __docker_complete_containers "$@" --filter status=paused -} - -__docker_complete_container_names() { - local containers=( $(__docker_q ps -aq --no-trunc) ) - local names=( $(__docker_q inspect --format '{{.Name}}' "${containers[@]}") ) - names=( "${names[@]#/}" ) # trim off the leading "/" from the container names - COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) -} - -__docker_complete_container_ids() { - local containers=( $(__docker_q ps -aq) ) - COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) -} - -# __docker_contexts returns a list of contexts without the special "default" context. -# Completions may be added with `--add`, e.g. `--add default`. -__docker_contexts() { - local add=() - while true ; do - case "$1" in - --add) - add+=("$2") - shift 2 - ;; - *) - break - ;; - esac - done - __docker_q context ls -q - echo "${add[@]}" -} - -__docker_complete_contexts() { - local contexts=( $(__docker_contexts "$@") ) - COMPREPLY=( $(compgen -W "${contexts[*]}" -- "$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 repo_format='{{.Repository}}' - local tag_format='{{.Repository}}:{{.Tag}}' - local id_format='{{.ID}}' - local all - local format - - if [ "$DOCKER_COMPLETION_SHOW_IMAGE_IDS" = "all" ] ; then - all='--all' - fi - - 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) - # like `--tag` but ignores environment setting - format+="$tag_format\n" - shift - ;; - *) - break - ;; - esac - done - - __docker_q image ls --no-trunc --format "${format%\\n}" $all "$@" | grep -v '$' -} - -# __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() { - 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 -# `docker network ls` may be specified in order to filter the list, e.g. -# `__docker_networks --filter type=custom` -# By default, only names are returned. -# Set DOCKER_COMPLETION_SHOW_NETWORK_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__docker_networks() { - local format - if [ "$1" = "--id" ] ; then - format='{{.ID}}' - shift - elif [ "$1" = "--name" ] ; then - format='{{.Name}}' - shift - elif [ "${DOCKER_COMPLETION_SHOW_NETWORK_IDS}" = yes ] ; then - format='{{.ID}} {{.Name}}' - else - format='{{.Name}}' - fi - __docker_q network ls --format "$format" "$@" -} - -# __docker_complete_networks applies completion of networks based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__docker_networks`. -__docker_complete_networks() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_networks "$@")" -- "$current") ) -} - -__docker_complete_containers_in_network() { - local containers=($(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1")) - COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) -} - -# __docker_volumes returns a list of all volumes. Additional options to -# `docker volume ls` may be specified in order to filter the list, e.g. -# `__docker_volumes --filter dangling=true` -# Because volumes do not have IDs, this function does not distinguish between -# IDs and names. -__docker_volumes() { - __docker_q volume ls -q "$@" -} - -# __docker_complete_volumes applies completion of volumes based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__docker_volumes`. -__docker_complete_volumes() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_volumes "$@")" -- "$current") ) -} - -# __docker_plugins_bundled returns a list of all plugins of a given type. -# The type has to be specified with the mandatory option `--type`. -# Valid types are: Network, Volume, Authorization. -# Completions may be added or removed with `--add` and `--remove` -# This function only deals with plugins that come bundled with Docker. -# For plugins managed by `docker plugin`, see `__docker_plugins_installed`. -__docker_plugins_bundled() { - local type add=() remove=() - while true ; do - case "$1" in - --type) - type="$2" - shift 2 - ;; - --add) - add+=("$2") - shift 2 - ;; - --remove) - remove+=("$2") - shift 2 - ;; - *) - break - ;; - esac - done - - local plugins=($(__docker_q info --format "{{range \$i, \$p := .Plugins.$type}}{{.}} {{end}}")) - for del in "${remove[@]}" ; do - plugins=(${plugins[@]/$del/}) - done - echo "${plugins[@]}" "${add[@]}" -} - -# __docker_complete_plugins_bundled applies completion of plugins based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# The plugin type has to be specified with the next option `--type`. -# This function only deals with plugins that come bundled with Docker. -# For completion of plugins managed by `docker plugin`, see -# `__docker_complete_plugins_installed`. -__docker_complete_plugins_bundled() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_plugins_bundled "$@")" -- "$current") ) -} - -# __docker_plugins_installed returns a list of all plugins that were installed with -# the Docker plugin API. -# By default, only names are returned. -# Set DOCKER_COMPLETION_SHOW_PLUGIN_IDS=yes to also complete IDs. -# Additional options to `docker plugin ls` may be specified in order to filter the list, -# e.g. `__docker_plugins_installed --filter enabled=true` -# For built-in pugins, see `__docker_plugins_bundled`. -__docker_plugins_installed() { - local format - if [ "$DOCKER_COMPLETION_SHOW_PLUGIN_IDS" = yes ] ; then - format='{{.ID}} {{.Name}}' - else - format='{{.Name}}' - fi - __docker_q plugin ls --format "$format" "$@" -} - -# __docker_complete_plugins_installed applies completion of plugins that were installed -# with the Docker plugin API, based on the current value of `$cur` or the value of -# the optional first option `--cur`, if given. -# Additional filters may be appended, see `__docker_plugins_installed`. -# For completion of built-in pugins, see `__docker_complete_plugins_bundled`. -__docker_complete_plugins_installed() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_plugins_installed "$@")" -- "$current") ) -} - -__docker_runtimes() { - __docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' -} - -__docker_complete_runtimes() { - COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") ) -} - -# __docker_secrets returns a list of secrets. Additional options to -# `docker secret ls` may be specified in order to filter the list, e.g. -# `__docker_secrets --filter label=stage=production` -# By default, only names are returned. -# Set DOCKER_COMPLETION_SHOW_SECRET_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__docker_secrets() { - local format - if [ "$1" = "--id" ] ; then - format='{{.ID}}' - shift - elif [ "$1" = "--name" ] ; then - format='{{.Name}}' - shift - elif [ "$DOCKER_COMPLETION_SHOW_SECRET_IDS" = yes ] ; then - format='{{.ID}} {{.Name}}' - else - format='{{.Name}}' - fi - - __docker_q secret ls --format "$format" "$@" -} - -# __docker_complete_secrets applies completion of secrets based on the current value -# of `$cur` or the value of the optional first option `--cur`, if given. -__docker_complete_secrets() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_secrets "$@")" -- "$current") ) -} - -# __docker_stacks returns a list of all stacks. -__docker_stacks() { - __docker_q stack ls | awk 'NR>1 {print $1}' -} - -# __docker_complete_stacks applies completion of stacks based on the current value -# of `$cur` or the value of the optional first option `--cur`, if given. -__docker_complete_stacks() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_stacks "$@")" -- "$current") ) -} - -# __docker_nodes returns a list of all nodes. Additional options to -# `docker node ls` may be specified in order to filter the list, e.g. -# `__docker_nodes --filter role=manager` -# By default, only node names are returned. -# Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete node IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -# Completions may be added with `--add`, e.g. `--add self`. -__docker_nodes() { - local format - if [ "$DOCKER_COMPLETION_SHOW_NODE_IDS" = yes ] ; then - format='{{.ID}} {{.Hostname}}' - else - format='{{.Hostname}}' - fi - - local add=() - - while true ; do - case "$1" in - --id) - format='{{.ID}}' - shift - ;; - --name) - format='{{.Hostname}}' - shift - ;; - --add) - add+=("$2") - shift 2 - ;; - *) - break - ;; - esac - done - - echo "$(__docker_q node ls --format "$format" "$@")" "${add[@]}" -} - -# __docker_complete_nodes applies completion of nodes based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__docker_nodes`. -__docker_complete_nodes() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_nodes "$@")" -- "$current") ) -} - -# __docker_services returns a list of all services. Additional options to -# `docker service ls` may be specified in order to filter the list, e.g. -# `__docker_services --filter name=xxx` -# By default, only node names are returned. -# Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__docker_services() { - local fields='$2' # default: service name only - [ "${DOCKER_COMPLETION_SHOW_SERVICE_IDS}" = yes ] && fields='$1,$2' # ID & name - - if [ "$1" = "--id" ] ; then - fields='$1' # IDs only - shift - elif [ "$1" = "--name" ] ; then - fields='$2' # names only - shift - fi - __docker_q service ls "$@" | awk "NR>1 {print $fields}" -} - -# __docker_complete_services applies completion of services based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__docker_services`. -__docker_complete_services() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__docker_services "$@")" -- "$current") ) -} - -# __docker_tasks returns a list of all task IDs. -__docker_tasks() { - __docker_q service ps --format '{{.ID}}' "" -} - -# __docker_complete_services_and_tasks applies completion of services and task IDs. -# shellcheck disable=SC2120 -__docker_complete_services_and_tasks() { - COMPREPLY=( $(compgen -W "$(__docker_services "$@") $(__docker_tasks)" -- "$cur") ) -} - -# __docker_append_to_completions appends the word passed as an argument to every -# word in `$COMPREPLY`. -# Normally you do this with `compgen -S` while generating the completions. -# This function allows you to append a suffix later. It allows you to use -# the __docker_complete_XXX functions in cases where you need a suffix. -__docker_append_to_completions() { - COMPREPLY=( ${COMPREPLY[@]/%/"$1"} ) -} - -# __docker_fetch_info fetches information about the configured Docker server and updates -# several variables with the results. -# The result is cached for the duration of one invocation of bash completion. -__docker_fetch_info() { - if [ -z "$info_fetched" ] ; then - read -r client_experimental server_experimental server_os <<< "$(__docker_q version -f '{{.Client.Experimental}} {{.Server.Experimental}} {{.Server.Os}}')" - info_fetched=true - fi -} - -# __docker_client_is_experimental tests whether the Docker cli is configured to support -# experimental features. If so, the function exits with 0 (true). -# Otherwise, or if the result cannot be determined, the exit value is 1 (false). -__docker_client_is_experimental() { - __docker_fetch_info - [ "$client_experimental" = "true" ] -} - -# __docker_server_is_experimental tests whether the currently configured Docker -# server runs in experimental mode. If so, the function exits with 0 (true). -# Otherwise, or if the result cannot be determined, the exit value is 1 (false). -__docker_server_is_experimental() { - __docker_fetch_info - [ "$server_experimental" = "true" ] -} - -# __docker_server_os_is tests whether the currently configured Docker server runs -# on the operating system passed in as the first argument. -# Known operating systems: linux, windows. -__docker_server_os_is() { - local expected_os="$1" - __docker_fetch_info - [ "$server_os" = "$expected_os" ] -} - -# __docker_stack_orchestrator_is tests whether the client is configured to use -# the orchestrator that is passed in as the first argument. -__docker_stack_orchestrator_is() { - case "$1" in - kubernetes) - if [ -z "$stack_orchestrator_is_kubernetes" ] ; then - __docker_q stack ls --help | grep -qe --namespace - stack_orchestrator_is_kubernetes=$? - fi - return $stack_orchestrator_is_kubernetes - ;; - swarm) - if [ -z "$stack_orchestrator_is_swarm" ] ; then - __docker_q stack deploy --help | grep -qe "with-registry-auth" - stack_orchestrator_is_swarm=$? - fi - return $stack_orchestrator_is_swarm - ;; - *) - return 1 - ;; - - esac -} - -# __docker_pos_first_nonflag finds the position of the first word that is neither -# option nor an option's argument. If there are options that require arguments, -# you should pass a glob describing those options, e.g. "--option1|-o|--option2" -# Use this function to restrict completions to exact positions after the argument list. -__docker_pos_first_nonflag() { - local argument_flags=$1 - - local counter=$((${subcommand_pos:-${command_pos}} + 1)) - while [ "$counter" -le "$cword" ]; do - if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then - (( counter++ )) - # eat "=" in case of --option=arg syntax - [ "${words[$counter]}" = "=" ] && (( counter++ )) - else - case "${words[$counter]}" in - -*) - ;; - *) - break - ;; - esac - fi - - # Bash splits words at "=", retaining "=" as a word, examples: - # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words - while [ "${words[$counter + 1]}" = "=" ] ; do - counter=$(( counter + 2)) - done - - (( counter++ )) - done - - echo $counter -} - -# __docker_map_key_of_current_option returns `key` if we are currently completing the -# value of a map option (`key=value`) which matches the extglob given as an argument. -# This function is needed for key-specific completions. -__docker_map_key_of_current_option() { - local glob="$1" - - local key glob_pos - if [ "$cur" = "=" ] ; then # key= case - key="$prev" - glob_pos=$((cword - 2)) - elif [[ $cur == *=* ]] ; then # key=value case (OSX) - key=${cur%=*} - glob_pos=$((cword - 1)) - elif [ "$prev" = "=" ] ; then - key=${words[$cword - 2]} # key=value case - glob_pos=$((cword - 3)) - else - return - fi - - [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax - - [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key" -} - -# __docker_value_of_option returns the value of the first option matching `option_glob`. -# Valid values for `option_glob` are option names like `--log-level` and globs like -# `--log-level|-l` -# Only positions between the command and the current word are considered. -__docker_value_of_option() { - local option_extglob=$(__docker_to_extglob "$1") - - local counter=$((command_pos + 1)) - while [ "$counter" -lt "$cword" ]; do - case ${words[$counter]} in - $option_extglob ) - echo "${words[$counter + 1]}" - break - ;; - esac - (( counter++ )) - done -} - -# __docker_to_alternatives transforms a multiline list of strings into a single line -# string with the words separated by `|`. -# This is used to prepare arguments to __docker_pos_first_nonflag(). -__docker_to_alternatives() { - local parts=( $1 ) - local IFS='|' - echo "${parts[*]}" -} - -# __docker_to_extglob transforms a multiline list of options into an extglob pattern -# suitable for use in case statements. -__docker_to_extglob() { - local extglob=$( __docker_to_alternatives "$1" ) - echo "@($extglob)" -} - -# __docker_subcommands processes subcommands -# Locates the first occurrence of any of the subcommands contained in the -# first argument. In case of a match, calls the corresponding completion -# function and returns 0. -# If no match is found, 1 is returned. The calling function can then -# continue processing its completion. -# -# TODO if the preceding command has options that accept arguments and an -# argument is equal ot one of the subcommands, this is falsely detected as -# a match. -__docker_subcommands() { - local subcommands="$1" - - local counter=$((command_pos + 1)) - while [ "$counter" -lt "$cword" ]; do - case "${words[$counter]}" in - $(__docker_to_extglob "$subcommands") ) - subcommand_pos=$counter - local subcommand=${words[$counter]} - local completions_func=_docker_${command}_${subcommand//-/_} - declare -F "$completions_func" >/dev/null && "$completions_func" - return 0 - ;; - esac - (( counter++ )) - done - return 1 -} - -# __docker_nospace suppresses trailing whitespace -__docker_nospace() { - # compopt is not available in ancient bash versions - type compopt &>/dev/null && compopt -o nospace -} - -__docker_complete_resolved_hostname() { - command -v host >/dev/null 2>&1 || return - COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) -} - -# __docker_local_interfaces returns a list of the names and addresses of all -# local network interfaces. -# If `--ip-only` is passed as a first argument, only addresses are returned. -__docker_local_interfaces() { - command -v ip >/dev/null 2>&1 || return - - local format - if [ "$1" = "--ip-only" ] ; then - format='\1' - shift - else - format='\1 \2' - fi - - ip addr show scope global 2>/dev/null | sed -n "s| \+inet \([0-9.]\+\).* \([^ ]\+\)|$format|p" -} - -# __docker_complete_local_interfaces applies completion of the names and addresses of all -# local network interfaces based on the current value of `$cur`. -# An additional value can be added to the possible completions with an `--add` argument. -__docker_complete_local_interfaces() { - local additional_interface - if [ "$1" = "--add" ] ; then - additional_interface="$2" - shift 2 - fi - - COMPREPLY=( $( compgen -W "$(__docker_local_interfaces "$@") $additional_interface" -- "$cur" ) ) -} - -# __docker_complete_local_ips applies completion of the addresses of all local network -# interfaces based on the current value of `$cur`. -__docker_complete_local_ips() { - __docker_complete_local_interfaces --ip-only -} - -# __docker_complete_capabilities_addable completes Linux capabilities which are -# not granted by default and may be added. -# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities -__docker_complete_capabilities_addable() { - COMPREPLY=( $( compgen -W " - ALL - AUDIT_CONTROL - BLOCK_SUSPEND - DAC_READ_SEARCH - IPC_LOCK - IPC_OWNER - LEASE - LINUX_IMMUTABLE - MAC_ADMIN - MAC_OVERRIDE - NET_ADMIN - NET_BROADCAST - SYS_ADMIN - SYS_BOOT - SYSLOG - SYS_MODULE - SYS_NICE - SYS_PACCT - SYS_PTRACE - SYS_RAWIO - SYS_RESOURCE - SYS_TIME - SYS_TTY_CONFIG - WAKE_ALARM - " -- "$cur" ) ) -} - -# __docker_complete_capabilities_droppable completes Linux capability options which are -# allowed by default and can be dropped. -# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities -__docker_complete_capabilities_droppable() { - COMPREPLY=( $( compgen -W " - ALL - AUDIT_WRITE - CHOWN - DAC_OVERRIDE - FOWNER - FSETID - KILL - MKNOD - NET_BIND_SERVICE - NET_RAW - SETFCAP - SETGID - SETPCAP - SETUID - SYS_CHROOT - " -- "$cur" ) ) -} - -__docker_complete_detach_keys() { - case "$prev" in - --detach-keys) - case "$cur" in - *,) - COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) ) - ;; - esac - - __docker_nospace - return - ;; - esac - return 1 -} - -__docker_complete_isolation() { - COMPREPLY=( $( compgen -W "default hyperv process" -- "$cur" ) ) -} - -__docker_complete_log_drivers() { - COMPREPLY=( $( compgen -W " - awslogs - etwlogs - fluentd - gcplogs - gelf - journald - json-file - local - logentries - none - splunk - syslog - " -- "$cur" ) ) -} - -__docker_complete_log_options() { - # see repository docker/docker.github.io/engine/admin/logging/ - - # really global options, defined in https://github.com/moby/moby/blob/master/daemon/logger/factory.go - local common_options1="max-buffer-size mode" - # common options defined in https://github.com/moby/moby/blob/master/daemon/logger/loginfo.go - # but not implemented in all log drivers - local common_options2="env env-regex labels" - - # awslogs does not implement the $common_options2. - local awslogs_options="$common_options1 awslogs-create-group awslogs-credentials-endpoint awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag" - - local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag" - local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project" - local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type gelf-tcp-max-reconnect gelf-tcp-reconnect-delay tag" - local journald_options="$common_options1 $common_options2 tag" - local json_file_options="$common_options1 $common_options2 compress max-file max-size" - local local_options="$common_options1 compress max-file max-size" - local logentries_options="$common_options1 $common_options2 line-only logentries-token tag" - local splunk_options="$common_options1 $common_options2 splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag" - local syslog_options="$common_options1 $common_options2 syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag" - - local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $logentries_options $json_file_options $syslog_options $splunk_options" - - case $(__docker_value_of_option --log-driver) in - '') - COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) - ;; - awslogs) - COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) ) - ;; - fluentd) - COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) ) - ;; - gcplogs) - COMPREPLY=( $( compgen -W "$gcplogs_options" -S = -- "$cur" ) ) - ;; - gelf) - COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) ) - ;; - journald) - COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) ) - ;; - json-file) - COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) ) - ;; - local) - COMPREPLY=( $( compgen -W "$local_options" -S = -- "$cur" ) ) - ;; - logentries) - COMPREPLY=( $( compgen -W "$logentries_options" -S = -- "$cur" ) ) - ;; - syslog) - COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) ) - ;; - splunk) - COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) ) - ;; - *) - return - ;; - esac - - __docker_nospace -} - -__docker_complete_log_driver_options() { - local key=$(__docker_map_key_of_current_option '--log-opt') - case "$key" in - awslogs-create-group) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - awslogs-credentials-endpoint) - COMPREPLY=( $( compgen -W "/" -- "${cur##*=}" ) ) - __docker_nospace - return - ;; - compress|fluentd-async-connect) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - fluentd-sub-second-precision) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - gelf-address) - COMPREPLY=( $( compgen -W "tcp udp" -S "://" -- "${cur##*=}" ) ) - __docker_nospace - return - ;; - gelf-compression-level) - COMPREPLY=( $( compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur##*=}" ) ) - return - ;; - gelf-compression-type) - COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) ) - return - ;; - line-only) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - mode) - COMPREPLY=( $( compgen -W "blocking non-blocking" -- "${cur##*=}" ) ) - return - ;; - syslog-address) - COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) ) - __docker_nospace - __ltrim_colon_completions "${cur}" - return - ;; - syslog-facility) - COMPREPLY=( $( compgen -W " - auth - authpriv - cron - daemon - ftp - kern - local0 - local1 - local2 - local3 - local4 - local5 - local6 - local7 - lpr - mail - news - syslog - user - uucp - " -- "${cur##*=}" ) ) - return - ;; - syslog-format) - COMPREPLY=( $( compgen -W "rfc3164 rfc5424 rfc5424micro" -- "${cur##*=}" ) ) - return - ;; - syslog-tls-ca-cert|syslog-tls-cert|syslog-tls-key) - _filedir - return - ;; - syslog-tls-skip-verify) - COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) ) - return - ;; - splunk-url) - COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) ) - __docker_nospace - __ltrim_colon_completions "${cur}" - return - ;; - splunk-gzip|splunk-insecureskipverify|splunk-verify-connection) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - splunk-format) - COMPREPLY=( $( compgen -W "inline json raw" -- "${cur##*=}" ) ) - return - ;; - esac - return 1 -} - -__docker_complete_log_levels() { - COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) -} - -__docker_complete_restart() { - case "$prev" in - --restart) - case "$cur" in - on-failure:*) - ;; - *) - COMPREPLY=( $( compgen -W "always no on-failure on-failure: unless-stopped" -- "$cur") ) - ;; - esac - return - ;; - esac - return 1 -} - -# __docker_complete_signals returns a subset of the available signals that is most likely -# relevant in the context of docker containers -__docker_complete_signals() { - local signals=( - SIGCONT - SIGHUP - SIGINT - SIGKILL - SIGQUIT - SIGSTOP - SIGTERM - SIGUSR1 - SIGUSR2 - ) - COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo "$cur" | tr '[:lower:]' '[:upper:]')" ) ) -} - -__docker_complete_stack_orchestrator_options() { - case "$prev" in - --kubeconfig) - _filedir - return 0 - ;; - --namespace) - return 0 - ;; - --orchestrator) - COMPREPLY=( $( compgen -W "all kubernetes swarm" -- "$cur") ) - return 0 - ;; - esac - return 1 -} - -__docker_complete_user_group() { - if [[ $cur == *:* ]] ; then - COMPREPLY=( $(compgen -g -- "${cur#*:}") ) - else - COMPREPLY=( $(compgen -u -S : -- "$cur") ) - __docker_nospace - fi -} - -_docker_docker() { - # global options that may appear after the docker command - local boolean_options=" - $global_boolean_options - --help - --version -v - " - - case "$prev" in - --config) - _filedir -d - return - ;; - --context|-c) - __docker_complete_contexts - return - ;; - --log-level|-l) - __docker_complete_log_levels - return - ;; - $(__docker_to_extglob "$global_options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" ) - if [ "$cword" -eq "$counter" ]; then - __docker_client_is_experimental && commands+=(${experimental_client_commands[*]}) - __docker_server_is_experimental && commands+=(${experimental_server_commands[*]}) - COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) - fi - ;; - esac -} - -_docker_attach() { - _docker_container_attach -} - -_docker_build() { - _docker_image_build -} - - -_docker_builder() { - local subcommands=" - prune - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_builder_prune() { - case "$prev" in - --filter) - COMPREPLY=( $( compgen -S = -W "description id inuse parent private shared type until unused-for" -- "$cur" ) ) - __docker_nospace - return - ;; - --keep-storage) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --filter --force -f --help --keep-storage" -- "$cur" ) ) - ;; - esac -} - -_docker_checkpoint() { - local subcommands=" - create - ls - rm - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_checkpoint_create() { - case "$prev" in - --checkpoint-dir) - _filedir -d - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--checkpoint-dir --help --leave-running" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_running - fi - ;; - esac -} - -_docker_checkpoint_ls() { - case "$prev" in - --checkpoint-dir) - _filedir -d - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_checkpoint_rm() { - case "$prev" in - --checkpoint-dir) - _filedir -d - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--checkpoint-dir --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - elif [ "$cword" -eq "$((counter + 1))" ]; then - COMPREPLY=( $( compgen -W "$(__docker_q checkpoint ls "$prev" | sed 1d)" -- "$cur" ) ) - fi - ;; - esac -} - - -_docker_config() { - local subcommands=" - create - inspect - ls - rm - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_config_create() { - case "$prev" in - --label|-l) - return - ;; - --template-driver) - COMPREPLY=( $( compgen -W "golang" -- "$cur" ) ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --label -l --template-driver" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--label|-l|--template-driver') - if [ "$cword" -eq "$((counter + 1))" ]; then - _filedir - fi - ;; - esac -} - -_docker_config_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) - ;; - *) - __docker_complete_configs - ;; - esac -} - -_docker_config_list() { - _docker_config_ls -} - -_docker_config_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - id) - __docker_complete_configs --cur "${cur##*=}" --id - return - ;; - name) - __docker_complete_configs --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_config_remove() { - _docker_config_rm -} - -_docker_config_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_configs - ;; - esac -} - - -_docker_container() { - local subcommands=" - attach - commit - cp - create - diff - exec - export - inspect - kill - logs - ls - pause - port - prune - rename - restart - rm - run - start - stats - stop - top - unpause - update - wait - " - local aliases=" - list - ps - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_container_attach() { - __docker_complete_detach_keys && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--detach-keys --help --no-stdin --sig-proxy=false" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--detach-keys') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_running - fi - ;; - esac -} - -_docker_container_commit() { - case "$prev" in - --author|-a|--change|-c|--message|-m) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--author -a --change -c --help --message -m --pause=false -p=false" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m') - - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - return - elif [ "$cword" -eq "$((counter + 1))" ]; then - __docker_complete_images --repo --tag - return - fi - ;; - esac -} - -_docker_container_cp() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--archive -a --follow-link -L --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - case "$cur" in - *:) - return - ;; - *) - # combined container and filename completion - _filedir - local files=( ${COMPREPLY[@]} ) - - __docker_complete_containers_all - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - local containers=( ${COMPREPLY[@]} ) - - COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) ) - if [[ "${COMPREPLY[*]}" = *: ]]; then - __docker_nospace - fi - return - ;; - esac - fi - (( counter++ )) - - if [ "$cword" -eq "$counter" ]; then - if [ -e "$prev" ]; then - __docker_complete_containers_all - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - __docker_nospace - else - _filedir - fi - return - fi - ;; - esac -} - -_docker_container_create() { - _docker_container_run_and_create -} - -_docker_container_diff() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_container_exec() { - __docker_complete_detach_keys && return - - case "$prev" in - --env|-e) - # we do not append a "=" here because "-e VARNAME" is legal syntax, too - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_nospace - return - ;; - --user|-u) - __docker_complete_user_group - return - ;; - --workdir|-w) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --help --interactive -i --privileged -t --tty -u --user --workdir -w" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -_docker_container_export() { - case "$prev" in - --output|-o) - _filedir - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_container_inspect() { - _docker_inspect --type container -} - -_docker_container_kill() { - case "$prev" in - --signal|-s) - __docker_complete_signals - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --signal -s" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -_docker_container_logs() { - case "$prev" in - --since|--tail|--until) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t --until" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--since|--tail|--until') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_container_list() { - _docker_container_ls -} - -_docker_container_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - ancestor) - __docker_complete_images --cur "${cur##*=}" --repo --tag --id - return - ;; - before) - __docker_complete_containers_all --cur "${cur##*=}" - return - ;; - expose|publish) - return - ;; - id) - __docker_complete_containers_all --cur "${cur##*=}" --id - return - ;; - health) - COMPREPLY=( $( compgen -W "healthy starting none unhealthy" -- "${cur##*=}" ) ) - return - ;; - is-task) - COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) - return - ;; - name) - __docker_complete_containers_all --cur "${cur##*=}" --name - return - ;; - network) - __docker_complete_networks --cur "${cur##*=}" - return - ;; - since) - __docker_complete_containers_all --cur "${cur##*=}" - return - ;; - status) - COMPREPLY=( $( compgen -W "created dead exited paused restarting running removing" -- "${cur##*=}" ) ) - return - ;; - volume) - __docker_complete_volumes --cur "${cur##*=}" - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "ancestor before exited expose health id is-task label name network publish since status volume" -- "$cur" ) ) - __docker_nospace - return - ;; - --format|--last|-n) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --filter -f --format --help --last -n --latest -l --no-trunc --quiet -q --size -s" -- "$cur" ) ) - ;; - esac -} - -_docker_container_pause() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -_docker_container_port() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_container_prune() { - case "$prev" in - --filter) - COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) ) - ;; - esac -} - -_docker_container_ps() { - _docker_container_ls -} - -_docker_container_rename() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_container_restart() { - case "$prev" in - --time|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_all - ;; - esac -} - -_docker_container_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help --link -l --volumes -v" -- "$cur" ) ) - ;; - *) - for arg in "${COMP_WORDS[@]}"; do - case "$arg" in - --force|-f) - __docker_complete_containers_all - return - ;; - esac - done - __docker_complete_containers_removable - ;; - esac -} - -_docker_container_run() { - _docker_container_run_and_create -} - -# _docker_container_run_and_create is the combined completion for `_docker_container_run` -# and `_docker_container_create` -_docker_container_run_and_create() { - local options_with_args=" - --add-host - --attach -a - --blkio-weight - --blkio-weight-device - --cap-add - --cap-drop - --cgroup-parent - --cidfile - --cpu-period - --cpu-quota - --cpu-rt-period - --cpu-rt-runtime - --cpuset-cpus - --cpus - --cpuset-mems - --cpu-shares -c - --device - --device-cgroup-rule - --device-read-bps - --device-read-iops - --device-write-bps - --device-write-iops - --dns - --dns-option - --dns-search - --domainname - --entrypoint - --env -e - --env-file - --expose - --group-add - --health-cmd - --health-interval - --health-retries - --health-start-period - --health-timeout - --hostname -h - --ip - --ip6 - --ipc - --kernel-memory - --label-file - --label -l - --link - --link-local-ip - --log-driver - --log-opt - --mac-address - --memory -m - --memory-swap - --memory-swappiness - --memory-reservation - --mount - --name - --network - --network-alias - --oom-score-adj - --pid - --pids-limit - --publish -p - --restart - --runtime - --security-opt - --shm-size - --stop-signal - --stop-timeout - --storage-opt - --tmpfs - --sysctl - --ulimit - --user -u - --userns - --uts - --volume-driver - --volumes-from - --volume -v - --workdir -w - " - __docker_server_os_is windows && options_with_args+=" - --cpu-count - --cpu-percent - --io-maxbandwidth - --io-maxiops - --isolation - " - __docker_server_is_experimental && options_with_args+=" - --platform - " - - local boolean_options=" - --disable-content-trust=false - --help - --init - --interactive -i - --no-healthcheck - --oom-kill-disable - --privileged - --publish-all -P - --read-only - --tty -t - " - - if [ "$command" = "run" ] || [ "$subcommand" = "run" ] ; then - options_with_args="$options_with_args - --detach-keys - " - boolean_options="$boolean_options - --detach -d - --rm - --sig-proxy=false - " - __docker_complete_detach_keys && return - fi - - local all_options="$options_with_args $boolean_options" - - - __docker_complete_log_driver_options && return - __docker_complete_restart && return - - local key=$(__docker_map_key_of_current_option '--security-opt') - case "$key" in - label) - [[ $cur == *: ]] && return - COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "${cur##*=}") ) - if [ "${COMPREPLY[*]}" != "disable" ] ; then - __docker_nospace - fi - return - ;; - seccomp) - local cur=${cur##*=} - _filedir - COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) ) - return - ;; - esac - - case "$prev" in - --add-host) - case "$cur" in - *:) - __docker_complete_resolved_hostname - return - ;; - esac - ;; - --attach|-a) - COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) - return - ;; - --cap-add) - __docker_complete_capabilities_addable - return - ;; - --cap-drop) - __docker_complete_capabilities_droppable - return - ;; - --cidfile|--env-file|--label-file) - _filedir - return - ;; - --device|--tmpfs|--volume|-v) - case "$cur" in - *:*) - # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine) - ;; - '') - COMPREPLY=( $( compgen -W '/' -- "$cur" ) ) - __docker_nospace - ;; - /*) - _filedir - __docker_nospace - ;; - esac - return - ;; - --env|-e) - # we do not append a "=" here because "-e VARNAME" is legal syntax, too - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_nospace - return - ;; - --ipc) - case "$cur" in - *:*) - cur="${cur#*:}" - __docker_complete_containers_running - ;; - *) - COMPREPLY=( $( compgen -W 'none host private shareable container:' -- "$cur" ) ) - if [ "${COMPREPLY[*]}" = "container:" ]; then - __docker_nospace - fi - ;; - esac - return - ;; - --isolation) - if __docker_server_os_is windows ; then - __docker_complete_isolation - return - fi - ;; - --link) - case "$cur" in - *:*) - ;; - *) - __docker_complete_containers_running - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - __docker_nospace - ;; - esac - return - ;; - --log-driver) - __docker_complete_log_drivers - return - ;; - --log-opt) - __docker_complete_log_options - return - ;; - --network) - case "$cur" in - container:*) - __docker_complete_containers_all --cur "${cur#*:}" - ;; - *) - COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") ) - if [ "${COMPREPLY[*]}" = "container:" ] ; then - __docker_nospace - fi - ;; - esac - return - ;; - --pid) - case "$cur" in - *:*) - __docker_complete_containers_running --cur "${cur#*:}" - ;; - *) - COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) - if [ "${COMPREPLY[*]}" = "container:" ]; then - __docker_nospace - fi - ;; - esac - return - ;; - --runtime) - __docker_complete_runtimes - return - ;; - --security-opt) - COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") ) - if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then - __docker_nospace - fi - return - ;; - --stop-signal) - __docker_complete_signals - return - ;; - --storage-opt) - COMPREPLY=( $( compgen -W "size" -S = -- "$cur") ) - __docker_nospace - return - ;; - --user|-u) - __docker_complete_user_group - return - ;; - --userns) - COMPREPLY=( $( compgen -W "host" -- "$cur" ) ) - return - ;; - --volume-driver) - __docker_complete_plugins_bundled --type Volume - return - ;; - --volumes-from) - __docker_complete_containers_all - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --repo --tag --id - fi - ;; - esac -} - -_docker_container_start() { - __docker_complete_detach_keys && return - case "$prev" in - --checkpoint) - if __docker_server_is_experimental ; then - return - fi - ;; - --checkpoint-dir) - if __docker_server_is_experimental ; then - _filedir -d - return - fi - ;; - esac - - case "$cur" in - -*) - local options="--attach -a --detach-keys --help --interactive -i" - __docker_server_is_experimental && options+=" --checkpoint --checkpoint-dir" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_stopped - ;; - esac -} - -_docker_container_stats() { - case "$prev" in - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --format --help --no-stream --no-trunc" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_running - ;; - esac -} - -_docker_container_stop() { - case "$prev" in - --time|-t) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --time -t" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_stoppable - ;; - esac -} - -_docker_container_top() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_running - fi - ;; - esac -} - -_docker_container_unpause() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_containers_unpauseable - fi - ;; - esac -} - -_docker_container_update() { - local options_with_args=" - --blkio-weight - --cpu-period - --cpu-quota - --cpu-rt-period - --cpu-rt-runtime - --cpus - --cpuset-cpus - --cpuset-mems - --cpu-shares -c - --kernel-memory - --memory -m - --memory-reservation - --memory-swap - --pids-limit - --restart - " - - local boolean_options=" - --help - " - - local all_options="$options_with_args $boolean_options" - - __docker_complete_restart && return - - case "$prev" in - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_all - ;; - esac -} - -_docker_container_wait() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_containers_all - ;; - esac -} - - -_docker_context() { - local subcommands=" - create - export - import - inspect - ls - rm - update - use - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_context_create() { - case "$prev" in - --default-stack-orchestrator) - COMPREPLY=( $( compgen -W "all kubernetes swarm" -- "$cur" ) ) - return - ;; - --description|--docker|--kubernetes) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--default-stack-orchestrator --description --docker --help --kubernetes" -- "$cur" ) ) - ;; - esac -} - -_docker_context_export() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --kubeconfig" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_contexts - elif [ "$cword" -eq "$((counter + 1))" ]; then - _filedir - fi - ;; - esac -} - -_docker_context_import() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - : - elif [ "$cword" -eq "$((counter + 1))" ]; then - _filedir - fi - ;; - esac -} - -_docker_context_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_contexts - ;; - esac -} - -_docker_context_list() { - _docker_context_ls -} - -_docker_context_ls() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_context_remove() { - _docker_context_rm -} - -_docker_context_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_contexts - ;; - esac -} - -_docker_context_update() { - case "$prev" in - --default-stack-orchestrator) - COMPREPLY=( $( compgen -W "all kubernetes swarm" -- "$cur" ) ) - return - ;; - --description|--docker|--kubernetes) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--default-stack-orchestrator --description --docker --help --kubernetes" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_contexts - fi - ;; - esac -} - -_docker_context_use() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_contexts --add default - fi - ;; - esac -} - - -_docker_commit() { - _docker_container_commit -} - -_docker_cp() { - _docker_container_cp -} - -_docker_create() { - _docker_container_create -} - -_docker_daemon() { - local boolean_options=" - $global_boolean_options - --experimental - --help - --icc=false - --init - --ip-forward=false - --ip-masq=false - --iptables=false - --ipv6 - --live-restore - --no-new-privileges - --raw-logs - --selinux-enabled - --userland-proxy=false - --version -v - " - local options_with_args=" - $global_options_with_args - --add-runtime - --allow-nondistributable-artifacts - --api-cors-header - --authorization-plugin - --bip - --bridge -b - --cgroup-parent - --cluster-advertise - --cluster-store - --cluster-store-opt - --config-file - --containerd - --cpu-rt-period - --cpu-rt-runtime - --data-root - --default-address-pool - --default-gateway - --default-gateway-v6 - --default-runtime - --default-shm-size - --default-ulimit - --dns - --dns-search - --dns-opt - --exec-opt - --exec-root - --fixed-cidr - --fixed-cidr-v6 - --group -G - --init-path - --insecure-registry - --ip - --label - --log-driver - --log-opt - --max-concurrent-downloads - --max-concurrent-uploads - --metrics-addr - --mtu - --network-control-plane-mtu - --node-generic-resource - --oom-score-adjust - --pidfile -p - --registry-mirror - --seccomp-profile - --shutdown-timeout - --storage-driver -s - --storage-opt - --swarm-default-advertise-addr - --userland-proxy-path - --userns-remap - " - - __docker_complete_log_driver_options && return - - key=$(__docker_map_key_of_current_option '--cluster-store-opt') - case "$key" in - kv.*file) - cur=${cur##*=} - _filedir - return - ;; - esac - - local key=$(__docker_map_key_of_current_option '--storage-opt') - case "$key" in - dm.blkdiscard|dm.override_udev_sync_check|dm.use_deferred_removal|dm.use_deferred_deletion) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - dm.directlvm_device|dm.thinpooldev) - cur=${cur##*=} - _filedir - return - ;; - dm.fs) - COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) ) - return - ;; - dm.libdm_log_level) - COMPREPLY=( $( compgen -W "2 3 4 5 6 7" -- "${cur##*=}" ) ) - return - ;; - esac - - case "$prev" in - --authorization-plugin) - __docker_complete_plugins_bundled --type Authorization - return - ;; - --cluster-store) - COMPREPLY=( $( compgen -W "consul etcd zk" -S "://" -- "$cur" ) ) - __docker_nospace - return - ;; - --cluster-store-opt) - COMPREPLY=( $( compgen -W "discovery.heartbeat discovery.ttl kv.cacertfile kv.certfile kv.keyfile kv.path" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --config-file|--containerd|--init-path|--pidfile|-p|--tlscacert|--tlscert|--tlskey|--userland-proxy-path) - _filedir - return - ;; - --exec-root|--data-root) - _filedir -d - return - ;; - --log-driver) - __docker_complete_log_drivers - return - ;; - --storage-driver|-s) - COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay overlay2 vfs zfs" -- "$(echo "$cur" | tr '[:upper:]' '[:lower:]')" ) ) - return - ;; - --storage-opt) - local btrfs_options="btrfs.min_space" - local devicemapper_options=" - dm.basesize - dm.blkdiscard - dm.blocksize - dm.directlvm_device - dm.fs - dm.libdm_log_level - dm.loopdatasize - dm.loopmetadatasize - dm.min_free_space - dm.mkfsarg - dm.mountopt - dm.override_udev_sync_check - dm.thinpooldev - dm.thinp_autoextend_percent - dm.thinp_autoextend_threshold - dm.thinp_metapercent - dm.thinp_percent - dm.use_deferred_deletion - dm.use_deferred_removal - " - local overlay2_options="overlay2.size" - local zfs_options="zfs.fsname" - - local all_options="$btrfs_options $devicemapper_options $overlay2_options $zfs_options" - - case $(__docker_value_of_option '--storage-driver|-s') in - '') - COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) - ;; - btrfs) - COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) ) - ;; - devicemapper) - COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) ) - ;; - overlay2) - COMPREPLY=( $( compgen -W "$overlay2_options" -S = -- "$cur" ) ) - ;; - zfs) - COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) ) - ;; - *) - return - ;; - esac - __docker_nospace - return - ;; - --log-level|-l) - __docker_complete_log_levels - return - ;; - --log-opt) - __docker_complete_log_options - return - ;; - --metrics-addr) - __docker_complete_local_ips - __docker_append_to_completions ":" - __docker_nospace - return - ;; - --seccomp-profile) - _filedir json - return - ;; - --swarm-default-advertise-addr) - __docker_complete_local_interfaces - return - ;; - --userns-remap) - __docker_complete_user_group - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - esac -} - -_docker_deploy() { - __docker_server_is_experimental && _docker_stack_deploy -} - -_docker_diff() { - _docker_container_diff -} - - -_docker_engine() { - local subcommands=" - activate - check - update - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_engine_activate() { - case "$prev" in - --containerd|--engine-image|--format|--license|--registry-prefix|--version) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--containerd --display-only --engine-image --format --help --license --quiet --registry-prefix --version" -- "$cur" ) ) - ;; - esac -} - -_docker_engine_check() { - case "$prev" in - --containerd|--engine-image|--format|--registry-prefix) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--containerd --downgrades --engine-image --format --help --pre-releases --quiet -q --registry-prefix --upgrades" -- "$cur" ) ) - ;; - esac -} - -_docker_engine_update() { - case "$prev" in - --containerd|--engine-image|--registry-prefix|--version) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--containerd --engine-image --help --registry-prefix --version" -- "$cur" ) ) - ;; - esac -} - - -_docker_events() { - _docker_system_events -} - -_docker_exec() { - _docker_container_exec -} - -_docker_export() { - _docker_container_export -} - -_docker_help() { - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) - fi -} - -_docker_history() { - _docker_image_history -} - - -_docker_image() { - local subcommands=" - build - history - import - inspect - load - ls - prune - pull - push - rm - save - tag - " - local aliases=" - images - list - remove - rmi - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_image_build() { - local options_with_args=" - --add-host - --build-arg - --cache-from - --cgroup-parent - --cpuset-cpus - --cpuset-mems - --cpu-shares -c - --cpu-period - --cpu-quota - --file -f - --iidfile - --label - --memory -m - --memory-swap - --network - --shm-size - --tag -t - --target - --ulimit - " - __docker_server_os_is windows && options_with_args+=" - --isolation - " - - local boolean_options=" - --compress - --disable-content-trust=false - --force-rm - --help - --no-cache - --pull - --quiet -q - --rm - " - if __docker_server_is_experimental ; then - options_with_args+=" - --platform - " - boolean_options+=" - --squash - --stream - " - fi - - local all_options="$options_with_args $boolean_options" - - case "$prev" in - --add-host) - case "$cur" in - *:) - __docker_complete_resolved_hostname - return - ;; - esac - ;; - --build-arg) - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_nospace - return - ;; - --cache-from) - __docker_complete_images --repo --tag --id - return - ;; - --file|-f|--iidfile) - _filedir - return - ;; - --isolation) - if __docker_server_os_is windows ; then - __docker_complete_isolation - return - fi - ;; - --network) - case "$cur" in - container:*) - __docker_complete_containers_all --cur "${cur#*:}" - ;; - *) - COMPREPLY=( $( compgen -W "$(__docker_plugins_bundled --type Network) $(__docker_networks) container:" -- "$cur") ) - if [ "${COMPREPLY[*]}" = "container:" ] ; then - __docker_nospace - fi - ;; - esac - return - ;; - --tag|-t) - __docker_complete_images --repo --tag - return - ;; - --target) - local context_pos=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) - local context="${words[$context_pos]}" - context="${context:-.}" - - local file="$( __docker_value_of_option '--file|f' )" - local default_file="${context%/}/Dockerfile" - local dockerfile="${file:-$default_file}" - - local targets="$( sed -n 's/^FROM .\+ AS \(.\+\)/\1/p' "$dockerfile" 2>/dev/null )" - COMPREPLY=( $( compgen -W "$targets" -- "$cur" ) ) - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) - if [ "$cword" -eq "$counter" ]; then - _filedir -d - fi - ;; - esac -} - -_docker_image_history() { - case "$prev" in - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format --help --human=false -H=false --no-trunc --quiet -q" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--format') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --force-tag --id - fi - ;; - esac -} - -_docker_image_images() { - _docker_image_ls -} - -_docker_image_import() { - case "$prev" in - --change|-c|--message|-m|--platform) - return - ;; - esac - - case "$cur" in - -*) - local options="--change -c --help --message -m" - __docker_server_is_experimental && options+=" --platform" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m') - if [ "$cword" -eq "$counter" ]; then - _filedir - return - elif [ "$cword" -eq "$((counter + 1))" ]; then - __docker_complete_images --repo --tag - return - fi - ;; - esac -} - -_docker_image_inspect() { - _docker_inspect --type image -} - -_docker_image_load() { - case "$prev" in - --input|-i|"<") - _filedir - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --input -i --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_image_list() { - _docker_image_ls -} - -_docker_image_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - before|since) - __docker_complete_images --cur "${cur##*=}" --force-tag --id - return - ;; - dangling) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - label) - return - ;; - reference) - __docker_complete_images --cur "${cur##*=}" --repo --tag - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "before dangling label reference since" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --digests --filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) - ;; - =) - return - ;; - *) - __docker_complete_images --repo --tag - ;; - esac -} - -_docker_image_prune() { - case "$prev" in - --filter) - COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help" -- "$cur" ) ) - ;; - esac -} - -_docker_image_pull() { - case "$prev" in - --platform) - return - ;; - esac - - case "$cur" in - -*) - local options="--all-tags -a --disable-content-trust=false --help --quiet -q" - __docker_server_is_experimental && options+=" --platform" - - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag --platform) - if [ "$cword" -eq "$counter" ]; then - for arg in "${COMP_WORDS[@]}"; do - case "$arg" in - --all-tags|-a) - __docker_complete_images --repo - return - ;; - esac - done - __docker_complete_images --repo --tag - fi - ;; - esac -} - -_docker_image_push() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--disable-content-trust=false --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --repo --tag - fi - ;; - esac -} - -_docker_image_remove() { - _docker_image_rm -} - -_docker_image_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help --no-prune" -- "$cur" ) ) - ;; - *) - __docker_complete_images --force-tag --id - ;; - esac -} - -_docker_image_rmi() { - _docker_image_rm -} - -_docker_image_save() { - case "$prev" in - --output|-o|">") - _filedir - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --output -o" -- "$cur" ) ) - ;; - *) - __docker_complete_images --repo --tag --id - ;; - esac -} - -_docker_image_tag() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --force-tag --id - return - elif [ "$cword" -eq "$((counter + 1))" ]; then - __docker_complete_images --repo --tag - return - fi - ;; - esac -} - - -_docker_images() { - _docker_image_ls -} - -_docker_import() { - _docker_image_import -} - -_docker_info() { - _docker_system_info -} - -_docker_inspect() { - local preselected_type - local type - - if [ "$1" = "--type" ] ; then - preselected_type=yes - type="$2" - else - type=$(__docker_value_of_option --type) - fi - - case "$prev" in - --format|-f) - return - ;; - --type) - if [ -z "$preselected_type" ] ; then - COMPREPLY=( $( compgen -W "container image network node plugin secret service volume" -- "$cur" ) ) - return - fi - ;; - esac - - case "$cur" in - -*) - local options="--format -f --help --size -s" - if [ -z "$preselected_type" ] ; then - options+=" --type" - fi - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - case "$type" in - '') - COMPREPLY=( $( compgen -W " - $(__docker_containers --all) - $(__docker_images --force-tag --id) - $(__docker_networks) - $(__docker_nodes) - $(__docker_plugins_installed) - $(__docker_secrets) - $(__docker_services) - $(__docker_volumes) - " -- "$cur" ) ) - __ltrim_colon_completions "$cur" - ;; - container) - __docker_complete_containers_all - ;; - image) - __docker_complete_images --force-tag --id - ;; - network) - __docker_complete_networks - ;; - node) - __docker_complete_nodes - ;; - plugin) - __docker_complete_plugins_installed - ;; - secret) - __docker_complete_secrets - ;; - service) - __docker_complete_services - ;; - volume) - __docker_complete_volumes - ;; - esac - esac -} - -_docker_kill() { - _docker_container_kill -} - -_docker_load() { - _docker_image_load -} - -_docker_login() { - case "$prev" in - --password|-p|--username|-u) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --password -p --password-stdin --username -u" -- "$cur" ) ) - ;; - esac -} - -_docker_logout() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - esac -} - -_docker_logs() { - _docker_container_logs -} - -_docker_network_connect() { - local options_with_args=" - --alias - --ip - --ip6 - --link - --link-local-ip - " - - local boolean_options=" - --help - " - - case "$prev" in - --link) - case "$cur" in - *:*) - ;; - *) - __docker_complete_containers_running - COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) - __docker_nospace - ;; - esac - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_networks - elif [ "$cword" -eq "$((counter + 1))" ]; then - __docker_complete_containers_all - fi - ;; - esac -} - -_docker_network_create() { - case "$prev" in - --aux-address|--gateway|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) - return - ;; - --config-from) - __docker_complete_networks - return - ;; - --driver|-d) - # remove drivers that allow one instance only, add drivers missing in `docker info` - __docker_complete_plugins_bundled --type Network --remove host --remove null --add macvlan - return - ;; - --ipam-driver) - COMPREPLY=( $( compgen -W "default" -- "$cur" ) ) - return - ;; - --label) - return - ;; - --scope) - COMPREPLY=( $( compgen -W "local swarm" -- "$cur" ) ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--attachable --aux-address --config-from --config-only --driver -d --gateway --help --ingress --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --scope --subnet" -- "$cur" ) ) - ;; - esac -} - -_docker_network_disconnect() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_networks - elif [ "$cword" -eq "$((counter + 1))" ]; then - __docker_complete_containers_in_network "$prev" - fi - ;; - esac -} - -_docker_network_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --verbose" -- "$cur" ) ) - ;; - *) - __docker_complete_networks - esac -} - -_docker_network_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - dangling) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - driver) - __docker_complete_plugins_bundled --cur "${cur##*=}" --type Network --add macvlan - return - ;; - id) - __docker_complete_networks --cur "${cur##*=}" --id - return - ;; - name) - __docker_complete_networks --cur "${cur##*=}" --name - return - ;; - scope) - COMPREPLY=( $( compgen -W "global local swarm" -- "${cur##*=}" ) ) - return - ;; - type) - COMPREPLY=( $( compgen -W "builtin custom" -- "${cur##*=}" ) ) - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "dangling driver id label name scope type" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_network_prune() { - case "$prev" in - --filter) - COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --filter --help" -- "$cur" ) ) - ;; - esac -} - -_docker_network_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_networks --filter type=custom - esac -} - -_docker_network() { - local subcommands=" - connect - create - disconnect - inspect - ls - prune - rm - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_service() { - local subcommands=" - create - inspect - logs - ls - rm - rollback - scale - ps - update - " - - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_service_create() { - _docker_service_update_and_create -} - -_docker_service_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) - ;; - *) - __docker_complete_services - esac -} - -_docker_service_logs() { - case "$prev" in - --since|--tail) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--details --follow -f --help --no-resolve --no-task-ids --no-trunc --raw --since --tail --timestamps -t" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--since|--tail') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_services_and_tasks - fi - ;; - esac -} - -_docker_service_list() { - _docker_service_ls -} - -_docker_service_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - id) - __docker_complete_services --cur "${cur##*=}" --id - return - ;; - mode) - COMPREPLY=( $( compgen -W "global replicated" -- "${cur##*=}" ) ) - return - ;; - name) - __docker_complete_services --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "id label mode name" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_service_remove() { - _docker_service_rm -} - -_docker_service_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_services - esac -} - -_docker_service_rollback() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--detach -d --help --quit -q" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag ) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_services - fi - ;; - esac -} - -_docker_service_scale() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--detach -d --help" -- "$cur" ) ) - ;; - *) - __docker_complete_services - __docker_append_to_completions "=" - __docker_nospace - ;; - esac -} - -_docker_service_ps() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - desired-state) - COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) - return - ;; - name) - __docker_complete_services --cur "${cur##*=}" --name - return - ;; - node) - __docker_complete_nodes --cur "${cur##*=}" --add self - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "desired-state id name node" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) - ;; - *) - __docker_complete_services - ;; - esac -} - -_docker_service_update() { - _docker_service_update_and_create -} - -# _docker_service_update_and_create is the combined completion for `docker service create` -# and `docker service update` -_docker_service_update_and_create() { - local options_with_args=" - --endpoint-mode - --entrypoint - --health-cmd - --health-interval - --health-retries - --health-start-period - --health-timeout - --hostname - --isolation - --limit-cpu - --limit-memory - --log-driver - --log-opt - --replicas - --replicas-max-per-node - --reserve-cpu - --reserve-memory - --restart-condition - --restart-delay - --restart-max-attempts - --restart-window - --rollback-delay - --rollback-failure-action - --rollback-max-failure-ratio - --rollback-monitor - --rollback-order - --rollback-parallelism - --stop-grace-period - --stop-signal - --update-delay - --update-failure-action - --update-max-failure-ratio - --update-monitor - --update-order - --update-parallelism - --user -u - --workdir -w - " - __docker_server_os_is windows && options_with_args+=" - --credential-spec - " - - local boolean_options=" - --detach -d - --help - --init - --no-healthcheck - --no-resolve-image - --read-only - --tty -t - --with-registry-auth - " - - __docker_complete_log_driver_options && return - - if [ "$subcommand" = "create" ] ; then - options_with_args="$options_with_args - --config - --constraint - --container-label - --dns - --dns-option - --dns-search - --env -e - --env-file - --generic-resource - --group - --host - --label -l - --mode - --mount - --name - --network - --placement-pref - --publish -p - --secret - --sysctl - " - - case "$prev" in - --env-file) - _filedir - return - ;; - --mode) - COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) ) - return - ;; - esac - fi - if [ "$subcommand" = "update" ] ; then - options_with_args="$options_with_args - --args - --config-add - --config-rm - --constraint-add - --constraint-rm - --container-label-add - --container-label-rm - --dns-add - --dns-option-add - --dns-option-rm - --dns-rm - --dns-search-add - --dns-search-rm - --env-add - --env-rm - --generic-resource-add - --generic-resource-rm - --group-add - --group-rm - --host-add - --host-rm - --image - --label-add - --label-rm - --mount-add - --mount-rm - --network-add - --network-rm - --placement-pref-add - --placement-pref-rm - --publish-add - --publish-rm - --rollback - --secret-add - --secret-rm - --sysctl-add - --sysctl-rm - " - - boolean_options="$boolean_options - --force - " - - case "$prev" in - --env-rm) - COMPREPLY=( $( compgen -e -- "$cur" ) ) - return - ;; - --image) - __docker_complete_images --repo --tag --id - return - ;; - esac - fi - - local strategy=$(__docker_map_key_of_current_option '--placement-pref|--placement-pref-add|--placement-pref-rm') - case "$strategy" in - spread) - COMPREPLY=( $( compgen -W "engine.labels node.labels" -S . -- "${cur##*=}" ) ) - __docker_nospace - return - ;; - esac - - case "$prev" in - --config|--config-add|--config-rm) - __docker_complete_configs - return - ;; - --endpoint-mode) - COMPREPLY=( $( compgen -W "dnsrr vip" -- "$cur" ) ) - return - ;; - --env|-e|--env-add) - # we do not append a "=" here because "-e VARNAME" is legal systax, too - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __docker_nospace - return - ;; - --group|--group-add|--group-rm) - COMPREPLY=( $(compgen -g -- "$cur") ) - return - ;; - --host|--host-add|--host-rm) - case "$cur" in - *:) - __docker_complete_resolved_hostname - return - ;; - esac - ;; - --isolation) - __docker_complete_isolation - return - ;; - --log-driver) - __docker_complete_log_drivers - return - ;; - --log-opt) - __docker_complete_log_options - return - ;; - --network|--network-add|--network-rm) - __docker_complete_networks - return - ;; - --placement-pref|--placement-pref-add|--placement-pref-rm) - COMPREPLY=( $( compgen -W "spread" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --restart-condition) - COMPREPLY=( $( compgen -W "any none on-failure" -- "$cur" ) ) - return - ;; - --rollback-failure-action) - COMPREPLY=( $( compgen -W "continue pause" -- "$cur" ) ) - return - ;; - --secret|--secret-add|--secret-rm) - __docker_complete_secrets - return - ;; - --stop-signal) - __docker_complete_signals - return - ;; - --update-failure-action) - COMPREPLY=( $( compgen -W "continue pause rollback" -- "$cur" ) ) - return - ;; - --update-order|--rollback-order) - COMPREPLY=( $( compgen -W "start-first stop-first" -- "$cur" ) ) - return - ;; - --user|-u) - __docker_complete_user_group - return - ;; - $(__docker_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) - if [ "$subcommand" = "update" ] ; then - if [ "$cword" -eq "$counter" ]; then - __docker_complete_services - fi - else - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --repo --tag --id - fi - fi - ;; - esac -} - -_docker_swarm() { - local subcommands=" - ca - init - join - join-token - leave - unlock - unlock-key - update - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_swarm_ca() { - case "$prev" in - --ca-cert|--ca-key) - _filedir - return - ;; - --cert-expiry|--external-ca) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--ca-cert --ca-key --cert-expiry --detach -d --external-ca --help --quiet -q --rotate" -- "$cur" ) ) - ;; - esac -} - -_docker_swarm_init() { - case "$prev" in - --advertise-addr) - if [[ $cur == *: ]] ; then - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - else - __docker_complete_local_interfaces - __docker_nospace - fi - return - ;; - --availability) - COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) - return - ;; - --cert-expiry|--data-path-port|--default-addr-pool|--default-addr-pool-mask-length|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit ) - return - ;; - --data-path-addr) - __docker_complete_local_interfaces - return - ;; - --listen-addr) - if [[ $cur == *: ]] ; then - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - else - __docker_complete_local_interfaces --add 0.0.0.0 - __docker_nospace - fi - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--advertise-addr --autolock --availability --cert-expiry --data-path-addr --data-path-port --default-addr-pool --default-addr-pool-mask-length --dispatcher-heartbeat --external-ca --force-new-cluster --help --listen-addr --max-snapshots --snapshot-interval --task-history-limit " -- "$cur" ) ) - ;; - esac -} - -_docker_swarm_join() { - case "$prev" in - --advertise-addr) - if [[ $cur == *: ]] ; then - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - else - __docker_complete_local_interfaces - __docker_nospace - fi - return - ;; - --availability) - COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) - return - ;; - --data-path-addr) - __docker_complete_local_interfaces - return - ;; - --listen-addr) - if [[ $cur == *: ]] ; then - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - else - __docker_complete_local_interfaces --add 0.0.0.0 - __docker_nospace - fi - return - ;; - --token) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--advertise-addr --availability --data-path-addr --help --listen-addr --token" -- "$cur" ) ) - ;; - *:) - COMPREPLY=( $( compgen -W "2377" -- "${cur##*:}" ) ) - ;; - esac -} - -_docker_swarm_join_token() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag ) - if [ "$cword" -eq "$counter" ]; then - COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) - fi - ;; - esac -} - -_docker_swarm_leave() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) - ;; - esac -} - -_docker_swarm_unlock() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - esac -} - -_docker_swarm_unlock_key() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --quiet -q --rotate" -- "$cur" ) ) - ;; - esac -} - -_docker_swarm_update() { - case "$prev" in - --cert-expiry|--dispatcher-heartbeat|--external-ca|--max-snapshots|--snapshot-interval|--task-history-limit) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--autolock --cert-expiry --dispatcher-heartbeat --external-ca --help --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) ) - ;; - esac -} - -_docker_manifest() { - local subcommands=" - annotate - create - inspect - push - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_manifest_annotate() { - case "$prev" in - --arch) - COMPREPLY=( $( compgen -W " - 386 - amd64 - arm - arm64 - mips64 - mips64le - ppc64le - s390x" -- "$cur" ) ) - return - ;; - --os) - COMPREPLY=( $( compgen -W " - darwin - dragonfly - freebsd - linux - netbsd - openbsd - plan9 - solaris - windows" -- "$cur" ) ) - return - ;; - --os-features|--variant) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--arch --help --os --os-features --variant" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag "--arch|--os|--os-features|--variant" ) - if [ "$cword" -eq "$counter" ] || [ "$cword" -eq "$((counter + 1))" ]; then - __docker_complete_images --force-tag --id - fi - ;; - esac -} - -_docker_manifest_create() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--amend -a --help --insecure" -- "$cur" ) ) - ;; - *) - __docker_complete_images --force-tag --id - ;; - esac -} - -_docker_manifest_inspect() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --insecure --verbose -v" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag ) - if [ "$cword" -eq "$counter" ] || [ "$cword" -eq "$((counter + 1))" ]; then - __docker_complete_images --force-tag --id - fi - ;; - esac -} - -_docker_manifest_push() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --insecure --purge -p" -- "$cur" ) ) - ;; - *) - local counter=$( __docker_pos_first_nonflag ) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --force-tag --id - fi - ;; - esac -} - -_docker_node() { - local subcommands=" - demote - inspect - ls - promote - rm - ps - update - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_node_demote() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes --filter role=manager - esac -} - -_docker_node_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes --add self - esac -} - -_docker_node_list() { - _docker_node_ls -} - -_docker_node_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - id) - __docker_complete_nodes --cur "${cur##*=}" --id - return - ;; - membership) - COMPREPLY=( $( compgen -W "accepted pending" -- "${cur##*=}" ) ) - return - ;; - name) - __docker_complete_nodes --cur "${cur##*=}" --name - return - ;; - role) - COMPREPLY=( $( compgen -W "manager worker" -- "${cur##*=}" ) ) - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "id label membership name role" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_node_promote() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes --filter role=worker - esac -} - -_docker_node_remove() { - _docker_node_rm -} - -_docker_node_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes - esac -} - -_docker_node_ps() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - desired-state) - COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) - return - ;; - name) - __docker_complete_services --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -W "desired-state id label name" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) - ;; - *) - __docker_complete_nodes --add self - ;; - esac -} - -_docker_node_update() { - case "$prev" in - --availability) - COMPREPLY=( $( compgen -W "active drain pause" -- "$cur" ) ) - return - ;; - --role) - COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) - return - ;; - --label-add|--label-rm) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--availability --help --label-add --label-rm --role" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--availability|--label-add|--label-rm|--role') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_nodes - fi - ;; - esac -} - -_docker_pause() { - _docker_container_pause -} - -_docker_plugin() { - local subcommands=" - create - disable - enable - inspect - install - ls - push - rm - set - upgrade - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_plugin_create() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--compress --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - # reponame - return - elif [ "$cword" -eq "$((counter + 1))" ]; then - _filedir -d - fi - ;; - esac -} - -_docker_plugin_disable() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_plugins_installed --filter enabled=true - fi - ;; - esac -} - -_docker_plugin_enable() { - case "$prev" in - --timeout) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --timeout" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--timeout') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_plugins_installed --filter enabled=false - fi - ;; - esac -} - -_docker_plugin_inspect() { - case "$prev" in - --format|f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_plugins_installed - ;; - esac -} - -_docker_plugin_install() { - case "$prev" in - --alias) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--alias --disable --disable-content-trust=false --grant-all-permissions --help" -- "$cur" ) ) - ;; - esac -} - -_docker_plugin_list() { - _docker_plugin_ls -} - -_docker_plugin_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - capability) - COMPREPLY=( $( compgen -W "authz ipamdriver logdriver metricscollector networkdriver volumedriver" -- "${cur##*=}" ) ) - return - ;; - enabled) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "capability enabled" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --no-trunc --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_plugin_push() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_plugins_installed - fi - ;; - esac -} - -_docker_plugin_remove() { - _docker_plugin_rm -} - -_docker_plugin_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_plugins_installed - ;; - esac -} - -_docker_plugin_set() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_plugins_installed - fi - ;; - esac -} - -_docker_plugin_upgrade() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--disable-content-trust --grant-all-permissions --help --skip-remote-check" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_plugins_installed - __ltrim_colon_completions "$cur" - elif [ "$cword" -eq "$((counter + 1))" ]; then - local plugin_images="$(__docker_plugins_installed)" - COMPREPLY=( $(compgen -S : -W "${plugin_images%:*}" -- "$cur") ) - __docker_nospace - fi - ;; - esac -} - - -_docker_port() { - _docker_container_port -} - -_docker_ps() { - _docker_container_ls -} - -_docker_pull() { - _docker_image_pull -} - -_docker_push() { - _docker_image_push -} - -_docker_rename() { - _docker_container_rename -} - -_docker_restart() { - _docker_container_restart -} - -_docker_rm() { - _docker_container_rm -} - -_docker_rmi() { - _docker_image_rm -} - -_docker_run() { - _docker_container_run -} - -_docker_save() { - _docker_image_save -} - - -_docker_secret() { - local subcommands=" - create - inspect - ls - rm - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_secret_create() { - case "$prev" in - --driver|-d|--label|-l) - return - ;; - --template-driver) - COMPREPLY=( $( compgen -W "golang" -- "$cur" ) ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--driver -d --help --label -l --template-driver" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--driver|-d|--label|-l|--template-driver') - if [ "$cword" -eq "$((counter + 1))" ]; then - _filedir - fi - ;; - esac -} - -_docker_secret_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) - ;; - *) - __docker_complete_secrets - ;; - esac -} - -_docker_secret_list() { - _docker_secret_ls -} - -_docker_secret_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - id) - __docker_complete_secrets --cur "${cur##*=}" --id - return - ;; - name) - __docker_complete_secrets --cur "${cur##*=}" --name - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_secret_remove() { - _docker_secret_rm -} - -_docker_secret_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - __docker_complete_secrets - ;; - esac -} - - - -_docker_search() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - is-automated) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - is-official) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "is-automated is-official stars" -- "$cur" ) ) - __docker_nospace - return - ;; - --format|--limit) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --limit --no-trunc" -- "$cur" ) ) - ;; - esac -} - - -_docker_stack() { - local subcommands=" - deploy - ls - ps - rm - services - " - local aliases=" - down - list - remove - up - " - - __docker_complete_stack_orchestrator_options && return - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - local options="--help --orchestrator" - __docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_stack_deploy() { - __docker_complete_stack_orchestrator_options && return - - case "$prev" in - --bundle-file) - _filedir dab - return - ;; - --compose-file|-c) - _filedir yml - return - ;; - --resolve-image) - COMPREPLY=( $( compgen -W "always changed never" -- "$cur" ) ) - return - ;; - esac - - case "$cur" in - -*) - local options="--compose-file -c --help --orchestrator" - __docker_server_is_experimental && __docker_stack_orchestrator_is swarm && options+=" --bundle-file" - __docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig --namespace" - __docker_stack_orchestrator_is swarm && options+=" --prune --resolve-image --with-registry-auth" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--bundle-file|--compose-file|-c|--kubeconfig|--namespace|--orchestrator|--resolve-image') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_stacks - fi - ;; - esac -} - -_docker_stack_down() { - _docker_stack_rm -} - -_docker_stack_list() { - _docker_stack_ls -} - -_docker_stack_ls() { - __docker_complete_stack_orchestrator_options && return - - case "$prev" in - --format) - return - ;; - esac - - case "$cur" in - -*) - local options="--format --help --orchestrator" - __docker_stack_orchestrator_is kubernetes && options+=" --all-namespaces --kubeconfig --namespace" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - esac -} - -_docker_stack_ps() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - desired-state) - COMPREPLY=( $( compgen -W "accepted running shutdown" -- "${cur##*=}" ) ) - return - ;; - id) - __docker_complete_stacks --cur "${cur##*=}" --id - return - ;; - name) - __docker_complete_stacks --cur "${cur##*=}" --name - return - ;; - esac - - __docker_complete_stack_orchestrator_options && return - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "id name desired-state" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - local options="--filter -f --format --help --no-resolve --no-trunc --orchestrator --quiet -q" - __docker_stack_orchestrator_is kubernetes && options+=" --all-namespaces --kubeconfig --namespace" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--all-namespaces|--filter|-f|--format|--kubeconfig|--namespace') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_stacks - fi - ;; - esac -} - -_docker_stack_remove() { - _docker_stack_rm -} - -_docker_stack_rm() { - __docker_complete_stack_orchestrator_options && return - - case "$cur" in - -*) - local options="--help --orchestrator" - __docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig --namespace" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - __docker_complete_stacks - ;; - esac -} - -_docker_stack_services() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - id) - __docker_complete_services --cur "${cur##*=}" --id - return - ;; - label) - return - ;; - name) - __docker_complete_services --cur "${cur##*=}" --name - return - ;; - esac - - __docker_complete_stack_orchestrator_options && return - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - local options="--filter -f --format --help --orchestrator --quiet -q" - __docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig --namespace" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag '--filter|-f|--format|--kubeconfig|--namespace|--orchestrator') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_stacks - fi - ;; - esac -} - -_docker_stack_up() { - _docker_stack_deploy -} - - -_docker_start() { - _docker_container_start -} - -_docker_stats() { - _docker_container_stats -} - -_docker_stop() { - _docker_container_stop -} - - -_docker_system() { - local subcommands=" - df - events - info - prune - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_system_df() { - case "$prev" in - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format --help --verbose -v" -- "$cur" ) ) - ;; - esac -} - -_docker_system_events() { - local key=$(__docker_map_key_of_current_option '-f|--filter') - case "$key" in - container) - __docker_complete_containers_all --cur "${cur##*=}" - return - ;; - daemon) - local name=$(__docker_q info | sed -n 's/^\(ID\|Name\): //p') - COMPREPLY=( $( compgen -W "$name" -- "${cur##*=}" ) ) - return - ;; - event) - COMPREPLY=( $( compgen -W " - attach - commit - connect - copy - create - delete - destroy - detach - die - disable - disconnect - enable - exec_create - exec_detach - exec_die - exec_start - export - health_status - import - install - kill - load - mount - oom - pause - pull - push - reload - remove - rename - resize - restart - save - start - stop - tag - top - unmount - unpause - untag - update - " -- "${cur##*=}" ) ) - return - ;; - image) - __docker_complete_images --cur "${cur##*=}" --repo --tag - return - ;; - network) - __docker_complete_networks --cur "${cur##*=}" - return - ;; - scope) - COMPREPLY=( $( compgen -W "local swarm" -- "${cur##*=}" ) ) - return - ;; - type) - COMPREPLY=( $( compgen -W "config container daemon image network plugin secret service volume" -- "${cur##*=}" ) ) - return - ;; - volume) - __docker_complete_volumes --cur "${cur##*=}" - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "container daemon event image label network scope type volume" -- "$cur" ) ) - __docker_nospace - return - ;; - --since|--until) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --help --since --until --format" -- "$cur" ) ) - ;; - esac -} - -_docker_system_info() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - esac -} - -_docker_system_prune() { - case "$prev" in - --filter) - COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--all -a --force -f --filter --help --volumes" -- "$cur" ) ) - ;; - esac -} - - -_docker_tag() { - _docker_image_tag -} - - -_docker_trust() { - local subcommands=" - inspect - revoke - sign - " - __docker_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_trust_inspect() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --pretty" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --repo --tag - fi - ;; - esac -} - -_docker_trust_revoke() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --yes -y" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --repo --tag - fi - ;; - esac -} - -_docker_trust_sign() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help --local" -- "$cur" ) ) - ;; - *) - local counter=$(__docker_pos_first_nonflag) - if [ "$cword" -eq "$counter" ]; then - __docker_complete_images --force-tag --id - fi - ;; - esac -} - - -_docker_unpause() { - _docker_container_unpause -} - -_docker_update() { - _docker_container_update -} - -_docker_top() { - _docker_container_top -} - -_docker_version() { - __docker_complete_stack_orchestrator_options && return - - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - local options="--format -f --help" - __docker_stack_orchestrator_is kubernetes && options+=" --kubeconfig" - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - esac -} - -_docker_volume_create() { - case "$prev" in - --driver|-d) - __docker_complete_plugins_bundled --type Volume - return - ;; - --label|--opt|-o) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--driver -d --help --label --opt -o" -- "$cur" ) ) - ;; - esac -} - -_docker_volume_inspect() { - case "$prev" in - --format|-f) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_volumes - ;; - esac -} - -_docker_volume_list() { - _docker_volume_ls -} - -_docker_volume_ls() { - local key=$(__docker_map_key_of_current_option '--filter|-f') - case "$key" in - dangling) - COMPREPLY=( $( compgen -W "true false" -- "${cur##*=}" ) ) - return - ;; - driver) - __docker_complete_plugins_bundled --cur "${cur##*=}" --type Volume - return - ;; - name) - __docker_complete_volumes --cur "${cur##*=}" - return - ;; - esac - - case "$prev" in - --filter|-f) - COMPREPLY=( $( compgen -S = -W "dangling driver label name" -- "$cur" ) ) - __docker_nospace - return - ;; - --format) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter -f --format --help --quiet -q" -- "$cur" ) ) - ;; - esac -} - -_docker_volume_prune() { - case "$prev" in - --filter) - COMPREPLY=( $( compgen -W "label label!" -S = -- "$cur" ) ) - __docker_nospace - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--filter --force -f --help" -- "$cur" ) ) - ;; - esac -} - -_docker_volume_remove() { - _docker_volume_rm -} - -_docker_volume_rm() { - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) - ;; - *) - __docker_complete_volumes - ;; - esac -} - -_docker_volume() { - local subcommands=" - create - inspect - ls - prune - rm - " - local aliases=" - list - remove - " - __docker_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_docker_wait() { - _docker_container_wait -} - -_docker() { - local previous_extglob_setting=$(shopt -p extglob) - shopt -s extglob - - local management_commands=( - builder - config - container - context - engine - image - network - node - plugin - secret - service - stack - swarm - system - trust - volume - ) - - local top_level_commands=( - build - login - logout - run - search - version - ) - - local legacy_commands=( - attach - commit - cp - create - diff - events - exec - export - history - images - import - info - inspect - kill - load - logs - pause - port - ps - pull - push - rename - restart - rm - rmi - save - start - stats - stop - tag - top - unpause - update - wait - ) - - local experimental_client_commands=( - manifest - ) - - local experimental_server_commands=( - checkpoint - deploy - ) - - local commands=(${management_commands[*]} ${top_level_commands[*]}) - [ -z "$DOCKER_HIDE_LEGACY_COMMANDS" ] && commands+=(${legacy_commands[*]}) - - # These options are valid as global options for all client commands - # and valid as command options for `docker daemon` - local global_boolean_options=" - --debug -D - --tls - --tlsverify - " - local global_options_with_args=" - --config - --context -c - --host -H - --log-level -l - --tlscacert - --tlscert - --tlskey - " - - # variables to cache server info, populated on demand for performance reasons - local info_fetched server_experimental server_os - # variables to cache client info, populated on demand for performance reasons - local client_experimental stack_orchestrator_is_kubernetes stack_orchestrator_is_swarm - - local host config context - - COMPREPLY=() - local cur prev words cword - _get_comp_words_by_ref -n : cur prev words cword - - local command='docker' command_pos=0 subcommand_pos - local counter=1 - while [ "$counter" -lt "$cword" ]; do - case "${words[$counter]}" in - docker) - return 0 - ;; - # save host so that completion can use custom daemon - --host|-H) - (( counter++ )) - host="${words[$counter]}" - ;; - # save config so that completion can use custom configuration directories - --config) - (( counter++ )) - config="${words[$counter]}" - ;; - # save context so that completion can use custom daemon - --context|-c) - (( counter++ )) - context="${words[$counter]}" - ;; - $(__docker_to_extglob "$global_options_with_args") ) - (( counter++ )) - ;; - -*) - ;; - =) - (( counter++ )) - ;; - *) - command="${words[$counter]}" - command_pos=$counter - break - ;; - esac - (( counter++ )) - done - - local binary="${words[0]}" - if [[ $binary == ?(*/)dockerd ]] ; then - # for the dockerd binary, we reuse completion of `docker daemon`. - # dockerd does not have subcommands and global options. - command=daemon - command_pos=0 - fi - - local completions_func=_docker_${command//-/_} - declare -F $completions_func >/dev/null && $completions_func - - eval "$previous_extglob_setting" - return 0 -} - -eval "$__docker_previous_extglob_setting" -unset __docker_previous_extglob_setting - -complete -F _docker docker docker.exe dockerd dockerd.exe +# Make sure docker is installed +_command_exists docker || return + +# Don't handle completion if it's already managed +complete -p docker &>/dev/null && return + +_docker_bash_completion_paths=( + # MacOS + '/Applications/Docker.app/Contents/Resources/etc/docker.bash-completion' + # Linux + '/usr/share/bash-completion/completions/docker' +) + +for fn in "${_docker_bash_completion_paths[@]}"; do + if [ -r "$fn" ]; then + source "$fn" + break + fi +done diff --git a/completion/available/gh.completion.bash b/completion/available/gh.completion.bash deleted file mode 100644 index b46de4dd..00000000 --- a/completion/available/gh.completion.bash +++ /dev/null @@ -1,365 +0,0 @@ -# hub tab-completion script for bash. -# This script complements the completion script that ships with git. - -# Check that git tab completion is available -if declare -F _git > /dev/null; then - # Duplicate and rename the 'list_all_commands' function - eval "$(declare -f __git_list_all_commands | \ - sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')" - - # Wrap the 'list_all_commands' function with extra hub commands - __git_list_all_commands() { - cat <<-EOF -alias -pull-request -fork -create -browse -compare -ci-status -release -issue -update -EOF - __git_list_all_commands_without_hub - } - - # Ensure cached commands are cleared - __git_all_commands="" - - ########################## - # hub command completions - ########################## - - # hub alias [-s] [SHELL] - _git_alias() { - local i c=2 s=-s sh shells="bash zsh sh ksh csh fish" - while [ $c -lt $cword ]; do - i="${words[c]}" - case "$i" in - -s) - unset s - ;; - *) - for sh in $shells; do - if [ "$sh" = "$i" ]; then - unset shells - break - fi - done - ;; - esac - ((c++)) - done - __gitcomp "$s $shells" - } - - # hub browse [-u] [--|[USER/]REPOSITORY] [SUBPAGE] - _git_browse() { - local i c=2 u=-u repo subpage - local subpages_="commits issues tree wiki pulls branches stargazers - contributors network network/ graphs graphs/" - local subpages_network="members" - local subpages_graphs="commit-activity code-frequency punch-card" - while [ $c -lt $cword ]; do - i="${words[c]}" - case "$i" in - -u) - unset u - ;; - *) - if [ -z "$repo" ]; then - repo=$i - else - subpage=$i - fi - ;; - esac - ((c++)) - done - if [ -z "$repo" ]; then - __gitcomp "$u -- $(__hub_github_repos '\p')" - elif [ -z "$subpage" ]; then - case "$cur" in - */*) - local pfx="${cur%/*}" cur_="${cur#*/}" - local subpages_var="subpages_$pfx" - __gitcomp "${!subpages_var}" "$pfx/" "$cur_" - ;; - *) - __gitcomp "$u ${subpages_}" - ;; - esac - else - __gitcomp "$u" - fi - } - - # hub compare [-u] [USER[/REPOSITORY]] [[START...]END] - _git_compare() { - local i c=$((cword - 1)) u=-u user remote owner repo arg_repo rev - while [ $c -gt 1 ]; do - i="${words[c]}" - case "$i" in - -u) - unset u - ;; - *) - if [ -z "$rev" ]; then - # Even though the logic below is able to complete both user/repo - # and revision in the right place, when there is only one argument - # (other than -u) in the command, that argument will be taken as - # revision. For example: - # $ hub compare -u upstream - # > https://github.com/USER/REPO/compare/upstream - if __hub_github_repos '\p' | grep -Eqx "^$i(/[^/]+)?"; then - arg_repo=$i - else - rev=$i - fi - elif [ -z "$arg_repo" ]; then - arg_repo=$i - fi - ;; - esac - ((c--)) - done - - # Here we want to find out the git remote name of user/repo, in order to - # generate an appropriate revision list - if [ -z "$arg_repo" ]; then - user=$(__hub_github_user) - if [ -z "$user" ]; then - for i in $(__hub_github_repos); do - remote=${i%%:*} - repo=${i#*:} - if [ "$remote" = origin ]; then - break - fi - done - else - for i in $(__hub_github_repos); do - remote=${i%%:*} - repo=${i#*:} - owner=${repo%%/*} - if [ "$user" = "$owner" ]; then - break - fi - done - fi - else - for i in $(__hub_github_repos); do - remote=${i%%:*} - repo=${i#*:} - owner=${repo%%/*} - case "$arg_repo" in - "$repo"|"$owner") - break - ;; - esac - done - fi - - local pfx cur_="$cur" - case "$cur_" in - *..*) - pfx="${cur_%%..*}..." - cur_="${cur_##*..}" - __gitcomp_nl "$(__hub_revlist $remote)" "$pfx" "$cur_" - ;; - *) - if [ -z "${arg_repo}${rev}" ]; then - __gitcomp "$u $(__hub_github_repos '\o\n\p') $(__hub_revlist $remote)" - elif [ -z "$rev" ]; then - __gitcomp "$u $(__hub_revlist $remote)" - else - __gitcomp "$u" - fi - ;; - esac - } - - # hub create [NAME] [-p] [-d DESCRIPTION] [-h HOMEPAGE] - _git_create() { - local i c=2 name repo flags="-p -d -h" - while [ $c -lt $cword ]; do - i="${words[c]}" - case "$i" in - -d|-h) - ((c++)) - flags=${flags/$i/} - ;; - -p) - flags=${flags/$i/} - ;; - *) - name=$i - ;; - esac - ((c++)) - done - if [ -z "$name" ]; then - repo=$(basename "$(pwd)") - fi - case "$prev" in - -d|-h) - COMPREPLY=() - ;; - -p|*) - __gitcomp "$repo $flags" - ;; - esac - } - - # hub fork [--no-remote] - _git_fork() { - local i c=2 remote=yes - while [ $c -lt $cword ]; do - i="${words[c]}" - case "$i" in - --no-remote) - unset remote - ;; - esac - ((c++)) - done - if [ -n "$remote" ]; then - __gitcomp "--no-remote" - fi - } - - # hub pull-request [-f] [-m |-F |-i |] [-b ] [-h ] - _git_pull_request() { - local i c=2 flags="-f -m -F -i -b -h" - while [ $c -lt $cword ]; do - i="${words[c]}" - case "$i" in - -m|-F|-i|-b|-h) - ((c++)) - flags=${flags/$i/} - ;; - -f) - flags=${flags/$i/} - ;; - esac - ((c++)) - done - case "$prev" in - -i) - COMPREPLY=() - ;; - -b|-h) - # (Doesn't seem to need this...) - # Uncomment the following line when 'owner/repo:[TAB]' misbehaved - #_get_comp_words_by_ref -n : cur - __gitcomp_nl "$(__hub_heads)" - # __ltrim_colon_completions "$cur" - ;; - -F) - COMPREPLY=( "$cur"* ) - ;; - -f|*) - __gitcomp "$flags" - ;; - esac - } - - ################### - # Helper functions - ################### - - # __hub_github_user [HOST] - # Return $GITHUB_USER or the default github user defined in hub config - # HOST - Host to be looked-up in hub config. Default is "github.com" - __hub_github_user() { - if [ -n "$GITHUB_USER" ]; then - echo $GITHUB_USER - return - fi - local line h k v host=${1:-github.com} config=${HUB_CONFIG:-~/.config/gh} - if [ -f "$config" ]; then - while read line; do - if [ "$line" = "---" ]; then - continue - fi - k=${line%%:*} - v=${line#*:} - if [ -z "$v" ]; then - if [ "$h" = "$host" ]; then - break - fi - h=$k - continue - fi - k=${k#* } - v=${v#* } - if [ "$h" = "$host" ] && [ "$k" = "user" ]; then - echo "$v" - break - fi - done < "$config" - fi - } - - # __hub_github_repos [FORMAT] - # List all github hosted repository - # FORMAT - Format string contains multiple of these: - # \m remote - # \p owner/repo - # \o owner - # escaped characters (\n, \t ...etc) work - # If omitted, prints all github repos in the format of "remote:owner/repo" - __hub_github_repos() { - local f format=$1 - if [ -z "$(__gitdir)" ]; then - return - fi - if [ -z "$format" ]; then - format='\1:\2' - else - format=${format//\m/\1} - format=${format//\p/\2} - format=${format//\o/\3} - fi - command git config --get-regexp 'remote\.[^.]*\.url' | - grep -E ' ((https?|git)://|git@)github\.com[:/][^:/]+/[^/]+$' | - sed -E 's#^remote\.([^.]+)\.url +.+[:/](([^/]+)/[^.]+)(\.git)?$#'"$format"'#' - } - - # __hub_heads - # List all local "branch", and remote "owner/repo:branch" - __hub_heads() { - local i remote repo branch dir=$(__gitdir) - if [ -d "$dir" ]; then - command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ - "refs/heads/" - for i in $(__hub_github_repos); do - remote=${i%%:*} - repo=${i#*:} - command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ - "refs/remotes/${remote}/" | while read branch; do - echo "${repo}:${branch#${remote}/}" - done - done - fi - } - - # __hub_revlist [REMOTE] - # List all tags, and branches under REMOTE, without the "remote/" prefix - # REMOTE - Remote name to search branches from. Default is "origin" - __hub_revlist() { - local i remote=${1:-origin} dir=$(__gitdir) - if [ -d "$dir" ]; then - command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ - "refs/remotes/${remote}/" | while read i; do - echo "${i#${remote}/}" - done - command git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ - "refs/tags/" - fi - } - - # Enable completion for hub even when not using the alias - complete -o bashdefault -o default -o nospace -F _git gh 2>/dev/null \ - || complete -o default -o nospace -F _git gh -fi diff --git a/completion/available/git.completion.bash b/completion/available/git.completion.bash index 499e56f8..c0c8748b 100644 --- a/completion/available/git.completion.bash +++ b/completion/available/git.completion.bash @@ -1,3055 +1,39 @@ -# bash/zsh completion support for core Git. -# -# Copyright (C) 2006,2007 Shawn O. Pearce -# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). -# Distributed under the GNU General Public License, version 2.0. -# -# The contained completion routines provide support for completing: -# -# *) local and remote branch names -# *) local and remote tag names -# *) .git/remotes file names -# *) git 'subcommands' -# *) git email aliases for git-send-email -# *) tree paths within 'ref:path/to/file' expressions -# *) file paths within current working directory and index -# *) common --long-options -# -# To use these routines: -# -# 1) Copy this file to somewhere (e.g. ~/.git-completion.bash). -# 2) Add the following line to your .bashrc/.zshrc: -# source ~/.git-completion.bash -# 3) Consider changing your PS1 to also show the current branch, -# see git-prompt.sh for details. -# -# If you use complex aliases of form '!f() { ... }; f', you can use the null -# command ':' as the first command in the function body to declare the desired -# completion style. For example '!f() { : git commit ; ... }; f' will -# tell the completion to use commit completion. This also works with aliases -# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '". -# -# Compatible with bash 3.2.57. -# -# You can set the following environment variables to influence the behavior of -# the completion routines: -# -# GIT_COMPLETION_CHECKOUT_NO_GUESS -# -# When set to "1", do not include "DWIM" suggestions in git-checkout -# completion (e.g., completing "foo" when "origin/foo" exists). +#!/usr/bin/env bash -case "$COMP_WORDBREAKS" in -*:*) : great ;; -*) COMP_WORDBREAKS="$COMP_WORDBREAKS:" -esac - -# Discovers the path to the git repository taking any '--git-dir=' and -# '-C ' options into account and stores it in the $__git_repo_path -# variable. -__git_find_repo_path () -{ - if [ -n "$__git_repo_path" ]; then - # we already know where it is - return - fi - - if [ -n "${__git_C_args-}" ]; then - __git_repo_path="$(git "${__git_C_args[@]}" \ - ${__git_dir:+--git-dir="$__git_dir"} \ - rev-parse --absolute-git-dir 2>/dev/null)" - elif [ -n "${__git_dir-}" ]; then - test -d "$__git_dir" && - __git_repo_path="$__git_dir" - elif [ -n "${GIT_DIR-}" ]; then - test -d "${GIT_DIR-}" && - __git_repo_path="$GIT_DIR" - elif [ -d .git ]; then - __git_repo_path=.git - else - __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)" - fi -} - -# Deprecated: use __git_find_repo_path() and $__git_repo_path instead -# __gitdir accepts 0 or 1 arguments (i.e., location) -# returns location of .git repo -__gitdir () -{ - if [ -z "${1-}" ]; then - __git_find_repo_path || return 1 - echo "$__git_repo_path" - elif [ -d "$1/.git" ]; then - echo "$1/.git" - else - echo "$1" - fi -} - -# Runs git with all the options given as argument, respecting any -# '--git-dir=' and '-C ' options present on the command line -__git () -{ - git ${__git_C_args:+"${__git_C_args[@]}"} \ - ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null -} - -# Removes backslash escaping, single quotes and double quotes from a word, -# stores the result in the variable $dequoted_word. -# 1: The word to dequote. -__git_dequote () -{ - local rest="$1" len ch - - dequoted_word="" - - while test -n "$rest"; do - len=${#dequoted_word} - dequoted_word="$dequoted_word${rest%%[\\\'\"]*}" - rest="${rest:$((${#dequoted_word}-$len))}" - - case "${rest:0:1}" in - \\) - ch="${rest:1:1}" - case "$ch" in - $'\n') - ;; - *) - dequoted_word="$dequoted_word$ch" - ;; - esac - rest="${rest:2}" - ;; - \') - rest="${rest:1}" - len=${#dequoted_word} - dequoted_word="$dequoted_word${rest%%\'*}" - rest="${rest:$((${#dequoted_word}-$len+1))}" - ;; - \") - rest="${rest:1}" - while test -n "$rest" ; do - len=${#dequoted_word} - dequoted_word="$dequoted_word${rest%%[\\\"]*}" - rest="${rest:$((${#dequoted_word}-$len))}" - case "${rest:0:1}" in - \\) - ch="${rest:1:1}" - case "$ch" in - \"|\\|\$|\`) - dequoted_word="$dequoted_word$ch" - ;; - $'\n') - ;; - *) - dequoted_word="$dequoted_word\\$ch" - ;; - esac - rest="${rest:2}" - ;; - \") - rest="${rest:1}" - break - ;; - esac - done - ;; - esac - done -} - -# The following function is based on code from: -# -# bash_completion - programmable completion functions for bash 3.2+ -# -# Copyright © 2006-2008, Ian Macdonald -# © 2009-2010, Bash Completion Maintainers -# -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# The latest version of this software can be obtained here: -# -# http://bash-completion.alioth.debian.org/ -# -# RELEASE: 2.x - -# This function can be used to access a tokenized list of words -# on the command line: -# -# __git_reassemble_comp_words_by_ref '=:' -# if test "${words_[cword_-1]}" = -w -# then -# ... -# fi -# -# The argument should be a collection of characters from the list of -# word completion separators (COMP_WORDBREAKS) to treat as ordinary -# characters. -# -# This is roughly equivalent to going back in time and setting -# COMP_WORDBREAKS to exclude those characters. The intent is to -# make option types like --date= and : easy to -# recognize by treating each shell word as a single token. -# -# It is best not to set COMP_WORDBREAKS directly because the value is -# shared with other completion scripts. By the time the completion -# function gets called, COMP_WORDS has already been populated so local -# changes to COMP_WORDBREAKS have no effect. -# -# Output: words_, cword_, cur_. - -__git_reassemble_comp_words_by_ref() -{ - local exclude i j first - # Which word separators to exclude? - exclude="${1//[^$COMP_WORDBREAKS]}" - cword_=$COMP_CWORD - if [ -z "$exclude" ]; then - words_=("${COMP_WORDS[@]}") - return - fi - # List of word completion separators has shrunk; - # re-assemble words to complete. - for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do - # Append each nonempty word consisting of just - # word separator characters to the current word. - first=t - while - [ $i -gt 0 ] && - [ -n "${COMP_WORDS[$i]}" ] && - # word consists of excluded word separators - [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ] - do - # Attach to the previous token, - # unless the previous token is the command name. - if [ $j -ge 2 ] && [ -n "$first" ]; then - ((j--)) - fi - first= - words_[$j]=${words_[j]}${COMP_WORDS[i]} - if [ $i = $COMP_CWORD ]; then - cword_=$j - fi - if (($i < ${#COMP_WORDS[@]} - 1)); then - ((i++)) - else - # Done. - return - fi - done - words_[$j]=${words_[j]}${COMP_WORDS[i]} - if [ $i = $COMP_CWORD ]; then - cword_=$j - fi - done -} - -if ! type _get_comp_words_by_ref >/dev/null 2>&1; then -_get_comp_words_by_ref () -{ - local exclude cur_ words_ cword_ - if [ "$1" = "-n" ]; then - exclude=$2 - shift 2 - fi - __git_reassemble_comp_words_by_ref "$exclude" - cur_=${words_[cword_]} - while [ $# -gt 0 ]; do - case "$1" in - cur) - cur=$cur_ - ;; - prev) - prev=${words_[$cword_-1]} - ;; - words) - words=("${words_[@]}") - ;; - cword) - cword=$cword_ - ;; - esac - shift - done -} +# Only operate on MacOS since there are no linux paths +if [[ "$(uname -s)" != 'Darwin' ]]; then + _log_warning "unsupported operating system - only 'Darwin' is supported" + return 0 fi -# Fills the COMPREPLY array with prefiltered words without any additional -# processing. -# Callers must take care of providing only words that match the current word -# to be completed and adding any prefix and/or suffix (trailing space!), if -# necessary. -# 1: List of newline-separated matching completion words, complete with -# prefix and suffix. -__gitcomp_direct () -{ - local IFS=$'\n' +# Make sure git is installed +_command_exists git || return 0 - COMPREPLY=($1) -} - -__gitcompappend () -{ - local x i=${#COMPREPLY[@]} - for x in $1; do - if [[ "$x" == "$3"* ]]; then - COMPREPLY[i++]="$2$x$4" - fi - done -} - -__gitcompadd () -{ - COMPREPLY=() - __gitcompappend "$@" -} - -# Generates completion reply, appending a space to possible completion words, -# if necessary. -# It accepts 1 to 4 arguments: -# 1: List of possible completion words. -# 2: A prefix to be added to each possible completion word (optional). -# 3: Generate possible completion matches for this word (optional). -# 4: A suffix to be appended to each possible completion word (optional). -__gitcomp () -{ - local cur_="${3-$cur}" - - case "$cur_" in - --*=) - ;; - --no-*) - local c i=0 IFS=$' \t\n' - for c in $1; do - if [[ $c == "--" ]]; then - continue - fi - c="$c${4-}" - if [[ $c == "$cur_"* ]]; then - case $c in - --*=*|*.) ;; - *) c="$c " ;; - esac - COMPREPLY[i++]="${2-}$c" - fi - done - ;; - *) - local c i=0 IFS=$' \t\n' - for c in $1; do - if [[ $c == "--" ]]; then - c="--no-...${4-}" - if [[ $c == "$cur_"* ]]; then - COMPREPLY[i++]="${2-}$c " - fi - break - fi - c="$c${4-}" - if [[ $c == "$cur_"* ]]; then - case $c in - --*=*|*.) ;; - *) c="$c " ;; - esac - COMPREPLY[i++]="${2-}$c" - fi - done - ;; - esac -} - -# Clear the variables caching builtins' options when (re-)sourcing -# the completion script. -if [[ -n ${ZSH_VERSION-} ]]; then - unset $(set |sed -ne 's/^\(__gitcomp_builtin_[a-zA-Z0-9_][a-zA-Z0-9_]*\)=.*/\1/p') 2>/dev/null -else - unset $(compgen -v __gitcomp_builtin_) +# Don't handle completion if it's already managed +if complete -p git &>/dev/null; then + _log_warning "completion already loaded - this usually means it is safe to stop using this completion" + return 0 fi -# This function is equivalent to -# -# __gitcomp "$(git xxx --git-completion-helper) ..." -# -# except that the output is cached. Accept 1-3 arguments: -# 1: the git command to execute, this is also the cache key -# 2: extra options to be added on top (e.g. negative forms) -# 3: options to be excluded -__gitcomp_builtin () -{ - # spaces must be replaced with underscore for multi-word - # commands, e.g. "git remote add" becomes remote_add. - local cmd="$1" - local incl="$2" - local excl="$3" - - local var=__gitcomp_builtin_"${cmd/-/_}" - local options - eval "options=\$$var" - - if [ -z "$options" ]; then - # leading and trailing spaces are significant to make - # option removal work correctly. - options=" $incl $(__git ${cmd/_/ } --git-completion-helper) " - for i in $excl; do - options="${options/ $i / }" - done - eval "$var=\"$options\"" - fi - - __gitcomp "$options" -} - -# Variation of __gitcomp_nl () that appends to the existing list of -# completion candidates, COMPREPLY. -__gitcomp_nl_append () -{ - local IFS=$'\n' - __gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }" -} - -# Generates completion reply from newline-separated possible completion words -# by appending a space to all of them. -# It accepts 1 to 4 arguments: -# 1: List of possible completion words, separated by a single newline. -# 2: A prefix to be added to each possible completion word (optional). -# 3: Generate possible completion matches for this word (optional). -# 4: A suffix to be appended to each possible completion word instead of -# the default space (optional). If specified but empty, nothing is -# appended. -__gitcomp_nl () -{ - COMPREPLY=() - __gitcomp_nl_append "$@" -} - -# Fills the COMPREPLY array with prefiltered paths without any additional -# processing. -# Callers must take care of providing only paths that match the current path -# to be completed and adding any prefix path components, if necessary. -# 1: List of newline-separated matching paths, complete with all prefix -# path components. -__gitcomp_file_direct () -{ - local IFS=$'\n' - - COMPREPLY=($1) - - # use a hack to enable file mode in bash < 4 - compopt -o filenames +o nospace 2>/dev/null || - compgen -f /non-existing-dir/ >/dev/null || - true -} - -# Generates completion reply with compgen from newline-separated possible -# completion filenames. -# It accepts 1 to 3 arguments: -# 1: List of possible completion filenames, separated by a single newline. -# 2: A directory prefix to be added to each possible completion filename -# (optional). -# 3: Generate possible completion matches for this word (optional). -__gitcomp_file () -{ - local IFS=$'\n' - - # XXX does not work when the directory prefix contains a tilde, - # since tilde expansion is not applied. - # This means that COMPREPLY will be empty and Bash default - # completion will be used. - __gitcompadd "$1" "${2-}" "${3-$cur}" "" - - # use a hack to enable file mode in bash < 4 - compopt -o filenames +o nospace 2>/dev/null || - compgen -f /non-existing-dir/ >/dev/null || - true -} - -# Execute 'git ls-files', unless the --committable option is specified, in -# which case it runs 'git diff-index' to find out the files that can be -# committed. It return paths relative to the directory specified in the first -# argument, and using the options specified in the second argument. -__git_ls_files_helper () -{ - if [ "$2" == "--committable" ]; then - __git -C "$1" -c core.quotePath=false diff-index \ - --name-only --relative HEAD -- "${3//\\/\\\\}*" - else - # NOTE: $2 is not quoted in order to support multiple options - __git -C "$1" -c core.quotePath=false ls-files \ - --exclude-standard $2 -- "${3//\\/\\\\}*" - fi -} - - -# __git_index_files accepts 1 or 2 arguments: -# 1: Options to pass to ls-files (required). -# 2: A directory path (optional). -# If provided, only files within the specified directory are listed. -# Sub directories are never recursed. Path must have a trailing -# slash. -# 3: List only paths matching this path component (optional). -__git_index_files () -{ - local root="$2" match="$3" - - __git_ls_files_helper "$root" "$1" "$match" | - awk -F / -v pfx="${2//\\/\\\\}" '{ - paths[$1] = 1 - } - END { - for (p in paths) { - if (substr(p, 1, 1) != "\"") { - # No special characters, easy! - print pfx p - continue - } - - # The path is quoted. - p = dequote(p) - if (p == "") - continue - - # Even when a directory name itself does not contain - # any special characters, it will still be quoted if - # any of its (stripped) trailing path components do. - # Because of this we may have seen the same direcory - # both quoted and unquoted. - if (p in paths) - # We have seen the same directory unquoted, - # skip it. - continue - else - print pfx p - } - } - function dequote(p, bs_idx, out, esc, esc_idx, dec) { - # Skip opening double quote. - p = substr(p, 2) - - # Interpret backslash escape sequences. - while ((bs_idx = index(p, "\\")) != 0) { - out = out substr(p, 1, bs_idx - 1) - esc = substr(p, bs_idx + 1, 1) - p = substr(p, bs_idx + 2) - - if ((esc_idx = index("abtvfr\"\\", esc)) != 0) { - # C-style one-character escape sequence. - out = out substr("\a\b\t\v\f\r\"\\", - esc_idx, 1) - } else if (esc == "n") { - # Uh-oh, a newline character. - # We cant reliably put a pathname - # containing a newline into COMPREPLY, - # and the newline would create a mess. - # Skip this path. - return "" - } else { - # Must be a \nnn octal value, then. - dec = esc * 64 + \ - substr(p, 1, 1) * 8 + \ - substr(p, 2, 1) - out = out sprintf("%c", dec) - p = substr(p, 3) - } - } - # Drop closing double quote, if there is one. - # (There isnt any if this is a directory, as it was - # already stripped with the trailing path components.) - if (substr(p, length(p), 1) == "\"") - out = out substr(p, 1, length(p) - 1) - else - out = out p - - return out - }' -} - -# __git_complete_index_file requires 1 argument: -# 1: the options to pass to ls-file -# -# The exception is --committable, which finds the files appropriate commit. -__git_complete_index_file () -{ - local dequoted_word pfx="" cur_ - - __git_dequote "$cur" - - case "$dequoted_word" in - ?*/*) - pfx="${dequoted_word%/*}/" - cur_="${dequoted_word##*/}" - ;; - *) - cur_="$dequoted_word" - esac - - __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")" -} - -# Lists branches from the local repository. -# 1: A prefix to be added to each listed branch (optional). -# 2: List only branches matching this word (optional; list all branches if -# unset or empty). -# 3: A suffix to be appended to each listed branch (optional). -__git_heads () -{ - local pfx="${1-}" cur_="${2-}" sfx="${3-}" - - __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ - "refs/heads/$cur_*" "refs/heads/$cur_*/**" -} - -# Lists tags from the local repository. -# Accepts the same positional parameters as __git_heads() above. -__git_tags () -{ - local pfx="${1-}" cur_="${2-}" sfx="${3-}" - - __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ - "refs/tags/$cur_*" "refs/tags/$cur_*/**" -} - -# Lists refs from the local (by default) or from a remote repository. -# It accepts 0, 1 or 2 arguments: -# 1: The remote to list refs from (optional; ignored, if set but empty). -# Can be the name of a configured remote, a path, or a URL. -# 2: In addition to local refs, list unique branches from refs/remotes/ for -# 'git checkout's tracking DWIMery (optional; ignored, if set but empty). -# 3: A prefix to be added to each listed ref (optional). -# 4: List only refs matching this word (optional; list all refs if unset or -# empty). -# 5: A suffix to be appended to each listed ref (optional; ignored, if set -# but empty). -# -# Use __git_complete_refs() instead. -__git_refs () -{ - local i hash dir track="${2-}" - local list_refs_from=path remote="${1-}" - local format refs - local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}" - local match="${4-}" - local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers - - __git_find_repo_path - dir="$__git_repo_path" - - if [ -z "$remote" ]; then - if [ -z "$dir" ]; then - return - fi - else - if __git_is_configured_remote "$remote"; then - # configured remote takes precedence over a - # local directory with the same name - list_refs_from=remote - elif [ -d "$remote/.git" ]; then - dir="$remote/.git" - elif [ -d "$remote" ]; then - dir="$remote" - else - list_refs_from=url - fi - fi - - if [ "$list_refs_from" = path ]; then - if [[ "$cur_" == ^* ]]; then - pfx="$pfx^" - fer_pfx="$fer_pfx^" - cur_=${cur_#^} - match=${match#^} - fi - case "$cur_" in - refs|refs/*) - format="refname" - refs=("$match*" "$match*/**") - track="" - ;; - *) - for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD; do - case "$i" in - $match*) - if [ -e "$dir/$i" ]; then - echo "$pfx$i$sfx" - fi - ;; - esac - done - format="refname:strip=2" - refs=("refs/tags/$match*" "refs/tags/$match*/**" - "refs/heads/$match*" "refs/heads/$match*/**" - "refs/remotes/$match*" "refs/remotes/$match*/**") - ;; - esac - __git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \ - "${refs[@]}" - if [ -n "$track" ]; then - # employ the heuristic used by git checkout - # Try to find a remote branch that matches the completion word - # but only output if the branch name is unique - __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ - --sort="refname:strip=3" \ - "refs/remotes/*/$match*" "refs/remotes/*/$match*/**" | \ - uniq -u - fi - return - fi - case "$cur_" in - refs|refs/*) - __git ls-remote "$remote" "$match*" | \ - while read -r hash i; do - case "$i" in - *^{}) ;; - *) echo "$pfx$i$sfx" ;; - esac - done - ;; - *) - if [ "$list_refs_from" = remote ]; then - case "HEAD" in - $match*) echo "${pfx}HEAD$sfx" ;; - esac - __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ - "refs/remotes/$remote/$match*" \ - "refs/remotes/$remote/$match*/**" - else - local query_symref - case "HEAD" in - $match*) query_symref="HEAD" ;; - esac - __git ls-remote "$remote" $query_symref \ - "refs/tags/$match*" "refs/heads/$match*" \ - "refs/remotes/$match*" | - while read -r hash i; do - case "$i" in - *^{}) ;; - refs/*) echo "$pfx${i#refs/*/}$sfx" ;; - *) echo "$pfx$i$sfx" ;; # symbolic refs - esac - done - fi - ;; - esac -} - -# Completes refs, short and long, local and remote, symbolic and pseudo. -# -# Usage: __git_complete_refs [