chef-cli 3.1.3 → 5.1.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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -0
  3. data/chef-cli.gemspec +1 -1
  4. data/lib/chef-cli/command/generate.rb +5 -3
  5. data/lib/chef-cli/command/generator_commands/cookbook.rb +32 -2
  6. data/lib/chef-cli/command/generator_commands/recipe.rb +7 -0
  7. data/lib/chef-cli/completions/chef.fish.erb +4 -5
  8. data/lib/chef-cli/helpers.rb +10 -7
  9. data/lib/chef-cli/skeletons/code_generator/recipes/cookbook.rb +50 -24
  10. data/lib/chef-cli/skeletons/code_generator/recipes/recipe.rb +11 -3
  11. data/lib/chef-cli/skeletons/code_generator/templates/default/delivery-project.toml.erb +36 -0
  12. data/lib/chef-cli/skeletons/code_generator/templates/default/kitchen_dokken.yml.erb +1 -0
  13. data/lib/chef-cli/skeletons/code_generator/templates/default/recipe.yml.erb +18 -0
  14. data/lib/chef-cli/version.rb +1 -1
  15. data/spec/unit/command/generate_spec.rb +7 -0
  16. data/spec/unit/command/generator_commands/cookbook_spec.rb +91 -226
  17. data/spec/unit/command/generator_commands/recipe_spec.rb +34 -0
  18. data/spec/unit/command/shell_init_spec.rb +10 -10
  19. data/spec/unit/helpers_spec.rb +111 -0
  20. metadata +7 -14
  21. data/lib/chef-cli/command/generator_commands/build_cookbook.rb +0 -126
  22. data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/README.md +0 -146
  23. data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/kitchen.yml +0 -21
  24. data/lib/chef-cli/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +0 -8
  25. data/lib/chef-cli/skeletons/code_generator/files/default/delivery-config.json +0 -17
  26. data/lib/chef-cli/skeletons/code_generator/recipes/build_cookbook.rb +0 -175
  27. data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +0 -7
  28. data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +0 -10
  29. data/lib/chef-cli/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +0 -9
  30. data/spec/unit/command/generator_commands/build_cookbook_spec.rb +0 -377
@@ -16,5 +16,5 @@
16
16
  #
17
17
 
18
18
  module ChefCLI
19
- VERSION = "3.1.3".freeze
19
+ VERSION = "5.1.0".freeze
20
20
  end
@@ -138,5 +138,12 @@ describe ChefCLI::Command::Generate do
138
138
 
139
139
  end
140
140
 
141
+ describe "When build-cookbookis given as subcommand" do
142
+ it "shows deprecation warning when" do
143
+ result = generate.run(%w{build-cookbook example})
144
+ expect(result).to eq(1)
145
+ end
146
+ end
147
+
141
148
  end
142
149
  end
@@ -30,6 +30,24 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
30
30
  let(:stderr_io) { StringIO.new }
31
31
 
32
32
  let(:expected_cookbook_file_relpaths) do
