chef-dk 0.13.21 → 0.14.25

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 (336) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +186 -186
  3. data/Gemfile +37 -14
  4. data/Gemfile.lock +178 -72
  5. data/LICENSE +201 -201
  6. data/README.md +11 -148
  7. data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -27
  8. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +288 -288
  9. data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -52
  10. data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -51
  11. data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -1
  12. data/acceptance/Gemfile +2 -1
  13. data/acceptance/Gemfile.lock +39 -42
  14. data/acceptance/README.md +132 -132
  15. data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -2
  16. data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -2
  17. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -1
  18. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -1
  19. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -1
  20. data/acceptance/trivial/.kitchen.yml +7 -7
  21. data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -5
  22. data/bin/chef +25 -25
  23. data/lib/chef-dk.rb +19 -19
  24. data/lib/chef-dk/authenticated_http.rb +40 -40
  25. data/lib/chef-dk/chef_runner.rb +107 -107
  26. data/lib/chef-dk/cli.rb +200 -200
  27. data/lib/chef-dk/command/base.rb +79 -79
  28. data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -116
  29. data/lib/chef-dk/command/clean_policy_revisions.rb +113 -113
  30. data/lib/chef-dk/command/delete_policy.rb +122 -122
  31. data/lib/chef-dk/command/delete_policy_group.rb +122 -122
  32. data/lib/chef-dk/command/diff.rb +316 -316
  33. data/lib/chef-dk/command/env.rb +90 -90
  34. data/lib/chef-dk/command/exec.rb +45 -45
  35. data/lib/chef-dk/command/export.rb +157 -157
  36. data/lib/chef-dk/command/gem.rb +47 -47
  37. data/lib/chef-dk/command/generate.rb +120 -120
  38. data/lib/chef-dk/command/generator_commands.rb +83 -80
  39. data/lib/chef-dk/command/generator_commands/app.rb +107 -107
  40. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -37
  41. data/lib/chef-dk/command/generator_commands/base.rb +148 -148
  42. data/lib/chef-dk/command/generator_commands/cookbook.rb +153 -153
  43. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  44. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  45. data/lib/chef-dk/command/generator_commands/generator_generator.rb +177 -177
  46. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -36
  47. data/lib/chef-dk/command/generator_commands/policyfile.rb +127 -127
  48. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  49. data/lib/chef-dk/command/generator_commands/repo.rb +125 -125
  50. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  51. data/lib/chef-dk/command/install.rb +121 -121
  52. data/lib/chef-dk/command/provision.rb +438 -438
  53. data/lib/chef-dk/command/push.rb +118 -118
  54. data/lib/chef-dk/command/push_archive.rb +126 -126
  55. data/lib/chef-dk/command/shell_init.rb +180 -180
  56. data/lib/chef-dk/command/show_policy.rb +165 -165
  57. data/lib/chef-dk/command/undelete.rb +155 -155
  58. data/lib/chef-dk/command/update.rb +148 -148
  59. data/lib/chef-dk/command/verify.rb +106 -29
  60. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  61. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  62. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  63. data/lib/chef-dk/component_test.rb +30 -1
  64. data/lib/chef-dk/configurable.rb +69 -69
  65. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  66. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  67. data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
  68. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  69. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -32
  70. data/lib/chef-dk/exceptions.rb +129 -129
  71. data/lib/chef-dk/generator.rb +163 -163
  72. data/lib/chef-dk/helpers.rb +159 -159
  73. data/lib/chef-dk/pager.rb +106 -106
  74. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  75. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +54 -54
  76. data/lib/chef-dk/policyfile/community_cookbook_source.rb +97 -97
  77. data/lib/chef-dk/policyfile/comparison_base.rb +124 -124
  78. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  79. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  80. data/lib/chef-dk/policyfile/cookbook_sources.rb +22 -22
  81. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +90 -90
  82. data/lib/chef-dk/policyfile/differ.rb +266 -266
  83. data/lib/chef-dk/policyfile/dsl.rb +261 -261
  84. data/lib/chef-dk/policyfile/lister.rb +232 -232
  85. data/lib/chef-dk/policyfile/null_cookbook_source.rb +45 -45
  86. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  87. data/lib/chef-dk/policyfile/reports/install.rb +70 -70
  88. data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -58
  89. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  90. data/lib/chef-dk/policyfile/solution_dependencies.rb +298 -298
  91. data/lib/chef-dk/policyfile/storage_config.rb +100 -100
  92. data/lib/chef-dk/policyfile/undo_record.rb +142 -142
  93. data/lib/chef-dk/policyfile/undo_stack.rb +130 -130
  94. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  95. data/lib/chef-dk/policyfile_compiler.rb +419 -419
  96. data/lib/chef-dk/policyfile_lock.rb +552 -552
  97. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  98. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -125
  99. data/lib/chef-dk/policyfile_services/export_repo.rb +421 -421
  100. data/lib/chef-dk/policyfile_services/install.rb +126 -126
  101. data/lib/chef-dk/policyfile_services/push.rb +114 -114
  102. data/lib/chef-dk/policyfile_services/push_archive.rb +204 -204
  103. data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -142
  104. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -86
  105. data/lib/chef-dk/policyfile_services/show_policy.rb +237 -237
  106. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  107. data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -104
  108. data/lib/chef-dk/service_exception_inspectors.rb +25 -25
  109. data/lib/chef-dk/service_exception_inspectors/base.rb +40 -40
  110. data/lib/chef-dk/service_exception_inspectors/http.rb +121 -121
  111. data/lib/chef-dk/service_exceptions.rb +143 -143
  112. data/lib/chef-dk/shell_out.rb +36 -36
  113. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -3
  114. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +102 -102
  115. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  116. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
  117. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -16
  118. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +28 -28
  119. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  120. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -7
  121. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +3 -3
  122. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -8
  123. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +58 -58
  124. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  125. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  126. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  127. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  128. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
  129. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  130. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  131. data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +8 -8
  132. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +2 -2
  133. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -2
  134. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  135. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +97 -97
  136. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -12
  137. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +117 -117
  138. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -24
  139. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -23
  140. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -8
  141. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +27 -27
  142. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +67 -67
  143. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  144. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  145. data/lib/chef-dk/skeletons/code_generator/templates/default/{LICENSE.apache2.erb → LICENSE.apachev2.erb} +201 -201
  146. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  147. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  148. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  149. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  150. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  151. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +21 -21
  152. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +32 -32
  153. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +7 -7
  154. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  155. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +20 -20
  156. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -11
  157. data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +9 -9
  158. data/lib/chef-dk/ui.rb +58 -58
  159. data/lib/chef-dk/version.rb +1 -1
  160. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
  161. data/omnibus_overrides.rb +19 -11
  162. data/spec/shared/a_file_generator.rb +125 -125
  163. data/spec/shared/a_generated_file.rb +12 -12
  164. data/spec/shared/command_with_ui_object.rb +11 -11
  165. data/spec/shared/custom_generator_cookbook.rb +130 -130
  166. data/spec/shared/fixture_cookbook_checksums.rb +47 -47
  167. data/spec/shared/setup_git_cookbooks.rb +53 -53
  168. data/spec/spec_helper.rb +51 -51
  169. data/spec/test_helpers.rb +84 -84
  170. data/spec/unit/chef_runner_spec.rb +139 -139
  171. data/spec/unit/cli_spec.rb +357 -357
  172. data/spec/unit/command/base_spec.rb +173 -169
  173. data/spec/unit/command/clean_policy_cookbooks_spec.rb +181 -181
  174. data/spec/unit/command/clean_policy_revisions_spec.rb +181 -181
  175. data/spec/unit/command/delete_policy_group_spec.rb +207 -207
  176. data/spec/unit/command/delete_policy_spec.rb +207 -207
  177. data/spec/unit/command/diff_spec.rb +312 -312
  178. data/spec/unit/command/env_spec.rb +52 -52
  179. data/spec/unit/command/exec_spec.rb +179 -179
  180. data/spec/unit/command/export_spec.rb +200 -200
  181. data/spec/unit/command/generate_spec.rb +142 -142
  182. data/spec/unit/command/generator_commands/app_spec.rb +169 -169
  183. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -32
  184. data/spec/unit/command/generator_commands/base_spec.rb +136 -136
  185. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -32
  186. data/spec/unit/command/generator_commands/cookbook_spec.rb +450 -450
  187. data/spec/unit/command/generator_commands/generator_generator_spec.rb +229 -229
  188. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -32
  189. data/spec/unit/command/generator_commands/policyfile_spec.rb +225 -225
  190. data/spec/unit/command/generator_commands/recipe_spec.rb +34 -34
  191. data/spec/unit/command/generator_commands/repo_spec.rb +374 -367
  192. data/spec/unit/command/generator_commands/template_spec.rb +32 -32
  193. data/spec/unit/command/install_spec.rb +179 -179
  194. data/spec/unit/command/provision_spec.rb +592 -592
  195. data/spec/unit/command/push_archive_spec.rb +153 -153
  196. data/spec/unit/command/push_spec.rb +199 -199
  197. data/spec/unit/command/shell_init_spec.rb +329 -329
  198. data/spec/unit/command/show_policy_spec.rb +235 -235
  199. data/spec/unit/command/undelete_spec.rb +246 -246
  200. data/spec/unit/command/update_spec.rb +275 -275
  201. data/spec/unit/command/verify_spec.rb +15 -6
  202. data/spec/unit/commands_map_spec.rb +57 -57
  203. data/spec/unit/component_test_spec.rb +128 -126
  204. data/spec/unit/configurable_spec.rb +41 -41
  205. data/spec/unit/cookbook_metadata_spec.rb +98 -98
  206. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  207. data/spec/unit/cookbook_profiler/identifiers_spec.rb +83 -83
  208. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  209. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  210. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  211. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  212. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  213. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  214. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  215. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  216. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  217. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  218. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  219. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  220. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  221. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  222. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  223. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  224. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  225. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  226. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  227. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  228. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  229. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  230. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  231. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  232. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  233. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  234. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  235. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -36
  236. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  237. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  238. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  239. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  240. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  241. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  242. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  243. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  244. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  245. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  246. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  247. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  248. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  249. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  250. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  251. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  252. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  253. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  254. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  255. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  256. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  257. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  258. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  259. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  260. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  261. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  262. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  263. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  264. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  265. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  266. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  267. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  268. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  269. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  270. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  271. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  272. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  273. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  274. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  275. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  276. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  277. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  278. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  279. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  280. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  281. data/spec/unit/generator_spec.rb +119 -120
  282. data/spec/unit/helpers_spec.rb +92 -92
  283. data/spec/unit/pager_spec.rb +119 -119
  284. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  285. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -34
  286. data/spec/unit/policyfile/community_cookbook_source_spec.rb +84 -84
  287. data/spec/unit/policyfile/comparison_base_spec.rb +343 -343
  288. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +277 -277
  289. data/spec/unit/policyfile/cookbook_locks_spec.rb +529 -529
  290. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +130 -130
  291. data/spec/unit/policyfile/differ_spec.rb +687 -687
  292. data/spec/unit/policyfile/lister_spec.rb +272 -272
  293. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -35
  294. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  295. data/spec/unit/policyfile/reports/install_spec.rb +115 -115
  296. data/spec/unit/policyfile/reports/upload_spec.rb +96 -96
  297. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -145
  298. data/spec/unit/policyfile/storage_config_spec.rb +172 -172
  299. data/spec/unit/policyfile/undo_record_spec.rb +260 -260
  300. data/spec/unit/policyfile/undo_stack_spec.rb +266 -266
  301. data/spec/unit/policyfile/uploader_spec.rb +410 -410
  302. data/spec/unit/policyfile_demands_spec.rb +1203 -1203
  303. data/spec/unit/policyfile_evaluation_spec.rb +642 -642
  304. data/spec/unit/policyfile_lock_build_spec.rb +1056 -1056
  305. data/spec/unit/policyfile_lock_install_spec.rb +138 -138
  306. data/spec/unit/policyfile_lock_serialization_spec.rb +425 -425
  307. data/spec/unit/policyfile_lock_validation_spec.rb +611 -611
  308. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  309. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -275
  310. data/spec/unit/policyfile_services/export_repo_spec.rb +481 -481
  311. data/spec/unit/policyfile_services/install_spec.rb +211 -211
  312. data/spec/unit/policyfile_services/push_archive_spec.rb +378 -378
  313. data/spec/unit/policyfile_services/push_spec.rb +233 -233
  314. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -241
  315. data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -266
  316. data/spec/unit/policyfile_services/show_policy_spec.rb +889 -889
  317. data/spec/unit/policyfile_services/undelete_spec.rb +304 -304
  318. data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -217
  319. data/spec/unit/service_exception_inspectors/base_spec.rb +43 -43
  320. data/spec/unit/service_exception_inspectors/http_spec.rb +140 -140
  321. data/spec/unit/shell_out_spec.rb +34 -34
  322. data/spec/unit/tasks/helpers_spec.rb +75 -0
  323. data/tasks/bin/bundle-platform +0 -0
  324. data/tasks/bin/bundle-platform.bat +0 -0
  325. data/tasks/bin/create-override-gemfile +110 -0
  326. data/tasks/bundle.rb +27 -11
  327. data/tasks/bundle_util.rb +6 -5
  328. data/tasks/dependencies.rb +97 -122
  329. data/tasks/gemfile_util.rb +357 -66
  330. data/tasks/helpers.rb +47 -0
  331. data/tasks/version.rb +1 -5
  332. data/version_policy.rb +66 -41
  333. data/warning.txt +9 -9
  334. metadata +7 -5
  335. data/Gemfile.windows +0 -34
  336. data/Gemfile.windows.lock +0 -936
