Browse Source

Fix: Plugin knife: Add relative local path for commands which upload files (#4240)

* Added autocomplete support for local knife file uploads

* Added option to allow for relative path resolution for cookbooks

* Updated _chef_root function to use directory:h
kierandoonan 8 years ago
parent
commit
80cac85419
1 changed files with 48 additions and 8 deletions
  1. 48 8
      plugins/knife/_knife

+ 48 - 8
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 "$@"