knife-essentials 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. data/lib/chef/knife/diff_essentials.rb +2 -2
  2. data/lib/chef/knife/download_essentials.rb +5 -1
  3. data/lib/chef/knife/list_essentials.rb +2 -1
  4. data/lib/chef/knife/upload_essentials.rb +5 -1
  5. data/lib/chef_fs/command_line.rb +94 -63
  6. data/lib/chef_fs/file_system.rb +113 -93
  7. data/lib/chef_fs/file_system/base_fs_object.rb +91 -37
  8. data/lib/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +14 -1
  9. data/lib/chef_fs/file_system/chef_server_root_dir.rb +2 -1
  10. data/lib/chef_fs/file_system/cookbook_file.rb +7 -1
  11. data/lib/chef_fs/file_system/cookbooks_dir.rb +13 -6
  12. data/lib/chef_fs/file_system/environments_dir.rb +59 -0
  13. data/lib/chef_fs/file_system/multiplexed_dir.rb +1 -1
  14. data/lib/chef_fs/file_system/nodes_dir.rb +1 -0
  15. data/lib/chef_fs/file_system/operation_not_allowed_error.rb +29 -0
  16. data/lib/chef_fs/file_system/operation_skipped_error.rb +29 -0
  17. data/lib/chef_fs/knife.rb +29 -21
  18. data/lib/chef_fs/version.rb +1 -1
  19. data/spec/chef_fs/diff_spec.rb +30 -30
  20. data/spec/chef_fs/file_system/cookbooks_dir_spec.rb +5 -1
  21. data/spec/integration/chef_repo_path_spec.rb +705 -0
  22. data/spec/integration/chef_repository_file_system_spec.rb +82 -713
  23. data/spec/integration/chefignore_spec.rb +258 -0
  24. data/spec/integration/diff_spec.rb +151 -0
  25. data/spec/integration/download_spec.rb +403 -0
  26. data/spec/integration/list_spec.rb +21 -21
  27. data/spec/integration/upload_spec.rb +407 -0
  28. data/spec/support/integration_helper.rb +9 -4
  29. data/spec/support/knife_support.rb +14 -2
  30. metadata +12 -3
@@ -1,4 +1,4 @@
1
1
  module ChefFS
2
- VERSION = "0.8.3"
2
+ VERSION = "0.8.4"
3
3
  end
4
4
 
@@ -85,9 +85,9 @@ describe 'diff', :uses_diff => true do
85
85
  :file_in_a_dir_in_b => {}
86
86
  }, /cannot_be_in_b/)
87
87
  }
88
- it 'ChefFS::CommandLine.diff(/)' do
88
+ it 'ChefFS::CommandLine.diff_print(/)' do
89
89
  results = []
90
- ChefFS::CommandLine.diff(pattern('/'), a, b, nil, nil) do |diff|
90
+ ChefFS::CommandLine.diff_print(pattern('/'), a, b, nil, nil) do |diff|
91
91
  results << remove_date(diff)
92
92
  end