data/tasks/bundle.rb CHANGED
@@ -17,10 +17,11 @@
17
17
 
18
18
  require_relative "bundle_util"
19
19
  require_relative "../version_policy"
20
+ require "fileutils"
20
21
 
21
22
  desc "Tasks to work with the main Gemfile and Gemfile.<platform>"
22
23
  namespace :bundle do
23
- desc "Update Gemfile.lock and all Gemfile.<platform>.locks (or one or more gems via bundle:update gem1 gem2 ...). NOTE: use rake dependencies:update_current_chef to update the version of chef first, if you want it updated as well)."
24
+ desc "Update Gemfile.lock and all Gemfile.<platform>.locks (or one or more gems via bundle:update gem1 gem2 ...)."
24
25
  task :update, [:args] do |t, rake_args|
25
26
  extend BundleUtil
26
27
  args = rake_args[:args] || ""
@@ -31,11 +32,7 @@ namespace :bundle do
31
32
  puts "-------------------------------------------------------------------"
32
33
  bundle "install #{args}", delete_gemfile_lock: true
33
34
  platforms.each do |platform|
34
- puts ""
35
- puts "-------------------------------------------------------------------"
36
- puts "Updating Gemfile.#{platform}.lock ..."
37
- puts "-------------------------------------------------------------------"
38
- bundle "lock", gemfile: "Gemfile.#{platform}", platform: platform, delete_gemfile_lock: true
35
+ bundle "lock", platform: platform
39
36
  end
