diff --git a/bash_completion b/bash_completion index d36fbb7d7c1..18d0404d1ef 100644 --- a/bash_completion +++ b/bash_completion @@ -61,6 +61,36 @@ _comp_deprecate_func() eval -- "$2() { $3 \"\$@\"; }" } +# Declare a compatibility variable name. +# For bash 4.3+, a real name alias is created, allowing value changes to +# "apply through" when the variables are set later. For bash versions earlier +# than that, the operation is once-only; the value of the new variable +# (if it's unset) is set to that of the old (if set) at call time. +# +# @param $1 Version of bash-completion where the deprecation occurred +# @param $2 Old variable name +# @param $3 New variable name +# @since 2.12 +_comp_deprecate_var() +{ + if (($# != 3)); then + printf 'bash_completion: %s: usage: %s DEPRECATION_VERSION OLD_NAME NEW_NAME\n' "$FUNCNAME" "$FUNCNAME" + return 2 + fi + if [[ $2 != [a-zA-Z_]*([a-zA-Z_0-9]) ]]; then + printf 'bash_completion: %s: %s\n' "$FUNCNAME" "\$2: invalid variable name '$1'" >&2 + return 2 + elif [[ $3 != [a-zA-Z_]*([a-zA-Z_0-9]) ]]; then + printf 'bash_completion: %s: %s\n' "$FUNCNAME" "\$3: invalid variable name '$2'" >&2 + return 2 + fi + if ((BASH_VERSINFO[0] >= 5 || BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 3)); then + eval "declare -gn $2=$3" + elif [[ -v $2 && ! -v $3 ]]; then + printf -v "$3" %s "$2" + fi +} + # A lot of the following one-liners were taken directly from the # completion examples provided with the bash 2.04 source distribution @@ -1092,14 +1122,13 @@ _comp_compgen_filedir() # the fallback condition with the "plus" dirs. local _opts=(-f -X "$_xspec") [[ $_xspec ]] && _plusdirs=(-o plusdirs) - [[ ${BASH_COMPLETION_FILEDIR_FALLBACK-${COMP_FILEDIR_FALLBACK-}} || - ! ${_plusdirs-} ]] || + [[ ${BASH_COMPLETION_FILEDIR_FALLBACK-} || ! ${_plusdirs-} ]] || _opts+=("${_plusdirs[@]}") _comp_compgen -v toks -c "$_quoted" -- "${_opts[@]}" # Try without filter if it failed to produce anything and configured to - [[ ${BASH_COMPLETION_FILEDIR_FALLBACK-${COMP_FILEDIR_FALLBACK-}} && + [[ ${BASH_COMPLETION_FILEDIR_FALLBACK-} && $_arg && ${#toks[@]} -lt 1 ]] && _comp_compgen -av toks -c "$_quoted" -- \ -f ${_plusdirs+"${_plusdirs[@]}"} @@ -2626,7 +2655,7 @@ _comp_compgen_known_hosts__impl() fi # Add hosts reported by avahi-browse, if desired and it's available. - if [[ ${BASH_COMPLETION_KNOWN_HOSTS_WITH_AVAHI-${COMP_KNOWN_HOSTS_WITH_AVAHI-}} ]] && + if [[ ${BASH_COMPLETION_KNOWN_HOSTS_WITH_AVAHI-} ]] && type avahi-browse &>/dev/null; then # Some old versions of avahi-browse reportedly didn't have -k # (even if mentioned in the manpage); those we do not support any more. @@ -2644,7 +2673,7 @@ _comp_compgen_known_hosts__impl() # Add results of normal hostname completion, unless # `BASH_COMPLETION_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value. - if [[ ${BASH_COMPLETION_KNOWN_HOSTS_WITH_HOSTFILE-${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1}} ]]; then + if [[ ${BASH_COMPLETION_KNOWN_HOSTS_WITH_HOSTFILE-set} ]]; then _comp_compgen -av known_hosts -- -A hostname -P "$prefix" -S "$suffix" fi @@ -3006,8 +3035,7 @@ _comp_compgen_filedir_xspec() _comp_compgen -av toks -c "$quoted" -- -f -X "@(|!($xspec))" # Try without filter if it failed to produce anything and configured to - [[ ${BASH_COMPLETION_FILEDIR_FALLBACK-${COMP_FILEDIR_FALLBACK-}} && - ${#toks[@]} -lt 1 ]] && + [[ ${BASH_COMPLETION_FILEDIR_FALLBACK-} && ${#toks[@]} -lt 1 ]] && _comp_compgen -av toks -c "$quoted" -- -f ((${#toks[@]})) || return 1 diff --git a/bash_completion.d/000_bash_completion_compat.bash b/bash_completion.d/000_bash_completion_compat.bash index 6971fa9651e..480ffcc6a75 100644 --- a/bash_completion.d/000_bash_completion_compat.bash +++ b/bash_completion.d/000_bash_completion_compat.bash @@ -42,6 +42,10 @@ _comp_deprecate_func 2.12 _longopt _comp_complete_longopt _comp_deprecate_func 2.12 _filedir_xspec _comp_complete_filedir_xspec _comp_deprecate_func 2.12 _minimal _comp_complete_minimal +_comp_deprecate_var 2.12 COMP_FILEDIR_FALLBACK BASH_COMPLETION_FILEDIR_FALLBACK +_comp_deprecate_var 2.12 COMP_KNOWN_HOSTS_WITH_AVAHI BASH_COMPLETION_KNOWN_HOSTS_WITH_AVAHI +_comp_deprecate_var 2.12 COMP_KNOWN_HOSTS_WITH_HOSTFILE BASH_COMPLETION_KNOWN_HOSTS_WITH_HOSTFILE + # @deprecated 2.12 Use `_comp_xspecs` declare -Ag _xspecs diff --git a/completions/configure b/completions/configure index 6d74b112862..a61a05dc382 100644 --- a/completions/configure +++ b/completions/configure @@ -1,5 +1,8 @@ # bash completion for configure -*- shell-script -*- +_comp_deprecate_var 2.12 \ + COMP_CONFIGURE_HINTS BASH_COMPLETION_CMD_CONFIGURE_HINTS + _comp_cmd_configure() { local cur prev words cword was_split comp_args @@ -27,7 +30,7 @@ _comp_cmd_configure() # if $BASH_COMPLETION_CMD_CONFIGURE_HINTS is not null, then completions of # the form --option=SETTING will include 'SETTING' as a contextual hint - if [[ ${BASH_COMPLETION_CMD_CONFIGURE_HINTS-${COMP_CONFIGURE_HINTS-}} ]]; then + if [[ ${BASH_COMPLETION_CMD_CONFIGURE_HINTS-} ]]; then _comp_compgen_split -- "$("$1" --help 2>&1 | _comp_awk '/^ --[A-Za-z]/ { print $1; \ if ($2 ~ /--[A-Za-z]/) print $2 }' | command sed -e 's/[[,].*//g')" diff --git a/completions/cvs b/completions/cvs index 50b9f2b83ed..b8398af3f1d 100644 --- a/completions/cvs +++ b/completions/cvs @@ -1,5 +1,8 @@ # cvs(1) completion -*- shell-script -*- +_comp_deprecate_var 2.12 \ + COMP_CVS_REMOTE BASH_COMPLETION_CMD_CVS_REMOTE + _comp_cmd_cvs__entries() { local prefix=${cur%/*}/ IFS=$'\n' @@ -256,7 +259,7 @@ _comp_cmd_cvs() # if $BASH_COMPLETION_CMD_CVS_REMOTE is not null, 'cvs commit' # will complete on remotely checked-out files (requires # passwordless access to the remote repository - if [[ ${BASH_COMPLETION_CMD_CVS_REMOTE-${COMP_CVS_REMOTE-}} ]]; then + if [[ ${BASH_COMPLETION_CMD_CVS_REMOTE-} ]]; then # this is the least computationally intensive way found so # far, but other changes (something other than # changed/removed/new) may be missing diff --git a/completions/iwconfig b/completions/iwconfig index dc5962fcce7..7fbc985b61c 100644 --- a/completions/iwconfig +++ b/completions/iwconfig @@ -1,5 +1,8 @@ # iwconfig completion -*- shell-script -*- +_comp_deprecate_var 2.12 \ + COMP_IWLIST_SCAN BASH_COMPLETION_CMD_IWCONFIG_SCAN + _comp_cmd_iwconfig() { local cur prev words cword comp_args @@ -13,7 +16,7 @@ _comp_cmd_iwconfig() ;; essid) _comp_compgen -- -W 'on off any' - if [[ ${BASH_COMPLETION_CMD_IWCONFIG_SCAN-${COMP_IWLIST_SCAN-}} ]]; then + if [[ ${BASH_COMPLETION_CMD_IWCONFIG_SCAN-} ]]; then _comp_compgen -a split -- "$(iwlist "${words[1]}" scan | _comp_awk -F '\"' '/ESSID/ {print $2}')" fi @@ -36,7 +39,7 @@ _comp_cmd_iwconfig() ;; ap) _comp_compgen -- -W 'on off any' - if [[ ${BASH_COMPLETION_CMD_IWCONFIG_SCAN-${COMP_IWLIST_SCAN-}} ]]; then + if [[ ${BASH_COMPLETION_CMD_IWCONFIG_SCAN-} ]]; then _comp_compgen -a split -- "$(iwlist "${words[1]}" scan | _comp_awk -F ': ' '/Address/ {print $2}')" fi diff --git a/completions/tar b/completions/tar index d4fa32fb0de..83a40735dfa 100644 --- a/completions/tar +++ b/completions/tar @@ -56,6 +56,9 @@ # `$BASH_COMPLETION_CMD_TAR_INTERNAL_PATHS` environment variable to a non-null # value *before sourcing* this completion toggles that the other way around. +_comp_deprecate_var 2.12 \ + COMP_TAR_INTERNAL_PATHS BASH_COMPLETION_CMD_TAR_INTERNAL_PATHS + _comp_cmd_gtar__parse_help_opt() { local opttype arg opt separator optvar @@ -723,7 +726,7 @@ _comp_cmd_tar() $func "$@" # Install real completion for subsequent completions - if [[ ${BASH_COMPLETION_CMD_TAR_INTERNAL_PATHS-${COMP_TAR_INTERNAL_PATHS-}} ]]; then + if [[ ${BASH_COMPLETION_CMD_TAR_INTERNAL_PATHS-} ]]; then complete -F $func -o dirnames tar else complete -F $func tar @@ -731,7 +734,7 @@ _comp_cmd_tar() unset -f "$FUNCNAME" } -if [[ ${BASH_COMPLETION_CMD_TAR_INTERNAL_PATHS-${COMP_TAR_INTERNAL_PATHS-}} ]]; then +if [[ ${BASH_COMPLETION_CMD_TAR_INTERNAL_PATHS-} ]]; then complete -F _comp_cmd_tar -o dirnames tar complete -F _comp_cmd_tar__gnu -o dirnames gtar complete -F _comp_cmd_tar__posix -o dirnames bsdtar diff --git a/test/t/test_cvsps.py b/test/t/test_cvsps.py index 4039893c853..209583255f1 100644 --- a/test/t/test_cvsps.py +++ b/test/t/test_cvsps.py @@ -1,7 +1,10 @@ import pytest -@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD/cvs",)) +@pytest.mark.bashcomp( + pre_cmds=("HOME=$PWD/cvs",), + ignore_env=r"^[+-]COMP_CVS_REMOTE=", +) class TestCvsps: @pytest.mark.complete("cvsps -", require_cmd=True) def test_1(self, completion):