chef-dk 3.9.0 → 3.10.1

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 (377) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +139 -139
  3. data/Gemfile.lock +917 -919
  4. data/LICENSE +201 -201
  5. data/Rakefile +77 -77
  6. data/bin/chef +25 -25
  7. data/chef-dk.gemspec +60 -60
  8. data/lib/chef-dk.rb +19 -19
  9. data/lib/chef-dk/authenticated_http.rb +22 -22
  10. data/lib/chef-dk/builtin_commands.rb +62 -62
  11. data/lib/chef-dk/chef_runner.rb +114 -114
  12. data/lib/chef-dk/chef_server_api_multi.rb +73 -73
  13. data/lib/chef-dk/cli.rb +201 -201
  14. data/lib/chef-dk/command/base.rb +79 -79
  15. data/lib/chef-dk/command/clean_policy_cookbooks.rb +114 -114
  16. data/lib/chef-dk/command/clean_policy_revisions.rb +111 -111
  17. data/lib/chef-dk/command/delete_policy.rb +120 -120
  18. data/lib/chef-dk/command/delete_policy_group.rb +120 -120
  19. data/lib/chef-dk/command/describe_cookbook.rb +95 -95
  20. data/lib/chef-dk/command/diff.rb +315 -315
  21. data/lib/chef-dk/command/env.rb +89 -89
  22. data/lib/chef-dk/command/exec.rb +44 -44
  23. data/lib/chef-dk/command/export.rb +155 -155
  24. data/lib/chef-dk/command/gem.rb +47 -47
  25. data/lib/chef-dk/command/generate.rb +126 -126
  26. data/lib/chef-dk/command/generator_commands.rb +83 -83
  27. data/lib/chef-dk/command/generator_commands/app.rb +106 -106
  28. data/lib/chef-dk/command/generator_commands/attribute.rb +36 -36
  29. data/lib/chef-dk/command/generator_commands/base.rb +157 -157
  30. data/lib/chef-dk/command/generator_commands/build_cookbook.rb +125 -125
  31. data/lib/chef-dk/command/generator_commands/chef_exts/generator_desc_resource.rb +85 -85
  32. data/lib/chef-dk/command/generator_commands/chef_exts/quieter_doc_formatter.rb +38 -38
  33. data/lib/chef-dk/command/generator_commands/chef_exts/recipe_dsl_ext.rb +39 -39
  34. data/lib/chef-dk/command/generator_commands/cookbook.rb +251 -251
  35. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  36. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  37. data/lib/chef-dk/command/generator_commands/generator_generator.rb +174 -174
  38. data/lib/chef-dk/command/generator_commands/helpers.rb +36 -36
  39. data/lib/chef-dk/command/generator_commands/policyfile.rb +124 -124
  40. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  41. data/lib/chef-dk/command/generator_commands/repo.rb +123 -123
  42. data/lib/chef-dk/command/generator_commands/resource.rb +36 -36
  43. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  44. data/lib/chef-dk/command/install.rb +120 -120
  45. data/lib/chef-dk/command/provision.rb +439 -439
  46. data/lib/chef-dk/command/push.rb +117 -117
  47. data/lib/chef-dk/command/push_archive.rb +125 -125
  48. data/lib/chef-dk/command/shell_init.rb +179 -179
  49. data/lib/chef-dk/command/show_policy.rb +163 -163
  50. data/lib/chef-dk/command/undelete.rb +154 -154
  51. data/lib/chef-dk/command/update.rb +139 -139
  52. data/lib/chef-dk/command/verify.rb +638 -638
  53. data/lib/chef-dk/commands_map.rb +113 -113
  54. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  55. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  56. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  57. data/lib/chef-dk/component_test.rb +227 -227
  58. data/lib/chef-dk/configurable.rb +88 -88
  59. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  60. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  61. data/lib/chef-dk/cookbook_profiler/git.rb +152 -152
  62. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  63. data/lib/chef-dk/cookbook_profiler/null_scm.rb +31 -31
  64. data/lib/chef-dk/exceptions.rb +151 -151
  65. data/lib/chef-dk/generator.rb +165 -165
  66. data/lib/chef-dk/helpers.rb +176 -176
  67. data/lib/chef-dk/pager.rb +104 -104
  68. data/lib/chef-dk/policyfile/artifactory_cookbook_source.rb +102 -102
  69. data/lib/chef-dk/policyfile/attribute_merge_checker.rb +110 -110
  70. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  71. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +99 -99
  72. data/lib/chef-dk/policyfile/chef_server_lock_fetcher.rb +167 -167
  73. data/lib/chef-dk/policyfile/community_cookbook_source.rb +95 -95
  74. data/lib/chef-dk/policyfile/comparison_base.rb +123 -123
  75. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  76. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  77. data/lib/chef-dk/policyfile/cookbook_sources.rb +23 -23
  78. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +89 -89
  79. data/lib/chef-dk/policyfile/differ.rb +263 -263
  80. data/lib/chef-dk/policyfile/dsl.rb +288 -288
  81. data/lib/chef-dk/policyfile/git_lock_fetcher.rb +265 -265
  82. data/lib/chef-dk/policyfile/included_policies_cookbook_source.rb +156 -156
  83. data/lib/chef-dk/policyfile/lister.rb +229 -229
  84. data/lib/chef-dk/policyfile/local_lock_fetcher.rb +132 -129
  85. data/lib/chef-dk/policyfile/lock_applier.rb +80 -80
  86. data/lib/chef-dk/policyfile/lock_fetcher_mixin.rb +37 -0
  87. data/lib/chef-dk/policyfile/null_cookbook_source.rb +49 -49
  88. data/lib/chef-dk/policyfile/policyfile_location_specification.rb +128 -125
  89. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  90. data/lib/chef-dk/policyfile/remote_lock_fetcher.rb +108 -0
  91. data/lib/chef-dk/policyfile/reports/install.rb +69 -69
  92. data/lib/chef-dk/policyfile/reports/table_printer.rb +57 -57
  93. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  94. data/lib/chef-dk/policyfile/solution_dependencies.rb +311 -311
  95. data/lib/chef-dk/policyfile/source_uri.rb +57 -57
  96. data/lib/chef-dk/policyfile/storage_config.rb +112 -112
  97. data/lib/chef-dk/policyfile/undo_record.rb +139 -139
  98. data/lib/chef-dk/policyfile/undo_stack.rb +128 -128
  99. data/lib/chef-dk/policyfile/uploader.rb +222 -222
  100. data/lib/chef-dk/policyfile_compiler.rb +528 -528
  101. data/lib/chef-dk/policyfile_lock.rb +581 -581
  102. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  103. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +123 -123
  104. data/lib/chef-dk/policyfile_services/export_repo.rb +419 -419
  105. data/lib/chef-dk/policyfile_services/install.rb +167 -167
  106. data/lib/chef-dk/policyfile_services/push.rb +112 -112
  107. data/lib/chef-dk/policyfile_services/push_archive.rb +164 -164
  108. data/lib/chef-dk/policyfile_services/rm_policy.rb +141 -141
  109. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +85 -85
  110. data/lib/chef-dk/policyfile_services/show_policy.rb +234 -234
  111. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  112. data/lib/chef-dk/policyfile_services/update_attributes.rb +110 -110
  113. data/lib/chef-dk/service_exception_inspectors.rb +24 -24
  114. data/lib/chef-dk/service_exception_inspectors/base.rb +39 -39
  115. data/lib/chef-dk/service_exception_inspectors/http.rb +119 -119
  116. data/lib/chef-dk/service_exceptions.rb +142 -142
  117. data/lib/chef-dk/shell_out.rb +36 -36
  118. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +4 -4
  119. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/.kitchen.yml +21 -21
  120. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/README.md +146 -146
  121. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +9 -9
  122. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +104 -104
  123. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  124. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +66 -66
  125. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-config.json +17 -17
  126. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-project.toml +36 -36
  127. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +22 -22
  128. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +24 -24
  129. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  130. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +8 -8
  131. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +7 -7
  132. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +9 -9
  133. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +56 -56
  134. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  135. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  136. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  137. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  138. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policyfiles/README.md +24 -24
  139. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  140. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  141. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +3 -3
  142. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +3 -3
  143. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  144. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +89 -89
  145. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +13 -13
  146. data/lib/chef-dk/skeletons/code_generator/recipes/build_cookbook.rb +177 -177
  147. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +161 -161
  148. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +25 -25
  149. data/lib/chef-dk/skeletons/code_generator/recipes/helpers.rb +21 -21
  150. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +9 -9
  151. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +52 -52
  152. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +68 -68
  153. data/lib/chef-dk/skeletons/code_generator/recipes/resource.rb +13 -13
  154. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  155. data/lib/chef-dk/skeletons/code_generator/templates/default/CHANGELOG.md.erb +11 -11
  156. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  157. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apachev2.erb +201 -201
  158. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  159. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  160. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  161. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  162. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  163. data/lib/chef-dk/skeletons/code_generator/templates/default/attribute.rb.erb +0 -0
  164. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +7 -7
  165. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +10 -10
  166. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +8 -8
  167. data/lib/chef-dk/skeletons/code_generator/templates/default/cookbook_file.erb +0 -0
  168. data/lib/chef-dk/skeletons/code_generator/templates/default/helpers.rb.erb +39 -39
  169. data/lib/chef-dk/skeletons/code_generator/templates/default/inspec_default_test.rb.erb +16 -16
  170. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +26 -26
  171. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_dokken.yml.erb +31 -31
  172. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +33 -33
  173. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +20 -20
  174. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  175. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +35 -35
  176. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +128 -128
  177. data/lib/chef-dk/skeletons/code_generator/templates/default/resource.rb.erb +1 -1
  178. data/lib/chef-dk/skeletons/code_generator/templates/default/template.erb +0 -0
  179. data/lib/chef-dk/ui.rb +57 -57
  180. data/lib/chef-dk/version.rb +20 -20
  181. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
  182. data/spec/shared/a_file_generator.rb +125 -125
  183. data/spec/shared/a_generated_file.rb +12 -12
  184. data/spec/shared/command_with_ui_object.rb +11 -11
  185. data/spec/shared/custom_generator_cookbook.rb +136 -136
  186. data/spec/shared/fixture_cookbook_checksums.rb +46 -46
  187. data/spec/shared/setup_git_committer_config.rb +54 -54
  188. data/spec/shared/setup_git_cookbooks.rb +53 -53
  189. data/spec/spec_helper.rb +51 -51
  190. data/spec/test_helpers.rb +84 -84
  191. data/spec/unit/chef_runner_spec.rb +139 -139
  192. data/spec/unit/chef_server_api_multi_spec.rb +120 -120
  193. data/spec/unit/cli_spec.rb +377 -377
  194. data/spec/unit/command/base_spec.rb +172 -172
  195. data/spec/unit/command/clean_policy_cookbooks_spec.rb +180 -180
  196. data/spec/unit/command/clean_policy_revisions_spec.rb +180 -180
  197. data/spec/unit/command/delete_policy_group_spec.rb +206 -206
  198. data/spec/unit/command/delete_policy_spec.rb +206 -206
  199. data/spec/unit/command/diff_spec.rb +311 -311
  200. data/spec/unit/command/env_spec.rb +52 -52
  201. data/spec/unit/command/exec_spec.rb +178 -178
  202. data/spec/unit/command/export_spec.rb +199 -199
  203. data/spec/unit/command/generate_spec.rb +142 -142
  204. data/spec/unit/command/generator_commands/app_spec.rb +166 -166
  205. data/spec/unit/command/generator_commands/attribute_spec.rb +31 -31
  206. data/spec/unit/command/generator_commands/base_spec.rb +181 -181
  207. data/spec/unit/command/generator_commands/build_cookbook_spec.rb +377 -377
  208. data/spec/unit/command/generator_commands/chef_exts/generator_desc_resource_spec.rb +97 -97
  209. data/spec/unit/command/generator_commands/chef_exts/recipe_dsl_ext_spec.rb +111 -111
  210. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +31 -31
  211. data/spec/unit/command/generator_commands/cookbook_spec.rb +765 -765
  212. data/spec/unit/command/generator_commands/generator_generator_spec.rb +227 -227
  213. data/spec/unit/command/generator_commands/helpers_spec.rb +31 -31
  214. data/spec/unit/command/generator_commands/policyfile_spec.rb +223 -223
  215. data/spec/unit/command/generator_commands/recipe_spec.rb +37 -37
  216. data/spec/unit/command/generator_commands/repo_spec.rb +374 -374
  217. data/spec/unit/command/generator_commands/resource_spec.rb +31 -31
  218. data/spec/unit/command/generator_commands/template_spec.rb +31 -31
  219. data/spec/unit/command/install_spec.rb +179 -179
  220. data/spec/unit/command/provision_spec.rb +589 -589
  221. data/spec/unit/command/push_archive_spec.rb +153 -153
  222. data/spec/unit/command/push_spec.rb +198 -198
  223. data/spec/unit/command/shell_init_spec.rb +339 -339
  224. data/spec/unit/command/show_policy_spec.rb +234 -234
  225. data/spec/unit/command/undelete_spec.rb +244 -244
  226. data/spec/unit/command/update_spec.rb +283 -283
  227. data/spec/unit/command/verify_spec.rb +342 -342
  228. data/spec/unit/commands_map_spec.rb +57 -57
  229. data/spec/unit/component_test_spec.rb +128 -128
  230. data/spec/unit/configurable_spec.rb +68 -68
  231. data/spec/unit/cookbook_metadata_spec.rb +96 -96
  232. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  233. data/spec/unit/cookbook_profiler/identifiers_spec.rb +81 -81
  234. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  235. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  236. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  237. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  238. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  239. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  240. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  241. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  242. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  243. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  244. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  245. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  246. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  247. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  248. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  249. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  250. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  251. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  252. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  253. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  254. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  255. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  256. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  257. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  258. data/spec/unit/fixtures/cookbooks_api/chef_server_universe.json +56 -56
  259. data/spec/unit/fixtures/cookbooks_api/pruned_chef_server_universe.json +30 -30
  260. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  261. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  262. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  263. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +33 -33
  264. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  265. data/spec/unit/fixtures/dev_cookbooks/bar-cookbook.gitbundle +0 -0
  266. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/bin/.keep +0 -0
  267. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/.keep +0 -0
  268. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/bin/.keep +0 -0
  269. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/bin/.keep +0 -0
  270. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/berkshelf/.keep +0 -0
  271. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/test-kitchen/.keep +0 -0
  272. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/bin/.keep +0 -0
  273. data/spec/unit/fixtures/eg_omnibus_dir/valid/bin/.keep +0 -0
  274. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  275. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  276. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef-dk/.keep +0 -0
  277. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  278. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  279. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/bin/.keep +0 -0
  280. data/spec/unit/fixtures/example_app/Policyfile.rb +0 -0
  281. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  282. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  283. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  284. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  285. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  286. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  287. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  288. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  289. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  290. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  291. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  292. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  293. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  294. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  295. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  296. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  297. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  298. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  299. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  300. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  301. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  302. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  303. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  304. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  305. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  306. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  307. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  308. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  309. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  310. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  311. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  312. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  313. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  314. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/extra/extra_file.txt +0 -0
  315. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  316. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  317. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  318. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  319. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  320. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  321. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  322. data/spec/unit/generator_spec.rb +119 -119
  323. data/spec/unit/pager_spec.rb +117 -117
  324. data/spec/unit/policyfile/artifactory_cookbook_source_spec.rb +59 -59
  325. data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -80
  326. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  327. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +55 -55
  328. data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -161
  329. data/spec/unit/policyfile/community_cookbook_source_spec.rb +83 -83
  330. data/spec/unit/policyfile/comparison_base_spec.rb +340 -340
  331. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +347 -347
  332. data/spec/unit/policyfile/cookbook_locks_spec.rb +527 -527
  333. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +129 -129
  334. data/spec/unit/policyfile/differ_spec.rb +686 -686
  335. data/spec/unit/policyfile/git_lock_fetcher_spec.rb +155 -155
  336. data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -242
  337. data/spec/unit/policyfile/lister_spec.rb +268 -268
  338. data/spec/unit/policyfile/local_lock_fetcher_spec.rb +199 -173
  339. data/spec/unit/policyfile/lock_applier_spec.rb +100 -100
  340. data/spec/unit/policyfile/lock_fetcher_mixin_spec.rb +60 -0
  341. data/spec/unit/policyfile/null_cookbook_source_spec.rb +34 -34
  342. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  343. data/spec/unit/policyfile/remote_lock_fetcher_spec.rb +129 -0
  344. data/spec/unit/policyfile/reports/install_spec.rb +114 -114
  345. data/spec/unit/policyfile/reports/upload_spec.rb +94 -94
  346. data/spec/unit/policyfile/solution_dependencies_spec.rb +170 -170
  347. data/spec/unit/policyfile/source_uri_spec.rb +36 -36
  348. data/spec/unit/policyfile/storage_config_spec.rb +180 -180
  349. data/spec/unit/policyfile/undo_record_spec.rb +258 -258
  350. data/spec/unit/policyfile/undo_stack_spec.rb +265 -265
  351. data/spec/unit/policyfile/uploader_spec.rb +410 -410
  352. data/spec/unit/policyfile_demands_spec.rb +1197 -1197
  353. data/spec/unit/policyfile_evaluation_spec.rb +628 -628
  354. data/spec/unit/policyfile_includes_dsl_spec.rb +220 -159
  355. data/spec/unit/policyfile_includes_spec.rb +720 -720
  356. data/spec/unit/policyfile_install_with_includes_spec.rb +232 -232
  357. data/spec/unit/policyfile_lock_build_spec.rb +1065 -1065
  358. data/spec/unit/policyfile_lock_install_spec.rb +137 -137
  359. data/spec/unit/policyfile_lock_serialization_spec.rb +424 -424
  360. data/spec/unit/policyfile_lock_validation_spec.rb +608 -608
  361. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  362. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +272 -272
  363. data/spec/unit/policyfile_services/export_repo_spec.rb +473 -473
  364. data/spec/unit/policyfile_services/install_spec.rb +209 -209
  365. data/spec/unit/policyfile_services/push_archive_spec.rb +359 -359
  366. data/spec/unit/policyfile_services/push_spec.rb +249 -249
  367. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +237 -237
  368. data/spec/unit/policyfile_services/rm_policy_spec.rb +263 -263
  369. data/spec/unit/policyfile_services/show_policy_spec.rb +887 -887
  370. data/spec/unit/policyfile_services/undelete_spec.rb +302 -302
  371. data/spec/unit/policyfile_services/update_attributes_spec.rb +229 -229
  372. data/spec/unit/policyfile_services/update_spec.rb +162 -162
  373. data/spec/unit/service_exception_inspectors/base_spec.rb +41 -41
  374. data/spec/unit/service_exception_inspectors/http_spec.rb +138 -138
  375. data/spec/unit/shell_out_spec.rb +34 -34
  376. data/warning.txt +9 -9
  377. metadata +8 -2