40
37
  end
41
38
  end
@@ -51,18 +48,37 @@ namespace :bundle do
51
48
  puts "-------------------------------------------------------------------"
52
49
  bundle "install #{args}"
53
50
  platforms.each do |platform|
51
+ bundle "lock", platform: platform
52
+ end
53
+ end
54
+ end
55
+
56
+ # Find out if we're using the latest gems we can (so we don't regress versions)
57
+ desc "Check for gems that are not at the latest released version, and report if anything not in ACCEPTABLE_OUTDATED_GEMS (version_policy.rb) is out of date."
58
+ task :outdated do
59
+ extend BundleUtil
60
+ puts ""
61
+ puts "-------------------------------------------------------------------"
62
+ puts "Checking for outdated gems ..."
63
+ puts "-------------------------------------------------------------------"
64
+ with_bundle_unfrozen do
65
+ bundle_outdated = bundle("outdated", extract_output: true)
66
+ puts bundle_outdated
67
+ outdated_gems = parse_bundle_outdated(bundle_outdated).map { |line, gem_name| gem_name }
68
+ # Weed out the acceptable ones
69
+ outdated_gems = outdated_gems.reject { |gem_name| ACCEPTABLE_OUTDATED_GEMS.include?(gem_name) }
70
+ if outdated_gems.empty?
54
71
  puts ""
55
- puts "-------------------------------------------------------------------"
56
- puts "Updating Gemfile.#{platform}.lock (conservatively) ..."
57
- puts "-------------------------------------------------------------------"
58
- bundle "lock", gemfile: "Gemfile.#{platform}", platform: platform
72
+ puts "SUCCESS!"
73
+ else
74
+ raise "ERROR: outdated gems: #{outdated_gems.join(", ")}. Either fix them or add them to ACCEPTABLE_OUTDATED_GEMS in #{__FILE__}."
59
75
  end
60
76
  end
61
77
  end
62
78
  end
63
79
 
64
80
  desc "Run bundle with arbitrary args against the given platform; e.g. rake bundle[show]. No platform to run against the main bundle; bundle[show,windows] to run the windows one; bundle[show,*] to run against all non-default platforms."
65
- task :bundle, [:args,:platform] do |t, rake_args|
81
+ task :bundle, [:args, :platform] do |t, rake_args|
66
82
  extend BundleUtil
67
83
  args = rake_args[:args] || ""
68
84
  platform = rake_args[:platform]
data/tasks/bundle_util.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'shellwords'
1
+ require "bundler"
2
+ require "shellwords"
2
3
 
3
4
  module BundleUtil
4
5
  PLATFORMS = { "windows" => %w{ruby x86-mingw32} }
@@ -24,12 +25,12 @@ module BundleUtil
24
25
  result
25
26
  end
26
27
 
27
- def with_bundle_unfrozen
28
- bundle "config --delete frozen"
28
+ def with_bundle_unfrozen(cwd: nil, leave_frozen: false)
29
+ bundle "config --delete frozen", cwd: cwd
29
30
  begin
30
31
  yield
31
32
  ensure
32
- bundle "config --local frozen 1"
33
+ bundle "config --local frozen 1", cwd: cwd unless leave_frozen
33
34
  end
34
35
  end
35
36
 
@@ -56,7 +57,7 @@ module BundleUtil
56
57
 
57
58
  # Run the bundle command
58
59
  ruby_platforms = platform ? PLATFORMS[platform].join(" ") : "ruby"
59
- cmd = Shellwords.join([bundle_platform, ruby_platforms, *args])
60
+ cmd = Shellwords.join([Gem.ruby, "-S", bundle_platform, ruby_platforms, *args])
60
61
  puts "#{prefix}#{Shellwords.join(["bundle", *args])}#{platform ? " for #{platform} platform" : ""}:"
61
62
  with_gemfile(gemfile) do
62
63
  puts "#{prefix}BUNDLE_GEMFILE=#{gemfile}"
@@ -18,158 +18,133 @@
18
18
  require_relative "bundle_util"
19
19
  require_relative "bundle"
20
20
  require_relative "../version_policy"
21
+ require_relative "helpers"
21
22
 
22
23
  desc "Tasks to update and check dependencies"
23
24
  namespace :dependencies do
24
25
  # Update all dependencies to the latest constraint-matching version
