chef-dk 0.3.0 → 0.3.5

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -0
  3. data/lib/chef-dk/cli.rb +7 -5
  4. data/lib/chef-dk/command/generate.rb +2 -0
  5. data/lib/chef-dk/command/generator_commands.rb +8 -0
  6. data/lib/chef-dk/command/generator_commands/base.rb +4 -1
  7. data/lib/chef-dk/command/generator_commands/policyfile.rb +83 -0
  8. data/lib/chef-dk/command/install.rb +4 -5
  9. data/lib/chef-dk/command/push.rb +4 -5
  10. data/lib/chef-dk/command/verify.rb +3 -2
  11. data/lib/chef-dk/component_test.rb +7 -2
  12. data/lib/chef-dk/exceptions.rb +3 -34
  13. data/lib/chef-dk/helpers.rb +20 -2
  14. data/lib/chef-dk/policyfile/cookbook_locks.rb +19 -1
  15. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +11 -1
  16. data/lib/chef-dk/policyfile/storage_config.rb +23 -0
  17. data/lib/chef-dk/policyfile/uploader.rb +1 -1
  18. data/lib/chef-dk/policyfile_services/install.rb +19 -32
  19. data/lib/chef-dk/policyfile_services/push.rb +17 -27
  20. data/lib/chef-dk/service_exception_inspectors.rb +25 -0
  21. data/lib/chef-dk/service_exception_inspectors/base.rb +40 -0
  22. data/lib/chef-dk/service_exception_inspectors/http.rb +121 -0
  23. data/lib/chef-dk/service_exceptions.rb +77 -0
  24. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -0
  25. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +16 -0
  26. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +1 -1
  27. data/lib/chef-dk/version.rb +1 -1
  28. data/spec/unit/cli_spec.rb +126 -65
  29. data/spec/unit/command/exec_spec.rb +7 -2
  30. data/spec/unit/command/generator_commands/cookbook_spec.rb +27 -1
  31. data/spec/unit/command/generator_commands/policyfile_spec.rb +125 -0
  32. data/spec/unit/command/install_spec.rb +3 -4
  33. data/spec/unit/command/push_spec.rb +6 -7
  34. data/spec/unit/command/shell_init_spec.rb +5 -1
  35. data/spec/unit/cookbook_profiler/git_spec.rb +2 -2
  36. data/spec/unit/policyfile/cookbook_locks_spec.rb +58 -0
  37. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +8 -1
  38. data/spec/unit/policyfile/storage_config_spec.rb +75 -1
  39. data/spec/unit/policyfile/uploader_spec.rb +31 -0
  40. data/spec/unit/policyfile_lock_validation_spec.rb +13 -12
  41. data/spec/unit/policyfile_services/install_spec.rb +5 -3
  42. data/spec/unit/policyfile_services/push_spec.rb +7 -5
  43. data/spec/unit/service_exception_inspectors/base_spec.rb +43 -0
  44. data/spec/unit/service_exception_inspectors/http_spec.rb +140 -0
  45. metadata +41 -2
