diff --git a/plugins/knife/_knife b/plugins/knife/_knife index 163149267..0d61ff15c 100644 --- a/plugins/knife/_knife +++ b/plugins/knife/_knife @@ -3,6 +3,9 @@ # You can override the path to knife.rb and your cookbooks by setting # KNIFE_CONF_PATH=/path/to/my/.chef/knife.rb # KNIFE_COOKBOOK_PATH=/path/to/my/chef/cookbooks +# If you want your local cookbooks path to be calculated relative to where you are then +# set the below option +# KNIFE_RELATIVE_PATH=true # Read around where these are used for more detail. # These flags should be available everywhere according to man knife @@ -119,7 +122,19 @@ _knife() { _arguments '4:Subsubsubcommands:($(_chef_$words[2]_$words[3]s_remote))' ;; file) - _arguments '*:file or directory:_files -g "*.(rb|json)"' + case $words[2] in + environment) + _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/environments"' + ;; + node) + _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/nodes"' + ;; + role) + _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/roles"' + ;; + *) + _arguments '*:Subsubcommands:($(_knife_options3))' + esac ;; list) compadd -a "$@" knife_general_flags @@ -132,11 +147,22 @@ _knife() { if (( versioncomp > 0 )); then compadd "$@" attributes definitions files libraries providers recipes resources templates else - _arguments '*:Subsubcommands:($(_knife_options2))' + case $words[5] in + file) + _arguments '*:directory:_path_files -/ -W "$(_chef_root)/data_bags" -qS \ ' + ;; + *) _arguments '*:Subsubcommands:($(_knife_options2))' + esac fi ;; knifesubcmd5) - _arguments '*:Subsubcommands:($(_knife_options3))' + case $words[5] in + file) + _arguments '*:files:_path_files -g "*.json" -W "$(_chef_root)/data_bags/$words[6]"' + ;; + *) + _arguments '*:Subsubcommands:($(_knife_options3))' + esac esac } @@ -184,12 +210,15 @@ _chef_environments_remote() { # The chef_x_local functions use the knife config to find the paths of relevant objects x to be uploaded to the server _chef_cookbooks_local() { - - local knife_rb=${KNIFE_CONF_PATH:-${HOME}/.chef/knife.rb} - if [ -f ./.chef/knife.rb ]; then - knife_rb="./.chef/knife.rb" + if [ $KNIFE_RELATIVE_PATH ]; then + local cookbook_path="$(_chef_root)/cookbooks" + else + local knife_rb=${KNIFE_CONF_PATH:-${HOME}/.chef/knife.rb} + if [ -f ./.chef/knife.rb ]; then + knife_rb="./.chef/knife.rb" + fi + local cookbook_path=${KNIFE_COOKBOOK_PATH:-$(grep cookbook_path $knife_rb | awk 'BEGIN {FS = "[" }; {print $2}' | sed 's/\,//g' | sed "s/'//g" | sed 's/\(.*\)]/\1/' )} fi - local cookbook_path=${KNIFE_COOKBOOK_PATH:-$(grep cookbook_path $knife_rb | awk 'BEGIN {FS = "[" }; {print $2}' | sed 's/\,//g' | sed "s/'//g" | sed 's/\(.*\)]/\1/' )} (for i in $cookbook_path; do ls $i; done) } @@ -198,4 +227,15 @@ _cookbook_versions() { (knife cookbook show $words[4] | grep -v $words[4] | grep -v -E '\]|\[|\{|\}' | sed 's/ //g' | sed 's/"//g') } +# Searches up from current directory to find the closest folder that has a .chef folder +# Useful for the knife upload/from file commands +_chef_root () { + directory="$PWD" + while [ $directory != '/' ] + do + test -e "$directory/.chef" && echo "$directory" && return + directory="${directory:h}" + done +} + _knife "$@"