80cac854191020cb874c04af862a6569e2156f8c

Author
kierandoonan <kieran.doonan@cloudreach.co.uk>
Committer
Marc Cornellà <marc.cornella@live.com>
Date

Message

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

Diff

 1diff --git a/plugins/knife/_knife b/plugins/knife/_knife
 2index 163149267dbd5589c0db6fcb06d2bebb606f9228..0d61ff15c5d9614e05fd662be261551c31915cfb 100644
 3--- a/plugins/knife/_knife
 4+++ b/plugins/knife/_knife
 5@@ -3,6 +3,9 @@
 6 # You can override the path to knife.rb and your cookbooks by setting
 7 # KNIFE_CONF_PATH=/path/to/my/.chef/knife.rb
 8 # KNIFE_COOKBOOK_PATH=/path/to/my/chef/cookbooks
 9+# If you want your local cookbooks path to be calculated relative to where you are then 
10+# set the below option
11+# KNIFE_RELATIVE_PATH=true 
12 # Read around where these are used for more detail.
13 
14 # These flags should be available everywhere according to man knife
15@@ -119,7 +122,19 @@ _knife() {
16      _arguments '4:Subsubsubcommands:($(_chef_$words[2]_$words[3]s_remote))'
17     ;;
18      file)
19-     _arguments '*:file or directory:_files -g "*.(rb|json)"'
20+      case $words[2] in
21+      environment)
22+        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/environments"'
23+      ;;
24+      node)
25+        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/nodes"'
26+      ;;
27+      role)
28+        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/roles"'
29+      ;;
30+      *)
31+        _arguments '*:Subsubcommands:($(_knife_options3))'
32+      esac 
33     ;;
34       list)
35      compadd -a "$@" knife_general_flags
36@@ -132,11 +147,22 @@ _knife() {
37       if (( versioncomp > 0 )); then
38         compadd "$@" attributes definitions files libraries providers recipes resources templates
39       else
40-       _arguments '*:Subsubcommands:($(_knife_options2))'
41+      case $words[5] in 
42+        file)
43+          _arguments '*:directory:_path_files -/ -W "$(_chef_root)/data_bags" -qS \ '
44+        ;;
45+        *) _arguments '*:Subsubcommands:($(_knife_options2))'
46+      esac
47       fi
48     ;; 
49     knifesubcmd5) 
50-      _arguments '*:Subsubcommands:($(_knife_options3))'
51+      case $words[5] in 
52+        file) 
53+          _arguments '*:files:_path_files -g "*.json" -W "$(_chef_root)/data_bags/$words[6]"'
54+        ;;
55+        *) 
56+          _arguments '*:Subsubcommands:($(_knife_options3))'
57+      esac
58    esac
59 }
60 
61@@ -184,12 +210,15 @@ _chef_environments_remote() {
62 
63 # The chef_x_local functions use the knife config to find the paths of relevant objects x to be uploaded to the server
64 _chef_cookbooks_local() {
65-  
66-  local knife_rb=${KNIFE_CONF_PATH:-${HOME}/.chef/knife.rb}
67-  if [ -f ./.chef/knife.rb ]; then
68-    knife_rb="./.chef/knife.rb"
69+  if [ $KNIFE_RELATIVE_PATH ]; then 
70+    local cookbook_path="$(_chef_root)/cookbooks"
71+  else 
72+    local knife_rb=${KNIFE_CONF_PATH:-${HOME}/.chef/knife.rb}
73+    if [ -f ./.chef/knife.rb ]; then
74+      knife_rb="./.chef/knife.rb"
75+    fi
76+    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/' )}
77   fi
78-  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/' )}
79   (for i in $cookbook_path; do ls $i; done)
80 }
81 
82@@ -198,4 +227,15 @@ _cookbook_versions() {
83   (knife cookbook show $words[4] | grep -v $words[4] | grep -v -E '\]|\[|\{|\}' | sed 's/ //g' | sed 's/"//g')
84 }
85 
86+# Searches up from current directory to find the closest folder that has a .chef folder 
87+# Useful for the knife upload/from file commands 
88+_chef_root () {
89+  directory="$PWD"
90+  while [ $directory != '/' ]
91+  do
92+    test -e "$directory/.chef" && echo "$directory" && return
93+    directory="${directory:h}"
94+  done
95+}
96+
97 _knife "$@"