chef-dk 0.2.0

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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +192 -0
  3. data/LICENSE +201 -0
  4. data/README.md +198 -0
  5. data/Rakefile +18 -0
  6. data/bin/chef +25 -0
  7. data/lib/chef-dk.rb +19 -0
  8. data/lib/chef-dk/builtin_commands.rb +31 -0
  9. data/lib/chef-dk/chef_runner.rb +83 -0
  10. data/lib/chef-dk/cli.rb +135 -0
  11. data/lib/chef-dk/command/base.rb +71 -0
  12. data/lib/chef-dk/command/exec.rb +33 -0
  13. data/lib/chef-dk/command/gem.rb +47 -0
  14. data/lib/chef-dk/command/generate.rb +97 -0
  15. data/lib/chef-dk/command/generator_commands.rb +417 -0
  16. data/lib/chef-dk/command/shell_init.rb +80 -0
  17. data/lib/chef-dk/command/verify.rb +226 -0
  18. data/lib/chef-dk/commands_map.rb +115 -0
  19. data/lib/chef-dk/component_test.rb +142 -0
  20. data/lib/chef-dk/cookbook_metadata.rb +36 -0
  21. data/lib/chef-dk/cookbook_omnifetch.rb +29 -0
  22. data/lib/chef-dk/cookbook_profiler/git.rb +95 -0
  23. data/lib/chef-dk/cookbook_profiler/identifiers.rb +79 -0
  24. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -0
  25. data/lib/chef-dk/exceptions.rb +46 -0
  26. data/lib/chef-dk/generator.rb +70 -0
  27. data/lib/chef-dk/helpers.rb +95 -0
  28. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +46 -0
  29. data/lib/chef-dk/policyfile/community_cookbook_source.rb +84 -0
  30. data/lib/chef-dk/policyfile/cookbook_sources.rb +20 -0
  31. data/lib/chef-dk/policyfile/cookbook_spec.rb +96 -0
  32. data/lib/chef-dk/policyfile/dsl.rb +148 -0
  33. data/lib/chef-dk/policyfile/null_cookbook_source.rb +37 -0
  34. data/lib/chef-dk/policyfile_compiler.rb +217 -0
  35. data/lib/chef-dk/policyfile_lock.rb +243 -0
  36. data/lib/chef-dk/shell_out.rb +36 -0
  37. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -0
  38. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +96 -0
  39. data/lib/chef-dk/skeletons/code_generator/files/default/converge_spec.rb +9 -0
  40. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -0
  41. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +8 -0
  42. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -0
  43. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +65 -0
  44. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -0
  45. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +50 -0
  46. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -0
  47. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -0
  48. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +9 -0
  49. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -0
  50. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -0
  51. data/lib/chef-dk/skeletons/code_generator/templates/default/attribute.rb.erb +0 -0
  52. data/lib/chef-dk/skeletons/code_generator/templates/default/cookbook_file.erb +0 -0
  53. data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +8 -0
  54. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +16 -0
  55. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +8 -0
  56. data/lib/chef-dk/skeletons/code_generator/templates/default/provider.rb.erb +0 -0
  57. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +0 -0
  58. data/lib/chef-dk/skeletons/code_generator/templates/default/resource.rb.erb +0 -0
  59. data/lib/chef-dk/skeletons/code_generator/templates/default/template.erb +0 -0
  60. data/lib/chef-dk/version.rb +20 -0
  61. data/spec/shared/setup_git_cookbooks.rb +53 -0
  62. data/spec/spec_helper.rb +32 -0
  63. data/spec/test_helpers.rb +59 -0
  64. data/spec/unit/chef_runner_spec.rb +70 -0
  65. data/spec/unit/cli_spec.rb +151 -0
  66. data/spec/unit/command/base_spec.rb +88 -0
  67. data/spec/unit/command/exec_spec.rb +123 -0
  68. data/spec/unit/command/generate_spec.rb +102 -0
  69. data/spec/unit/command/generator_commands_spec.rb +504 -0
  70. data/spec/unit/command/shell_init_spec.rb +109 -0
  71. data/spec/unit/command/verify_spec.rb +311 -0
  72. data/spec/unit/commands_map_spec.rb +57 -0
  73. data/spec/unit/component_test_spec.rb +126 -0
  74. data/spec/unit/cookbook_metadata_spec.rb +62 -0
  75. data/spec/unit/cookbook_profiler/git_spec.rb +127 -0
  76. data/spec/unit/cookbook_profiler/identifiers_spec.rb +79 -0
  77. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -0
  78. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -0
  79. data/spec/unit/fixtures/command/cli_test_command.rb +26 -0
  80. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -0
  81. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  82. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -0
  83. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  84. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -0
  85. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  86. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  87. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -0
  88. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -0
  89. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -0
  90. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -0
  91. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -0
  92. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -0
  93. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -0
  94. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -0
  95. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -0
  96. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -0
  97. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -0
  98. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -0
  99. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1322 -0
  100. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -0
  101. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -0
  102. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -0
  103. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -0
  104. data/spec/unit/fixtures/dev_cookbooks/bar-cookbook.gitbundle +0 -0
  105. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/bin/.keep +0 -0
  106. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/.keep +0 -0
  107. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/bin/.keep +0 -0
  108. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/bin/.keep +0 -0
  109. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/berkshelf/.keep +0 -0
  110. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/test-kitchen/.keep +0 -0
  111. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/bin/.keep +0 -0
  112. data/spec/unit/fixtures/eg_omnibus_dir/valid/bin/.keep +0 -0
  113. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -0
  114. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -0
  115. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef-dk/.keep +0 -0
  116. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -0
  117. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -0
  118. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/bin/.keep +0 -0
  119. data/spec/unit/fixtures/example_app/Policyfile.rb +0 -0
  120. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -0
  121. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -0
  122. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -0
  123. data/spec/unit/fixtures/example_cookbook/README.md +4 -0
  124. data/spec/unit/fixtures/example_cookbook/chefignore +96 -0
  125. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -0
  126. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -0
  127. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -0
  128. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -0
  129. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -0
  130. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -0
  131. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -0
  132. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -0
  133. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -0
  134. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -0
  135. data/spec/unit/policyfile/community_cookbook_source_spec.rb +51 -0
  136. data/spec/unit/policyfile/cookbook_spec_spec.rb +200 -0
  137. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -0
  138. data/spec/unit/policyfile_builder_spec.rb +489 -0
  139. data/spec/unit/policyfile_demands_spec.rb +484 -0
  140. data/spec/unit/policyfile_evaluation_spec.rb +284 -0
  141. data/spec/unit/shell_out_spec.rb +34 -0
  142. metadata +422 -0
