From 84280f1148e541f1c6e0d4793afffe86c3239335 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 18 Mar 2021 10:14:13 +0300 Subject: [PATCH] Add bash completion support for clickhouse utils --- debian/clickhouse-common-static.install | 1 + programs/CMakeLists.txt | 1 + programs/bash-completion/CMakeLists.txt | 1 + .../completions/CMakeLists.txt | 28 +++++++ .../bash-completion/completions/clickhouse | 43 ++++++++++ .../completions/clickhouse-benchmark | 2 + .../completions/clickhouse-bootstrap | 81 +++++++++++++++++++ .../completions/clickhouse-client | 2 + .../completions/clickhouse-local | 2 + 9 files changed, 161 insertions(+) create mode 100644 programs/bash-completion/CMakeLists.txt create mode 100644 programs/bash-completion/completions/CMakeLists.txt create mode 100644 programs/bash-completion/completions/clickhouse create mode 100644 programs/bash-completion/completions/clickhouse-benchmark create mode 100644 programs/bash-completion/completions/clickhouse-bootstrap create mode 100644 programs/bash-completion/completions/clickhouse-client create mode 100644 programs/bash-completion/completions/clickhouse-local diff --git a/debian/clickhouse-common-static.install b/debian/clickhouse-common-static.install index f1cbf0848d3..17c955a12a9 100644 --- a/debian/clickhouse-common-static.install +++ b/debian/clickhouse-common-static.install @@ -1,4 +1,5 @@ usr/bin/clickhouse usr/bin/clickhouse-odbc-bridge usr/bin/clickhouse-extract-from-config +usr/share/bash-completion/completions etc/security/limits.d/clickhouse.conf diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 6b322df5ffd..c3600e5812a 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -188,6 +188,7 @@ add_subdirectory (format) add_subdirectory (obfuscator) add_subdirectory (install) add_subdirectory (git-import) +add_subdirectory (bash-completion) if (ENABLE_CLICKHOUSE_ODBC_BRIDGE) add_subdirectory (odbc-bridge) diff --git a/programs/bash-completion/CMakeLists.txt b/programs/bash-completion/CMakeLists.txt new file mode 100644 index 00000000000..d3a47f5a35e --- /dev/null +++ b/programs/bash-completion/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(completions) diff --git a/programs/bash-completion/completions/CMakeLists.txt b/programs/bash-completion/completions/CMakeLists.txt new file mode 100644 index 00000000000..d364e07ef6e --- /dev/null +++ b/programs/bash-completion/completions/CMakeLists.txt @@ -0,0 +1,28 @@ +macro(configure_bash_completion) + set(out "/usr/share/bash-completion/completions") + find_program(pkg-config PKG_CONFIG_BIN) + if (PKG_CONFIG_BIN) + execute_process( + COMMAND ${PKG_CONFIG_BIN} --variable=completionsdir bash-completion + OUTPUT_VARIABLE ${out} + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + string(REPLACE /usr "${CMAKE_INSTALL_PREFIX}" out "${out}") + message(STATUS "bash_completion will be written to ${out}") +endmacro() + +configure_bash_completion() +foreach (name + # set of functions + clickhouse-bootstrap + + # binaries that accept settings as command line argument + clickhouse-client + clickhouse-local + clickhouse-benchmark + + clickhouse +) + install(FILES ${name} DESTINATION ${out}) +endforeach() diff --git a/programs/bash-completion/completions/clickhouse b/programs/bash-completion/completions/clickhouse new file mode 100644 index 00000000000..c4b77cf3f7a --- /dev/null +++ b/programs/bash-completion/completions/clickhouse @@ -0,0 +1,43 @@ +[[ -v $_CLICKHOUSE_COMPLETION_LOADED ]] || source "$(dirname "${BASH_SOURCE[0]}")/clickhouse-bootstrap" + +function _clickhouse_get_utils() +{ + local cmd=$1 && shift + "$cmd" --help |& awk '/^clickhouse.*args/ { print $2 }' +} + +function _complete_for_clickhouse_entrypoint_bin() +{ + local cur prev cword words + eval local cmd="$( _clickhouse_quote "$1" )" + _clickhouse_bin_exist "$cmd" || return 0 + + COMPREPLY=() + _get_comp_words_by_ref cur prev cword words + + local util="$cur" + # complete utils, until it will be finished + if [[ $cword -lt 2 ]]; then + COMPREPLY=( $(compgen -W "$(_clickhouse_get_utils "$cmd")" -- "$cur") ) + return + fi + util="${words[1]}" + + case "$prev" in + -C|--config-file|--config) + return + ;; + # Argh... This looks like a bash bug... + # Redirections are passed to the completion function + # although it is managed by the shell directly... + '<'|'>'|'>>'|[12]'>'|[12]'>>') + return + ;; + esac + + COMPREPLY=( $(compgen -W "$(_clickhouse_get_options "$cmd" "$util")" -- "$cur") ) + + return 0 +} + +_complete_clickhouse_generic clickhouse _complete_for_clickhouse_entrypoint_bin diff --git a/programs/bash-completion/completions/clickhouse-benchmark b/programs/bash-completion/completions/clickhouse-benchmark new file mode 100644 index 00000000000..13064b7417d --- /dev/null +++ b/programs/bash-completion/completions/clickhouse-benchmark @@ -0,0 +1,2 @@ +[[ -v $_CLICKHOUSE_COMPLETION_LOADED ]] || source "$(dirname "${BASH_SOURCE[0]}")/clickhouse-bootstrap" +_complete_clickhouse_generic clickhouse-benchmark diff --git a/programs/bash-completion/completions/clickhouse-bootstrap b/programs/bash-completion/completions/clickhouse-bootstrap new file mode 100644 index 00000000000..dc8dcd5ad8d --- /dev/null +++ b/programs/bash-completion/completions/clickhouse-bootstrap @@ -0,0 +1,81 @@ +# +# bash autocomplete, that can work with: +# a) --help of program +# +# Also you may like: +# $ bind "set completion-ignore-case on" +# $ bind "set show-all-if-ambiguous on" +# +# It uses bash-completion dynamic loader. + +# Known to work with bash 3.* with programmable completion and extended +# pattern matching enabled (use 'shopt -s extglob progcomp' to enable +# these if they are not already enabled). +shopt -s extglob + +export _CLICKHOUSE_COMPLETION_LOADED=1 + +function _clickhouse_bin_exist() +{ [ -x "$1" ] || command -v "$1" >& /dev/null; } + +function _clickhouse_quote() +{ + local quoted=${1//\'/\'\\\'\'}; + printf "'%s'" "$quoted" +} + +# Extract every option (everything that starts with "-") from the --help dialog. +function _clickhouse_get_options() +{ + "$@" --help 2>&1 | awk -F '[ ,=<>]' '{ for (i=1; i <= NF; ++i) { if (substr($i, 0, 1) == "-" && length($i) > 1) print $i; } }' | sort -u +} + +function _complete_for_clickhouse_generic_bin() +{ + local cur prev + eval local cmd="$( _clickhouse_quote "$1" )" + _clickhouse_bin_exist "$cmd" || return 0 + + COMPREPLY=() + _get_comp_words_by_ref cur prev + + case "$prev" in + -C|--config-file|--config) + return + ;; + # Argh... This looks like a bash bug... + # Redirections are passed to the completion function + # although it is managed by the shell directly... + '<'|'>'|'>>'|[12]'>'|[12]'>>') + return + ;; + esac + + COMPREPLY=( $(compgen -W "$(_clickhouse_get_options "$cmd")" -- "$cur") ) + + return 0 +} + +function _complete_clickhouse_generic() +{ + local bin=$1 && shift + local f=${1:-_complete_for_clickhouse_generic_bin} + local o=( + -o default + -o bashdefault + -o nospace + -F "$f" + "$bin" + ) + complete "${o[@]}" +} + +function _complete_clickhouse_bootstrap_main() +{ + local runtime=/usr/share/bash-completion/bash_completion + if ! type _get_comp_words_by_ref >& /dev/null && [[ -f $runtime ]]; then + source $runtime + fi + type _get_comp_words_by_ref >& /dev/null || return 0 +} +_complete_clickhouse_bootstrap_main "$@" diff --git a/programs/bash-completion/completions/clickhouse-client b/programs/bash-completion/completions/clickhouse-client new file mode 100644 index 00000000000..6b7899b7263 --- /dev/null +++ b/programs/bash-completion/completions/clickhouse-client @@ -0,0 +1,2 @@ +[[ -v $_CLICKHOUSE_COMPLETION_LOADED ]] || source "$(dirname "${BASH_SOURCE[0]}")/clickhouse-bootstrap" +_complete_clickhouse_generic clickhouse-client diff --git a/programs/bash-completion/completions/clickhouse-local b/programs/bash-completion/completions/clickhouse-local new file mode 100644 index 00000000000..7b12b48c7cd --- /dev/null +++ b/programs/bash-completion/completions/clickhouse-local @@ -0,0 +1,2 @@ +[[ -v $_CLICKHOUSE_COMPLETION_LOADED ]] || source "$(dirname "${BASH_SOURCE[0]}")/clickhouse-bootstrap" +_complete_clickhouse_generic clickhouse-local