93
93
  results.should =~ [
@@ -116,8 +116,8 @@ deleted file
116
116
  +++ /dev/null DATE
117
117
  @@ -1 +0,0 @@
118
118
  -sub_a_only_file
119
- ','File b/both_dirs/sub_dir_in_a_file_in_b is a directory while file b/both_dirs/sub_dir_in_a_file_in_b is a regular file
120
- ','File a/both_dirs/sub_file_in_a_dir_in_b is a regular file while file a/both_dirs/sub_file_in_a_dir_in_b is a directory
119
+ ','File a/both_dirs/sub_dir_in_a_file_in_b is a directory while file b/both_dirs/sub_dir_in_a_file_in_b is a regular file
120
+ ','File a/both_dirs/sub_file_in_a_dir_in_b is a regular file while file b/both_dirs/sub_file_in_a_dir_in_b is a directory
121
121
  ','Only in b/both_dirs: sub_b_only_dir
122
122
  ','diff --knife a/both_dirs/sub_b_only_file b/both_dirs/sub_b_only_file
123
123
  new file
@@ -150,8 +150,8 @@ deleted file
150
150
  +++ /dev/null DATE
151
151
  @@ -1 +0,0 @@
152
152
  -a_only_file
153
- ','File b/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
154
- ','File a/file_in_a_dir_in_b is a regular file while file a/file_in_a_dir_in_b is a directory
153
+ ','File a/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
154
+ ','File a/file_in_a_dir_in_b is a regular file while file b/file_in_a_dir_in_b is a directory
155
155
  ','Only in b: b_only_dir
156
156
  ','diff --knife a/b_only_file b/b_only_file
157
157
  new file
@@ -161,9 +161,9 @@ new file
161
161
  +b_only_file
162
162
  ' ]
163
163
  end
164
- it 'ChefFS::CommandLine.diff(/both_dirs)' do
164
+ it 'ChefFS::CommandLine.diff_print(/both_dirs)' do
165
165
  results = []
166
- ChefFS::CommandLine.diff(pattern('/both_dirs'), a, b, nil, nil) do |diff|
166
+ ChefFS::CommandLine.diff_print(pattern('/both_dirs'), a, b, nil, nil) do |diff|
167
167
  results << remove_date(diff)
168
168
  end
169
169
  results.should =~ [
@@ -192,8 +192,8 @@ deleted file
192
192
  +++ /dev/null DATE
193
193
  @@ -1 +0,0 @@
194
194
  -sub_a_only_file
195
- ','File b/both_dirs/sub_dir_in_a_file_in_b is a directory while file b/both_dirs/sub_dir_in_a_file_in_b is a regular file
196
- ','File a/both_dirs/sub_file_in_a_dir_in_b is a regular file while file a/both_dirs/sub_file_in_a_dir_in_b is a directory
195
+ ','File a/both_dirs/sub_dir_in_a_file_in_b is a directory while file b/both_dirs/sub_dir_in_a_file_in_b is a regular file
196
+ ','File a/both_dirs/sub_file_in_a_dir_in_b is a regular file while file b/both_dirs/sub_file_in_a_dir_in_b is a directory
197
197
  ','Only in b/both_dirs: sub_b_only_dir
198
198
  ','diff --knife a/both_dirs/sub_b_only_file b/both_dirs/sub_b_only_file
199
199
  new file
@@ -203,22 +203,22 @@ new file
203
203
  +sub_b_only_file
204
204
  ' ]
205
205
  end
206
- it 'ChefFS::CommandLine.diff(/) with depth 1' do
206
+ it 'ChefFS::CommandLine.diff_print(/) with depth 1' do
207
207
  results = []
208
- ChefFS::CommandLine.diff(pattern('/'), a, b, 1, nil) do |diff|
208
+ ChefFS::CommandLine.diff_print(pattern('/'), a, b, 1, nil) do |diff|
209
209
  results << remove_date(diff)
210
210
  end
211
211
  results.should =~ [
212
- 'Common subdirectories: /both_dirs
212
+ 'Common subdirectories: b/both_dirs
213
213
  ','diff --knife a/both_files_different b/both_files_different
214
214
  --- a/both_files_different DATE
215
215
  +++ b/both_files_different DATE
216
216
  @@ -1 +1 @@
217
217
  -a
218
218
  +b
219
- ','Common subdirectories: /both_dirs_empty
220
- ','Common subdirectories: /dirs_empty_in_b_filled_in_a
221
- ','Common subdirectories: /dirs_empty_in_a_filled_in_b
219
+ ','Common subdirectories: b/both_dirs_empty
220
+ ','Common subdirectories: b/dirs_empty_in_b_filled_in_a
221
+ ','Common subdirectories: b/dirs_empty_in_a_filled_in_b
222
222
  ','Only in a: a_only_dir
223
223
  ','diff --knife a/a_only_file b/a_only_file
224
224
  deleted file
@@ -226,8 +226,8 @@ deleted file
226
226
  +++ /dev/null DATE
227
227
  @@ -1 +0,0 @@
228
228
  -a_only_file
229
- ','File b/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
230
- ','File a/file_in_a_dir_in_b is a regular file while file a/file_in_a_dir_in_b is a directory
229
+ ','File a/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
230
+ ','File a/file_in_a_dir_in_b is a regular file while file b/file_in_a_dir_in_b is a directory
231
231
  ','Only in b: b_only_dir
232
232
  ','diff --knife a/b_only_file b/b_only_file
233
233
  new file
@@ -237,22 +237,22 @@ new file
237
237
  +b_only_file
238
238
  ' ]
239
239
  end
240
- it 'ChefFS::CommandLine.diff(/*_*) with depth 0' do
240
+ it 'ChefFS::CommandLine.diff_print(/*_*) with depth 0' do
241
241
  results = []
242
- ChefFS::CommandLine.diff(pattern('/*_*'), a, b, 0, nil) do |diff|
242
+ ChefFS::CommandLine.diff_print(pattern('/*_*'), a, b, 0, nil) do |diff|
243
243
  results << remove_date(diff)
244
244
  end
245
245
  results.should =~ [
246
- 'Common subdirectories: /both_dirs
246
+ 'Common subdirectories: b/both_dirs
247
247
  ','diff --knife a/both_files_different b/both_files_different
248
248
  --- a/both_files_different DATE
249
249
  +++ b/both_files_different DATE
250
250
  @@ -1 +1 @@
251
251
  -a
252
252
  +b
253
- ','Common subdirectories: /both_dirs_empty
254
- ','Common subdirectories: /dirs_empty_in_b_filled_in_a
255
- ','Common subdirectories: /dirs_empty_in_a_filled_in_b
253
+ ','Common subdirectories: b/both_dirs_empty
254
+ ','Common subdirectories: b/dirs_empty_in_b_filled_in_a
255
+ ','Common subdirectories: b/dirs_empty_in_a_filled_in_b
256
256
  ','Only in a: a_only_dir
257
257
  ','diff --knife a/a_only_file b/a_only_file
258
258
  deleted file
@@ -260,8 +260,8 @@ deleted file
260
260
  +++ /dev/null DATE
261
261
  @@ -1 +0,0 @@
262
262
  -a_only_file
263
- ','File b/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
264
- ','File a/file_in_a_dir_in_b is a regular file while file a/file_in_a_dir_in_b is a directory
263
+ ','File a/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
264
+ ','File a/file_in_a_dir_in_b is a regular file while file b/file_in_a_dir_in_b is a directory
265
265
  ','Only in b: b_only_dir
266
266
  ','diff --knife a/b_only_file b/b_only_file
267
267
  new file
@@ -271,9 +271,9 @@ new file
271
271
  +b_only_file
272
272
  ' ]
273
273
  end
274
- it 'ChefFS::CommandLine.diff(/) in name-only mode' do
274
+ it 'ChefFS::CommandLine.diff_print(/) in name-only mode' do
275
275
  results = []
276
- ChefFS::CommandLine.diff(pattern('/'), a, b, nil, :name_only) do |diff|
276
+ ChefFS::CommandLine.diff_print(pattern('/'), a, b, nil, :name_only) do |diff|
277
277
  results << remove_date(diff)
278
278
  end
279
279
  results.should =~ [
@@ -297,9 +297,9 @@ new file
297
297
  "b/file_in_a_dir_in_b\n"
298
298
  ]
299
299
  end
300
- it 'ChefFS::CommandLine.diff(/) in name-status mode' do
300
+ it 'ChefFS::CommandLine.diff_print(/) in name-status mode' do
301
301
  results = []
302
- ChefFS::CommandLine.diff(pattern('/'), a, b, nil, :name_status) do |diff|
302
+ ChefFS::CommandLine.diff_print(pattern('/'), a, b, nil, :name_status) do |diff|
303
303
  results << remove_date(diff)
304
304
  end
305
305
  results.should =~ [
@@ -274,7 +274,11 @@ describe ChefFS::FileSystem::CookbooksDir do
274
274
  it 'all files can be read' do
275
275
  should_get_cookbook
276
276
  files.each do |path|
277
- @rest.should_receive(:get_rest).with("cookbook_file:#{path}").once.and_return("This is #{path}'s content")
277
+ cookbook_file = double(path)
278
+ cookbook_file.should_receive(:open).with(no_args()).once
279
+ cookbook_file.should_receive(:read).with(no_args()).once.and_return("This is #{path}'s content")
280
+ cookbook_file.should_receive(:close!).with(no_args()).once
281
+ @rest.should_receive(:get_rest).with("cookbook_file:#{path}", true).once.and_return(cookbook_file)
278
282
  @rest.should_receive(:sign_on_redirect).with(no_args()).once.and_return(true)
279
283
  @rest.should_receive(:sign_on_redirect=).with(false).once
280
284
  @rest.should_receive(:sign_on_redirect=).with(true).once
@@ -0,0 +1,705 @@
1
+ require 'support/integration_helper'
2
+ require 'chef/knife/list_essentials'
3
+ require 'chef/knife/show_essentials'
4
+
5
+ describe 'chef_repo_path tests' do
6
+ extend IntegrationSupport
7
+ include KnifeSupport
8
+
9
+ # TODO alternate repo_path / *_path
10
+ context 'alternate *_path' do
11
+ when_the_repository 'has clients and clients2, cookbooks and cookbooks2, etc.' do
12
+ file 'clients/client1.json', {}
13
+ file 'cookbooks/cookbook1/metadata.rb', ''
14
+ file 'data_bags/bag/item.json', {}
15
+ file 'environments/env1.json', {}
16
+ file 'nodes/node1.json', {}
17
+ file 'roles/role1.json', {}
18
+ file 'users/user1.json', {}
19
+
20
+ file 'clients2/client1.json', {}
21
+ file 'cookbooks2/cookbook2/metadata.rb', ''
22
+ file 'data_bags2/bag2/item2.json', {}
23
+ file 'environments2/env2.json', {}
24
+ file 'nodes2/node2.json', {}
25
+ file 'roles2/role2.json', {}
26
+ file 'users2/user2.json', {}
27
+
28
+ directory 'chef_repo2' do
29
+ file 'clients/client3.json', {}
30
+ file 'cookbooks/cookbook3/metadata.rb', ''
31
+ file 'data_bags/bag3/item3.json', {}
32
+ file 'environments/env3.json', {}
33
+ file 'nodes/node3.json', {}
34
+ file 'roles/role3.json', {}
35
+ file 'users/user3.json', {}
36
+ end
37
+
38
+ context 'when all _paths are set to alternates' do
39
+ before :each do
40
+ %w(client cookbook data_bag environment node role user).each do |object_name|
41
+ Chef::Config["#{object_name}_path".to_sym] = File.join(Chef::Config.chef_repo_path, "#{object_name}s2")
42
+ end
43
+ Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2')
44
+ end
45
+
46
+ context 'when cwd is at the top level' do
47
+ cwd '.'
48
+ it 'knife list --local -Rfp fails' do
49
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
50
+ end
51
+ end
52
+
53
+ context 'when cwd is inside the data_bags directory' do
54
+ cwd 'data_bags'
55
+ it 'knife list --local -Rfp fails' do
56
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
57
+ end
58
+ end
59
+
60
+ context 'when cwd is inside chef_repo2' do
61
+ cwd 'chef_repo2'
62
+ it 'knife list --local -Rfp lists everything' do
63
+ knife('list --local -Rfp').should_succeed <<EOM
64
+ cookbooks/
65
+ cookbooks/cookbook2/
66
+ cookbooks/cookbook2/metadata.rb
67
+ data_bags/
68
+ data_bags/bag2/
69
+ data_bags/bag2/item2.json
70
+ environments/
71
+ environments/env2.json
72
+ roles/
73
+ roles/role2.json
74
+ EOM
75
+ end
76
+ end
77
+
78
+ context 'when cwd is inside data_bags2' do
79
+ cwd 'data_bags2'
80
+ it 'knife list --local -Rfp lists data bags' do
81
+ knife('list --local -Rfp').should_succeed <<EOM
82
+ bag2/
83
+ bag2/item2.json
84
+ EOM
85
+ end
86
+ it 'knife list --local -Rfp ../roles lists roles' do
87
+ knife('list --local -Rfp ../roles').should_succeed "/roles/role2.json\n"
88
+ end
89
+ end
90
+ end
91
+
92
+ context 'when all _paths except chef_repo_path are set to alternates' do
93
+ before :each do
94
+ %w(client cookbook data_bag environment node role user).each do |object_name|
95
+ Chef::Config["#{object_name}_path".to_sym] = File.join(Chef::Config.chef_repo_path, "#{object_name}s2")
96
+ end
97
+ end
98
+
99
+ context 'when cwd is at the top level' do
100
+ cwd '.'
101
+ it 'knife list --local -Rfp lists everything' do
102
+ knife('list --local -Rfp').should_succeed <<EOM
103
+ cookbooks/
104
+ cookbooks/cookbook2/
105
+ cookbooks/cookbook2/metadata.rb
106
+ data_bags/
107
+ data_bags/bag2/
108
+ data_bags/bag2/item2.json
109
+ environments/
110
+ environments/env2.json
111
+ roles/
112
+ roles/role2.json
113
+ EOM
114
+ end
115
+ end
116
+
117
+ context 'when cwd is inside the data_bags directory' do
118
+ cwd 'data_bags'
119
+ it 'knife list --local -Rfp fails' do
120
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
121
+ end
122
+ end
123
+
124
+ context 'when cwd is inside chef_repo2' do
125
+ cwd 'chef_repo2'
126
+ it 'knife list -Rfp fails' do
127
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
128
+ end
129
+ end
130
+
131
+ context 'when cwd is inside data_bags2' do
132
+ cwd 'data_bags2'
133
+ it 'knife list --local -Rfp lists data bags' do
134
+ knife('list --local -Rfp').should_succeed <<EOM
135
+ bag2/
136
+ bag2/item2.json
137
+ EOM
138
+ end
139
+ end
140
+ end
141
+
142
+ context 'when only chef_repo_path is set to its alternate' do
143
+ before :each do
144
+ %w(client cookbook data_bag environment node role user).each do |object_name|
145
+ Chef::Config["#{object_name}_path".to_sym] = nil
146
+ end
147
+ Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2')
148
+ end
149
+
150
+ context 'when cwd is at the top level' do
151
+ cwd '.'
152
+ it 'knife list --local -Rfp fails' do
153
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
154
+ end
155
+ end
156
+
157
+ context 'when cwd is inside the data_bags directory' do
158
+ cwd 'data_bags'
159
+ it 'knife list --local -Rfp fails' do
160
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
161
+ end
162
+ end
163
+
164
+ context 'when cwd is inside chef_repo2' do
165
+ cwd 'chef_repo2'
166
+ it 'knife list --local -Rfp lists everything' do
167
+ knife('list --local -Rfp').should_succeed <<EOM
168
+ cookbooks/
169
+ cookbooks/cookbook3/
170
+ cookbooks/cookbook3/metadata.rb
171
+ data_bags/
172
+ data_bags/bag3/
173
+ data_bags/bag3/item3.json
174
+ environments/
175
+ environments/env3.json
176
+ roles/
177
+ roles/role3.json
178
+ EOM
179
+ end
180
+ end
181
+
182
+ context 'when cwd is inside chef_repo2/data_bags' do
183
+ cwd 'chef_repo2/data_bags'
184
+ it 'knife list --local -Rfp lists data bags' do
185
+ knife('list --local -Rfp').should_succeed <<EOM
186
+ bag3/
187
+ bag3/item3.json
188
+ EOM
189
+ end
190
+ end
191
+ end
192
+
193
+ context 'when paths are set to point to both versions of each' do
194
+ before :each do
195
+ %w(client cookbook data_bag environment node role user).each do |object_name|
196
+ Chef::Config["#{object_name}_path".to_sym] = [
197
+ File.join(Chef::Config.chef_repo_path, "#{object_name}s"),
198
+ File.join(Chef::Config.chef_repo_path, "#{object_name}s2")
199
+ ]
200
+ end
201
+ Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2')
202
+ end
203
+
204
+ context 'when there is a directory in clients1 and file in clients2 with the same name' do
205
+ directory 'clients/blah.json'
206
+ file 'clients2/blah.json', {}
207
+ it 'knife show /clients/blah.json succeeds' do
208
+ pending "don't count directories in clients" do
209
+ knife('show --local /clients/blah.json').should_succeed ''
210
+ end
211
+ end
212
+ end
213
+
214
+ context 'when there is a file in cookbooks1 and directory in cookbooks2 with the same name' do
215
+ file 'cookbooks/blah', ''
216
+ file 'cookbooks2/blah/metadata.rb', ''
217
+ it 'knife list -Rfp cookbooks shows files in blah' do
218
+ knife('list --local -Rfp /cookbooks').should_succeed <<EOM
219
+ /cookbooks/blah/
220
+ /cookbooks/blah/metadata.rb
221
+ /cookbooks/cookbook1/
222
+ /cookbooks/cookbook1/metadata.rb
223
+ /cookbooks/cookbook2/
224
+ /cookbooks/cookbook2/metadata.rb
225
+ EOM
226
+ end
227
+ end
228
+
229
+ context 'when there is an empty directory in cookbooks1 and a real cookbook in cookbooks2 with the same name' do
230
+ directory 'cookbooks/blah'
231
+ file 'cookbooks2/blah/metadata.rb', ''
232
+ it 'knife list -Rfp cookbooks shows files in blah' do
233
+ knife('list --local -Rfp /cookbooks').should_succeed(<<EOM, :stderr => "WARN: Cookbook 'blah' is empty or entirely chefignored at #{Chef::Config.cookbook_path[0]}/blah\n")
234
+ /cookbooks/blah/
235
+ /cookbooks/blah/metadata.rb
236
+ /cookbooks/cookbook1/
237
+ /cookbooks/cookbook1/metadata.rb
238
+ /cookbooks/cookbook2/
239
+ /cookbooks/cookbook2/metadata.rb
240
+ EOM
241
+ end
242
+ end
243
+
244
+ context 'when there is a cookbook in cookbooks1 and a cookbook in cookbooks2 with the same name' do
245
+ file 'cookbooks/blah/metadata.json', {}
246
+ file 'cookbooks2/blah/metadata.rb', ''
247
+ it 'knife list -Rfp cookbooks shows files in the first cookbook and not the second' do
248
+ knife('list --local -Rfp /cookbooks').should_succeed(<<EOM, :stderr => "WARN: Child with name 'blah' found in multiple directories: #{Chef::Config.cookbook_path[0]}/blah and #{Chef::Config.cookbook_path[1]}/blah\n")
249
+ /cookbooks/blah/
250
+ /cookbooks/blah/metadata.json
251
+ /cookbooks/cookbook1/
252
+ /cookbooks/cookbook1/metadata.rb
253
+ /cookbooks/cookbook2/
254
+ /cookbooks/cookbook2/metadata.rb
255
+ EOM
256
+ end
257
+ end
258
+
259
+ context 'when there is a file in data_bags1 and a directory in data_bags2 with the same name' do
260
+ file 'data_bags/blah', ''
261
+ file 'data_bags2/blah/item.json', ''
262
+ it 'knife list -Rfp data_bags shows files in blah' do
263
+ pending "Don't count files as data bags" do
264
+ knife('list --local -Rfp /data_bags').should_succeed <<EOM
265
+ /data_bags/bag/
266
+ /data_bags/bag/item.json
267
+ /data_bags/bag2/
268
+ /data_bags/bag2/item2.json
269
+ /data_bags/blah/
270
+ /data_bags/blah/item1.json
271
+ EOM
272
+ end
273
+ end
274
+ end
275
+
276
+ context 'when there is a data bag in data_bags1 and a data bag in data_bags2 with the same name' do
277
+ file 'data_bags/blah/item1.json', ''
278
+ file 'data_bags2/blah/item2.json', ''
279
+ it 'knife list -Rfp data_bags shows only items in data_bags1' do
280
+ knife('list --local -Rfp /data_bags').should_succeed(<<EOM, :stderr => "WARN: Child with name 'blah' found in multiple directories: #{Chef::Config.data_bag_path[0]}/blah and #{Chef::Config.data_bag_path[1]}/blah\n")
281
+ /data_bags/bag/
282
+ /data_bags/bag/item.json
283
+ /data_bags/bag2/
284
+ /data_bags/bag2/item2.json
285
+ /data_bags/blah/
286
+ /data_bags/blah/item1.json
287
+ EOM
288
+ end
289
+ end
290
+
291
+ context 'when there is a directory in environments1 and file in environments2 with the same name' do
292
+ directory 'environments/blah.json'
293
+ file 'environments2/blah.json', {}
294
+ it 'knife show /environments/blah.json succeeds' do
295
+ pending "don't count directories in environments" do
296
+ knife('show --local /environments/blah.json').should_succeed ''
297
+ end
298
+ end
299
+ end
300
+
301
+ context 'when there is a directory in nodes1 and file in nodes2 with the same name' do
302
+ directory 'nodes/blah.json'
303
+ file 'nodes2/blah.json', {}
304
+ it 'knife show /nodes/blah.json succeeds' do
305
+ pending "don't count directories in nodes" do
306
+ knife('show --local /nodes/blah.json').should_succeed ''
307
+ end
308
+ end
309
+ end
310
+
311
+ context 'when there is a directory in roles1 and file in roles2 with the same name' do
312
+ directory 'roles/blah.json'
313
+ file 'roles2/blah.json', {}
314
+ it 'knife show /roles/blah.json succeeds' do
315
+ pending "don't count directories in roles" do
316
+ knife('show --local /roles/blah.json').should_succeed ''
317
+ end
318
+ end
319
+ end
320
+
321
+ context 'when there is a directory in users1 and file in users2 with the same name' do
322
+ directory 'users/blah.json'
323
+ file 'users2/blah.json', {}
324
+ it 'knife show /users/blah.json succeeds' do
325
+ pending "don't count directories in users" do
326
+ knife('show --local /users/blah.json').should_succeed ''
327
+ end
328
+ end
329
+ end
330
+
331
+ context 'when cwd is at the top level' do
332
+ cwd '.'
333
+ it 'knife list --local -Rfp fails' do
334
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
335
+ end
336
+ end
337
+
338
+ context 'when cwd is inside the data_bags directory' do
339
+ cwd 'data_bags'
340
+ it 'knife list --local -Rfp lists data bags' do
341
+ knife('list --local -Rfp').should_succeed <<EOM
342
+ bag/
343
+ bag/item.json
344
+ bag2/
345
+ bag2/item2.json
346
+ EOM
347
+ end
348
+ end
349
+
350
+ context 'when cwd is inside chef_repo2' do
351
+ cwd 'chef_repo2'
352
+ it 'knife list --local -Rfp lists everything' do
353
+ knife('list --local -Rfp').should_succeed <<EOM
354
+ cookbooks/
355
+ cookbooks/cookbook1/
356
+ cookbooks/cookbook1/metadata.rb
357
+ cookbooks/cookbook2/
358
+ cookbooks/cookbook2/metadata.rb
359
+ data_bags/
360
+ data_bags/bag/
361
+ data_bags/bag/item.json
362
+ data_bags/bag2/
363
+ data_bags/bag2/item2.json
364
+ environments/
365
+ environments/env1.json
366
+ environments/env2.json
367
+ roles/
368
+ roles/role1.json
369
+ roles/role2.json
370
+ EOM
371
+ end
372
+ end
373
+
374
+ context 'when cwd is inside data_bags2' do
375
+ cwd 'data_bags2'
376
+ it 'knife list --local -Rfp lists data bags' do
377
+ knife('list --local -Rfp').should_succeed <<EOM
378
+ bag/
379
+ bag/item.json
380
+ bag2/
381
+ bag2/item2.json
382
+ EOM
383
+ end
384
+ end
385
+ end
386
+
387
+ context 'when when chef_repo_path is set to both places and no other _path is set' do
388
+ before :each do
389
+ %w(client cookbook data_bag environment node role user).each do |object_name|
390
+ Chef::Config["#{object_name}_path".to_sym] = nil
391
+ end
392
+ Chef::Config.chef_repo_path = [
393
+ Chef::Config.chef_repo_path,
394
+ File.join(Chef::Config.chef_repo_path, 'chef_repo2')
395
+ ]
396
+ end
397
+
398
+ context 'when cwd is at the top level' do
399
+ cwd '.'
400
+ it 'knife list --local -Rfp lists everything' do
401
+ knife('list --local -Rfp').should_succeed <<EOM
402
+ cookbooks/
403
+ cookbooks/cookbook1/
404
+ cookbooks/cookbook1/metadata.rb
405
+ cookbooks/cookbook3/
406
+ cookbooks/cookbook3/metadata.rb
407
+ data_bags/
408
+ data_bags/bag/
409
+ data_bags/bag/item.json
410
+ data_bags/bag3/
411
+ data_bags/bag3/item3.json
412
+ environments/
413
+ environments/env1.json
414
+ environments/env3.json
415
+ roles/
416
+ roles/role1.json
417
+ roles/role3.json
418
+ EOM
419
+ end
420
+ end
421
+
422
+ context 'when cwd is inside the data_bags directory' do
423
+ cwd 'data_bags'
424
+ it 'knife list --local -Rfp lists data bags' do
425
+ knife('list --local -Rfp').should_succeed <<EOM
426
+ bag/
427
+ bag/item.json
428
+ bag3/
429
+ bag3/item3.json
430
+ EOM
431
+ end
432
+ end
433
+
434
+ context 'when cwd is inside chef_repo2' do
435
+ cwd 'chef_repo2'
436
+ it 'knife list --local -Rfp lists everything' do
437
+ knife('list --local -Rfp').should_succeed <<EOM
438
+ cookbooks/
439
+ cookbooks/cookbook1/
440
+ cookbooks/cookbook1/metadata.rb
441
+ cookbooks/cookbook3/
442
+ cookbooks/cookbook3/metadata.rb
443
+ data_bags/
444
+ data_bags/bag/
445
+ data_bags/bag/item.json
446
+ data_bags/bag3/
447
+ data_bags/bag3/item3.json
448
+ environments/
449
+ environments/env1.json
450
+ environments/env3.json
451
+ roles/
452
+ roles/role1.json
453
+ roles/role3.json
454
+ EOM
455
+ end
456
+ end
457
+
458
+ context 'when cwd is inside chef_repo2/data_bags' do
459
+ cwd 'chef_repo2/data_bags'
460
+ it 'knife list --local -Rfp lists data bags' do
461
+ knife('list --local -Rfp').should_succeed <<EOM
462
+ bag/
463
+ bag/item.json
464
+ bag3/
465
+ bag3/item3.json
466
+ EOM
467
+ end
468
+ end
469
+ end
470
+
471
+ context 'when cookbook_path is set and nothing else' do
472
+ before :each do
473
+ %w(client data_bag environment node role user).each do |object_name|
474
+ Chef::Config["#{object_name}_path".to_sym] = nil
475
+ end
476
+ Chef::Config.cookbook_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2', 'cookbooks')
477
+ Chef::Config.chef_repo_path = nil
478
+ end
479
+
480
+ context 'when cwd is at the top level' do
481
+ cwd '.'
482
+ it 'knife list --local -Rfp fails' do
483
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
484
+ end
485
+ end
486
+
487
+ context 'when cwd is inside the data_bags directory' do
488
+ cwd 'data_bags'
489
+ it 'knife list --local -Rfp fails' do
490
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
491
+ end
492
+ end
493
+
494
+ context 'when cwd is inside chef_repo2' do
495
+ cwd 'chef_repo2'
496
+ it 'knife list --local -Rfp lists everything' do
497
+ knife('list --local -Rfp').should_succeed <<EOM
498
+ cookbooks/
499
+ cookbooks/cookbook3/
500
+ cookbooks/cookbook3/metadata.rb
501
+ data_bags/
502
+ data_bags/bag3/
503
+ data_bags/bag3/item3.json
504
+ environments/
505
+ environments/env3.json
506
+ roles/
507
+ roles/role3.json
508
+ EOM
509
+ end
510
+ end
511
+
512
+ context 'when cwd is inside chef_repo2/data_bags' do
513
+ cwd 'chef_repo2/data_bags'
514
+ it 'knife list --local -Rfp lists data bags' do
515
+ knife('list --local -Rfp').should_succeed <<EOM
516
+ bag3/
517
+ bag3/item3.json
518
+ EOM
519
+ end
520
+ end
521
+ end
522
+
523
+ context 'when cookbook_path is set to multiple places and nothing else is set' do
524
+ before :each do
525
+ %w(client data_bag environment node role user).each do |object_name|
526
+ Chef::Config["#{object_name}_path".to_sym] = nil
527
+ end
528
+ Chef::Config.cookbook_path = [
529
+ File.join(Chef::Config.chef_repo_path, 'cookbooks'),
530
+ File.join(Chef::Config.chef_repo_path, 'chef_repo2', 'cookbooks')
531
+ ]
532
+ Chef::Config.chef_repo_path = nil
533
+ end
534
+
535
+ context 'when cwd is at the top level' do
536
+ cwd '.'
537
+ it 'knife list --local -Rfp lists everything' do
538
+ knife('list --local -Rfp').should_succeed <<EOM
539
+ cookbooks/
540
+ cookbooks/cookbook1/
541
+ cookbooks/cookbook1/metadata.rb
542
+ cookbooks/cookbook3/
543
+ cookbooks/cookbook3/metadata.rb
544
+ data_bags/
545
+ data_bags/bag/
546
+ data_bags/bag/item.json
547
+ data_bags/bag3/
548
+ data_bags/bag3/item3.json
549
+ environments/
550
+ environments/env1.json
551
+ environments/env3.json
552
+ roles/
553
+ roles/role1.json
554
+ roles/role3.json
555
+ EOM
556
+ end
557
+ end
558
+
559
+ context 'when cwd is inside the data_bags directory' do
560
+ cwd 'data_bags'
561
+ it 'knife list --local -Rfp lists data bags' do
562
+ knife('list --local -Rfp').should_succeed <<EOM
563
+ bag/
564
+ bag/item.json
565
+ bag3/
566
+ bag3/item3.json
567
+ EOM
568
+ end
569
+ end
570
+
571
+ context 'when cwd is inside chef_repo2' do
572
+ cwd 'chef_repo2'
573
+ it 'knife list --local -Rfp lists everything' do
574
+ knife('list --local -Rfp').should_succeed <<EOM
575
+ cookbooks/
576
+ cookbooks/cookbook1/
577
+ cookbooks/cookbook1/metadata.rb
578
+ cookbooks/cookbook3/
579
+ cookbooks/cookbook3/metadata.rb
580
+ data_bags/
581
+ data_bags/bag/
582
+ data_bags/bag/item.json
583
+ data_bags/bag3/
584
+ data_bags/bag3/item3.json
585
+ environments/
586
+ environments/env1.json
587
+ environments/env3.json
588
+ roles/
589
+ roles/role1.json
590
+ roles/role3.json
591
+ EOM
592
+ end
593
+ end
594
+
595
+ context 'when cwd is inside chef_repo2/data_bags' do
596
+ cwd 'chef_repo2/data_bags'
597
+ it 'knife list --local -Rfp lists data bags' do
598
+ knife('list --local -Rfp').should_succeed <<EOM
599
+ bag/
600
+ bag/item.json
601
+ bag3/
602
+ bag3/item3.json
603
+ EOM
604
+ end
605
+ end
606
+ end
607
+
608
+ context 'when data_bag_path and chef_repo_path are set, and nothing else' do
609
+ before :each do
610
+ %w(client cookbook environment node role user).each do |object_name|
611
+ Chef::Config["#{object_name}_path".to_sym] = nil
612
+ end
613
+ Chef::Config.data_bag_path = File.join(Chef::Config.chef_repo_path, 'data_bags')
614
+ Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'chef_repo2')
615
+ end
616
+
617
+ context 'when cwd is at the top level' do
618
+ cwd '.'
619
+ it 'knife list --local -Rfp fails' do
620
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
621
+ end
622
+ end
623
+
624
+ context 'when cwd is inside the data_bags directory' do
625
+ cwd 'data_bags'
626
+ it 'knife list --local -Rfp lists data bags' do
627
+ knife('list --local -Rfp').should_succeed <<EOM
628
+ bag/
629
+ bag/item.json
630
+ EOM
631
+ end
632
+ end
633
+
634
+ context 'when cwd is inside chef_repo2' do
635
+ cwd 'chef_repo2'
636
+ it 'knife list --local -Rfp lists everything' do
637
+ knife('list --local -Rfp').should_succeed <<EOM
638
+ cookbooks/
639
+ cookbooks/cookbook3/
640
+ cookbooks/cookbook3/metadata.rb
641
+ data_bags/
642
+ data_bags/bag/
643
+ data_bags/bag/item.json
644
+ environments/
645
+ environments/env3.json
646
+ roles/
647
+ roles/role3.json
648
+ EOM
649
+ end
650
+ end
651
+
652
+ context 'when cwd is inside chef_repo2/data_bags' do
653
+ cwd 'chef_repo2/data_bags'
654
+ it 'knife list --local -Rfp fails' do
655
+ knife('list --local -Rfp').should_fail("ERROR: Attempt to use relative path '' when current directory is outside the repository path\n")
656
+ end
657
+ end
658
+ end
659
+
660
+ context 'when data_bag_path is set and nothing else' do
661
+ before :each do
662
+ %w(client cookbook environment node role user).each do |object_name|
663
+ Chef::Config["#{object_name}_path".to_sym] = nil
664
+ end
665
+ Chef::Config.data_bag_path = File.join(Chef::Config.chef_repo_path, 'data_bags')
666
+ Chef::Config.chef_repo_path = nil
667
+ end
668
+
669
+ it 'knife list --local -Rfp / fails' do
670
+ knife('list --local -Rfp /').should_fail("ERROR: Must specify either chef_repo_path or cookbook_path in Chef config file\n")
671
+ end
672
+
673
+ it 'knife list --local -Rfp /data_bags fails' do
674
+ knife('list --local -Rfp /data_bags').should_fail("ERROR: Must specify either chef_repo_path or cookbook_path in Chef config file\n")
675
+ end
676
+
677
+ context 'when cwd is inside the data_bags directory' do
678
+ cwd 'data_bags'
679
+ it 'knife list --local -Rfp fails' do
680
+ knife('list --local -Rfp').should_fail("ERROR: Must specify either chef_repo_path or cookbook_path in Chef config file\n")
681
+ end
682
+ end
683
+ end
684
+ end
685
+
686
+ when_the_repository 'is empty' do
687
+ context 'when the repository _paths point to places that do not exist' do
688
+ before :each do
689
+ %w(client cookbook data_bag environment node role user).each do |object_name|
690
+ Chef::Config["#{object_name}_path".to_sym] = File.join(Chef::Config.chef_repo_path, 'nowhere', object_name)
691
+ end
692
+ Chef::Config.chef_repo_path = File.join(Chef::Config.chef_repo_path, 'nowhere')
693
+ end
694
+
695
+ it 'knife list --local -Rfp / fails' do
696
+ knife('list --local -Rfp /').should_succeed ''
697
+ end
698
+
699
+ it 'knife list --local -Rfp /data_bags fails' do
700
+ knife('list --local -Rfp /data_bags').should_fail("ERROR: /data_bags: No such file or directory\n")
701
+ end
702
+ end
703
+ end
704
+ end
705
+ end