@@ -0,0 +1,504 @@
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 'chef-dk/command/generator_commands'
20
+
21
+ describe ChefDK::Command::GeneratorCommands::App do
22
+
23
+ let(:argv) { %w[new_app] }
24
+
25
+ let(:stdout_io) { StringIO.new }
26
+ let(:stderr_io) { StringIO.new }
27
+
28
+ let(:expected_cookbook_file_relpaths) do
29
+ %w[
30
+ .gitignore
31
+ .kitchen.yml
32
+ README.md
33
+ cookbooks/new_app/Berksfile
34
+ cookbooks/new_app/chefignore
35
+ cookbooks/new_app/metadata.rb
36
+ cookbooks/new_app/recipes
37
+ cookbooks/new_app/recipes/default.rb
38
+ ]
39
+ end
40
+
41
+ let(:expected_cookbook_files) do
42
+ expected_cookbook_file_relpaths.map do |relpath|
43
+ File.join(tempdir, "new_app", relpath)
44
+ end
45
+ end
46
+
47
+ subject(:cookbook_generator) { described_class.new(argv) }
48
+
49
+ def generator_context
50
+ ChefDK::Generator.context
51
+ end
52
+
53
+ before do
54
+ ChefDK::Generator.reset
55
+ end
56
+
57
+ context "when given the name of the cookbook to generate" do
58
+
59
+ before do
60
+ reset_tempdir
61
+ end
62
+
63
+ it "configures the generator context" do
64
+ cookbook_generator.read_and_validate_params
65
+ cookbook_generator.setup_context
66
+ expect(generator_context.app_root).to eq(Dir.pwd)
67
+ expect(generator_context.app_name).to eq("new_app")
68
+ expect(generator_context.cookbook_root).to eq(File.join(Dir.pwd, "new_app", "cookbooks"))
69
+ expect(generator_context.cookbook_name).to eq("new_app")
70
+ end
71
+
72
+ describe "generated files" do
73
+ it "creates a new cookbook" do
74
+ Dir.chdir(tempdir) do
75
+ cookbook_generator.chef_runner.stub(:stdout).and_return(stdout_io)
76
+ cookbook_generator.run
77
+ end
78
+ generated_files = Dir.glob(File.join(tempdir, "new_app", "**", "*"), File::FNM_DOTMATCH)
79
+ expected_cookbook_files.each do |expected_file|
80
+ expect(generated_files).to include(expected_file)
81
+ end
82
+ end
83
+
84
+ shared_examples_for "a generated file" do |context_var|
85
+ before do
86
+ Dir.chdir(tempdir) do
87
+ cookbook_generator.chef_runner.stub(:stdout).and_return(stdout_io)
88
+ cookbook_generator.run
89
+ end
90
+ end
91
+
92
+ it "should contain #{context_var} from the generator context" do
93
+ File.read(file).should match line
94
+ end
95
+ end
96
+
97
+ describe "README.md" do
98
+ let(:file) { File.join(tempdir, "new_app", "README.md") }
99
+
100
+ include_examples "a generated file", :cookbook_name do
101
+ let(:line) { "# new_app" }
102
+ end
103
+ end
104
+
105
+ describe ".kitchen.yml" do
106
+ let(:file) { File.join(tempdir, "new_app", ".kitchen.yml") }
107
+
108
+ include_examples "a generated file", :cookbook_name do
109
+ let(:line) { /\s*- recipe\[new_app::default\]/ }
110
+ end
111
+ end
112
+
113
+ describe "cookbooks/new_app/metadata.rb" do
114
+ let(:file) { File.join(tempdir, "new_app", "cookbooks", "new_app", "metadata.rb") }
115
+
116
+ include_examples "a generated file", :cookbook_name do
117
+ let(:line) { /name\s+'new_app'/ }
118
+ end
119
+ end
120
+
121
+ describe "cookbooks/new_app/recipes/default.rb" do
122
+ let(:file) { File.join(tempdir, "new_app", "cookbooks", "new_app", "recipes", "default.rb") }
123
+
124
+ include_examples "a generated file", :cookbook_name do
125
+ let(:line) { "# Cookbook Name:: new_app" }
126
+ end
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+
134
+ describe ChefDK::Command::GeneratorCommands::Cookbook do
135
+
136
+ let(:argv) { %w[new_cookbook] }
137
+
138
+ let(:stdout_io) { StringIO.new }
139
+ let(:stderr_io) { StringIO.new }
140
+
141
+ let(:expected_cookbook_file_relpaths) do
142
+ %w[
143
+ .gitignore
144
+ .kitchen.yml
145
+ Berksfile
146
+ chefignore
147
+ metadata.rb
148
+ README.md
149
+ recipes
150
+ recipes/default.rb
151
+ ]
152
+ end
153
+
154
+ let(:expected_cookbook_files) do
155
+ expected_cookbook_file_relpaths.map do |relpath|
156
+ File.join(tempdir, "new_cookbook", relpath)
157
+ end
158
+ end
159
+
160
+ subject(:cookbook_generator) do
161
+ g = described_class.new(argv)
162
+ g.stub(:cookbook_path_in_git_repo?).and_return(false)
163
+ g
164
+ end
165
+
166
+ def generator_context
167
+ ChefDK::Generator.context
168
+ end
169
+
170
+ before do
171
+ ChefDK::Generator.reset
172
+ end
173
+
174
+ it "configures the chef runner" do
175
+ expect(cookbook_generator.chef_runner).to be_a(ChefDK::ChefRunner)
176
+ expect(cookbook_generator.chef_runner.cookbook_path).to eq(File.expand_path('lib/chef-dk/skeletons', project_root))
177
+ end
178
+
179
+ context "when given invalid/incomplete arguments" do
180
+
181
+ let(:expected_help_message) do
182
+ "Usage: chef generate cookbook NAME [options]\n"
183
+ end
184
+
185
+
186
+ def with_argv(argv)
187
+ generator = described_class.new(argv)
188
+ generator.stub(:stdout).and_return(stdout_io)
189
+ generator.stub(:stderr).and_return(stderr_io)
190
+ generator
191
+ end
192
+
193
+ it "prints usage when args are empty" do
194
+ with_argv([]).run
195
+ expect(stdout_io.string).to eq(expected_help_message)
196
+ end
197
+
198
+ end
199
+
200
+ context "when given the name of the cookbook to generate" do
201
+
202
+ let(:argv) { %w[new_cookbook] }
203
+
204
+ before do
205
+ reset_tempdir
206
+ end
207
+
208
+ it "configures the generator context" do
209
+ cookbook_generator.read_and_validate_params
210
+ cookbook_generator.setup_context
211
+ expect(generator_context.cookbook_root).to eq(Dir.pwd)
212
+ expect(generator_context.cookbook_name).to eq("new_cookbook")
213
+ end
214
+
215
+ it "creates a new cookbook" do
216
+ Dir.chdir(tempdir) do
217
+ cookbook_generator.chef_runner.stub(:stdout).and_return(stdout_io)
218
+ cookbook_generator.run
219
+ end
220
+ generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
221
+ expected_cookbook_files.each do |expected_file|
222
+ expect(generated_files).to include(expected_file)
223
+ end
224
+ end
225
+
226
+ shared_examples_for "a generated file" do |context_var|
227
+ before do
228
+ Dir.chdir(tempdir) do
229
+ cookbook_generator.chef_runner.stub(:stdout).and_return(stdout_io)
230
+ cookbook_generator.run
231
+ end
232
+ end
233
+
234
+ it "should contain #{context_var} from the generator context" do
235
+ File.read(file).should match line
236
+ end
237
+ end
238
+
239
+ describe "README.md" do
240
+ let(:file) { File.join(tempdir, "new_cookbook", "README.md") }
241
+
242
+ include_examples "a generated file", :cookbook_name do
243
+ let(:line) { "# new_cookbook" }
244
+ end
245
+ end
246
+
247
+ describe ".kitchen.yml" do
248
+ let(:file) { File.join(tempdir, "new_cookbook", ".kitchen.yml") }
249
+
250
+ include_examples "a generated file", :cookbook_name do
251
+ let(:line) { /\s*- recipe\[new_cookbook::default\]/ }
252
+ end
253
+ end
254
+
255
+ describe "metadata.rb" do
256
+ let(:file) { File.join(tempdir, "new_cookbook", "metadata.rb") }
257
+
258
+ include_examples "a generated file", :cookbook_name do
259
+ let(:line) { /name\s+'new_cookbook'/ }
260
+ end
261
+ end
262
+
263
+ describe "recipes/default.rb" do
264
+ let(:file) { File.join(tempdir, "new_cookbook", "recipes", "default.rb") }
265
+
266
+ include_examples "a generated file", :cookbook_name do
267
+ let(:line) { "# Cookbook Name:: new_cookbook" }
268
+ end
269
+ end
270
+
271
+ end
272
+
273
+ context "when given the path to the cookbook to generate" do
274
+ let(:argv) { [ File.join(tempdir, "a_new_cookbook") ] }
275
+
276
+ before do
277
+ reset_tempdir
278
+ end
279
+
280
+ it "configures the generator context" do
281
+ cookbook_generator.read_and_validate_params
282
+ cookbook_generator.setup_context
283
+ expect(generator_context.cookbook_root).to eq(tempdir)
284
+ expect(generator_context.cookbook_name).to eq("a_new_cookbook")
285
+ end
286
+
287
+ end
288
+
289
+ context "when given a generator-cookbook path" do
290
+ let(:generator_cookbook_path) { File.join(tempdir, 'a_generator_cookbook') }
291
+ let(:argv) { ["new_cookbook", "--generator-cookbook", generator_cookbook_path] }
292
+
293
+ before do
294
+ reset_tempdir
295
+ end
296
+
297
+ it "configures the generator context" do
298
+ cookbook_generator.read_and_validate_params
299
+ cookbook_generator.setup_context
300
+ expect(generator_context.cookbook_root).to eq(Dir.pwd)
301
+ expect(generator_context.cookbook_name).to eq("new_cookbook")
302
+ expect(cookbook_generator.chef_runner.cookbook_path).to eq(generator_cookbook_path)
303
+ end
304
+
305
+ it "creates a new cookbook" do
306
+ Dir.chdir(tempdir) do
307
+ cookbook_generator.chef_runner.stub(:stdout).and_return(stdout_io)
308
+ cookbook_generator.run
309
+ end
310
+ generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
311
+ expected_cookbook_files.each do |expected_file|
312
+ expect(generated_files).to include(expected_file)
313
+ end
314
+ end
315
+ end
316
+
317
+ end
318
+
319
+ shared_examples_for "a file generator" do
320
+
321
+ let(:stdout_io) { StringIO.new }
322
+ let(:stderr_io) { StringIO.new }
323
+
324
+ def stdout
325
+ stdout_io.string
326
+ end
327
+
328
+ def stderr
329
+ stderr_io.string
330
+ end
331
+
332
+ let(:expected_cookbook_root) { tempdir }
333
+ let(:cookbook_name) { "example_cookbook" }
334
+
335
+ let(:cookbook_path) { File.join(tempdir, cookbook_name) }
336
+
337
+ subject(:recipe_generator) do
338
+ generator = described_class.new(argv)
339
+ generator.stub(:stdout).and_return(stdout_io)
340
+ generator.stub(:stderr).and_return(stderr_io)
341
+ generator
342
+ end
343
+
344
+ def generator_context
345
+ ChefDK::Generator.context
346
+ end
347
+
348
+ before do
349
+ ChefDK::Generator.reset
350
+ reset_tempdir
351
+ end
352
+
353
+ context "when argv is empty" do
354
+ let(:argv) { [] }
355
+
356
+ it "emits an error message and exits" do
357
+ expected_stdout = "Usage: chef generate #{generator_name} [path/to/cookbook] NAME [options]"
358
+
359
+ expect(recipe_generator.run).to eq(1)
360
+ expect(stdout).to include(expected_stdout)
361
+ end
362
+ end
363
+
364
+ context "when CWD is a cookbook" do
365
+
366
+ let(:argv) { [ new_file_name ] }
367
+
368
+ before do
369
+ FileUtils.cp_r(File.join(fixtures_path, "example_cookbook"), tempdir)
370
+ end
371
+
372
+ it "configures the generator context" do
373
+ Dir.chdir(cookbook_path) do
374
+ recipe_generator.read_and_validate_params
375
+ recipe_generator.setup_context
376
+
377
+ expect(generator_context.cookbook_root).to eq(expected_cookbook_root)
378
+ expect(generator_context.cookbook_name).to eq(cookbook_name)
379
+ expect(generator_context.new_file_basename).to eq(new_file_name)
380
+ end
381
+ end
382
+
383
+ it "creates a new recipe" do
384
+ Dir.chdir(cookbook_path) do
385
+ recipe_generator.chef_runner.stub(:stdout).and_return(stdout_io)
386
+ recipe_generator.run
387
+ end
388
+
389
+ generated_files.each do |expected_file|
390
+ expect(File).to exist(File.join(cookbook_path, expected_file))
391
+ end
392
+ end
393
+
394
+ end
395
+
396
+ context "when CWD is not a cookbook" do
397
+ context "and path to the cookbook is not given in the agv" do
398
+ let(:argv) { [ new_file_name ] }
399
+
400
+ it "emits an error message and exits" do
401
+ expected_stdout = "Usage: chef generate #{generator_name} [path/to/cookbook] NAME [options]"
402
+ expected_stderr = "Error: Directory #{Dir.pwd} is not a cookbook\n"
403
+
404
+ expect(recipe_generator.run).to eq(1)
405
+ expect(stdout).to include(expected_stdout)
406
+ expect(stderr).to eq(expected_stderr)
407
+ end
408
+ end
409
+
410
+ context "and path to the cookbook is given in the argv" do
411
+ let(:argv) { [cookbook_path, new_file_name ] }
412
+
413
+ before do
414
+ FileUtils.cp_r(File.join(fixtures_path, "example_cookbook"), tempdir)
415
+ end
416
+
417
+ it "configures the generator context" do
418
+ recipe_generator.read_and_validate_params
419
+ recipe_generator.setup_context
420
+
421
+ expect(generator_context.cookbook_root).to eq(File.dirname(cookbook_path))
422
+ expect(generator_context.cookbook_name).to eq(cookbook_name)
423
+ expect(generator_context.new_file_basename).to eq(new_file_name)
424
+ end
425
+
426
+ it "creates a new recipe" do
427
+ recipe_generator.chef_runner.stub(:stdout).and_return(stdout_io)
428
+ recipe_generator.run
429
+
430
+ generated_files.each do |expected_file|
431
+ expect(File).to exist(File.join(cookbook_path, expected_file))
432
+ end
433
+ end
434
+
435
+ end
436
+ end
437
+
438
+ end
439
+
440
+ describe ChefDK::Command::GeneratorCommands::Recipe do
441
+
442
+ include_examples "a file generator" do
443
+
444
+ let(:generator_name) { "recipe" }
445
+ let(:generated_files) { [ "recipes/new_recipe.rb" ] }
446
+ let(:new_file_name) { "new_recipe" }
447
+
448
+ end
449
+ end
450
+
451
+ describe ChefDK::Command::GeneratorCommands::Attribute do
452
+
453
+ include_examples "a file generator" do
454
+
455
+ let(:generator_name) { "attribute" }
456
+ let(:generated_files) { [ "attributes/new_attribute_file.rb" ] }
457
+ let(:new_file_name) { "new_attribute_file" }
458
+
459
+ end
460
+ end
461
+
462
+ describe ChefDK::Command::GeneratorCommands::LWRP do
463
+
464
+ include_examples "a file generator" do
465
+
466
+ let(:generator_name) { "lwrp" }
467
+ let(:generated_files) { [ "resources/new_lwrp.rb", "providers/new_lwrp.rb" ] }
468
+ let(:new_file_name) { "new_lwrp" }
469
+
470
+ end
471
+ end
472
+
473
+ describe ChefDK::Command::GeneratorCommands::Template do
474
+
475
+ include_examples "a file generator" do
476
+
477
+ let(:generator_name) { "template" }
478
+ let(:generated_files) { [ "templates/default/new_template.txt.erb" ] }
479
+ let(:new_file_name) { "new_template.txt" }
480
+
481
+ end
482
+ end
483
+
484
+ describe ChefDK::Command::GeneratorCommands::Template do
485
+
486
+ include_examples "a file generator" do
487
+
488
+ let(:generator_name) { "template" }
489
+ let(:generated_files) { [ "templates/default/new_template.erb" ] }
490
+ let(:new_file_name) { "new_template.erb" }
491
+
492
+ end
493
+ end
494
+
495
+ describe ChefDK::Command::GeneratorCommands::CookbookFile do
496
+
497
+ include_examples "a file generator" do
498
+
499
+ let(:generator_name) { "file" }
500
+ let(:generated_files) { [ "files/default/new_file.txt" ] }
501
+ let(:new_file_name) { "new_file.txt" }
502
+
503
+ end
504
+ end