@@ -0,0 +1,77 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ ##
19
+ # Exceptions for Service classes have more complex behaviors and more
20
+ # dependencies, so they are split into their own file here.
21
+ ##
22
+
23
+ require 'chef-dk/service_exception_inspectors'
24
+
25
+ module ChefDK
26
+
27
+ # Base class for errors raised by ChefDK::PolicyfileServices objects. Don't
28
+ # raise this directly, create a descriptively-named subclass. You can rescue
29
+ # this to catch all errors from PolicyfileServices objects though.
30
+ class PolicyfileServiceError < StandardError
31
+ end
32
+
33
+ class PolicyfileNotFound < PolicyfileServiceError
34
+ end
35
+
36
+ class LockfileNotFound < PolicyfileServiceError
37
+ end
38
+
39
+ class PolicyfileNestedException < PolicyfileServiceError
40
+
41
+ attr_reader :cause
42
+ attr_reader :inspector
43
+
44
+ def initialize(message, cause)
45
+ super(message)
46
+ @inspector = inspector_for(cause)
47
+ @cause = cause
48
+ end
49
+
50
+ def reason
51
+ "(#{cause.class.name}) #{inspector.message}"
52
+ end
53
+
54
+ def extended_error_info
55
+ inspector.extended_error_info
56
+ end
57
+
58
+ private
59
+
60
+ def inspector_for(exception)
61
+ if exception.respond_to?(:response)
62
+ ServiceExceptionInspectors::HTTP.new(exception)
63
+ else
64
+ ServiceExceptionInspectors::Base.new(exception)
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ class PolicyfileInstallError < PolicyfileNestedException
71
+ end
72
+
73
+ class PolicyfilePushError < PolicyfileNestedException
74
+ end
75
+
76
+ end
77
+
@@ -0,0 +1,8 @@
1
+
2
+ context = ChefDK::Generator.context
3
+ policyfile_path = File.join(context.policyfile_dir, "#{context.new_file_basename}.rb")
4
+
5
+ template policyfile_path do
6
+ source "Policyfile.rb.erb"
7
+ helpers(ChefDK::Generator::TemplateHelper)
8
+ end
@@ -0,0 +1,16 @@
1
+ # Policyfile.rb - Describe how you want Chef to build your system.
2
+ #
3
+ # For more information on the Policyfile feature, visit
4
+ # https://github.com/opscode/chef-dk/blob/master/POLICYFILE_README.md
5
+
6
+ # A name that describes what the system you're building with Chef does.
7
+ name "example_application"
8
+
9
+ # Where to find external cookbooks:
10
+ default_source :community
11
+
12
+ # run_list: chef-client will run these recipes in the order specified.
13
+ run_list "cookbook::recipe", "other_cookbook::recipe"
14
+
15
+ # Specify a custom source for a single cookbook:
16
+ # cookbook "development_cookbook", path: "../cookbooks/development_cookbook"
@@ -7,7 +7,7 @@ provisioner:
7
7
 
8
8
  platforms:
9
9
  - name: ubuntu-12.04
10
- - name: centos-6.4
10
+ - name: centos-6.5
11
11
 
12
12
  suites:
13
13
  - name: default
@@ -16,5 +16,5 @@
16
16
  #
17
17
 
18
18
  module ChefDK
19
- VERSION = "0.3.0"
19
+ VERSION = "0.3.5"
20
20
  end
@@ -166,85 +166,146 @@ E
166
166
  end
167
167
 
168
168
  context "sanity_check!" do
