[chef] Knife bash completion - improved


Chronological Thread 
  • From: Avishai Ish-Shalom < >
  • To:
  • Subject: [chef] Knife bash completion - improved
  • Date: Thu, 20 Jan 2011 11:06:05 +0200
  • Organization: Fewbytes LTD

OK. Now it works fast, used cache files for command completions and
while i was at it i added roles and nodes completion.

Cache files reside in $CHEF_HOME/.completion_cache and you have to
create this directory if you want cached completion.


And yes, now it will read chef repository locations from either
CHEF_REPOS or $CHEF_HOME/knife.rb


enjoy.

Avishai

# vim: ft=sh:ts=4:sw=4:autoindent:
# Author: Avishai Ish-Shalom 
< >

# first argument set the command level
_get_knife_completions() {
        n=$1
        shift
        # first argument is knife, so shift it
        [ "$1" == "knife" ] && shift
        local opts
        opts="$(knife $@ --help | grep -E '^knife' | cut -f$n -d" " | grep -v 
'(options)')"
        _upvar opts "$opts"
}

_flatten_knife_command() {
    echo ${words[*]} |sed -r -e "s/\ *${words[$cword]}\$//" -e 's/\W/_/g'
}
# Check cache file for category ( passed as $1 ) and run command if cache is 
empty
# Designed to be used with _get_knife_completions() and use the opts 
variables for options
_completion_cache() {
    local CACHE_DIR=${CHEF_HOME:-"$HOME/.chef"}/.completion_cache
    local flag COMMAND
    local OPTIND=1
    while getopts "c" flag "$@"; do
        case $flag in
        c)
            COMMAND=yes
            ;;
        *)
            ;;
        esac
    done
    shift $(( $OPTIND - 1 ))

    local CACHE_FILE="$CACHE_DIR/$1"
    shift
    if [ ! -f "$CACHE_FILE" ]; then
                if [[ "$COMMAND" == "yes" ]]; then
                        opts=$( eval $@ )
                else
                        $@
                fi
                [ -d "$CACHE_DIR" ] && echo $opts >"$CACHE_FILE"
    else
        opts=$(cat "$CACHE_FILE")
    fi
    _upvar opts "$opts"
}

_knife() {
        local opts cur prev cword words flattened_knife_command
        opts="bootstrap client configure cookbook data ec2 exec index node 
rackspace recipe role search slicehost ssh status terremark windows"
        _get_comp_words_by_ref cur prev cword words
    flattened_knife_command=$(_flatten_knife_command)
        COMPREPLY=()
        case $flattened_knife_command in
        knife_cookbook_upload)
        local chef_repos
                if [[ -z $CHEF_REPOS ]]; then
            chef_repos=( $(sed -rn '/cookbook_path/ {s/.*\[(.*)\]/\1/g; 
s/[,'\'']//g; p}' ${CHEF_HOME:-"$HOME/.chef"}/knife.rb) )
        else
            chef_repos=( 

 )
        fi
        if [[ -n "$chef_repos" ]]; then
            opts=$( ls -1p 

 | sort -u | sed -n 's/\/$//p' )
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        fi
                ;;
    knife_data)
        opts="bag"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
    knife_node_show|knife_node_edit|knife_node_delete)
        _completion_cache -c knife_nodes 'knife node list|sed -r -e "s/[\"\ 
,]//g" -e "/[^\.a-z0-9\-]+/d"'
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
    knife_role_edit|knife_role_show|knife_role_delete)
        _completion_cache -c knife_roles 'knife role list|sed -r -e "s/[\"\ 
,]//g" -e "/[^\.a-z0-9\-]+/d"'
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
        ;;
        *)
                case $cword in
                1)
                        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                        return 0
                        ;;
                *)
            _completion_cache $flattened_knife_command  
_get_knife_completions $(( $cword + 1 )) ${words[*]}
                        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                        return 0
                        ;;
                esac
                ;;
        esac
        [[ 

 -ge 1 ]] && return 0
}
complete -F _knife knife



Archive powered by MHonArc 2.6.16.

§