33
+ %w{
34
+ .gitignore
35
+ kitchen.yml
36
+ test
37
+ test/integration
38
+ test/integration/default/default_test.rb
39
+ Policyfile.rb
40
+ chefignore
41
+ LICENSE
42
+ metadata.rb
43
+ README.md
44
+ CHANGELOG.md
45
+ recipes
46
+ recipes/default.rb
47
+ }
48
+ end
49
+
50
+ let(:expected_cookbook_file_relpaths_specs) do
33
51
  %w{
34
52
  .gitignore
35
53
  kitchen.yml
@@ -58,6 +76,12 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
58
76
  end
59
77
  end
60
78
 
79
+ let(:expected_cookbook_files_specs) do
80
+ expected_cookbook_file_relpaths_specs.map do |relpath|
81
+ File.join(tempdir, "new_cookbook", relpath)
82
+ end
83
+ end
84
+
61
85
  let(:non_delivery_breadcrumb) do
62
86
  <<~EOF
63
87
  Your cookbook is ready. Type `cd new_cookbook` to enter it.
@@ -150,9 +174,11 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
150
174
  expect(generator_context.cookbook_name).to eq("new_cookbook")
151
175
  expect(generator_context.recipe_name).to eq("default")
152
176
  expect(generator_context.verbose).to be(false)
177
+ expect(generator_context.specs).to be(false)
153
178
  end
154
179
 
155
180
  it "creates a new cookbook" do
181
+
156
182
  Dir.chdir(tempdir) do
157
183
  allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
158
184
  expect(cookbook_generator.run).to eq(0)
@@ -163,237 +189,24 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
163
189
  end
164
190
  end
165
191
 
166
- context "when passed workflow option" do
167
-
168
- context "generates a workflow (delivery) cookbook" do
169
-
170
- let(:argv) { %w{new_cookbook --workflow} }
192
+ context "when given the specs flag" do
171
193
 
172
- let(:dot_delivery) { File.join(tempdir, "new_cookbook", ".delivery") }
194
+ let(:argv) { %w{ new_cookbook --specs } }
173
195
 
174
- before do
175
- Dir.chdir(tempdir) do
176
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
177
- expect(cookbook_generator.run).to eq(0)
178
- end
179
- end
180
-
181
- describe ".delivery/project.toml" do
182
-
183
- let(:file) { File.join(tempdir, "new_cookbook", ".delivery", "project.toml") }
184
-
185
- let(:expected_content) do
186
- <<~PROJECT_DOT_TOML
187
- # Delivery for Local Phases Execution
188
- #
189
- # This file allows you to execute test phases locally on a workstation or
190
- # in a CI pipeline. The delivery-cli will read this file and execute the
191
- # command(s) that are configured for each phase. You can customize them
192
- # by just modifying the phase key on this file.
193
- #
194
- # By default these phases are configured for Cookbook Workflow only
195
- #
196
-
197
- [local_phases]
198
- unit = "chef exec rspec spec/"
199
- lint = "chef exec cookstyle"
200
- # foodcritic has been deprecated in favor of cookstyle so we skip the syntax
201
- # phase now.
202
- syntax = "echo skipping syntax phase. Use lint phase instead."
203
- provision = "chef exec kitchen create"
204
- deploy = "chef exec kitchen converge"
205
- smoke = "chef exec kitchen verify"
206
- # The functional phase is optional, you can define it by uncommenting
207
- # the line below and running the command: `delivery local functional`
208
- # functional = ""
209
- cleanup = "chef exec kitchen destroy"
210
-
211
- # Remote project.toml file
212
- #
213
- # Instead of the local phases above, you may specify a remote URI location for
214
- # the `project.toml` file. This is useful for teams that wish to centrally
215
- # manage the behavior of the `delivery local` command across many different
216
- # projects.
217
- #
218
- # remote_file = "https://url/project.toml"
219
- PROJECT_DOT_TOML
220
- end
221
-
222
- it "exists with default config for Cookbook Workflow" do
223
- expect(IO.read(file)).to eq(expected_content)
224
- end
225
-
226
- end
227
-
228
- describe ".delivery/config.json" do
229
-
230
- let(:file) { File.join(tempdir, "new_cookbook", ".delivery", "config.json") }
231
-
232
- let(:expected_content) do
233
- <<~CONFIG_DOT_JSON
234
- {
235
- "version": "2",
236
- "build_cookbook": {
237
- "name": "build_cookbook",
238
- "path": ".delivery/build_cookbook"
239
- },
240
- "delivery-truck": {
241
- "lint": {
242
- "enable_cookstyle": true
243
- }
244
- },
245
- "skip_phases": [],
246
- "job_dispatch": {
247
- "version": "v2"
248
- },
249
- "dependencies": []
250
- }
251
- CONFIG_DOT_JSON
252
- end
253
-
254
- it "configures delivery to use a local build cookbook" do
255
- expect(IO.read(file)).to eq(expected_content)
256
- end
257
-
258
- end
259
-
260
- describe "build cookbook recipes" do
261
-
262
- let(:file) do
263
- File.join(dot_delivery, "build_cookbook", "recipes", "publish.rb")
264
- end
265
-
266
- let(:expected_content) do
267
- <<~CONFIG_DOT_JSON
268
- #
269
- # Cookbook:: build_cookbook
270
- # Recipe:: publish
271
- #
272
- # Copyright:: #{DateTime.now.year}, The Authors, All Rights Reserved.
273
-
274
- include_recipe 'delivery-truck::publish'
275
- CONFIG_DOT_JSON
276
- end
277
-
278
- it "delegates functionality to delivery-truck" do
279
- expect(IO.read(file)).to include(expected_content)
280
- end
281
-
282
- end
283
-
284
- describe "build cookbook Berksfile" do
285
-
286
- let(:file) do
287
- File.join(dot_delivery, "build_cookbook", "Berksfile")
288
- end
289
-
290
- let(:expected_content) do
291
- <<~CONFIG_DOT_JSON
292
- source 'https://supermarket.chef.io'
293
-
294
- metadata
295
-
296
- group :workflow do
297
- cookbook 'test', path: './test/fixtures/cookbooks/test'
298
- end
299
- CONFIG_DOT_JSON
300
- end
301
-
302
- it "sets the sources for delivery library cookbooks to github" do
303
- expect(IO.read(file)).to include(expected_content)
304
- end
305
-
306
- end
307
- end
308
-
309
- context "when no delivery CLI configuration is present" do
310
-
311
- let(:argv) { %w{new_cookbook --workflow} }
312
-
313
- it "detects no delivery config" do
314
- Dir.chdir(tempdir) do
315
- expect(cookbook_generator.have_delivery_config?).to be(false)
316
- end
317
- end
318
-
319
- it "emits concise output" do
320
- Dir.chdir(tempdir) do
321
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
322
- expect(cookbook_generator.run).to eq(0)
323
- end
324
-
325
- expected = <<~OUTPUT
326
- Generating cookbook new_cookbook
327
- - Ensuring correct cookbook content
328
- - Committing cookbook files to git
329
- - Ensuring delivery CLI configuration
330
- - Ensuring correct Workflow (Delivery) build cookbook content
331
- - Adding delivery configuration to feature branch
332
- - Adding build cookbook to feature branch
333
- - Merging delivery content feature branch to master
334
-
335
- #{non_delivery_breadcrumb}
336
- OUTPUT
337
-
338
- actual = stdout_io.string
339
-
340
- # the formatter will add escape sequences to turn off any colors
341
- actual.gsub!("\e[0m", "")
342
- expect(actual).to eq(expected)
343
- end
196
+ it "configures the generator context with specs mode enabled" do
197
+ cookbook_generator.read_and_validate_params
198
+ cookbook_generator.setup_context
199
+ expect(generator_context.specs).to be(true)
344
200
  end
345
201
 
346
- context "when a delivery CLI config is present" do
347
-
348
- # Setup a situation like this:
349
- # there is a dir for the delivery organization with the
350
- # `.delivery/cli.toml` in it. Inside that is another dir (maybe IRL this
351
- # would be "cookbooks"), then we create the cookbook inside that.
352
-
353
- let(:argv) { %w{new_cookbook --workflow} }
354
-
355
- let(:tempdir_subdir) { File.join(tempdir, "subdirectory") }
356
-
357
- let(:dot_delivery_dir) { File.join(tempdir, ".delivery") }
358
-
359
- let(:dot_delivery_cli_toml) { File.join(dot_delivery_dir, "cli.toml") }
360
-
361
- before do
362
- Dir.mkdir(tempdir_subdir)
363
- Dir.mkdir(dot_delivery_dir)
364
- FileUtils.touch(dot_delivery_cli_toml)
365
- end
366
-
367
- it "detects the delivery config" do
368
- Dir.chdir(tempdir_subdir) do
369
- expect(cookbook_generator.have_delivery_config?).to be(true)
370
- end
202
+ it "creates a new cookbook" do
203
+ Dir.chdir(tempdir) do
204
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
205
+ expect(cookbook_generator.run).to eq(0)
371
206
  end
372
-
373
- it "emits concise output" do
374
- Dir.chdir(tempdir) do
375
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
376
- expect(cookbook_generator.run).to eq(0)
377
- end
378
-
379
- expected = <<~OUTPUT
380
- Generating cookbook new_cookbook
381
- - Ensuring correct cookbook content
382
- - Committing cookbook files to git
383
- - Ensuring delivery CLI configuration
384
- - Ensuring correct Workflow (Delivery) build cookbook content
385
- - Adding delivery configuration to feature branch
386
- - Adding build cookbook to feature branch
387
- - Merging delivery content feature branch to master
388
-
389
- Your cookbook is ready. To setup the pipeline, type `cd new_cookbook`, then run `delivery init`
390
- OUTPUT
391
-
392
- actual = stdout_io.string
393
-
394
- # the formatter will add escape sequences to turn off any colors
395
- actual.gsub!("\e[0m", "")
396
- expect(actual).to eq(expected)
207
+ generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
208
+ expected_cookbook_files_specs.each do |expected_file|
209
+ expect(generated_files).to include(expected_file)
397
210
  end
398
211
  end
399
212
  end
@@ -594,6 +407,7 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
594
407
  end
595
408
 
596
409
  include_examples "chefspec_spec_helper_file" do
410
+ let(:argv) { %w{ new_cookbook --policy --specs } }
597
411
 
598
412
  let(:expected_chefspec_spec_helper_content) do
599
413
  <<~SPEC_HELPER
@@ -606,6 +420,55 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
606
420
 
607
421
  end
608
422
 
423
+ context "when YAML recipe flag is passed" do
424
+
425
+ let(:argv) { %w{new_cookbook --yaml} }
426
+
427
+ describe "recipes/default.yml" do
428
+ let(:file) { File.join(tempdir, "new_cookbook", "recipes", "default.yml") }
429
+
430
+ let(:expected_content_header) do
431
+ <<~DEFAULT_YML_HEADER
432
+ #
433
+ # Cookbook:: new_cookbook
434
+ # Recipe:: default
435
+ #
436
+ DEFAULT_YML_HEADER
437
+ end
438
+
439
+ let(:expected_content) do
440
+ <<~DEFAULT_YML_CONTENT
441
+ ---
442
+ resources:
443
+ # Example Syntax
444
+ # Additional snippets are available using the Chef Infra Extension for Visual Studio Code
445
+ # - type: file
446
+ # name: '/path/to/file'
447
+ # content: 'content'
448
+ # owner: 'root'
449
+ # group: 'root'
450
+ # mode: '0755'
451
+ # action:
452
+ # - create
453
+ DEFAULT_YML_CONTENT
454
+ end
455
+
456
+ before do
457
+ Dir.chdir(tempdir) do
458
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
459
+ expect(cookbook_generator.run).to eq(0)
460
+ end
461
+ end
462
+
463
+ it "has a default.yml file with template contents" do
464
+ expect(IO.read(file)).to match(expected_content_header)
465
+ expect(IO.read(file)).to match(expected_content)
466
+ end
467
+
468
+ end
469
+
470
+ end
471
+
609
472
  context "when configured for Berkshelf" do
610
473
 
611
474
  let(:argv) { %w{new_cookbook --berks} }
@@ -683,6 +546,7 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
683
546
  end
684
547
 
685
548
  include_examples "chefspec_spec_helper_file" do
549
+ let(:argv) { %w{ new_cookbook --berks --specs } }
686
550
 
687
551
  let(:expected_chefspec_spec_helper_content) do
688
552
  <<~SPEC_HELPER
@@ -712,6 +576,7 @@ describe ChefCLI::Command::GeneratorCommands::Cookbook do
712
576
  end
713
577
 
714
578
  describe "spec/unit/recipes/default_spec.rb" do
579
+ let(:argv) { %w{ new_cookbook --specs } }
715
580
  let(:file) { File.join(tempdir, "new_cookbook", "spec", "unit", "recipes", "default_spec.rb") }
716
581
 
717
582
  include_examples "a generated file", :cookbook_name do
@@ -35,4 +35,38 @@ describe ChefCLI::Command::GeneratorCommands::Recipe do
35
35
 
36
36
  end
37
37
 
38
+ context "when YAML recipe flag is passed" do
39
+
40
+ let(:argv) { %w{some_recipe --yaml} }
41
+ let(:expected_cookbook_root) { tempdir }
42
+ let(:cookbook_name) { "example_cookbook" }
43
+ let(:cookbook_path) { File.join(tempdir, cookbook_name) }
44
+
45
+ let(:generator_name) { "recipe" }
46
+ let(:generated_files) do
47
+ [ "recipes/some_recipe.yml",
48
+ "spec/spec_helper.rb",
49
+ "spec/unit/recipes/some_recipe_spec.rb",
50
+ "test/integration/default/some_recipe_test.rb",
51
+ ]
52
+ end
53
+ let(:new_file_name) { "some_recipe" }
54
+
55
+ before do
56
+ FileUtils.cp_r(File.join(fixtures_path, "example_cookbook"), tempdir)
57
+ end
58
+
59
+ it "creates a new recipe" do
60
+ Dir.chdir(cookbook_path) do
61
+ allow(recipe_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
62
+ recipe_generator.run
63
+ end
64
+
65
+ generated_files.each do |expected_file|
66
+ expect(File).to exist(File.join(cookbook_path, expected_file))
67
+ end
68
+ end
69
+
70
+ end
71
+
38
72
  end
@@ -264,8 +264,8 @@ describe ChefCLI::Command::ShellInit do
264
264
  {
265
265
  "exec" => "Runs the command in context of the embedded ruby",
266
266
  "env" => "Prints environment variables used by #{ChefCLI::Dist::PRODUCT}",
267
- "gem" => "Runs the `gem` command in context of the embedded ruby",
268
- "generate" => "Generate a new app, cookbook, or component",
267
+ "gem" => "Runs the `gem` command in context of the embedded Ruby",
268
+ "generate" => "Generate a new repository, cookbook, or other component",
269
269
  }
270
270
  end
271
271
 
@@ -276,17 +276,17 @@ describe ChefCLI::Command::ShellInit do
276
276
 
277
277
  let(:expected_completion_function) do
278
278
  <<~END_COMPLETION
279
+
279
280
  # Fish Shell command-line completions for #{ChefCLI::Dist::PRODUCT}
280
281
 
281
- function __fish_chef_no_command --description 'Test if chef has yet to be given the main command'
282
- set -l cmd (commandline -opc)
283
- test (count $cmd) -eq 1
284
- end
282
+ # set a list of all the chef commands in the Ruby chef-cli
283
+ set -l chef_commands exec env gem generate;
284
+
285
+ complete -c chef -f -n "not __fish_seen_subcommand_from $chef_commands" -a exec -d "Runs the command in context of the embedded ruby";
286
+ complete -c chef -f -n "not __fish_seen_subcommand_from $chef_commands" -a env -d "Prints environment variables used by #{ChefCLI::Dist::PRODUCT}";
287
+ complete -c chef -f -n "not __fish_seen_subcommand_from $chef_commands" -a gem -d "Runs the `gem` command in context of the embedded Ruby";
288
+ complete -c chef -f -n "not __fish_seen_subcommand_from $chef_commands" -a generate -d "Generate a new repository, cookbook, or other component";
285
289
 
286
- complete -c chef -f -n '__fish_chef_no_command' -a exec -d "Runs the command in context of the embedded ruby"
287
- complete -c chef -f -n '__fish_chef_no_command' -a env -d "Prints environment variables used by Chef Workstation"
288
- complete -c chef -f -n '__fish_chef_no_command' -a gem -d "Runs the `gem` command in context of the embedded ruby"
289
- complete -c chef -f -n '__fish_chef_no_command' -a generate -d "Generate a new app, cookbook, or component"
290
290
  END_COMPLETION
291
291
  end
292
292