169
- context "on unix" do
170
- it "complains if embedded is first" do
171
- expect(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/embedded/bin:/opt/chefdk/bin' })
172
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
173
- allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
174
- run_cli_with_sanity_check(0)
175
- expect(stdout).not_to eq(base_help_message)
176
- expect(stdout).to include("please reverse that order")
177
- expect(stdout).to include("chef shell-init")
178
- end
179
169
 
180
- it "complains if only embedded is present" do
181
- expect(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/embedded/bin' })
182
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
183
- allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
184
- run_cli_with_sanity_check(0)
185
- expect(stdout).not_to eq(base_help_message)
186
- expect(stdout).to include("you must add")
187
- expect(stdout).to include("chef shell-init")
188
- end
170
+ before do
171
+ allow(Gem).to receive(:ruby).and_return(ruby_path)
172
+ allow(File).to receive(:exist?).with(chefdk_embedded_path).and_return(true)
173
+ allow(cli).to receive(:omnibus_chefdk_location).and_return(chefdk_embedded_path)
174
+ end
189
175
 
190
- it "passes when both are present in the correct order" do
191
- expect(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/bin:/opt/chefdk/embedded/bin' })
192
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
193
- allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
194
- run_cli_with_sanity_check(0)
195
- expect(stdout).to eq(base_help_message)
176
+ context "when installed via omnibus" do
177
+
178
+ context "on unix" do
179
+
180
+ let(:ruby_path) { '/opt/chefdk/embedded/bin/ruby' }
181
+ let(:chefdk_embedded_path) { '/opt/chefdk/embedded/apps/chef-dk' }
182
+
183
+ before do
184
+ stub_const("File::PATH_SEPARATOR", ':')
185
+ allow(Chef::Util::PathHelper).to receive(:cleanpath) do |path|
186
+ path
187
+ end
188
+ end
189
+
190
+ it "complains if embedded is first" do
191
+ allow(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/embedded/bin:/opt/chefdk/bin' })
192
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
193
+ allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
194
+ run_cli_with_sanity_check(0)
195
+ expect(stdout).to eq(base_help_message)
196
+ expect(stderr).to include("please reverse that order")
197
+ expect(stderr).to include("chef shell-init")
198
+ end
199
+
200
+ it "complains if only embedded is present" do
201
+ allow(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/embedded/bin' })
202
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
203
+ allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
204
+ run_cli_with_sanity_check(0)
205
+ expect(stdout).to eq(base_help_message)
206
+ expect(stderr).to include("you must add")
207
+ expect(stderr).to include("chef shell-init")
208
+ end
209
+
210
+ it "passes when both are present in the correct order" do
211
+ allow(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/bin:/opt/chefdk/embedded/bin' })
212
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
213
+ allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
214
+ run_cli_with_sanity_check(0)
215
+ expect(stdout).to eq(base_help_message)
216
+ end
217
+
218
+ it "passes when only the omnibus bin dir is present" do
219
+ allow(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/bin' })
220
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
221
+ allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
222
+ run_cli_with_sanity_check(0)
223
+ expect(stdout).to eq(base_help_message)
224
+ end
196
225
  end
197
226
 
198
- it "passes when only the omnibus bin dir is present" do
199
- expect(cli).to receive(:env).and_return({'PATH' => '/opt/chefdk/bin' })
200
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("/opt/chefdk/embedded/bin")
201
- allow(cli).to receive(:omnibus_bin_dir).and_return("/opt/chefdk/bin")
202
- run_cli_with_sanity_check(0)
203
- expect(stdout).to eq(base_help_message)
227
+ context "on windows" do
228
+
229
+ let(:ruby_path) { "c:/opscode/chefdk/embedded/bin/ruby.exe" }
230
+ let(:chefdk_embedded_path) { "c:/opscode/chefdk/embedded/apps/chef-dk" }
231
+
232
+ before do
233
+ # Would be preferable not to stub this, but `File.expand_path` does
234
+ # weird things with windows paths on unix machines.
235
+ #
236
+ # I manually verified the behavior:
237
+ #
238
+ # $ /c/opscode/chefdk/embedded/bin/ruby -e 'p File.expand_path(File.join(Gem.ruby, "..", "..", ".."))'
239
+ # "c:/opscode/chefdk"
240
+ allow(cli).to receive(:omnibus_chefdk_location).and_return(chefdk_embedded_path)
241
+
242
+ allow(Chef::Platform).to receive(:windows?).and_return(true)
243
+ stub_const("File::PATH_SEPARATOR", ';')
244
+ allow(Chef::Util::PathHelper).to receive(:cleanpath) do |path|
245
+ path.gsub "/", "\\"
246
+ end
247
+ end
248
+
249
+ it "complains if embedded is first" do
250
+ allow(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\embedded\bin;C:\opscode\chefdk\bin' })
251
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
252
+ allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
253
+ run_cli_with_sanity_check(0)
254
+ expect(stdout).to eq(base_help_message)
255
+ expect(stderr).to include("please reverse that order")
256
+ expect(stderr).to include("chef shell-init")
257
+ end
258
+
259
+ it "complains if only embedded is present" do
260
+ allow(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\embedded\bin' })
261
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
262
+ allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
263
+ run_cli_with_sanity_check(0)
264
+ expect(stdout).to eq(base_help_message)
265
+ expect(stderr).to include("you must add")
266
+ expect(stderr).to include("chef shell-init")
267
+ end
268
+
269
+ it "passes when both are present in the correct order" do
270
+ allow(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\bin;C:\opscode\chefdk\embedded\bin' })
271
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
272
+ allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
273
+ run_cli_with_sanity_check(0)
274
+ expect(stdout).to eq(base_help_message)
275
+ end
276
+
277
+ it "passes when only the omnibus bin dir is present" do
278
+ allow(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\bin' })
279
+ allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
280
+ allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
281
+ run_cli_with_sanity_check(0)
282
+ expect(stdout).to eq(base_help_message)
283
+ end
204
284
  end
205
285
  end
206
286
 
207
- context "on windows" do
208
- before do
209
- allow(Chef::Platform).to receive(:windows?).and_return(true)
210
- stub_const("File::PATH_SEPARATOR", ';')
211
- end
287
+ context "when not installed via omnibus" do
212
288
 
213
- it "complains if embedded is first" do
214
- expect(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\embedded\bin;C:\opscode\chefdk\bin' })
215
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
216
- allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
217
- run_cli_with_sanity_check(0)
218
- expect(stdout).not_to eq(base_help_message)
219
- expect(stdout).to include("please reverse that order")
220
- expect(stdout).to include("chef shell-init")
221
- end
289
+ let(:ruby_path) { '/Users/bog/.lots_o_rubies/2.1.2/bin/ruby' }
290
+ let(:chefdk_embedded_path) { '/Users/bog/.lots_o_rubies/embedded/apps/chef-dk' }
222
291
 
223
- it "complains if only embedded is present" do
224
- expect(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\embedded\bin' })
225
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
226
- allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
227
- run_cli_with_sanity_check(0)
228
- expect(stdout).not_to eq(base_help_message)
229
- expect(stdout).to include("you must add")
230
- expect(stdout).to include("chef shell-init")
292
+ before do
293
+ allow(File).to receive(:exist?).with(chefdk_embedded_path).and_return(false)
294
+
295
+ [
296
+ :omnibus_root,
297
+ :omnibus_apps_dir,
298
+ :omnibus_bin_dir,
299
+ :omnibus_embedded_bin_dir
300
+ ].each do |method_name|
301
+ allow(cli).to receive(method_name).and_raise(ChefDK::OmnibusInstallNotFound.new)
302
+ end
231
303
  end
232
304
 
233
- it "passes when both are present in the correct order" do
234
- expect(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\bin;C:\opscode\chefdk\embedded\bin' })
235
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
236
- allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
305
+ it "skips the sanity check without error" do
237
306
  run_cli_with_sanity_check(0)
238
- expect(stdout).to eq(base_help_message)
239
307
  end
240
308
 
241
- it "passes when only the omnibus bin dir is present" do
242
- expect(cli).to receive(:env).and_return({'PATH' => 'C:\opscode\chefdk\bin' })
243
- allow(cli).to receive(:omnibus_embedded_bin_dir).and_return("c:/opscode/chefdk/embedded/bin")
244
- allow(cli).to receive(:omnibus_bin_dir).and_return("c:/opscode/chefdk/bin")
245
- run_cli_with_sanity_check(0)
246
- expect(stdout).to eq(base_help_message)
247
- end
248
309
  end
249
310
  end
250
311
  end
@@ -58,6 +58,11 @@ describe ChefDK::Command::Exec do
58
58
 
59
59
  before do
60
60
  allow(Gem).to receive(:ruby).and_return(ruby_path)
61
+
62
+ # Using a fake path separator to keep to prevent people from accidently
63
+ # getting things correct on their system. This enforces that, in general,
64
+ # you should use the path separator ruby is telling you to use.
65
+ stub_const("File::PATH_SEPARATOR", '<>')
61
66
  end
62
67
 
63
68
  context "when running exec env" do
@@ -69,7 +74,7 @@ describe ChefDK::Command::Exec do
69
74
 
70
75
  let(:omnibus_bin_dir) { "/foo/bin" }
71
76
 
72
- let(:expected_PATH) { "#{omnibus_bin_dir}:#{user_bin_dir}:#{omnibus_embedded_bin_dir}:#{ENV['PATH']}" }
77
+ let(:expected_PATH) { [omnibus_bin_dir, user_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) }
73
78
 
74
79
  let(:expected_GEM_ROOT) { Gem.default_dir.inspect }
75
80
 
@@ -103,7 +108,7 @@ describe ChefDK::Command::Exec do
103
108
 
104
109
  let(:omnibus_embedded_bin_dir) { "/foo/embedded/bin" }
105
110
 
106
- let(:expected_PATH) { "#{omnibus_bin_dir}:#{user_bin_dir}:#{omnibus_embedded_bin_dir}:#{ENV['PATH']}" }
111
+ let(:expected_PATH) { [omnibus_bin_dir, user_bin_dir, omnibus_embedded_bin_dir, ENV['PATH']].join(File::PATH_SEPARATOR) }
107
112
 
108
113
  let(:expected_GEM_ROOT) { Gem.default_dir.inspect }
109
114
 
@@ -201,5 +201,31 @@ describe ChefDK::Command::GeneratorCommands::Cookbook do
201
201
  end
202
202
  end
203
203
 
204
- end
204
+ context "when given generic arguments to populate the generator context" do
205
+ let(:argv) { [ "new_cookbook", "--generator-arg", "key1=value1", "-a", "key2=value2", "-a", " key3 = value3 " ] }
206
+
207
+ before do
208
+ reset_tempdir
209
+ end
210
+
211
+ it "configures the generator context for long form option key1" do
212
+ cookbook_generator.read_and_validate_params
213
+ cookbook_generator.setup_context
214
+ expect(generator_context.key1).to eq('value1')
215
+ end
216
+
217
+ it "configures the generator context for short form option key2" do
218
+ cookbook_generator.read_and_validate_params
219
+ cookbook_generator.setup_context
220
+ expect(generator_context.key2).to eq('value2')
221
+ end
222
+
223
+ it "configures the generator context for key3 containing additional spaces" do
224
+ cookbook_generator.read_and_validate_params
225
+ cookbook_generator.setup_context
226
+ expect(generator_context.key3).to eq('value3')
227
+ end
205
228
 
229
+ end
230
+
231
+ end
@@ -0,0 +1,125 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'spec_helper'
19
+ require 'shared/a_file_generator'
20
+ require 'chef-dk/command/generator_commands/policyfile'
21
+
22
+ describe ChefDK::Command::GeneratorCommands::Policyfile do
23
+
24
+ let(:stdout_io) { StringIO.new }
25
+ let(:stderr_io) { StringIO.new }
26
+
27
+ def stdout
28
+ stdout_io.string
29
+ end
30
+
31
+ def stderr
32
+ stderr_io.string
33
+ end
34
+
35
+ subject(:generator) do
36
+ generator = described_class.new(argv)
37
+ allow(generator).to receive(:stdout).and_return(stdout_io)
38
+ allow(generator).to receive(:stderr).and_return(stderr_io)
39
+ generator
40
+ end
41
+
42
+ def generator_context
43
+ ChefDK::Generator.context
44
+ end
45
+
46
+ before do
47
+ allow(generator.chef_runner).to receive(:stdout).and_return(stdout_io)
48
+ ChefDK::Generator.reset
49
+ reset_tempdir
50
+ end
51
+
52
+ after(:each) do
53
+ ChefDK::Generator::Context.reset
54
+ end
55
+
56
+ shared_examples_for "it creates a Policyfile" do
57
+
58
+ it "configures the generator context" do
59
+ Dir.chdir(tempdir) do
60
+ generator.read_and_validate_params
61
+ generator.setup_context
62
+
63
+ expect(generator_context.policyfile_dir).to eq(tempdir)
64
+ expect(generator_context.new_file_basename).to eq(new_file_basename)
65
+ end
66
+ end
67
+
68
+ it "generates a Policyfile.rb in the CWD" do
69
+ Dir.chdir(tempdir) do
70
+ expect(generator.run).to eq(0)
71
+ expect(File).to exist(File.join(tempdir, expected_file_name))
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ context "when ARGV is empty" do
78
+
79
+ let(:argv) { [] }
80
+
81
+ let(:expected_file_name) { "Policyfile.rb" }
82
+ let(:new_file_basename) { "Policyfile" }
83
+
84
+ include_examples "it creates a Policyfile"
85
+
86
+ end
87
+
88
+ context "when ARGV is a relative path with no `.rb' extension" do
89
+
90
+ let(:argv) { ["MyPolicy"] }
91
+
92
+ let(:expected_file_name) { "MyPolicy.rb" }
93
+ let(:new_file_basename) { "MyPolicy" }
94
+
95
+ include_examples "it creates a Policyfile"
96
+
97
+ end
98
+
99
+ context "when ARGV is a relative path with a `.rb' extension" do
100
+
101
+ let(:argv) { ["MyApplication.rb"] }
102
+
103
+ let(:expected_file_name) { "MyApplication.rb" }
104
+ let(:new_file_basename) { "MyApplication" }
105
+
106
+ include_examples "it creates a Policyfile"
107
+
108
+ end
109
+
110
+ context "when ARGV has too many arguments" do
111
+
112
+ let(:argv) { %w{ foo bar baz } }
113
+
114
+ it "shows usage and exits" do
115
+ expected_stdout = "Usage: chef generate policyfile [NAME] [options]"
116
+
117
+ expect(generator.run).to eq(1)
118
+ expect(stdout).to include(expected_stdout)
119
+ end
120
+
121
+ end
122
+
123
+ end
124
+
125
+