@@ -1,765 +1,765 @@
1
- #
2
- # Copyright:: Copyright (c) 2014-2019 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/custom_generator_cookbook"
20
- require "shared/setup_git_committer_config"
21
- require "chef-dk/command/generator_commands/cookbook"
22
-
23
- describe ChefDK::Command::GeneratorCommands::Cookbook do
24
-
25
- include_context("setup_git_committer_config")
26
-
27
- let(:argv) { %w{new_cookbook} }
28
-
29
- let(:stdout_io) { StringIO.new }
30
- let(:stderr_io) { StringIO.new }
31
-
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
- Berksfile
40
- chefignore
41
- LICENSE
42
- metadata.rb
43
- README.md
44
- CHANGELOG.md
45
- recipes
46
- recipes/default.rb
47
- spec
48
- spec/spec_helper.rb
49
- spec/unit
50
- spec/unit/recipes
51
- spec/unit/recipes/default_spec.rb
52
- }
53
- end
54
-
55
- let(:expected_cookbook_files) do
56
- expected_cookbook_file_relpaths.map do |relpath|
57
- File.join(tempdir, "new_cookbook", relpath)
58
- end
59
- end
60
-
61
- let(:non_delivery_breadcrumb) do
62
- <<~EOF
63
- Your cookbook is ready. Type `cd new_cookbook` to enter it.
64
-
65
- There are several commands you can run to get started locally developing and testing your cookbook.
66
- Type `delivery local --help` to see a full list.
67
-
68
- Why not start by writing a test? Tests for the default recipe are stored at:
69
-
70
- test/integration/default/default_test.rb
71
-
72
- If you'd prefer to dive right in, the default recipe can be found at:
73
-
74
- recipes/default.rb
75
- EOF
76
- end
77
-
78
- subject(:cookbook_generator) do
79
- g = described_class.new(argv)
80
- allow(g).to receive(:cookbook_path_in_git_repo?).and_return(false)
81
- allow(g).to receive(:stdout).and_return(stdout_io)
82
- g
83
- end
84
-
85
- def generator_context
86
- ChefDK::Generator.context
87
- end
88
-
89
- before do
90
- ChefDK::Generator.reset
91
- end
92
-
93
- include_examples "custom generator cookbook" do
94
-
95
- let(:generator_arg) { "new_cookbook" }
96
-
97
- let(:generator_name) { "cookbook" }
98
-
99
- end
100
-
101
- it "configures the chef runner" do
102
- expect(cookbook_generator.chef_runner).to be_a(ChefDK::ChefRunner)
103
- expect(cookbook_generator.chef_runner.cookbook_path).to eq(File.expand_path("lib/chef-dk/skeletons", project_root))
104
- end
105
-
106
- context "when given invalid/incomplete arguments" do
107
-
108
- let(:expected_help_message) do
109
- "Usage: chef generate cookbook NAME [options]\n"
110
- end
111
-
112
- def with_argv(argv)
113
- generator = described_class.new(argv)
114
- allow(generator).to receive(:stdout).and_return(stdout_io)
115
- allow(generator).to receive(:stderr).and_return(stderr_io)
116
- generator
117
- end
118
-
119
- it "prints usage when args are empty" do
120
- with_argv([]).run
121
- expect(stderr_io.string).to include(expected_help_message)
122
- end
123
-
124
- it "errors if both berks and policyfiles are requested" do
125
- expect(with_argv(%w{my_cookbook --berks --policy}).run).to eq(1)
126
- message = "Berkshelf and Policyfiles are mutually exclusive. Please specify only one."
127
- expect(stderr_io.string).to include(message)
128
- end
129
-
130
- it "warns if a hyphenated cookbook name is passed" do
131
- expect(with_argv(%w{my-cookbook}).run).to eq(0)
132
- message = "Hyphens are discouraged in cookbook names as they may cause problems with custom resources. See https://docs.chef.io/ctl_chef.html#chef-generate-cookbook for more information."
133
- expect(stdout_io.string).to include(message)
134
- end
135
-
136
- end
137
-
138
- context "when given the name of the cookbook to generate" do
139
-
140
- let(:argv) { %w{new_cookbook} }
141
-
142
- before do
143
- reset_tempdir
144
- end
145
-
146
- it "configures the generator context" do
147
- cookbook_generator.read_and_validate_params
148
- cookbook_generator.setup_context
149
- expect(generator_context.cookbook_root).to eq(Dir.pwd)
150
- expect(generator_context.cookbook_name).to eq("new_cookbook")
151
- expect(generator_context.recipe_name).to eq("default")
152
- expect(generator_context.verbose).to be(false)
153
- end
154
-
155
- it "creates a new cookbook" do
156
- Dir.chdir(tempdir) do
157
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
158
- expect(cookbook_generator.run).to eq(0)
159
- end
160
- generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
161
- expected_cookbook_files.each do |expected_file|
162
- expect(generated_files).to include(expected_file)
163
- end
164
- end
165
-
166
- context "by default configure for delivery" do
167
-
168
- let(:dot_delivery) { File.join(tempdir, "new_cookbook", ".delivery") }
169
-
170
- before do
171
- Dir.chdir(tempdir) do
172
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
173
- expect(cookbook_generator.run).to eq(0)
174
- end
175
- end
176
-
177
- describe ".delivery/project.toml" do
178
-
179
- let(:file) { File.join(tempdir, "new_cookbook", ".delivery", "project.toml") }
180
-
181
- let(:expected_content) do
182
- <<~PROJECT_DOT_TOML
183
- # Delivery Prototype for Local Phases Execution
184
- #
185
- # The purpose of this file is to prototype a new way to execute
186
- # phases locally on your workstation. The delivery-cli will read
187
- # this file and execute the command(s) that are configured for
188
- # each phase. You can customize them by just modifying the phase
189
- # key on this file.
190
- #
191
- # By default these phases are configured for Cookbook Workflow only
192
- #
193
- # As this is still a prototype we are not modifying the current
194
- # config.json file and it will continue working as usual.
195
-
196
- [local_phases]
197
- unit = "chef exec rspec spec/"
198
- lint = "chef exec cookstyle"
199
- # Foodcritic includes rules only appropriate for community cookbooks
200
- # uploaded to Supermarket. We turn off any rules tagged "supermarket"
201
- # by default. If you plan to share this cookbook you should remove
202
- # '-t ~supermarket' below to enable supermarket rules.
203
- syntax = "chef exec foodcritic . -t ~supermarket"
204
- provision = "chef exec kitchen create"
205
- deploy = "chef exec kitchen converge"
206
- smoke = "chef exec kitchen verify"
207
- # The functional phase is optional, you can define it by uncommenting
208
- # the line below and running the command: `delivery local functional`
209
- # functional = ""
210
- cleanup = "chef exec kitchen destroy"
211
-
212
- # Remote project.toml file
213
- #
214
- # Specify a remote URI location for the `project.toml` file.
215
- # This is useful for teams that wish to centrally manage the behavior
216
- # of the `delivery local` command across many different 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:: 2019, The Authors, All Rights Reserved.
273
- include_recipe 'delivery-truck::publish'
274
- CONFIG_DOT_JSON
275
- end
276
-
277
- it "delegates functionality to delivery-truck" do
278
- expect(IO.read(file)).to include(expected_content)
279
- end
280
-
281
- end
282
-
283
- describe "build cookbook Berksfile" do
284
-
285
- let(:file) do
286
- File.join(dot_delivery, "build_cookbook", "Berksfile")
287
- end
288
-
289
- let(:expected_content) do
290
- <<~CONFIG_DOT_JSON
291
- source 'https://supermarket.chef.io'
292
-
293
- metadata
294
-
295
- group :delivery do
296
- cookbook 'test', path: './test/fixtures/cookbooks/test'
297
- end
298
- CONFIG_DOT_JSON
299
- end
300
-
301
- it "sets the sources for delivery library cookbooks to github" do
302
- expect(IO.read(file)).to include(expected_content)
303
- end
304
-
305
- end
306
- end
307
-
308
- context "when passed delivery option" do
309
-
310
- let(:argv) { %w{new_cookbook --delivery} }
311
-
312
- it "still works with no action" do
313
- Dir.chdir(tempdir) do
314
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
315
- expect(cookbook_generator.run).to eq(0)
316
- end
317
- end
318
- end
319
-
320
- context "when given the verbose flag" do
321
-
322
- let(:argv) { %w{ new_cookbook --verbose } }
323
-
324
- it "configures the generator context with verbose mode enabled" do
325
- cookbook_generator.read_and_validate_params
326
- cookbook_generator.setup_context
327
- expect(generator_context.verbose).to be(true)
328
- end
329
-
330
- it "emits verbose output" do
331
- Dir.chdir(tempdir) do
332
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
333
- expect(cookbook_generator.run).to eq(0)
334
- end
335
-
336
- # The normal chef formatter puts a heading for each recipe like this.
337
- # Full output is large and subject to change with minor changes in the
338
- # generator cookbook, so we just look for this line
339
- expected_line = "Recipe: code_generator::cookbook"
340
-
341
- actual = stdout_io.string
342
-
343
- expect(actual).to include(expected_line)
344
- end
345
- end
346
-
347
- context "when no delivery CLI configuration is present" do
348
-
349
- it "detects no delivery config" do
350
- Dir.chdir(tempdir) do
351
- expect(cookbook_generator.have_delivery_config?).to be(false)
352
- end
353
- end
354
-
355
- it "emits concise output" do
356
- Dir.chdir(tempdir) do
357
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
358
- expect(cookbook_generator.run).to eq(0)
359
- end
360
-
361
- expected = <<~OUTPUT
362
- Generating cookbook new_cookbook
363
- - Ensuring correct cookbook file content
364
- - Committing cookbook files to git
365
- - Ensuring delivery configuration
366
- - Ensuring correct delivery build cookbook content
367
- - Adding delivery configuration to feature branch
368
- - Adding build cookbook to feature branch
369
- - Merging delivery content feature branch to master
370
-
371
- #{non_delivery_breadcrumb}
372
- OUTPUT
373
-
374
- actual = stdout_io.string
375
-
376
- # the formatter will add escape sequences to turn off any colors
377
- actual.gsub!("\e[0m", "")
378
- expect(actual).to eq(expected)
379
- end
380
- end
381
-
382
- context "when a delivery CLI config is present" do
383
-
384
- # Setup a situation like this:
385
- # there is a dir for the delivery organization with the
386
- # `.delivery/cli.toml` in it. Inside that is another dir (maybe IRL this
387
- # would be "cookbooks"), then we create the cookbook inside that.
388
-
389
- let(:tempdir_subdir) { File.join(tempdir, "subdirectory") }
390
-
391
- let(:dot_delivery_dir) { File.join(tempdir, ".delivery") }
392
-
393
- let(:dot_delivery_cli_toml) { File.join(dot_delivery_dir, "cli.toml") }
394
-
395
- before do
396
- Dir.mkdir(tempdir_subdir)
397
- Dir.mkdir(dot_delivery_dir)
398
- FileUtils.touch(dot_delivery_cli_toml)
399
- end
400
-
401
- it "detects the delivery config" do
402
- Dir.chdir(tempdir_subdir) do
403
- expect(cookbook_generator.have_delivery_config?).to be(true)
404
- end
405
- end
406
-
407
- it "emits concise output" do
408
- Dir.chdir(tempdir) do
409
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
410
- expect(cookbook_generator.run).to eq(0)
411
- end
412
-
413
- expected = <<~OUTPUT
414
- Generating cookbook new_cookbook
415
- - Ensuring correct cookbook file content
416
- - Committing cookbook files to git
417
- - Ensuring delivery configuration
418
- - Ensuring correct delivery build cookbook content
419
- - Adding delivery configuration to feature branch
420
- - Adding build cookbook to feature branch
421
- - Merging delivery content feature branch to master
422
-
423
- Your cookbook is ready. To setup the pipeline, type `cd new_cookbook`, then run `delivery init`
424
- OUTPUT
425
-
426
- actual = stdout_io.string
427
-
428
- # the formatter will add escape sequences to turn off any colors
429
- actual.gsub!("\e[0m", "")
430
- expect(actual).to eq(expected)
431
- end
432
- end
433
-
434
- shared_examples_for "a generated file" do |context_var|
435
- before do
436
- Dir.chdir(tempdir) do
437
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
438
- expect(cookbook_generator.run).to eq(0)
439
- end
440
- end
441
-
442
- it "should contain #{context_var} from the generator context" do
443
- expect(File.read(file)).to match line
444
- end
445
- end
446
-
447
- describe "README.md" do
448
- let(:file) { File.join(tempdir, "new_cookbook", "README.md") }
449
-
450
- include_examples "a generated file", :cookbook_name do
451
- let(:line) { "# new_cookbook" }
452
- end
453
- end
454
-
455
- describe "CHANGELOG.md" do
456
- let(:file) { File.join(tempdir, "new_cookbook", "CHANGELOG.md") }
457
-
458
- include_examples "a generated file", :cookbook_name do
459
- let(:line) { "# new_cookbook" }
460
- end
461
- end
462
-
463
- # This shared example group requires a let binding for
464
- # `expected_kitchen_yml_content`
465
- shared_examples_for "kitchen_yml_and_integration_tests" do
466
-
467
- describe "Generating Test Kitchen and integration testing files" do
468
-
469
- describe "generating kitchen config" do
470
-
471
- before do
472
- Dir.chdir(tempdir) do
473
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
474
- expect(cookbook_generator.run).to eq(0)
475
- end
476
- end
477
-
478
- let(:file) { File.join(tempdir, "new_cookbook", ".kitchen.yml") }
479
-
480
- it "creates a .kitchen.yml with the expected content" do
481
- expect(IO.read(file)).to eq(expected_kitchen_yml_content)
482
- end
483
-
484
- end
485
-
486
- describe "test/integration/default/default_test.rb" do
487
- let(:file) { File.join(tempdir, "new_cookbook", "test", "integration", "default", "default_test.rb") }
488
-
489
- include_examples "a generated file", :cookbook_name do
490
- let(:line) { "describe port" }
491
- end
492
- end
493
- end
494
- end
495
-
496
- # This shared example group requires you to define a let binding for
497
- # `expected_chefspec_spec_helper_content`
498
- shared_examples_for "chefspec_spec_helper_file" do
499
-
500
- describe "Generating ChefSpec files" do
501
-
502
- before do
503
- Dir.chdir(tempdir) do
504
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
505
- expect(cookbook_generator.run).to eq(0)
506
- end
507
- end
508
-
509
- let(:file) { File.join(tempdir, "new_cookbook", "spec", "spec_helper.rb") }
510
-
511
- it "creates a spec/spec_helper.rb for ChefSpec with the expected content" do
512
- expect(IO.read(file)).to eq(expected_chefspec_spec_helper_content)
513
- end
514
-
515
- end
516
-
517
- end
518
-
519
- context "when configured for Policyfiles" do
520
-
521
- let(:argv) { %w{new_cookbook --policy} }
522
-
523
- describe "Policyfile.rb" do
524
-
525
- let(:file) { File.join(tempdir, "new_cookbook", "Policyfile.rb") }
526
-
527
- let(:expected_content) do
528
- <<~POLICYFILE_RB
529
- # Policyfile.rb - Describe how you want Chef to build your system.
530
- #
531
- # For more information on the Policyfile feature, visit
532
- # https://docs.chef.io/policyfile.html
533
-
534
- # A name that describes what the system you're building with Chef does.
535
- name 'new_cookbook'
536
-
537
- # Where to find external cookbooks:
538
- default_source :supermarket
539
-
540
- # run_list: chef-client will run these recipes in the order specified.
541
- run_list 'new_cookbook::default'
542
-
543
- # Specify a custom source for a single cookbook:
544
- cookbook 'new_cookbook', path: '.'
545
- POLICYFILE_RB
546
- end
547
-
548
- before do
549
- Dir.chdir(tempdir) do
550
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
551
- expect(cookbook_generator.run).to eq(0)
552
- end
553
- end
554
-
555
- it "has a run_list and cookbook path that will work out of the box" do
556
- expect(IO.read(file)).to eq(expected_content)
557
- end
558
-
559
- end
560
-
561
- include_examples "kitchen_yml_and_integration_tests" do
562
-
563
- let(:expected_kitchen_yml_content) do
564
- <<~KITCHEN_YML
565
- ---
566
- driver:
567
- name: vagrant
568
-
569
- ## The forwarded_port port feature lets you connect to ports on the VM guest via
570
- ## localhost on the host.
571
- ## see also: https://docs.vagrantup.com/v2/networking/forwarded_ports.html
572
-
573
- # network:
574
- # - ["forwarded_port", {guest: 80, host: 8080}]
575
-
576
- provisioner:
577
- name: chef_zero
578
-
579
- ## require_chef_omnibus specifies a specific chef version to install. You can
580
- ## also set this to `true` to always use the latest version.
581
- ## see also: https://docs.chef.io/config_yml_kitchen.html
582
-
583
- # require_chef_omnibus: 12.8.1
584
-
585
- verifier:
586
- name: inspec
587
-
588
- platforms:
589
- - name: ubuntu-16.04
590
- - name: centos-7
591
-
592
- suites:
593
- - name: default
594
- verifier:
595
- inspec_tests:
596
- - test/integration/default
597
- attributes:
598
- KITCHEN_YML
599
- end
600
-
601
- end
602
-
603
- include_examples "chefspec_spec_helper_file" do
604
-
605
- let(:expected_chefspec_spec_helper_content) do
606
- <<~SPEC_HELPER
607
- # frozen_string_literal: true
608
- require 'chefspec'
609
- require 'chefspec/policyfile'
610
- SPEC_HELPER
611
- end
612
-
613
- end
614
-
615
- end
616
-
617
- context "when configured for Berkshelf" do
618
-
619
- let(:argv) { %w{new_cookbook --berks} }
620
-
621
- describe "Berksfile" do
622
-
623
- let(:file) { File.join(tempdir, "new_cookbook", "Berksfile") }
624
-
625
- let(:expected_content) do
626
- <<~POLICYFILE_RB
627
- # frozen_string_literal: true
628
- source 'https://supermarket.chef.io'
629
-
630
- metadata
631
- POLICYFILE_RB
632
- end
633
-
634
- before do
635
- Dir.chdir(tempdir) do
636
- allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
637
- expect(cookbook_generator.run).to eq(0)
638
- end
639
- end
640
-
641
- it "pulls deps from metadata" do
642
- expect(IO.read(file)).to eq(expected_content)
643
- end
644
-
645
- end
646
-
647
- include_examples "kitchen_yml_and_integration_tests" do
648
-
649
- let(:expected_kitchen_yml_content) do
650
- <<~KITCHEN_YML
651
- ---
652
- driver:
653
- name: vagrant
654
-
655
- provisioner:
656
- name: chef_zero
657
- # You may wish to disable always updating cookbooks in CI or other testing environments.
658
- # For example:
659
- # always_update_cookbooks: <%= !ENV['CI'] %>
660
- always_update_cookbooks: true
661
-
662
- verifier:
663
- name: inspec
664
-
665
- platforms:
666
- - name: ubuntu-16.04
667
- - name: centos-7
668
-
669
- suites:
670
- - name: default
671
- run_list:
672
- - recipe[new_cookbook::default]
673
- verifier:
674
- inspec_tests:
675
- - test/integration/default
676
- attributes:
677
- KITCHEN_YML
678
- end
679
-
680
- end
681
-
682
- include_examples "chefspec_spec_helper_file" do
683
-
684
- let(:expected_chefspec_spec_helper_content) do
685
- <<~SPEC_HELPER
686
- # frozen_string_literal: true
687
- require 'chefspec'
688
- require 'chefspec/berkshelf'
689
- SPEC_HELPER
690
- end
691
-
692
- end
693
-
694
- end
695
-
696
- describe "metadata.rb" do
697
- let(:file) { File.join(tempdir, "new_cookbook", "metadata.rb") }
698
-
699
- include_examples "a generated file", :cookbook_name do
700
- let(:line) { /name\s+'new_cookbook'.+# issues_url.+# source_url/m }
701
- end
702
- end
703
-
704
- describe "recipes/default.rb" do
705
- let(:file) { File.join(tempdir, "new_cookbook", "recipes", "default.rb") }
706
-
707
- include_examples "a generated file", :cookbook_name do
708
- let(:line) { "# Cookbook:: new_cookbook" }
709
- end
710
- end
711
-
712
- describe "spec/unit/recipes/default_spec.rb" do
713
- let(:file) { File.join(tempdir, "new_cookbook", "spec", "unit", "recipes", "default_spec.rb") }
714
-
715
- include_examples "a generated file", :cookbook_name do
716
- let(:line) { "describe 'new_cookbook::default' do" }
717
- end
718
- end
719
-
720
- end
721
-
722
- context "when given the path to the cookbook to generate" do
723
- let(:argv) { [ File.join(tempdir, "a_new_cookbook") ] }
724
-
725
- before do
726
- reset_tempdir
727
- end
728
-
729
- it "configures the generator context" do
730
- cookbook_generator.read_and_validate_params
731
- cookbook_generator.setup_context
732
- expect(generator_context.cookbook_root).to eq(tempdir)
733
- expect(generator_context.cookbook_name).to eq("a_new_cookbook")
734
- end
735
-
736
- end
737
-
738
- context "when given generic arguments to populate the generator context" do
739
- let(:argv) { [ "new_cookbook", "--generator-arg", "key1=value1", "-a", "key2=value2", "-a", " key3 = value3 " ] }
740
-
741
- before do
742
- reset_tempdir
743
- end
744
-
745
- it "configures the generator context for long form option key1" do
746
- cookbook_generator.read_and_validate_params
747
- cookbook_generator.setup_context
748
- expect(generator_context.key1).to eq("value1")
749
- end
750
-
751
- it "configures the generator context for short form option key2" do
752
- cookbook_generator.read_and_validate_params
753
- cookbook_generator.setup_context
754
- expect(generator_context.key2).to eq("value2")
755
- end
756
-
757
- it "configures the generator context for key3 containing additional spaces" do
758
- cookbook_generator.read_and_validate_params
759
- cookbook_generator.setup_context
760
- expect(generator_context.key3).to eq("value3")
761
- end
762
-
763
- end
764
-
765
- end
1
+ #
2
+ # Copyright:: Copyright (c) 2014-2019 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/custom_generator_cookbook"
20
+ require "shared/setup_git_committer_config"
21
+ require "chef-dk/command/generator_commands/cookbook"
22
+
23
+ describe ChefDK::Command::GeneratorCommands::Cookbook do
24
+
25
+ include_context("setup_git_committer_config")
26
+
27
+ let(:argv) { %w{new_cookbook} }
28
+
29
+ let(:stdout_io) { StringIO.new }
30
+ let(:stderr_io) { StringIO.new }
31
+
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
+ Berksfile
40
+ chefignore
41
+ LICENSE
42
+ metadata.rb
43
+ README.md
44
+ CHANGELOG.md
45
+ recipes
46
+ recipes/default.rb
47
+ spec
48
+ spec/spec_helper.rb
49
+ spec/unit
50
+ spec/unit/recipes
51
+ spec/unit/recipes/default_spec.rb
52
+ }
53
+ end
54
+
55
+ let(:expected_cookbook_files) do
56
+ expected_cookbook_file_relpaths.map do |relpath|
57
+ File.join(tempdir, "new_cookbook", relpath)
58
+ end
59
+ end
60
+
61
+ let(:non_delivery_breadcrumb) do
62
+ <<~EOF
63
+ Your cookbook is ready. Type `cd new_cookbook` to enter it.
64
+
65
+ There are several commands you can run to get started locally developing and testing your cookbook.
66
+ Type `delivery local --help` to see a full list.
67
+
68
+ Why not start by writing a test? Tests for the default recipe are stored at:
69
+
70
+ test/integration/default/default_test.rb
71
+
72
+ If you'd prefer to dive right in, the default recipe can be found at:
73
+
74
+ recipes/default.rb
75
+ EOF
76
+ end
77
+
78
+ subject(:cookbook_generator) do
79
+ g = described_class.new(argv)
80
+ allow(g).to receive(:cookbook_path_in_git_repo?).and_return(false)
81
+ allow(g).to receive(:stdout).and_return(stdout_io)
82
+ g
83
+ end
84
+
85
+ def generator_context
86
+ ChefDK::Generator.context
87
+ end
88
+
89
+ before do
90
+ ChefDK::Generator.reset
91
+ end
92
+
93
+ include_examples "custom generator cookbook" do
94
+
95
+ let(:generator_arg) { "new_cookbook" }
96
+
97
+ let(:generator_name) { "cookbook" }
98
+
99
+ end
100
+
101
+ it "configures the chef runner" do
102
+ expect(cookbook_generator.chef_runner).to be_a(ChefDK::ChefRunner)
103
+ expect(cookbook_generator.chef_runner.cookbook_path).to eq(File.expand_path("lib/chef-dk/skeletons", project_root))
104
+ end
105
+
106
+ context "when given invalid/incomplete arguments" do
107
+
108
+ let(:expected_help_message) do
109
+ "Usage: chef generate cookbook NAME [options]\n"
110
+ end
111
+
112
+ def with_argv(argv)
113
+ generator = described_class.new(argv)
114
+ allow(generator).to receive(:stdout).and_return(stdout_io)
115
+ allow(generator).to receive(:stderr).and_return(stderr_io)
116
+ generator
117
+ end
118
+
119
+ it "prints usage when args are empty" do
120
+ with_argv([]).run
121
+ expect(stderr_io.string).to include(expected_help_message)
122
+ end
123
+
124
+ it "errors if both berks and policyfiles are requested" do
125
+ expect(with_argv(%w{my_cookbook --berks --policy}).run).to eq(1)
126
+ message = "Berkshelf and Policyfiles are mutually exclusive. Please specify only one."
127
+ expect(stderr_io.string).to include(message)
128
+ end
129
+
130
+ it "warns if a hyphenated cookbook name is passed" do
131
+ expect(with_argv(%w{my-cookbook}).run).to eq(0)
132
+ message = "Hyphens are discouraged in cookbook names as they may cause problems with custom resources. See https://docs.chef.io/ctl_chef.html#chef-generate-cookbook for more information."
133
+ expect(stdout_io.string).to include(message)
134
+ end
135
+
136
+ end
137
+
138
+ context "when given the name of the cookbook to generate" do
139
+
140
+ let(:argv) { %w{new_cookbook} }
141
+
142
+ before do
143
+ reset_tempdir
144
+ end
145
+
146
+ it "configures the generator context" do
147
+ cookbook_generator.read_and_validate_params
148
+ cookbook_generator.setup_context
149
+ expect(generator_context.cookbook_root).to eq(Dir.pwd)
150
+ expect(generator_context.cookbook_name).to eq("new_cookbook")
151
+ expect(generator_context.recipe_name).to eq("default")
152
+ expect(generator_context.verbose).to be(false)
153
+ end
154
+
155
+ it "creates a new cookbook" do
156
+ Dir.chdir(tempdir) do
157
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
158
+ expect(cookbook_generator.run).to eq(0)
159
+ end
160
+ generated_files = Dir.glob("#{tempdir}/new_cookbook/**/*", File::FNM_DOTMATCH)
161
+ expected_cookbook_files.each do |expected_file|
162
+ expect(generated_files).to include(expected_file)
163
+ end
164
+ end
165
+
166
+ context "by default configure for delivery" do
167
+
168
+ let(:dot_delivery) { File.join(tempdir, "new_cookbook", ".delivery") }
169
+
170
+ before do
171
+ Dir.chdir(tempdir) do
172
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
173
+ expect(cookbook_generator.run).to eq(0)
174
+ end
175
+ end
176
+
177
+ describe ".delivery/project.toml" do
178
+
179
+ let(:file) { File.join(tempdir, "new_cookbook", ".delivery", "project.toml") }
180
+
181
+ let(:expected_content) do
182
+ <<~PROJECT_DOT_TOML
183
+ # Delivery Prototype for Local Phases Execution
184
+ #
185
+ # The purpose of this file is to prototype a new way to execute
186
+ # phases locally on your workstation. The delivery-cli will read
187
+ # this file and execute the command(s) that are configured for
188
+ # each phase. You can customize them by just modifying the phase
189
+ # key on this file.
190
+ #
191
+ # By default these phases are configured for Cookbook Workflow only
192
+ #
193
+ # As this is still a prototype we are not modifying the current
194
+ # config.json file and it will continue working as usual.
195
+
196
+ [local_phases]
197
+ unit = "chef exec rspec spec/"
198
+ lint = "chef exec cookstyle"
199
+ # Foodcritic includes rules only appropriate for community cookbooks
200
+ # uploaded to Supermarket. We turn off any rules tagged "supermarket"
201
+ # by default. If you plan to share this cookbook you should remove
202
+ # '-t ~supermarket' below to enable supermarket rules.
203
+ syntax = "chef exec foodcritic . -t ~supermarket"
204
+ provision = "chef exec kitchen create"
205
+ deploy = "chef exec kitchen converge"
206
+ smoke = "chef exec kitchen verify"
207
+ # The functional phase is optional, you can define it by uncommenting
208
+ # the line below and running the command: `delivery local functional`
209
+ # functional = ""
210
+ cleanup = "chef exec kitchen destroy"
211
+
212
+ # Remote project.toml file
213
+ #
214
+ # Specify a remote URI location for the `project.toml` file.
215
+ # This is useful for teams that wish to centrally manage the behavior
216
+ # of the `delivery local` command across many different 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:: 2019, The Authors, All Rights Reserved.
273
+ include_recipe 'delivery-truck::publish'
274
+ CONFIG_DOT_JSON
275
+ end
276
+
277
+ it "delegates functionality to delivery-truck" do
278
+ expect(IO.read(file)).to include(expected_content)
279
+ end
280
+
281
+ end
282
+
283
+ describe "build cookbook Berksfile" do
284
+
285
+ let(:file) do
286
+ File.join(dot_delivery, "build_cookbook", "Berksfile")
287
+ end
288
+
289
+ let(:expected_content) do
290
+ <<~CONFIG_DOT_JSON
291
+ source 'https://supermarket.chef.io'
292
+
293
+ metadata
294
+
295
+ group :delivery do
296
+ cookbook 'test', path: './test/fixtures/cookbooks/test'
297
+ end
298
+ CONFIG_DOT_JSON
299
+ end
300
+
301
+ it "sets the sources for delivery library cookbooks to github" do
302
+ expect(IO.read(file)).to include(expected_content)
303
+ end
304
+
305
+ end
306
+ end
307
+
308
+ context "when passed delivery option" do
309
+
310
+ let(:argv) { %w{new_cookbook --delivery} }
311
+
312
+ it "still works with no action" do
313
+ Dir.chdir(tempdir) do
314
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
315
+ expect(cookbook_generator.run).to eq(0)
316
+ end
317
+ end
318
+ end
319
+
320
+ context "when given the verbose flag" do
321
+
322
+ let(:argv) { %w{ new_cookbook --verbose } }
323
+
324
+ it "configures the generator context with verbose mode enabled" do
325
+ cookbook_generator.read_and_validate_params
326
+ cookbook_generator.setup_context
327
+ expect(generator_context.verbose).to be(true)
328
+ end
329
+
330
+ it "emits verbose output" do
331
+ Dir.chdir(tempdir) do
332
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
333
+ expect(cookbook_generator.run).to eq(0)
334
+ end
335
+
336
+ # The normal chef formatter puts a heading for each recipe like this.
337
+ # Full output is large and subject to change with minor changes in the
338
+ # generator cookbook, so we just look for this line
339
+ expected_line = "Recipe: code_generator::cookbook"
340
+
341
+ actual = stdout_io.string
342
+
343
+ expect(actual).to include(expected_line)
344
+ end
345
+ end
346
+
347
+ context "when no delivery CLI configuration is present" do
348
+
349
+ it "detects no delivery config" do
350
+ Dir.chdir(tempdir) do
351
+ expect(cookbook_generator.have_delivery_config?).to be(false)
352
+ end
353
+ end
354
+
355
+ it "emits concise output" do
356
+ Dir.chdir(tempdir) do
357
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
358
+ expect(cookbook_generator.run).to eq(0)
359
+ end
360
+
361
+ expected = <<~OUTPUT
362
+ Generating cookbook new_cookbook
363
+ - Ensuring correct cookbook file content
364
+ - Committing cookbook files to git
365
+ - Ensuring delivery configuration
366
+ - Ensuring correct delivery build cookbook content
367
+ - Adding delivery configuration to feature branch
368
+ - Adding build cookbook to feature branch
369
+ - Merging delivery content feature branch to master
370
+
371
+ #{non_delivery_breadcrumb}
372
+ OUTPUT
373
+
374
+ actual = stdout_io.string
375
+
376
+ # the formatter will add escape sequences to turn off any colors
377
+ actual.gsub!("\e[0m", "")
378
+ expect(actual).to eq(expected)
379
+ end
380
+ end
381
+
382
+ context "when a delivery CLI config is present" do
383
+
384
+ # Setup a situation like this:
385
+ # there is a dir for the delivery organization with the
386
+ # `.delivery/cli.toml` in it. Inside that is another dir (maybe IRL this
387
+ # would be "cookbooks"), then we create the cookbook inside that.
388
+
389
+ let(:tempdir_subdir) { File.join(tempdir, "subdirectory") }
390
+
391
+ let(:dot_delivery_dir) { File.join(tempdir, ".delivery") }
392
+
393
+ let(:dot_delivery_cli_toml) { File.join(dot_delivery_dir, "cli.toml") }
394
+
395
+ before do
396
+ Dir.mkdir(tempdir_subdir)
397
+ Dir.mkdir(dot_delivery_dir)
398
+ FileUtils.touch(dot_delivery_cli_toml)
399
+ end
400
+
401
+ it "detects the delivery config" do
402
+ Dir.chdir(tempdir_subdir) do
403
+ expect(cookbook_generator.have_delivery_config?).to be(true)
404
+ end
405
+ end
406
+
407
+ it "emits concise output" do
408
+ Dir.chdir(tempdir) do
409
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
410
+ expect(cookbook_generator.run).to eq(0)
411
+ end
412
+
413
+ expected = <<~OUTPUT
414
+ Generating cookbook new_cookbook
415
+ - Ensuring correct cookbook file content
416
+ - Committing cookbook files to git
417
+ - Ensuring delivery configuration
418
+ - Ensuring correct delivery build cookbook content
419
+ - Adding delivery configuration to feature branch
420
+ - Adding build cookbook to feature branch
421
+ - Merging delivery content feature branch to master
422
+
423
+ Your cookbook is ready. To setup the pipeline, type `cd new_cookbook`, then run `delivery init`
424
+ OUTPUT
425
+
426
+ actual = stdout_io.string
427
+
428
+ # the formatter will add escape sequences to turn off any colors
429
+ actual.gsub!("\e[0m", "")
430
+ expect(actual).to eq(expected)
431
+ end
432
+ end
433
+
434
+ shared_examples_for "a generated file" do |context_var|
435
+ before do
436
+ Dir.chdir(tempdir) do
437
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
438
+ expect(cookbook_generator.run).to eq(0)
439
+ end
440
+ end
441
+
442
+ it "should contain #{context_var} from the generator context" do
443
+ expect(File.read(file)).to match line
444
+ end
445
+ end
446
+
447
+ describe "README.md" do
448
+ let(:file) { File.join(tempdir, "new_cookbook", "README.md") }
449
+
450
+ include_examples "a generated file", :cookbook_name do
451
+ let(:line) { "# new_cookbook" }
452
+ end
453
+ end
454
+
455
+ describe "CHANGELOG.md" do
456
+ let(:file) { File.join(tempdir, "new_cookbook", "CHANGELOG.md") }
457
+
458
+ include_examples "a generated file", :cookbook_name do
459
+ let(:line) { "# new_cookbook" }
460
+ end
461
+ end
462
+
463
+ # This shared example group requires a let binding for
464
+ # `expected_kitchen_yml_content`
465
+ shared_examples_for "kitchen_yml_and_integration_tests" do
466
+
467
+ describe "Generating Test Kitchen and integration testing files" do
468
+
469
+ describe "generating kitchen config" do
470
+
471
+ before do
472
+ Dir.chdir(tempdir) do
473
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
474
+ expect(cookbook_generator.run).to eq(0)
475
+ end
476
+ end
477
+
478
+ let(:file) { File.join(tempdir, "new_cookbook", ".kitchen.yml") }
479
+
480
+ it "creates a .kitchen.yml with the expected content" do
481
+ expect(IO.read(file)).to eq(expected_kitchen_yml_content)
482
+ end
483
+
484
+ end
485
+
486
+ describe "test/integration/default/default_test.rb" do
487
+ let(:file) { File.join(tempdir, "new_cookbook", "test", "integration", "default", "default_test.rb") }
488
+
489
+ include_examples "a generated file", :cookbook_name do
490
+ let(:line) { "describe port" }
491
+ end
492
+ end
493
+ end
494
+ end
495
+
496
+ # This shared example group requires you to define a let binding for
497
+ # `expected_chefspec_spec_helper_content`
498
+ shared_examples_for "chefspec_spec_helper_file" do
499
+
500
+ describe "Generating ChefSpec files" do
501
+
502
+ before do
503
+ Dir.chdir(tempdir) do
504
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
505
+ expect(cookbook_generator.run).to eq(0)
506
+ end
507
+ end
508
+
509
+ let(:file) { File.join(tempdir, "new_cookbook", "spec", "spec_helper.rb") }
510
+
511
+ it "creates a spec/spec_helper.rb for ChefSpec with the expected content" do
512
+ expect(IO.read(file)).to eq(expected_chefspec_spec_helper_content)
513
+ end
514
+
515
+ end
516
+
517
+ end
518
+
519
+ context "when configured for Policyfiles" do
520
+
521
+ let(:argv) { %w{new_cookbook --policy} }
522
+
523
+ describe "Policyfile.rb" do
524
+
525
+ let(:file) { File.join(tempdir, "new_cookbook", "Policyfile.rb") }
526
+
527
+ let(:expected_content) do
528
+ <<~POLICYFILE_RB
529
+ # Policyfile.rb - Describe how you want Chef to build your system.
530
+ #
531
+ # For more information on the Policyfile feature, visit
532
+ # https://docs.chef.io/policyfile.html
533
+
534
+ # A name that describes what the system you're building with Chef does.
535
+ name 'new_cookbook'
536
+
537
+ # Where to find external cookbooks:
538
+ default_source :supermarket
539
+
540
+ # run_list: chef-client will run these recipes in the order specified.
541
+ run_list 'new_cookbook::default'
542
+
543
+ # Specify a custom source for a single cookbook:
544
+ cookbook 'new_cookbook', path: '.'
545
+ POLICYFILE_RB
546
+ end
547
+
548
+ before do
549
+ Dir.chdir(tempdir) do
550
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
551
+ expect(cookbook_generator.run).to eq(0)
552
+ end
553
+ end
554
+
555
+ it "has a run_list and cookbook path that will work out of the box" do
556
+ expect(IO.read(file)).to eq(expected_content)
557
+ end
558
+
559
+ end
560
+
561
+ include_examples "kitchen_yml_and_integration_tests" do
562
+
563
+ let(:expected_kitchen_yml_content) do
564
+ <<~KITCHEN_YML
565
+ ---
566
+ driver:
567
+ name: vagrant
568
+
569
+ ## The forwarded_port port feature lets you connect to ports on the VM guest via
570
+ ## localhost on the host.
571
+ ## see also: https://docs.vagrantup.com/v2/networking/forwarded_ports.html
572
+
573
+ # network:
574
+ # - ["forwarded_port", {guest: 80, host: 8080}]
575
+
576
+ provisioner:
577
+ name: chef_zero
578
+
579
+ ## require_chef_omnibus specifies a specific chef version to install. You can
580
+ ## also set this to `true` to always use the latest version.
581
+ ## see also: https://docs.chef.io/config_yml_kitchen.html
582
+
583
+ # require_chef_omnibus: 12.8.1
584
+
585
+ verifier:
586
+ name: inspec
587
+
588
+ platforms:
589
+ - name: ubuntu-16.04
590
+ - name: centos-7
591
+
592
+ suites:
593
+ - name: default
594
+ verifier:
595
+ inspec_tests:
596
+ - test/integration/default
597
+ attributes:
598
+ KITCHEN_YML
599
+ end
600
+
601
+ end
602
+
603
+ include_examples "chefspec_spec_helper_file" do
604
+
605
+ let(:expected_chefspec_spec_helper_content) do
606
+ <<~SPEC_HELPER
607
+ # frozen_string_literal: true
608
+ require 'chefspec'
609
+ require 'chefspec/policyfile'
610
+ SPEC_HELPER
611
+ end
612
+
613
+ end
614
+
615
+ end
616
+
617
+ context "when configured for Berkshelf" do
618
+
619
+ let(:argv) { %w{new_cookbook --berks} }
620
+
621
+ describe "Berksfile" do
622
+
623
+ let(:file) { File.join(tempdir, "new_cookbook", "Berksfile") }
624
+
625
+ let(:expected_content) do
626
+ <<~POLICYFILE_RB
627
+ # frozen_string_literal: true
628
+ source 'https://supermarket.chef.io'
629
+
630
+ metadata
631
+ POLICYFILE_RB
632
+ end
633
+
634
+ before do
635
+ Dir.chdir(tempdir) do
636
+ allow(cookbook_generator.chef_runner).to receive(:stdout).and_return(stdout_io)
637
+ expect(cookbook_generator.run).to eq(0)
638
+ end
639
+ end
640
+
641
+ it "pulls deps from metadata" do
642
+ expect(IO.read(file)).to eq(expected_content)
643
+ end
644
+
645
+ end
646
+
647
+ include_examples "kitchen_yml_and_integration_tests" do
648
+
649
+ let(:expected_kitchen_yml_content) do
650
+ <<~KITCHEN_YML
651
+ ---
652
+ driver:
653
+ name: vagrant
654
+
655
+ provisioner:
656
+ name: chef_zero
657
+ # You may wish to disable always updating cookbooks in CI or other testing environments.
658
+ # For example:
659
+ # always_update_cookbooks: <%= !ENV['CI'] %>
660
+ always_update_cookbooks: true
661
+
662
+ verifier:
663
+ name: inspec
664
+
665
+ platforms:
666
+ - name: ubuntu-16.04
667
+ - name: centos-7
668
+
669
+ suites:
670
+ - name: default
671
+ run_list:
672
+ - recipe[new_cookbook::default]
673
+ verifier:
674
+ inspec_tests:
675
+ - test/integration/default
676
+ attributes:
677
+ KITCHEN_YML
678
+ end
679
+
680
+ end
681
+
682
+ include_examples "chefspec_spec_helper_file" do
683
+
684
+ let(:expected_chefspec_spec_helper_content) do
685
+ <<~SPEC_HELPER
686
+ # frozen_string_literal: true
687
+ require 'chefspec'
688
+ require 'chefspec/berkshelf'
689
+ SPEC_HELPER
690
+ end
691
+
692
+ end
693
+
694
+ end
695
+
696
+ describe "metadata.rb" do
697
+ let(:file) { File.join(tempdir, "new_cookbook", "metadata.rb") }
698
+
699
+ include_examples "a generated file", :cookbook_name do
700
+ let(:line) { /name\s+'new_cookbook'.+# issues_url.+# source_url/m }
701
+ end
702
+ end
703
+
704
+ describe "recipes/default.rb" do
705
+ let(:file) { File.join(tempdir, "new_cookbook", "recipes", "default.rb") }
706
+
707
+ include_examples "a generated file", :cookbook_name do
708
+ let(:line) { "# Cookbook:: new_cookbook" }
709
+ end
710
+ end
711
+
712
+ describe "spec/unit/recipes/default_spec.rb" do
713
+ let(:file) { File.join(tempdir, "new_cookbook", "spec", "unit", "recipes", "default_spec.rb") }
714
+
715
+ include_examples "a generated file", :cookbook_name do
716
+ let(:line) { "describe 'new_cookbook::default' do" }
717
+ end
718
+ end
719
+
720
+ end
721
+
722
+ context "when given the path to the cookbook to generate" do
723
+ let(:argv) { [ File.join(tempdir, "a_new_cookbook") ] }
724
+
725
+ before do
726
+ reset_tempdir
727
+ end
728
+
729
+ it "configures the generator context" do
730
+ cookbook_generator.read_and_validate_params
731
+ cookbook_generator.setup_context
732
+ expect(generator_context.cookbook_root).to eq(tempdir)
733
+ expect(generator_context.cookbook_name).to eq("a_new_cookbook")
734
+ end
735
+
736
+ end
737
+
738
+ context "when given generic arguments to populate the generator context" do
739
+ let(:argv) { [ "new_cookbook", "--generator-arg", "key1=value1", "-a", "key2=value2", "-a", " key3 = value3 " ] }
740
+
741
+ before do
742
+ reset_tempdir
743
+ end
744
+
745
+ it "configures the generator context for long form option key1" do
746
+ cookbook_generator.read_and_validate_params
747
+ cookbook_generator.setup_context
748
+ expect(generator_context.key1).to eq("value1")
749
+ end
750
+
751
+ it "configures the generator context for short form option key2" do
752
+ cookbook_generator.read_and_validate_params
753
+ cookbook_generator.setup_context
754
+ expect(generator_context.key2).to eq("value2")
755
+ end
756
+
757
+ it "configures the generator context for key3 containing additional spaces" do
758
+ cookbook_generator.read_and_validate_params
759
+ cookbook_generator.setup_context
760
+ expect(generator_context.key3).to eq("value3")
761
+ end
762
+
763
+ end
764
+
765
+ end