Skip to content

Instantly share code, notes, and snippets.

@UnderGreen
Last active August 13, 2019 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save UnderGreen/5e4deaa9178bc9b0b27b46b327a4423b to your computer and use it in GitHub Desktop.
Save UnderGreen/5e4deaa9178bc9b0b27b46b327a4423b to your computer and use it in GitHub Desktop.
tele bash completion
__tele_previous_extglob_setting=$(shopt -p extglob)
shopt -s extglob
__tele_complete_apps() {
if [ -z "$tele_apps_info_fetched" ]; then
tele_apps=$(tele get app 2>/dev/null | awk 'NR>2 {print $1":"$2}')
tele_apps_info_fetched=true
fi
COMPREPLY=( $(compgen -W "$tele_apps" -- "$cur") )
__ltrim_colon_completions "$cur"
}
__tele_complete_clusters() {
if [ -z "$tele_clusters_info_fetched" ]; then
tele_clusters=$(tele get cluster 2>/dev/null | awk 'NR>2 {print $1}')
tele_clusters_info_fetched=true
fi
COMPREPLY=( $(compgen -W "$tele_clusters" -- "$cur") )
__ltrim_colon_completions "$cur"
}
# __tele_binary_is_enterprise tests whether tele binary is enteprise edition.
# The result is cached for the duration of one invocation of bash completion.
__tele_binary_is_enterprise() {
if [ -z "$info_fetched" ]; then
read -r tele_edition < <(tele version | awk '/Edition/ {print $2}')
info_fetched=true
fi
[ "$tele_edition" = "enterprise" ]
}
# __tele_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 __tele_pos_first_nonflag().
__tele_to_alternatives() {
local parts=( $1 )
local IFS='|'
echo "${parts[*]}"
}
# __tele_to_extglob transforms a multiline list of options into an extglob pattern
# suitable for use in case statements.
__tele_to_extglob() {
local extglob=$( __tele_to_alternatives "$1" )
Echo "@($extglob)"
}
# __tele_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.
__tele_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,
# "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words
while [ "${words[$counter + 1]}" = "=" ] ; do
counter=$(( counter + 2))
done
(( counter++ ))
done
echo $counter
}
_tele_build() {
local options_with_args="
--parallel
-o --output
--repository
--name
--version
--glob
--ignore
--set-image
--set-dep
--upgrade-via
"
local boolean_options="
-f --overwrite
-q --quiet
--skip-version-check
"
__tele_binary_is_enterprise && options_with_args+="--remote-support-addr
--remote-support-token
--ca-cert
--encryption-key
"
case "$prev" in
--ca-cert)
_filedir '@(c?(e)rt|cer|pem|der)'
return
;;
"$(__tele_to_extglob "$options_with_args")")
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$boolean_options $options_with_args" -- "$cur"))
;;
*)
local counter=$(__tele_pos_first_nonflag "$( __tele_to_alternatives "$options_with_args" )")
if [ "$cword" -eq "$counter" ]; then
_filedir '@(y?(a)ml)'
return
fi
;;
esac
}
_tele_create() {
local boolean_options="--force -f"
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$boolean_options" -- "$cur"))
;;
*)
_filedir '@(y?(a)ml)'
return
;;
esac
}
_tele_get() {
local options_with_args="
--format
--output -o"
case "$prev" in
--format|-o|--output)
COMPREPLY=( $(compgen -W "text json yaml" -- "$cur") )
;;
"$(__tele_to_extglob "$options_with_args")")
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$options_with_args" -- "$cur"))
;;
*)
local counter=$(__tele_pos_first_nonflag "$( __tele_to_alternatives "$options_with_args" )")
if [ "$cword" -eq "$counter" ]; then
COMPREPLY=( $(compgen -W "app cluster") )
return
fi
;;
esac
}
_tele_help() {
local counter=$(__tele_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
fi
}
_tele_login() {
local options_with_args="
--ops -o
--auth
--ttl
--token"
case "$prev" in
"$(__tele_to_extglob "$options_with_args")")
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$options_with_args" -- "$cur"))
;;
*)
local counter=$(__tele_pos_first_nonflag "$( __tele_to_alternatives "$options_with_args" )")
if [ "$cword" -eq "$counter" ]; then
return
fi
;;
esac
}
_tele_ls() {
case "$prev" in
--format)
COMPREPLY=( $(compgen -W "text json yaml" -- "$cur") )
;;
esac
case "$cur" in
-*)
local options="--format --all"
COMPREPLY=( $(compgen -W "$options" -- "$cur") )
;;
esac
}
_tele_pull() {
local options_with_args="--output -o"
local boolean_options="--force -f --quiet -q"
case "$prev" in
"$(__tele_to_extglob "$options_with_args")")
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$options_with_args $boolean_options" -- "$cur"))
;;
*)
local counter=$(__tele_pos_first_nonflag "$( __tele_to_alternatives "$options_with_args" )")
if [ "$cword" -eq "$counter" ]; then
__tele_complete_apps
return
fi
;;
esac
}
_tele_push() {
local boolean_options="--force -f --quiet -q"
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$boolean_options" -- "$cur"))
;;
*)
local counter=$(__tele_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
_filedir '@(tar?(.gz))'
return
fi
;;
esac
}
_tele_rm() {
local boolean_options="--force -f"
case "$prev" in
app|apps)
__tele_complete_apps
;;
cluster|clusters)
__tele_complete_clusters
;;
esac
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$boolean_options" -- "$cur"))
;;
*)
local counter=$(__tele_pos_first_nonflag "$( __tele_to_alternatives "app apps cluster clusters" )")
if [ "$cword" -eq "$counter" ]; then
COMPREPLY=( $(compgen -W "app cluster") )
return
fi
;;
esac
}
_tele_tele() {
case "$prev" in
--state-dir)
_filedir -d
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "$global_options" -- "$cur") )
;;
*)
local counter=$( __tele_pos_first_nonflag "$(__tele_to_extglob "$global_options")" )
if [ "$cword" -eq "$counter" ]; then
COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) )
fi
;;
esac
}
_tele_version() {
case "$prev" in
--output|-o)
COMPREPLY=( $(compgen -W "text json" -- "$cur") )
;;
esac
case "$cur" in
-*)
COMPREPLY=( $(compgen -W "-o --output" -- "$cur") )
;;
esac
}
_tele()
{
local previous_extglob_setting=$(shopt -p extglob)
shopt -s extglob
# local info_fetched tele_edition
# local tele_apps tele_apps_info_fetched
local global_options='
--debug
--insecure
--state-dir
'
local top_level_commands=(
build
ls
pull
version
)
local enterprise_top_level_commands=(
create
get
login
logout
push
rm
status
)
local commands=(${top_level_commands[*]})
__tele_binary_is_enterprise && commands+=(${enterprise_top_level_commands[@]})
COMPREPLY=()
local cur prev words cword
_get_comp_words_by_ref -n : cur prev words cword
local command='tele' command_pos=0 subcommand_pos
local counter=1
while [ "$counter" -lt "$cword" ]; do
case "${words[$counter]}" in
tele)
return 0
;;
"$global_options")
(( counter++ ))
;;
-*)
;;
=)
(( counter++ ))
;;
*)
command="${words[$counter]}"
command_pos=$counter
break
;;
esac
(( counter++ ))
done
local completions_func=_tele_${command//-/_}
declare -F $completions_func >/dev/null && $completions_func
eval "$previous_extglob_setting"
return 0
}
eval "$__tele_previous_extglob_setting"
unset __tele_previous_extglob_setting
complete -F _tele tele
# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment