Skip to content

Commit

Permalink
Merge pull request kubernetes#1246 from eparis/bash_completions
Browse files Browse the repository at this point in the history
Introduce bash completions for kubecfg
  • Loading branch information
filbranden committed Sep 30, 2014
2 parents 8469a34 + 59e1c5c commit 33afc2f
Showing 1 changed file with 202 additions and 0 deletions.
202 changes: 202 additions & 0 deletions misc/completions/bash/kubecfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
#!bash
#
# bash completion file for core kubecfg commands
#
# This script provides completion of non replication controller options
#
# To enable the completions either:
# - place this file in /etc/bash_completion.d
# or
# - copy this file and add the line below to your .bashrc after
# bash completion features are loaded
# . kubecfg
#
# Note:
# Currently, the completions will not work if the apiserver daemon is not
# running on localhost on the standard port 8080

__contains_word () {
local w word=$1; shift
for w in "$@"; do
[[ $w = "$word" ]] && return
done
return 1
}

# This should be provided by the bash-completions, but give a really simple
# stoopid version just in case. It works most of the time.
if ! declare -F _get_comp_words_by_ref >/dev/null 2>&1; then
_get_comp_words_by_ref ()
{
while [ $# -gt 0 ]; do
case "$1" in
cur)
cur=${COMP_WORDS[COMP_CWORD]}
;;
prev)
prev=${COMP_WORDS[COMP_CWORD-1]}
;;
words)
words=("${COMP_WORDS[@]}")
;;
cword)
cword=$COMP_CWORD
;;
-n)
shift # we don't handle excludes
;;
esac
shift
done
}
fi


__has_service() {
local i
for ((i=0; i < cword; i++)); do
local word=${words[i]}
# strip everything after a / so things like pods/[id] match
word=${word%%/*}
if __contains_word "${word}" "${services[@]}" &&
! __contains_word "${words[i-1]}" "${opts[@]}"; then
return 0
fi
done
return 1
}

# call kubecfg list $1,
# exclude blank lines
# skip the header stuff kubecfg prints on the first 2 lines
# append $1/ to the first column and use that in compgen
__kubecfg_parse_list()
{
local kubecfg_output
if kubecfg_output=$(kubecfg list "$1" 2>/dev/null); then
out=($(echo "${kubecfg_output}" | awk -v prefix="$1" '/^$/ {next} NR > 2 {print prefix"/"$1}'))
COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) )
fi
}

_kubecfg_specific_service_match()
{
case "$cur" in
pods/*)
__kubecfg_parse_list pods
;;
minions/*)
__kubecfg_parse_list minions
;;
replicationControllers/*)
__kubecfg_parse_list replicationControllers
;;
services/*)
__kubecfg_parse_list services
;;
*)
if __has_service; then
return 0
fi
compopt -o nospace
COMPREPLY=( $( compgen -S / -W "${services[*]}" -- "$cur" ) )
;;
esac
}

_kubecfg_service_match()
{
if __has_service; then
return 0
fi

COMPREPLY=( $( compgen -W "${services[*]}" -- "$cur" ) )
}

_kubecfg()
{
local opts=(
-h
-c
)
local -A all_services=(
[CREATE]="pods replicationControllers services"
[UPDATE]="replicationControllers"
[ALL]="pods replicationControllers services minions"
)
local services=(${all_services[ALL]})
local -A all_commands=(
[WITH_JSON]="create update"
[ALL]="create update get list delete stop rm rollingupdate resize"
)
local commands=(${all_commands[ALL]})

COMPREPLY=()
local command
local cur prev words cword
_get_comp_words_by_ref -n : cur prev words cword

if __contains_word "$prev" "${opts[@]}"; then
case $prev in
-c)
_filedir '@(json|yml|yaml)'
return 0
;;
-h)
return 0
;;
esac
fi

if [[ "$cur" = -* ]]; then
COMPREPLY=( $(compgen -W "${opts[*]}" -- "$cur") )
return 0
fi

# if you passed -c, you are limited to create or update
if __contains_word "-c" "${words[@]}"; then
services=(${all_services[CREATE]} ${all_services[UPDATE]})
commands=(${all_commands[WITH_JSON]})
fi

# figure out which command they are running, remembering that arguments to
# options don't count as the command! So a hostname named 'create' won't
# trip things up
local i
for ((i=0; i < cword; i++)); do
if __contains_word "${words[i]}" "${commands[@]}" &&
! __contains_word "${words[i-1]}" "${opts[@]}"; then
command=${words[i]}
break
fi
done

# tell the list of possible commands
if [[ -z ${command} ]]; then
COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
return 0
fi

# remove services which you can't update given your command
if [[ ${command} == "create" ]]; then
services=(${all_services[CREATE]})
elif [[ ${command} == "update" ]]; then
services=(${all_services[UPDATE]})
fi

case $command in
create | list)
_kubecfg_service_match
;;
update | get | delete)
_kubecfg_specific_service_match
;;
*)
;;
esac

return 0
}

complete -F _kubecfg kubecfg
# ex: ts=4 sw=4 et filetype=sh

0 comments on commit 33afc2f

Please sign in to comment.