25
- desc "Update all dependencies. dependencies:update[conservative] to update as little as possible."
26
- task :update, [:conservative] => %w{
27
- dependencies:update_current_chef
26
+ desc "Update all dependencies."
27
+ task :update => %w{
28
+ dependencies:update_stable_channel_gems
28
29
  dependencies:update_gemfile_lock
29
30
  dependencies:update_omnibus_overrides
30
31
  dependencies:update_omnibus_gemfile_lock
31
32
  dependencies:update_acceptance_gemfile_lock
32
33
  }
33
34
 
34
- desc "Update Gemfile.lock and all Gemfile.<platform>.locks. update_gemfile_lock[conservative] to update as little as possible."
35
- task :update_gemfile_lock, [:conservative] do |t, rake_args|
36
- conservative = rake_args[:conservative]
37
- if conservative
38
- Rake::Task["bundle:install"].invoke
39
- else
40
- Rake::Task["bundle:update"].invoke
35
+ desc "Update Gemfile.lock and all Gemfile.<platform>.locks."
36
+ task :update_gemfile_lock do |t, rake_args|
37
+ Rake::Task["bundle:update"].invoke
38
+ end
39
+
40
+ def gemfile_lock_task(task_name, dirs: [], other_platforms: true, leave_frozen: true)
41
+ dirs.each do |dir|
42
+ desc "Update #{dir}/Gemfile.lock."
43
+ task task_name do |t, rake_args|
44
+ extend BundleUtil
45
+ puts ""
46
+ puts "-------------------------------------------------------------------"
47
+ puts "Updating #{dir}/Gemfile.lock ..."
48
+ puts "-------------------------------------------------------------------"
49
+ with_bundle_unfrozen(cwd: dir, leave_frozen: leave_frozen) do
50
+ bundle "install", cwd: dir, delete_gemfile_lock: true
51
+ if other_platforms
52
+ # Include all other supported platforms into the lockfile as well
53
+ platforms.each do |platform|
54
+ bundle "lock", cwd: dir, platform: platform
55
+ end
56
+ end
57
+ end
58
+ end
41
59
  end
42
60
  end
43
61
 
44
- desc "Update omnibus/Gemfile.lock. update_omnibus_gemfile_lock[conservative] to update as little as possible."
45
- task :update_omnibus_gemfile_lock, [:conservative] do |t, rake_args|
46
- extend BundleUtil
47
- conservative = rake_args[:conservative]
48
- puts ""
49
- puts "-------------------------------------------------------------------"
50
- puts "Updating omnibus/Gemfile.lock#{conservative ? " (conservatively)" : ""} ..."
51
- puts "-------------------------------------------------------------------"
52
- bundle "install", cwd: "omnibus", delete_gemfile_lock: !conservative
62
+ def berksfile_lock_task(task_name, dirs: [])
63
+ dirs.each do |dir|
64
+ desc "Update #{dir}/Berksfile.lock."
65
+ task task_name do |t, rake_args|
66
+ extend BundleUtil
67
+ puts ""
68
+ puts "-------------------------------------------------------------------"
69
+ puts "Updating #{dir}/Berksfile.lock ..."
70
+ puts "-------------------------------------------------------------------"
71
+ if File.exist?("#{project_root}/#{dir}/Berksfile.lock")
72
+ File.delete("#{project_root}/#{dir}/Berksfile.lock")
73
+ end
74
+ Dir.chdir("#{project_root}/#{dir}") do
75
+ Bundler.with_clean_env do
76
+ sh "bundle exec berks install"
77
+ end
78
+ end
79
+ end
80
+ end
53
81
  end
54
82
 
55
- desc "Update acceptance/Gemfile.lock (or one or more gems via update[gem1,gem2,...]). update_acceptance_gemfile_lock[conservative] to update as little as possible."
56
- task :update_acceptance_gemfile_lock, [:conservative] do |t, rake_args|
83
+ include RakeDependenciesTaskHelpers
84
+
85
+ gemfile_lock_task :update_omnibus_gemfile_lock, dirs: %w{omnibus}
86
+ gemfile_lock_task :update_acceptance_gemfile_lock, dirs: %w{acceptance},
87
+ other_platforms: false, leave_frozen: false
88
+
89
+ desc "Update gems to the versions specified by the stable channel."
90
+ task :update_stable_channel_gems do |t, rake_args|
57
91
  extend BundleUtil
58
- conservative = rake_args[:conservative]
59
92
  puts ""
60
93
  puts "-------------------------------------------------------------------"
61
- puts "Updating acceptance/Gemfile.lock#{conservative ? " (conservatively)" : ""} ..."
94
+ puts "Updating Gemfile ..."
62
95
  puts "-------------------------------------------------------------------"
63
- bundle "install", cwd: "acceptance", delete_gemfile_lock: !conservative
64
- end
65
96
 
66
- desc "Update current chef release in Gemfile. update_current_chef[conservative] does nothing."
67
- task :update_current_chef, [:conservative] do |t, rake_args|
68
- extend BundleUtil
69
- conservative = rake_args[:conservative]
70
- unless conservative
71
- puts ""
72
- puts "-------------------------------------------------------------------"
73
- puts "Updating Gemfile ..."
74
- puts "-------------------------------------------------------------------"
75
-
76
- require "mixlib/install"
77
- # TODO in some edge cases, stable will actually be the latest chef because
78
- # promotion *moves* the package out of current into stable rather than
79
- # copying
80
- puts "Getting latest chef 'current' version from omnitruck ..."
81
- options = {
82
- channel: :current,
83
- product_name: 'chef',
84
- product_version: :latest
85
- }
86
- version = Mixlib::Install.new(options).artifact_info.first.version
87
-
88
- # Modify the gemfile to pin to current chef
89
- gemfile_path = File.join(project_root, "Gemfile")
90
- gemfile = IO.read(gemfile_path)
91
- found = gemfile.sub!(/^(\s*gem "chef", github: "chef\/chef", branch: ")([^"]*)(")$/m) do
92
- if $2 != "v#{version}"
93
- puts "Setting chef version in Gemfile to v#{version} (was #{$2})"
94
- else
95
- puts "chef version in Gemfile already at latest current (#{$2})"
96
- end
97
- "#{$1}v#{version}#{$3}"
98
- end
99
- unless found
100
- raise "Gemfile does not have a line of the form 'gem \"chef\", github: \"chef/chef\", branch: \"v<version>\"', so we didn't update it to latest current (v#{version}). Remove dependencies:update_current_chef from the `dependencies:update` rake task to prevent it from being run if this is intentional."
101
- end
97
+ # Modify the gemfile to pin to stable chef
98
+ gemfile_path = File.join(project_root, "Gemfile")
99
+ gemfile = IO.read(gemfile_path)
100
+ update_gemfile_from_stable(gemfile, "chef", "chef", "v")
101
+ update_gemfile_from_stable(gemfile, "push-jobs-client", "opscode-pushy-client")
102
102
 
103
- if gemfile != IO.read(gemfile_path)
104
- puts "Writing modified #{gemfile_path} ..."
105
- IO.write(gemfile_path, gemfile)
106
- end
103
+ if gemfile != IO.read(gemfile_path)
104
+ puts "Writing modified #{gemfile_path} ..."
105
+ IO.write(gemfile_path, gemfile)
107
106
  end
108
107
  end
109
108
 
110
- desc "Update omnibus overrides, including versions in version_policy.rb and latest version of gems: #{OMNIBUS_RUBYGEMS_AT_LATEST_VERSION.keys}. update_omnibus_overrides[conservative] does nothing."
111
- task :update_omnibus_overrides, [:conservative] do |t, rake_args|
112
- conservative = rake_args[:conservative]
113
- unless conservative
114
- puts ""
115
- puts "-------------------------------------------------------------------"
116
- puts "Updating omnibus_overrides.rb ..."
117
- puts "-------------------------------------------------------------------"
118
-
119
- # Generate the new overrides file
120
- overrides = "# Generated by \"rake dependencies\". Do not edit.\n"
121
-
122
- # Replace the bundler and rubygems versions
123
- OMNIBUS_RUBYGEMS_AT_LATEST_VERSION.each do |override_name, gem_name|
124
- # Get the latest bundler version
125
- puts "Running gem list -re #{gem_name} ..."
126
- gem_list = `gem list -re #{gem_name}`
127
- unless gem_list =~ /^#{gem_name}\s*\(([^)]*)\)$/
128
- raise "gem list -re #{gem_name} failed with output:\n#{gem_list}"
129
- end
109
+ desc "Update omnibus overrides, including versions in version_policy.rb and latest version of gems: #{OMNIBUS_RUBYGEMS_AT_LATEST_VERSION.keys}."
110
+ task :update_omnibus_overrides do |t, rake_args|
111
+ puts ""
112
+ puts "-------------------------------------------------------------------"
113
+ puts "Updating omnibus_overrides.rb ..."
114
+ puts "-------------------------------------------------------------------"
130
115
 
131
- # Emit it
132
- puts "Latest version of #{gem_name} is #{$1}"
133
- overrides << "override #{override_name.inspect}, version: #{$1.inspect}\n"
134
- end
116
+ # Generate the new overrides file
117
+ overrides = "# DO NOT EDIT. Generated by \"rake dependencies\". Edit version_policy.rb instead.\n"
135
118
 
136
- # Add explicit overrides
137
- OMNIBUS_OVERRIDES.each do |override_name, version|
138
- overrides << "override #{override_name.inspect}, version: #{version.inspect}\n"
119
+ # Replace the bundler and rubygems versions
120
+ OMNIBUS_RUBYGEMS_AT_LATEST_VERSION.each do |override_name, gem_name|
121
+ # Get the latest bundler version
122
+ puts "Running gem list -r #{gem_name} ..."
123
+ gem_list = `gem list -r #{gem_name}`
124
+ unless gem_list =~ /^#{gem_name}\s*\(([^)]*)\)$/
125
+ raise "gem list -r #{gem_name} failed with output:\n#{gem_list}"
139
126
  end
140
127
 
141
- # Write the file out (if changed)
142
- overrides_path = File.expand_path("../../omnibus_overrides.rb", __FILE__)
143
- if overrides != IO.read(overrides_path)
144
- puts "Overrides changed!"
145
- puts `git diff #{overrides_path}`
146
- puts "Writing modified #{overrides_path} ..."
147
- IO.write(overrides_path, overrides)
148
- end
128
+ # Emit it
129
+ puts "Latest version of #{gem_name} is #{$1}"
130
+ overrides << "override #{override_name.inspect}, version: #{$1.inspect}\n"
149
131
  end
150
- end
151
132
 
152
- # Find out if we're using the latest gems we can (so we don't regress versions)
153
- desc "Check for gems that are not at the latest released version, and report if anything not in ACCEPTABLE_OUTDATED_GEMS (version_policy.rb) is out of date."
154
- task :check_outdated do
155
- puts ""
156
- puts "-------------------------------------------------------------------"
157
- puts "Checking for outdated gems ..."
158
- puts "-------------------------------------------------------------------"
159
- # TODO check for outdated windows gems too
160
- bundle_outdated = bundle("outdated", extract_output: true)
161
- puts bundle_outdated
162
- outdated_gems = parse_bundle_outdated(bundle_outdated).map { |line, gem_name| gem_name }
163
- # Weed out the acceptable ones
164
- outdated_gems = outdated_gems.reject { |gem_name| ACCEPTABLE_OUTDATED_GEMS.include?(gem_name) }
165
- if outdated_gems.empty?
166
- puts ""
167
- puts "SUCCESS!"
168
- else
169
- raise "ERROR: outdated gems: #{outdated_gems.join(", ")}. Either fix them or add them to ACCEPTABLE_OUTDATED_GEMS in #{__FILE__}."
133
+ # Add explicit overrides
134
+ OMNIBUS_OVERRIDES.each do |override_name, version|
135
+ overrides << "override #{override_name.inspect}, version: #{version.inspect}\n"
136
+ end
137
+
138
+ # Write the file out (if changed)
139
+ overrides_path = File.expand_path("../../omnibus_overrides.rb", __FILE__)
140
+ if overrides != IO.read(overrides_path)
141
+ puts "Overrides changed!"
142
+ puts `git diff #{overrides_path}`
143
+ puts "Writing modified #{overrides_path} ..."
144
+ IO.write(overrides_path, overrides)
170
145
  end
171
146
  end
172
147
  end
173
- desc "Update all dependencies and check for outdated gems. Call dependencies[conservative] to update as little as possible."
174
- task :dependencies, [:conservative] => [ "dependencies:update", "dependencies:check_outdated" ]
175
- task :update, [:conservative] => [ "dependencies:update", "dependencies:check_outdated"]
148
+ desc "Update all dependencies and check for outdated gems."
149
+ task :dependencies => [ "dependencies:update", "bundle:outdated" ]
150
+ task :update => [ "dependencies:update", "bundle:outdated"]
@@ -1,99 +1,390 @@
1
+ require "rubygems"
1
2
  require "bundler"
3
+ require "shellwords"
4
+ require "set"
2
5
 
3
6
  module GemfileUtil
4
7
  #
5
- # Given a set of dependencies with groups in them, and a resolved set of
6
- # gemspecs (with dependency info in them), creates a full set of specs
7
- # with group information on it. If A is in groups x and y, and A depends on
8
- # B and C, then B and C are also in groups x and y.
8
+ # Adds `override: true`, which allows your statement to override any other
9
+ # gem statement about the same gem in the Gemfile.
9
10
  #
10
- class GemGroups < Hash
11
- def initialize(resolved)
12
- @resolved = resolved
11
+ def gem(name, *args)
12
+ options = args[-1].is_a?(Hash) ? args[-1] : {}
13
+
14
+ # Unless we're finished with everything, ignore gems that are being overridden
15
+ unless overridden_gems == :finished
16
+ # If it's a path or override gem, it overrides whatever else is there.
17
+ if options[:path] || options[:override]
18
+ options.delete(:override)
19
+ warn_if_replacing(name, overridden_gems[name], args)
20
+ overridden_gems[name] = args
21
+ return
22
+
23
+ # If there's an override gem, and we're *not* an override gem, don't do anything
24
+ elsif overridden_gems[name]
25
+ warn_if_replacing(name, args, overridden_gems[name])
26
+ return
27
+ end
28
+ end
29
+
30
+ # Otherwise, add the gem normally
31
+ super
32
+ rescue
33
+ puts $!.backtrace
34
+ raise
35
+ end
36
+
37
+ def overridden_gems
38
+ @overridden_gems ||= {}
39
+ end
40
+
41
+ #
42
+ # Just before we finish the Gemfile, finish up the override gems
43
+ #
44
+ def to_definition(*args)
45
+ complete_overrides
46
+ super
47
+ end
48
+
49
+ def complete_overrides
50
+ to_override = overridden_gems
51
+ unless to_override == :finished
52
+ @overridden_gems = :finished
53
+ to_override.each do |name, args|
54
+ gem name, *args
55
+ end
13
56
  end
14
- attr_reader :resolved
57
+ end
15
58
 
16
- def add_dependency(dep)
17
- add_gem_groups(dep.name, dep.groups)
59
+ #
60
+ # Include all gems in the locked gemfile.
61
+ #
62
+ # @param gemfile_path Path to the Gemfile to load (relative to your Gemfile)
63
+ # @param lockfile_path Path to the Gemfile to load (relative to your Gemfile).
64
+ # Defaults to <gemfile_path>.lock.
65
+ # @param groups A list of groups to include (whitelist). If not passed (or set
66
+ # to nil), all gems will be selected.
67
+ # @param without_groups A list of groups to ignore. Gems will be excluded from
68
+ # the results if all groups they belong to are ignored. This matches
69
+ # bundler's `without` behavior.
70
+ # @param gems A list of gems to include above and beyond the given groups.
71
+ # Gems in this list must be explicitly included in the Gemfile
72
+ # with a `gem "gem_name", ...` line or they will be silently
73
+ # ignored.
74
+ # @param copy_groups Whether to copy the groups over from the old lockfile to
75
+ # the new. Use this when the new lockfile has the same convention for
76
+ # groups as the old. Defaults to `false`.
77
+ #
78
+ def include_locked_gemfile(gemfile_path, lockfile_path = "#{gemfile_path}.lock", groups: nil, without_groups: nil, gems: [], copy_groups: false)
79
+ # Parse the desired lockfile
80
+ gemfile_path = Pathname.new(gemfile_path).expand_path(Bundler.default_gemfile.dirname).realpath
81
+ lockfile_path = Pathname.new(lockfile_path).expand_path(Bundler.default_gemfile.dirname).realpath
82
+
83
+ # Calculate relative_to
84
+ relative_to = Bundler.default_gemfile.dirname.realpath
85
+
86
+ # Call out to create-override-gemfile to read the Gemfile+Gemfile.lock (bundler does not work well if you do two things in one process)
87
+ create_override_gemfile_bin = File.expand_path("../bin/create-override-gemfile", __FILE__)
88
+ arguments = [
89
+ "--gemfile", gemfile_path,
90
+ "--lockfile", lockfile_path,
91
+ "--override"
92
+ ]
93
+ arguments += [ "--relative-to", relative_to ] if relative_to != "."
94
+ arguments += Array(groups).flat_map { |group| [ "--group", group ] }
95
+ arguments += Array(without_groups).flat_map { |without| [ "--without", without ] }
96
+ arguments += Array(gems).flat_map { |name| [ "--gem", name ] }
97
+ arguments << "--copy-groups" if copy_groups
98
+ cmd = Shellwords.join([ Gem.ruby, "-S", create_override_gemfile_bin, *arguments ])
99
+ output = nil
100
+ Bundler.ui.info("> #{cmd}")
101
+ Bundler.with_clean_env do
102
+ output = `#{cmd}`
18
103
  end
104
+ instance_eval(output, cmd, 1)
105
+ end
19
106
 
20
- private
107
+ #
108
+ # Include all gems in the locked gemfile.
109
+ #
110
+ # @param current_gemfile The Gemfile you are currently loading (`self`).
111
+ # @param gemfile_path Path to the Gemfile to load (relative to your Gemfile)
112
+ # @param lockfile_path Path to the Gemfile to load (relative to your Gemfile).
113
+ # Defaults to <gemfile_path>.lock.
114
+ # @param groups A list of groups to include (whitelist). If not passed (or set
115
+ # to nil), all gems will be selected.
116
+ # @param without_groups A list of groups to ignore. Gems will be excluded from
117
+ # the results if all groups they belong to are ignored. This matches
118
+ # bundler's `without` behavior.
119
+ # @param gems A list of gems to include above and beyond the given groups.
120
+ # Gems in this list must be explicitly included in the Gemfile
121
+ # with a `gem "gem_name", ...` line or they will be silently
122
+ # ignored.
123
+ # @param copy_groups Whether to copy the groups over from the old lockfile to
124
+ # the new. Use this when the new lockfile has the same convention for
125
+ # groups as the old. Defaults to `false`.
126
+ #
127
+ def self.include_locked_gemfile(current_gemfile, gemfile_path, lockfile_path = "#{gemfile_path}.lock", groups: nil, without_groups: nil, gems: [], copy_groups: false)
128
+ current_gemfile.instance_eval do
129
+ extend GemfileUtil
130
+ include_locked_gemfile(gemfile_path, lockfile_path, groups: groups, without_groups: without_groups, gems: gems, copy_groups: copy_groups)
131
+ end
132
+ end
133
+
134
+ def warn_if_replacing(name, old_args, new_args)
135
+ return if !old_args || !new_args
136
+ if args_to_dep(name, *old_args) =~ args_to_dep(name, *new_args)
137
+ Bundler.ui.debug "Replaced Gemfile dependency #{name} (#{old_args}) with (#{new_args})"
138
+ else
139
+ Bundler.ui.warn "Replaced Gemfile dependency #{name} (#{old_args}) with (#{new_args})"
140
+ end
141
+ end
142
+
143
+ def args_to_dep(name, *version, **options)
144
+ version = [">= 0"] if version.empty?
145
+ Bundler::Dependency.new(name, version, options)
146
+ end
147
+
148
+ #
149
+ # Reads a bundle, including a gemfile and lockfile.
150
+ #
151
+ # Does no validation, does not update the lockfile or its gems in any way.
152
+ #
153
+ class Bundle
154
+ #
155
+ # Parse the given gemfile/lockfile pair.
156
+ #
157
+ # @return [Bundle] The parsed bundle.
158
+ #
159
+ def self.parse(gemfile_path, lockfile_path = "#{gemfile_path}.lock")
160
+ result = new(gemfile_path, lockfile_path)
161
+ result.gems
162
+ result
163
+ end
164
+
165
+ #
166
+ # Create a new Bundle to parse the given gemfile/lockfile pair.
167
+ #
168
+ def initialize(gemfile_path, lockfile_path = "#{gemfile_path}.lock")
169
+ @gemfile_path = gemfile_path
170
+ @lockfile_path = lockfile_path
171
+ end
172
+
173
+ #
174
+ # The path to the Gemfile
175
+ #
176
+ attr_reader :gemfile_path
177
+
178
+ #
179
+ # The path to the Lockfile
180
+ #
181
+ attr_reader :lockfile_path
21
182
 
22
- def add_gem_groups(name, groups)
23
- self[name] ||= []
24
- difference = groups - self[name]
25
- unless difference.empty?
26
- self[name] += difference
27
- spec = resolved.find { |spec| spec.name == name }
28
- if spec
29
- spec.dependencies.each do |spec|
30
- add_gem_groups(spec.name, difference)
183
+ #
184
+ # The list of gems.
185
+ #
186
+ # @return [Hash<String, Hash>] The resulting gems, where key = gem_name, and the
187
+ # hash has:
188
+ # - version: version of the gem.
189
+ # - source info (:source/:git/:ref/:path) from the lockfile
190
+ # - dependencies: A list of gem names this gem has a runtime
191
+ # dependency on. Dependencies are transitive: if A depends on B,
192
+ # and B depends on C, then A has C in its :dependencies list.
193
+ # - development_dependencies: - A list of gem names this gem has a
194
+ # development dependency on. Dependencies are transitive: if A
195
+ # depends on B, and B depends on C, then A has C in its
196
+ # :development_dependencies list. development dependencies *include*
197
+ # runtime dependencies.
198
+ # - groups: The list of groups (symbols) this gem is in. Groups
199
+ # are transitive: if A has a runtime dependency on B, and A is
200
+ # in group X, then B is also in group X.
201
+ # - declared_groups: The list of groups (symbols) this gem was
202
+ # declared in the Gemfile.
203
+ #
204
+ def gems
205
+ @gems ||= begin
206
+ gems = locks.dup
207
+ gems.each do |name, g|
208
+ if gem_declarations.has_key?(name)
209
+ g[:declared_groups] = gem_declarations[name][:groups]
210
+ else
211
+ g[:declared_groups] = []
212
+ end
213
+ g[:groups] = g[:declared_groups].dup
214
+ end
215
+ # Transitivize groups (since dependencies are already transitive, this is easy)
216
+ gems.each do |name, g|
217
+ g[:dependencies].each do |dep|
218
+ gems[dep][:groups] |= gems[name][:declared_groups].dup
31
219
  end
32
220
  end
221
+ gems
33
222
  end
34
223
  end
35
- end
36
224
 
37
- def calculate_dependents(spec_set)
38
- dependents = {}
39
- spec_set.each do |spec|
40
- dependents[spec] ||= []
225
+ #
226
+ # Get the gems (and their deps) in the given group.
227
+ #
228
+ # @param groups A list of groups to include (whitelist). If not passed (or set
229
+ # to nil), all gems will be selected.
230
+ # @param without_groups A list of groups to ignore. Gems will be excluded from
231
+ # the results if all groups they belong to are ignored.
232
+ # This matches bundler's `without` behavior.
233
+ # @param gems A list of gems to include regardless of what groups are included.
234
+ #
235
+ # @return Hash[String, Hash] The resulting gems, where key = gem_name, and the
236
+ # hash has:
237
+ # - version: version of the gem.
238
+ # - source info (:source/:git/:ref/:path) from the lockfile
239
+ # - dependencies: A list of gem names this gem has a runtime
240
+ # dependency on. Dependencies are transitive: if A depends on B,
241
+ # and B depends on C, then A has C in its :dependencies list.
242
+ # - development_dependencies: - A list of gem names this gem has a
243
+ # development dependency on. Dependencies are transitive: if A
244
+ # depends on B, and B depends on C, then A has C in its
245
+ # :development_dependencies list. development dependencies
246
+ # *include* runtime dependencies.
247
+ # - groups: The list of groups (symbols) this gem is in. Groups
248
+ # are transitive: if A has a runtime dependency on B, and A is
249
+ # in group X, then B is also in group X.
250
+ # - declared_groups: The list of groups (symbols) this gem was
251
+ # declared in the Gemfile.
252
+ #
253
+ def select_gems(groups: nil, without_groups: nil)
254
+ # First, select the gems that match
255
+ result = {}
256
+ gems.each do |name, g|
257
+ dep_groups = g[:declared_groups] - [ :only_a_runtime_dependency_of_other_gems ]
258
+ dep_groups = dep_groups & groups if groups
259
+ dep_groups = dep_groups - without_groups if without_groups
260
+ if dep_groups.any?
261
+ result[name] ||= g
262
+ g[:dependencies].each do |dep|
263
+ result[dep] ||= gems[dep]
264
+ end
265
+ end
266
+ end
267
+ result
41
268
  end
42
- spec_set.each do |spec|
43
- spec.dependencies.each do |dep|
44
- puts "#{dep.class} -> #{spec.class}"
45
- dependents[dep] << spec
269
+
270
+ #
271
+ # Get all locks from the given lockfile.
272
+ #
273
+ # @return Hash[String, Hash] The resulting gems, where key = gem_name, and the
274
+ # hash has:
275
+ # - version: version of the gem.
276
+ # - source info (:source/:git/:ref/:path)
277
+ # - dependencies: A list of gem names this gem has a runtime
278
+ # dependency on. Dependencies are transitive: if A depends on B,
279
+ # and B depends on C, then A has C in its :dependencies list.
280
+ # - development_dependencies: - A list of gem names this gem has a
281
+ # development dependency on. Dependencies are transitive: if A
282
+ # depends on B, and B depends on C, then A has C in its
283
+ # :development_dependencies list. development dependencies *include*
284
+ # runtime dependencies.
285
+ #
286
+ def locks
287
+ @locks ||= begin
288
+ # Grab all the specs from the lockfile
289
+ locks = {}
290
+ parsed_lockfile = Bundler::LockfileParser.new(IO.read(lockfile_path))
291
+ parsed_lockfile.specs.each do |spec|
292
+ # Never include bundler, it can't be bundled and doesn't put itself in
293
+ # the lockfile correctly anyway
294
+ next if spec.name == "bundler"
295
+ # Only the platform-specific locks for now (TODO make it possible to emit all locks)
296
+ next if spec.platform && spec.platform != Gem::Platform::RUBY
297
+ lock = lock_source_metadata(spec)
298
+ lock[:version] = spec.version.to_s
299
+ runtime = spec.dependencies.select { |dep| dep.type == :runtime }
300
+ lock[:dependencies] = Set.new(runtime.map { |dep| dep.name })
301
+ lock[:development_dependencies] = Set.new(spec.dependencies.map { |dep| dep.name })
302
+ lock[:dependencies].delete("bundler")
303
+ lock[:development_dependencies].delete("bundler")
304
+ locks[spec.name] = lock
305
+ end
306
+
307
+ # Transitivize the deps.
308
+ locks.each do |name, lock|
309
+ # Not all deps were brought over (platform-specific ones) so weed them out
310
+ lock[:dependencies] &= locks.keys
311
+ lock[:development_dependencies] &= locks.keys
312
+
313
+ lock[:dependencies] = transitive_dependencies(locks, name, :dependencies)
314
+ lock[:development_dependencies] = transitive_dependencies(locks, name, :development_dependencies)
315
+ end
316
+
317
+ locks
46
318
  end
47
319
  end
48
- dependents
49
- end
50
320
 
51
- def include_locked_gemfile(gemfile)
52
321
  #
53
- # Read the gemfile and inject its locks as first-class dependencies
322
+ # Get all desired gems, sans dependencies, from the gemfile.
323
+ #
324
+ # @param gemfile Path to the Gemfile to load
54
325
  #
55
- current_source = nil
56
- bundle = Bundler::Definition.build(gemfile, "#{gemfile}.lock", nil)
326
+ # @return Hash<String, Hash> An array of hashes where key = gem name and value
327
+ # has :groups (an array of symbols representing the groups the gem
328
+ # is in). :groups are not transitive, since we don't know the
329
+ # dependency tree yet.
330
+ #
331
+ def gem_declarations
332
+ @gem_declarations ||= begin
333
+ Bundler.with_clean_env do
334
+ # Set BUNDLE_GEMFILE to the new gemfile temporarily so all bundler's things work
335
+ # This works around some issues in bundler 1.11.2.
336
+ ENV["BUNDLE_GEMFILE"] = gemfile_path
337
+
338
+ parsed_gemfile = Bundler::Dsl.new
339
+ parsed_gemfile.eval_gemfile(gemfile_path)
340
+ parsed_gemfile.complete_overrides if parsed_gemfile.respond_to?(:complete_overrides)
57
341
 
58
- # Go through and create the actual gemfile from the given locks and
59
- # groups.
60
- bundle.resolve.sort_by { |spec| spec.name }.each do |spec|
61
- # bundler can't be installed by bundler so don't pin it.
62
- next if spec.name == "bundler"
63
- dep = bundle.dependencies.find { |d| d.name == spec.name}
64
- gem_metadata = ""
65
- if dep
66
- gem_metadata << ", groups: #{dep.groups.inspect}" if dep.groups != [:default]
67
- gem_metadata << ", platforms: #{dep.platforms.inspect}" if dep.platforms && !dep.platforms.empty?
342
+ result = {}
343
+ parsed_gemfile.dependencies.each do |dep|
344
+ groups = dep.groups.empty? ? [:default] : dep.groups
345
+ result[dep.name] = { groups: groups, platforms: dep.platforms }
346
+ end
347
+ result
348
+ end
68
349
  end
350
+ end
351
+
352
+ private
353
+
354
+ #
355
+ # Given a bunch of locks (name -> { dependencies: [name,name] }) and a
356
+ # dependency name, add its dependencies to the result transitively.
357
+ #
358
+ def transitive_dependencies(locks, name, dep_key, result = Set.new)
359
+ locks[name][dep_key].each do |dep|
360
+ # Only ever add a dep once, so we don't infinitely recurse
361
+ if result.add?(dep)
362
+ transitive_dependencies(locks, dep, dep_key, result)
363
+ end
364
+ end
365
+ result
366
+ end
367
+
368
+ #
369
+ # Get source and version metadata for the given Bundler spec (coming from a lockfile).
370
+ #
371
+ # @return Hash { version: <version>, git: <git>, path: <path>, source: <source>, ref: <ref> }
372
+ #
373
+ def lock_source_metadata(spec)
374
+ # Copy source information from included Gemfile
375
+ result = {}
69
376
  case spec.source
70
377
  when Bundler::Source::Rubygems
71
- if current_source
72
- if current_source != spec.source
73
- raise "Gem #{spec.name} has source #{spec.source}, but other gems have #{current_source}. Multiple rubygems sources are not supported."
74
- end
75
- else
76
- current_source = spec.source
77
- add_gemfile_line("source #{spec.source.remotes.first.to_s.inspect}", __LINE__)
78
- end
79
- add_gemfile_line("gem #{spec.name.inspect}, #{spec.version.to_s.inspect}#{gem_metadata}", __LINE__)
378
+ result[:source] = spec.source.remotes.first.to_s
80
379
  when Bundler::Source::Git
81
- add_gemfile_line("gem #{spec.name.inspect}, git: #{spec.source.uri.to_s.inspect}, ref: #{spec.source.revision.inspect}#{gem_metadata}", __LINE__)
380
+ result[:git] = spec.source.uri.to_s
381
+ result[:ref] = spec.source.revision
82
382
  when Bundler::Source::Path
83
- add_gemfile_line("gem #{spec.name.inspect}, path: #{spec.source.path.to_s.inspect}#{gem_metadata}", __LINE__)
383
+ result[:path] = spec.source.path.to_s
84
384
  else
85
385
  raise "Unknown source #{spec.source} for gem #{spec.name}"
86
386
  end
387
+ result
87
388
  end
88
- rescue
89
- puts $!
90
- puts $!.backtrace
91
- raise
92
- end
93
-
94
- private
95
-
96
- def add_gemfile_line(line, lineno)
97
- instance_eval(line, __FILE__, lineno)
98
389
  end
99
390
  end