bundler 1.11.1 → 2.2.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (328) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +2125 -840
  3. data/LICENSE.md +18 -19
  4. data/README.md +33 -11
  5. data/bundler.gemspec +34 -21
  6. data/exe/bundle +36 -6
  7. data/exe/bundler +2 -18
  8. data/lib/bundler.rb +435 -160
  9. data/lib/bundler/build_metadata.rb +45 -0
  10. data/lib/bundler/capistrano.rb +9 -3
  11. data/lib/bundler/cli.rb +550 -130
  12. data/lib/bundler/cli/add.rb +47 -0
  13. data/lib/bundler/cli/binstubs.rb +26 -10
  14. data/lib/bundler/cli/cache.rb +25 -17
  15. data/lib/bundler/cli/check.rb +8 -7
  16. data/lib/bundler/cli/clean.rb +8 -8
  17. data/lib/bundler/cli/common.rb +69 -9
  18. data/lib/bundler/cli/config.rb +170 -76
  19. data/lib/bundler/cli/console.rb +6 -1
  20. data/lib/bundler/cli/doctor.rb +140 -0
  21. data/lib/bundler/cli/exec.rb +63 -21
  22. data/lib/bundler/cli/fund.rb +36 -0
  23. data/lib/bundler/cli/gem.rb +158 -42
  24. data/lib/bundler/cli/info.rb +73 -0
  25. data/lib/bundler/cli/init.rb +22 -7
  26. data/lib/bundler/cli/inject.rb +38 -10
  27. data/lib/bundler/cli/install.rb +139 -104
  28. data/lib/bundler/cli/issue.rb +40 -0
  29. data/lib/bundler/cli/list.rb +60 -0
  30. data/lib/bundler/cli/lock.rb +27 -5
  31. data/lib/bundler/cli/open.rb +13 -5
  32. data/lib/bundler/cli/outdated.rb +251 -46
  33. data/lib/bundler/cli/platform.rb +6 -2
  34. data/lib/bundler/cli/plugin.rb +41 -0
  35. data/lib/bundler/cli/pristine.rb +52 -0
  36. data/lib/bundler/cli/remove.rb +18 -0
  37. data/lib/bundler/cli/show.rb +5 -4
  38. data/lib/bundler/cli/update.rb +67 -26
  39. data/lib/bundler/cli/viz.rb +11 -6
  40. data/lib/bundler/compact_index_client.rb +125 -0
  41. data/lib/bundler/compact_index_client/cache.rb +110 -0
  42. data/lib/bundler/compact_index_client/gem_parser.rb +28 -0
  43. data/lib/bundler/compact_index_client/updater.rb +104 -0
  44. data/lib/bundler/constants.rb +2 -0
  45. data/lib/bundler/current_ruby.rb +51 -174
  46. data/lib/bundler/definition.rb +533 -216
  47. data/lib/bundler/dep_proxy.rb +18 -8
  48. data/lib/bundler/dependency.rb +39 -12
  49. data/lib/bundler/deployment.rb +7 -0
  50. data/lib/bundler/deprecate.rb +31 -2
  51. data/lib/bundler/dsl.rb +188 -91
  52. data/lib/bundler/endpoint_specification.rb +51 -10
  53. data/lib/bundler/env.rb +116 -48
  54. data/lib/bundler/environment_preserver.rb +82 -0
  55. data/lib/bundler/errors.rb +108 -31
  56. data/lib/bundler/feature_flag.rb +60 -0
  57. data/lib/bundler/fetcher.rb +81 -52
  58. data/lib/bundler/fetcher/base.rb +15 -3
  59. data/lib/bundler/fetcher/compact_index.rb +140 -0
  60. data/lib/bundler/fetcher/dependency.rb +36 -42
  61. data/lib/bundler/fetcher/downloader.rb +39 -12
  62. data/lib/bundler/fetcher/index.rb +34 -9
  63. data/lib/bundler/friendly_errors.rb +132 -88
  64. data/lib/bundler/gem_helper.rb +92 -50
  65. data/lib/bundler/gem_helpers.rb +90 -5
  66. data/lib/bundler/gem_tasks.rb +3 -1
  67. data/lib/bundler/gem_version_promoter.rb +190 -0
  68. data/lib/bundler/gemdeps.rb +29 -0
  69. data/lib/bundler/graph.rb +20 -41
  70. data/lib/bundler/index.rb +74 -57
  71. data/lib/bundler/injector.rb +242 -31
  72. data/lib/bundler/inline.rb +49 -23
  73. data/lib/bundler/installer.rb +190 -74
  74. data/lib/bundler/installer/gem_installer.rb +33 -20
  75. data/lib/bundler/installer/parallel_installer.rb +201 -97
  76. data/lib/bundler/installer/standalone.rb +10 -6
  77. data/lib/bundler/lazy_specification.rb +74 -10
  78. data/lib/bundler/lockfile_generator.rb +95 -0
  79. data/lib/bundler/lockfile_parser.rb +126 -74
  80. data/lib/bundler/{ssl_certs → man}/.document +0 -0
  81. data/lib/bundler/man/bundle-add.1 +66 -0
  82. data/lib/bundler/man/bundle-add.1.ronn +46 -0
  83. data/lib/bundler/man/bundle-binstubs.1 +42 -0
  84. data/lib/bundler/man/bundle-binstubs.1.ronn +41 -0
  85. data/lib/bundler/man/bundle-cache.1 +55 -0
  86. data/{man/bundle-package.ronn → lib/bundler/man/bundle-cache.1.ronn} +22 -16
  87. data/lib/bundler/man/bundle-check.1 +31 -0
  88. data/lib/bundler/man/bundle-check.1.ronn +26 -0
  89. data/lib/bundler/man/bundle-clean.1 +24 -0
  90. data/lib/bundler/man/bundle-clean.1.ronn +18 -0
  91. data/lib/bundler/man/bundle-config.1 +488 -0
  92. data/lib/bundler/man/bundle-config.1.ronn +388 -0
  93. data/lib/bundler/man/bundle-doctor.1 +44 -0
  94. data/lib/bundler/man/bundle-doctor.1.ronn +33 -0
  95. data/lib/bundler/man/bundle-exec.1 +165 -0
  96. data/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +20 -4
  97. data/lib/bundler/man/bundle-gem.1 +102 -0
  98. data/{man/bundle-gem.ronn → lib/bundler/man/bundle-gem.1.ronn} +37 -13
  99. data/lib/bundler/man/bundle-info.1 +20 -0
  100. data/lib/bundler/man/bundle-info.1.ronn +17 -0
  101. data/lib/bundler/man/bundle-init.1 +25 -0
  102. data/lib/bundler/man/bundle-init.1.ronn +29 -0
  103. data/lib/bundler/man/bundle-inject.1 +33 -0
  104. data/lib/bundler/man/bundle-inject.1.ronn +22 -0
  105. data/lib/bundler/man/bundle-install.1 +338 -0
  106. data/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +82 -76
  107. data/lib/bundler/man/bundle-list.1 +50 -0
  108. data/lib/bundler/man/bundle-list.1.ronn +33 -0
  109. data/lib/bundler/man/bundle-lock.1 +84 -0
  110. data/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +47 -0
  111. data/lib/bundler/man/bundle-open.1 +32 -0
  112. data/lib/bundler/man/bundle-open.1.ronn +19 -0
  113. data/lib/bundler/man/bundle-outdated.1 +155 -0
  114. data/lib/bundler/man/bundle-outdated.1.ronn +111 -0
  115. data/lib/bundler/man/bundle-platform.1 +61 -0
  116. data/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +1 -1
  117. data/lib/bundler/man/bundle-pristine.1 +34 -0
  118. data/lib/bundler/man/bundle-pristine.1.ronn +34 -0
  119. data/lib/bundler/man/bundle-remove.1 +31 -0
  120. data/lib/bundler/man/bundle-remove.1.ronn +23 -0
  121. data/lib/bundler/man/bundle-show.1 +23 -0
  122. data/lib/bundler/man/bundle-show.1.ronn +21 -0
  123. data/lib/bundler/man/bundle-update.1 +394 -0
  124. data/lib/bundler/man/bundle-update.1.ronn +350 -0
  125. data/lib/bundler/man/bundle-viz.1 +39 -0
  126. data/lib/bundler/man/bundle-viz.1.ronn +30 -0
  127. data/lib/bundler/man/bundle.1 +136 -0
  128. data/lib/bundler/man/bundle.1.ronn +111 -0
  129. data/lib/bundler/man/gemfile.5 +686 -0
  130. data/{man → lib/bundler/man}/gemfile.5.ronn +117 -95
  131. data/lib/bundler/man/index.txt +25 -0
  132. data/lib/bundler/match_platform.rb +15 -4
  133. data/lib/bundler/mirror.rb +223 -0
  134. data/lib/bundler/plugin.rb +330 -0
  135. data/lib/bundler/plugin/api.rb +81 -0
  136. data/lib/bundler/plugin/api/source.rb +304 -0
  137. data/lib/bundler/plugin/dsl.rb +53 -0
  138. data/lib/bundler/plugin/events.rb +61 -0
  139. data/lib/bundler/plugin/index.rb +182 -0
  140. data/lib/bundler/plugin/installer.rb +109 -0
  141. data/lib/bundler/plugin/installer/git.rb +38 -0
  142. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  143. data/lib/bundler/plugin/source_list.rb +27 -0
  144. data/lib/bundler/process_lock.rb +24 -0
  145. data/lib/bundler/psyched_yaml.rb +2 -6
  146. data/lib/bundler/remote_specification.rb +42 -9
  147. data/lib/bundler/resolver.rb +312 -225
  148. data/lib/bundler/resolver/spec_group.rb +122 -0
  149. data/lib/bundler/retry.rb +11 -5
  150. data/lib/bundler/ruby_dsl.rb +9 -2
  151. data/lib/bundler/ruby_version.rb +84 -61
  152. data/lib/bundler/rubygems_ext.rb +92 -53
  153. data/lib/bundler/rubygems_gem_installer.rb +84 -0
  154. data/lib/bundler/rubygems_integration.rb +320 -395
  155. data/lib/bundler/runtime.rb +87 -75
  156. data/lib/bundler/settings.rb +297 -119
  157. data/lib/bundler/settings/validator.rb +102 -0
  158. data/lib/bundler/setup.rb +13 -12
  159. data/lib/bundler/shared_helpers.rb +234 -53
  160. data/lib/bundler/similarity_detector.rb +5 -3
  161. data/lib/bundler/source.rb +63 -4
  162. data/lib/bundler/source/gemspec.rb +18 -0
  163. data/lib/bundler/source/git.rb +97 -50
  164. data/lib/bundler/source/git/git_proxy.rb +138 -65
  165. data/lib/bundler/source/metadata.rb +67 -0
  166. data/lib/bundler/source/path.rb +83 -47
  167. data/lib/bundler/source/path/installer.rb +42 -11
  168. data/lib/bundler/source/rubygems.rb +231 -116
  169. data/lib/bundler/source/rubygems/remote.rb +30 -1
  170. data/lib/bundler/source_list.rb +103 -21
  171. data/lib/bundler/spec_set.rb +96 -51
  172. data/lib/bundler/stub_specification.rb +87 -4
  173. data/lib/bundler/templates/.document +1 -0
  174. data/lib/bundler/templates/Executable +14 -1
  175. data/lib/bundler/templates/Executable.bundler +114 -0
  176. data/lib/bundler/templates/Executable.standalone +6 -4
  177. data/lib/bundler/templates/Gemfile +4 -1
  178. data/lib/bundler/templates/gems.rb +8 -0
  179. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +79 -44
  180. data/lib/bundler/templates/newgem/Gemfile.tt +18 -2
  181. data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
  182. data/lib/bundler/templates/newgem/README.md.tt +16 -10
  183. data/lib/bundler/templates/newgem/Rakefile.tt +22 -8
  184. data/lib/bundler/templates/newgem/bin/console.tt +2 -1
  185. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  186. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  187. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
  188. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
  189. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +18 -0
  190. data/lib/bundler/templates/newgem/gitignore.tt +5 -1
  191. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  192. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +9 -6
  193. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +6 -4
  194. data/lib/bundler/templates/newgem/newgem.gemspec.tt +27 -28
  195. data/lib/bundler/templates/newgem/rspec.tt +1 -0
  196. data/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  197. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +4 -4
  198. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +15 -2
  199. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +3 -1
  200. data/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt +6 -0
  201. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  202. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  203. data/lib/bundler/templates/newgem/{.travis.yml.tt → travis.yml.tt} +2 -0
  204. data/lib/bundler/ui.rb +5 -3
  205. data/lib/bundler/ui/rg_proxy.rb +3 -1
  206. data/lib/bundler/ui/shell.rb +54 -21
  207. data/lib/bundler/ui/silent.rb +26 -1
  208. data/lib/bundler/uri_credentials_filter.rb +43 -0
  209. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
  210. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
  211. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
  212. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  213. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1764 -0
  214. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +11 -5
  215. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  216. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
  217. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +113 -134
  218. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
  219. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
  220. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
  221. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  222. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
  223. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
  224. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
  225. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
  226. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +158 -0
  227. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +82 -8
  228. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +4 -1
  229. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +2 -0
  230. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +6 -2
  231. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +555 -150
  232. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +6 -3
  233. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +19 -12
  234. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +310 -467
  235. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
  236. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
  237. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  238. data/lib/bundler/vendor/thor/lib/thor.rb +58 -25
  239. data/lib/bundler/vendor/thor/lib/thor/actions.rb +50 -33
  240. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
  241. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +5 -3
  242. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +9 -19
  243. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +16 -8
  244. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +79 -22
  245. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +33 -20
  246. data/lib/bundler/vendor/thor/lib/thor/base.rb +110 -67
  247. data/lib/bundler/vendor/thor/lib/thor/command.rb +33 -24
  248. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +21 -1
  249. data/lib/bundler/vendor/thor/lib/thor/error.rb +81 -3
  250. data/lib/bundler/vendor/thor/lib/thor/group.rb +16 -16
  251. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +5 -5
  252. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
  253. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +2 -0
  254. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +6 -6
  255. data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
  256. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
  257. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +4 -7
  258. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +18 -18
  259. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +60 -26
  260. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +31 -13
  261. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +1 -0
  262. data/lib/bundler/vendor/thor/lib/thor/runner.rb +42 -39
  263. data/lib/bundler/vendor/thor/lib/thor/shell.rb +5 -5
  264. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +109 -39
  265. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +7 -3
  266. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +5 -5
  267. data/lib/bundler/vendor/thor/lib/thor/util.rb +26 -9
  268. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  269. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +154 -0
  270. data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
  271. data/lib/bundler/vendor/uri/lib/uri/common.rb +744 -0
  272. data/lib/bundler/vendor/uri/lib/uri/file.rb +94 -0
  273. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
  274. data/lib/bundler/vendor/uri/lib/uri/generic.rb +1568 -0
  275. data/lib/bundler/vendor/uri/lib/uri/http.rb +88 -0
  276. data/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
  277. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
  278. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +21 -0
  279. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +294 -0
  280. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
  281. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +125 -0
  282. data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
  283. data/lib/bundler/vendored_fileutils.rb +4 -0
  284. data/lib/bundler/vendored_molinillo.rb +3 -1
  285. data/lib/bundler/vendored_persistent.rb +45 -9
  286. data/lib/bundler/vendored_thor.rb +8 -3
  287. data/lib/bundler/vendored_tmpdir.rb +4 -0
  288. data/lib/bundler/vendored_uri.rb +4 -0
  289. data/lib/bundler/version.rb +7 -4
  290. data/lib/bundler/version_ranges.rb +122 -0
  291. data/lib/bundler/vlad.rb +8 -2
  292. data/lib/bundler/worker.rb +38 -6
  293. data/lib/bundler/yaml_serializer.rb +89 -0
  294. metadata +164 -158
  295. data/.gitignore +0 -16
  296. data/.rspec +0 -3
  297. data/.rubocop.yml +0 -105
  298. data/.rubocop_todo.yml +0 -120
  299. data/.travis.yml +0 -97
  300. data/CODE_OF_CONDUCT.md +0 -42
  301. data/CONTRIBUTING.md +0 -32
  302. data/DEVELOPMENT.md +0 -118
  303. data/ISSUES.md +0 -96
  304. data/Rakefile +0 -309
  305. data/bin/rake +0 -14
  306. data/bin/rspec +0 -10
  307. data/bin/rubocop +0 -11
  308. data/exe/bundle_ruby +0 -60
  309. data/lib/bundler/cli/package.rb +0 -45
  310. data/lib/bundler/environment.rb +0 -41
  311. data/lib/bundler/gem_path_manipulation.rb +0 -8
  312. data/lib/bundler/gem_remote_fetcher.rb +0 -41
  313. data/lib/bundler/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
  314. data/lib/bundler/ssl_certs/AddTrustExternalCARoot.pem +0 -32
  315. data/lib/bundler/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  316. data/lib/bundler/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
  317. data/lib/bundler/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  318. data/lib/bundler/ssl_certs/GeoTrustGlobalCA.pem +0 -20
  319. data/lib/bundler/ssl_certs/certificate_manager.rb +0 -64
  320. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +0 -4
  321. data/lib/bundler/vendor/net/http/faster.rb +0 -26
  322. data/lib/bundler/vendor/net/http/persistent/ssl_reuse.rb +0 -128
  323. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +0 -10
  324. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -98
  325. data/man/bundle-config.ronn +0 -187
  326. data/man/bundle-update.ronn +0 -188
  327. data/man/bundle.ronn +0 -98
  328. data/man/index.txt +0 -8
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class Gemdeps
5
+ def initialize(runtime)
6
+ @runtime = runtime
7
+ end
8
+
9
+ def requested_specs
10
+ @runtime.requested_specs
11
+ end
12
+
13
+ def specs
14
+ @runtime.specs
15
+ end
16
+
17
+ def dependencies
18
+ @runtime.dependencies
19
+ end
20
+
21
+ def current_dependencies
22
+ @runtime.current_dependencies
23
+ end
24
+
25
+ def requires
26
+ @runtime.requires
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
  module Bundler
3
5
  class Graph
@@ -16,7 +18,6 @@ module Bundler
16
18
  @node_options = {}
17
19
  @edge_options = {}
18
20
 
19
- _patching_gem_dependency_class
20
21
  _populate_relations
21
22
  end
22
23
 
@@ -26,30 +27,25 @@ module Bundler
26
27
  GraphVizClient.new(self).run
27
28
  end
28
29
 
29
- private
30
+ private
30
31
 
31
32
  def _populate_relations
32
33
  parent_dependencies = _groups.values.to_set.flatten
33
34
  loop do
34
- if parent_dependencies.empty?
35
- break
36
- else
37
- tmp = Set.new
38
- parent_dependencies.each do |dependency|
39
- # if the dependency is a prerelease, allow to_spec to be non-nil
40
- dependency.prerelease = true
41
-
42
- child_dependencies = dependency.to_spec.runtime_dependencies.to_set
43
- @relations[dependency.name] += child_dependencies.map(&:name).to_set
44
- tmp += child_dependencies
45
-
46
- @node_options[dependency.name] = _make_label(dependency, :node)
47
- child_dependencies.each do |c_dependency|
48
- @edge_options["#{dependency.name}_#{c_dependency.name}"] = _make_label(c_dependency, :edge)
49
- end
35
+ break if parent_dependencies.empty?
36
+
37
+ tmp = Set.new
38
+ parent_dependencies.each do |dependency|
39
+ child_dependencies = spec_for_dependency(dependency).runtime_dependencies.to_set
40
+ @relations[dependency.name] += child_dependencies.map(&:name).to_set
41
+ tmp += child_dependencies
42
+
43
+ @node_options[dependency.name] = _make_label(dependency, :node)
44
+ child_dependencies.each do |c_dependency|
45
+ @edge_options["#{dependency.name}_#{c_dependency.name}"] = _make_label(c_dependency, :edge)
50
46
  end
51
- parent_dependencies = tmp
52
47
  end
48
+ parent_dependencies = tmp
53
49
  end
54
50
  end
55
51
 
@@ -75,7 +71,7 @@ module Bundler
75
71
  when :node
76
72
  if symbol_or_string_or_dependency.is_a?(Gem::Dependency)
77
73
  label = symbol_or_string_or_dependency.name.dup
78
- label << "\n#{symbol_or_string_or_dependency.to_spec.version}" if @show_version
74
+ label << "\n#{spec_for_dependency(symbol_or_string_or_dependency).version}" if @show_version
79
75
  else
80
76
  label = symbol_or_string_or_dependency.to_s
81
77
  end
@@ -91,25 +87,8 @@ module Bundler
91
87
  label.nil? ? {} : { :label => label }
92
88
  end
93
89
 
94
- def _patching_gem_dependency_class
95
- # method borrow from rubygems/dependency.rb
96
- # redefinition of matching_specs will also redefine to_spec and to_specs
97
- Gem::Dependency.class_eval do
98
- def matching_specs(platform_only = false)
99
- matches = Bundler.load.specs.select do |spec|
100
- name == spec.name &&
101
- requirement.satisfied_by?(spec.version)
102
- end
103
-
104
- if platform_only
105
- matches.select! do |spec|
106
- Gem::Platform.match spec.platform
107
- end
108
- end
109
-
110
- matches = matches.sort_by(&:sort_obj) # HACK: shouldn't be needed
111
- end
112
- end
90
+ def spec_for_dependency(dependency)
91
+ @env.requested_specs.find {|s| s.name == dependency.name }
113
92
  end
114
93
 
115
94
  class GraphVizClient
@@ -138,7 +117,7 @@ module Bundler
138
117
  :style => "filled",
139
118
  :fillcolor => "#B9B9D5",
140
119
  :shape => "box3d",
141
- :fontsize => 16
120
+ :fontsize => 16,
142
121
  }.merge(@node_options[group])
143
122
  )
144
123
  end
@@ -163,7 +142,7 @@ module Bundler
163
142
  g.output @output_format.to_sym => "#{@output_file}.#{@output_format}"
164
143
  Bundler.ui.info "#{@output_file}.#{@output_format}"
165
144
  rescue ArgumentError => e
166
- $stderr.puts "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
145
+ warn "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
167
146
  raise e
168
147
  end
169
148
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
 
3
5
  module Bundler
@@ -20,15 +22,14 @@ module Bundler
20
22
  @sources = []
21
23
  @cache = {}
22
24
  @specs = Hash.new {|h, k| h[k] = {} }
23
- @all_specs = Hash.new {|h, k| h[k] = [] }
25
+ @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH }
24
26
  end
25
27
 
26
28
  def initialize_copy(o)
27
- super
28
- @sources = @sources.dup
29
+ @sources = o.sources.dup
29
30
  @cache = {}
30
31
  @specs = Hash.new {|h, k| h[k] = {} }
31
- @all_specs = Hash.new {|h, k| h[k] = [] }
32
+ @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH }
32
33
 
33
34
  o.specs.each do |name, hash|
34
35
  @specs[name] = hash.dup
@@ -48,7 +49,7 @@ module Bundler
48
49
  end
49
50
 
50
51
  def search_all(name)
51
- all_matches = @all_specs[name] + local_search(name)
52
+ all_matches = local_search(name) + @all_specs[name]
52
53
  @sources.each do |source|
53
54
  all_matches.concat(source.search_all(name))
54
55
  end
@@ -58,20 +59,33 @@ module Bundler
58
59
  # Search this index's specs, and any source indexes that this index knows
59
60
  # about, returning all of the results.
60
61
  def search(query, base = nil)
62
+ sort_specs(unsorted_search(query, base))
63
+ end
64
+
65
+ def unsorted_search(query, base)
61
66
  results = local_search(query, base)
62
- seen = Set.new(results.map {|spec| [spec.name, spec.version, spec.platform] })
67
+
68
+ seen = results.map(&:full_name).to_set unless @sources.empty?
63
69
 
64
70
  @sources.each do |source|
65
- source.search(query, base).each do |spec|
66
- lookup = [spec.name, spec.version, spec.platform]
67
- unless seen.include?(lookup)
68
- results << spec
69
- seen << lookup
70
- end
71
+ source.unsorted_search(query, base).each do |spec|
72
+ results << spec if seen.add?(spec.full_name)
71
73
  end
72
74
  end
73
75
 
74
- results.sort_by {|s| [s.version, s.platform.to_s == RUBY ? NULL : s.platform.to_s] }
76
+ results
77
+ end
78
+ protected :unsorted_search
79
+
80
+ def self.sort_specs(specs)
81
+ specs.sort_by do |s|
82
+ platform_string = s.platform.to_s
83
+ [s.version, platform_string == RUBY ? NULL : platform_string]
84
+ end
85
+ end
86
+
87
+ def sort_specs(specs)
88
+ self.class.sort_specs(specs)
75
89
  end
76
90
 
77
91
  def local_search(query, base = nil)
@@ -88,37 +102,50 @@ module Bundler
88
102
  alias_method :[], :search
89
103
 
90
104
  def <<(spec)
91
- @specs[spec.name]["#{spec.version}-#{spec.platform}"] = spec
92
-
105
+ @specs[spec.name][spec.full_name] = spec
93
106
  spec
94
107
  end
95
108
 
96
109
  def each(&blk)
110
+ return enum_for(:each) unless blk
97
111
  specs.values.each do |spec_sets|
98
112
  spec_sets.values.each(&blk)
99
113
  end
114
+ sources.each {|s| s.each(&blk) }
115
+ self
116
+ end
117
+
118
+ def spec_names
119
+ names = specs.keys + sources.map(&:spec_names)
120
+ names.uniq!
121
+ names
100
122
  end
101
123
 
102
124
  # returns a list of the dependencies
103
125
  def unmet_dependency_names
104
- names = dependency_names
105
- names.delete_if {|n| n == "bundler" }
106
- names.select {|n| search(n).empty? }
126
+ dependency_names.select do |name|
127
+ name != "bundler" && search(name).empty?
128
+ end
107
129
  end
108
130
 
109
131
  def dependency_names
110
132
  names = []
111
- each {|s| names.push(*s.dependencies.map(&:name)) }
133
+ each do |spec|
134
+ spec.dependencies.each do |dep|
135
+ next if dep.type == :development
136
+ names << dep.name
137
+ end
138
+ end
112
139
  names.uniq
113
140
  end
114
141
 
115
142
  def use(other, override_dupes = false)
116
143
  return unless other
117
144
  other.each do |s|
118
- if (dupes = search_by_spec(s)) && dupes.any?
119
- @all_specs[s.name] = [s] + dupes
145
+ if (dupes = search_by_spec(s)) && !dupes.empty?
146
+ # safe to << since it's a new array when it has contents
147
+ @all_specs[s.name] = dupes << s
120
148
  next unless override_dupes
121
- self << s
122
149
  end
123
150
  self << s
124
151
  end
@@ -131,23 +158,28 @@ module Bundler
131
158
  end
132
159
  end
133
160
 
161
+ # Whether all the specs in self are in other
162
+ # TODO: rename to #include?
134
163
  def ==(other)
135
164
  all? do |spec|
136
165
  other_spec = other[spec].first
137
- other_spec && (spec.dependencies & other_spec.dependencies).empty? && spec.source == other_spec.source
166
+ other_spec && dependencies_eql?(spec, other_spec) && spec.source == other_spec.source
138
167
  end
139
168
  end
140
169
 
170
+ def dependencies_eql?(spec, other_spec)
171
+ deps = spec.dependencies.select {|d| d.type != :development }
172
+ other_deps = other_spec.dependencies.select {|d| d.type != :development }
173
+ Set.new(deps) == Set.new(other_deps)
174
+ end
175
+
141
176
  def add_source(index)
142
- if index.is_a?(Index)
143
- @sources << index
144
- @sources.uniq! # need to use uniq! here instead of checking for the item before adding
145
- else
146
- raise ArgumentError, "Source must be an index, not #{index.class}"
147
- end
177
+ raise ArgumentError, "Source must be an index, not #{index.class}" unless index.is_a?(Index)
178
+ @sources << index
179
+ @sources.uniq! # need to use uniq! here instead of checking for the item before adding
148
180
  end
149
181
 
150
- private
182
+ private
151
183
 
152
184
  def specs_by_name(name)
153
185
  @specs[name].values
@@ -156,45 +188,30 @@ module Bundler
156
188
  def search_by_dependency(dependency, base = nil)
157
189
  @cache[base || false] ||= {}
158
190
  @cache[base || false][dependency] ||= begin
159
- specs = specs_by_name(dependency.name) + (base || [])
191
+ specs = specs_by_name(dependency.name)
192
+ specs += base if base
160
193
  found = specs.select do |spec|
194
+ next true if spec.source.is_a?(Source::Gemspec)
161
195
  if base # allow all platforms when searching from a lockfile
162
196
  dependency.matches_spec?(spec)
163
197
  else
164
- dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
198
+ if Gem::Platform.respond_to? :match_spec?
199
+ dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
200
+ else
201
+ dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
202
+ end
165
203
  end
166
204
  end
167
205
 
168
- wants_prerelease = dependency.requirement.prerelease?
169
- only_prerelease = specs.all? {|spec| spec.version.prerelease? }
170
-
171
- unless wants_prerelease || only_prerelease
172
- found.reject! {|spec| spec.version.prerelease? }
173
- end
174
-
175
206
  found
176
207
  end
177
208
  end
178
209
 
179
- def search_by_spec(spec)
180
- spec = @specs[spec.name]["#{spec.version}-#{spec.platform}"]
181
- spec ? [spec] : []
182
- end
210
+ EMPTY_SEARCH = [].freeze
183
211
 
184
- if RUBY_VERSION < "1.9"
185
- def same_version?(a, b)
186
- regex = /^(.*?)(?:\.0)*$/
187
- a.to_s[regex, 1] == b.to_s[regex, 1]
188
- end
189
- else
190
- def same_version?(a, b)
191
- a == b
192
- end
193
- end
194
-
195
- def spec_satisfies_dependency?(spec, dep)
196
- return false unless dep.name == spec.name
197
- dep.requirement.satisfied_by?(spec.version)
212
+ def search_by_spec(spec)
213
+ spec = @specs[spec.name][spec.full_name]
214
+ spec ? [spec] : EMPTY_SEARCH
198
215
  end
199
216
  end
200
217
  end
@@ -1,62 +1,273 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bundler
2
4
  class Injector
3
- def self.inject(new_deps)
4
- injector = new(new_deps)
5
+ INJECTED_GEMS = "injected gems".freeze
6
+
7
+ def self.inject(new_deps, options = {})
8
+ injector = new(new_deps, options)
5
9
  injector.inject(Bundler.default_gemfile, Bundler.default_lockfile)
6
10
  end
7
11
 
8
- def initialize(new_deps)
9
- @new_deps = new_deps
12
+ def self.remove(gems, options = {})
13
+ injector = new(gems, options)
14
+ injector.remove(Bundler.default_gemfile, Bundler.default_lockfile)
10
15
  end
11
16
 
17
+ def initialize(deps, options = {})
18
+ @deps = deps
19
+ @options = options
20
+ end
21
+
22
+ # @param [Pathname] gemfile_path The Gemfile in which to inject the new dependency.
23
+ # @param [Pathname] lockfile_path The lockfile in which to inject the new dependency.
24
+ # @return [Array]
12
25
  def inject(gemfile_path, lockfile_path)
13
- if Bundler.settings[:frozen]
26
+ if Bundler.frozen_bundle?
14
27
  # ensure the lock and Gemfile are synced
15
28
  Bundler.definition.ensure_equivalent_gemfile_and_lockfile(true)
16
- # temporarily remove frozen while we inject
17
- frozen = Bundler.settings.delete(:frozen)
18
29
  end
19
30
 
20
- # evaluate the Gemfile we have now
21
- builder = Dsl.new
22
- builder.eval_gemfile(gemfile_path)
31
+ # temporarily unfreeze
32
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
33
+ # evaluate the Gemfile we have now
34
+ builder = Dsl.new
35
+ builder.eval_gemfile(gemfile_path)
36
+
37
+ # don't inject any gems that are already in the Gemfile
38
+ @deps -= builder.dependencies
39
+
40
+ # add new deps to the end of the in-memory Gemfile
41
+ # Set conservative versioning to false because
42
+ # we want to let the resolver resolve the version first
43
+ builder.eval_gemfile(INJECTED_GEMS, build_gem_lines(false)) if @deps.any?
44
+
45
+ # resolve to see if the new deps broke anything
46
+ @definition = builder.to_definition(lockfile_path, {})
47
+ @definition.resolve_remotely!
23
48
 
24
- # don't inject any gems that are already in the Gemfile
25
- @new_deps -= builder.dependencies
49
+ # since nothing broke, we can add those gems to the gemfile
50
+ append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @deps.any?
26
51
 
27
- # add new deps to the end of the in-memory Gemfile
28
- builder.eval_gemfile("injected gems", new_gem_lines) if @new_deps.any?
52
+ # since we resolved successfully, write out the lockfile
53
+ @definition.lock(Bundler.default_lockfile)
54
+
55
+ # invalidate the cached Bundler.definition
56
+ Bundler.reset_paths!
57
+
58
+ # return an array of the deps that we added
59
+ @deps
60
+ end
61
+ end
62
+
63
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
64
+ # @param [Pathname] lockfile_path The lockfile from which to remove dependencies.
65
+ # @return [Array]
66
+ def remove(gemfile_path, lockfile_path)
67
+ # remove gems from each gemfiles we have
68
+ Bundler.definition.gemfiles.each do |path|
69
+ deps = remove_deps(path)
70
+
71
+ show_warning("No gems were removed from the gemfile.") if deps.empty?
72
+
73
+ deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep, false)} was removed." }
74
+ end
75
+ end
29
76
 
30
- # resolve to see if the new deps broke anything
31
- definition = builder.to_definition(lockfile_path, {})
32
- definition.resolve_remotely!
77
+ private
33
78
 
34
- # since nothing broke, we can add those gems to the gemfile
35
- append_to(gemfile_path) if @new_deps.any?
79
+ def conservative_version(spec)
80
+ version = spec.version
81
+ return ">= 0" if version.nil?
82
+ segments = version.segments
83
+ seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2
36
84
 
37
- # since we resolved successfully, write out the lockfile
38
- definition.lock(Bundler.default_lockfile)
85
+ prerelease_suffix = version.to_s.gsub(version.release.to_s, "") if version.prerelease?
86
+ "#{version_prefix}#{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
87
+ end
39
88
 
40
- # return an array of the deps that we added
41
- return @new_deps
42
- ensure
43
- Bundler.settings[:frozen] = "1" if frozen
89
+ def version_prefix
90
+ if @options[:strict]
91
+ "= "
92
+ elsif @options[:optimistic]
93
+ ">= "
94
+ else
95
+ "~> "
96
+ end
44
97
  end
45
98
 
46
- private
99
+ def build_gem_lines(conservative_versioning)
100
+ @deps.map do |d|
101
+ name = d.name.dump
102
+
103
+ requirement = if conservative_versioning
104
+ ", \"#{conservative_version(@definition.specs[d.name][0])}\""
105
+ else
106
+ ", #{d.requirement.as_list.map(&:dump).join(", ")}"
107
+ end
108
+
109
+ if d.groups != Array(:default)
110
+ group = d.groups.size == 1 ? ", :group => #{d.groups.first.inspect}" : ", :groups => #{d.groups.inspect}"
111
+ end
112
+
113
+ source = ", :source => \"#{d.source}\"" unless d.source.nil?
114
+ git = ", :git => \"#{d.git}\"" unless d.git.nil?
115
+ branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil?
47
116
 
48
- def new_gem_lines
49
- @new_deps.map do |d|
50
- %(gem '#{d.name}', '#{d.requirement}')
117
+ %(gem #{name}#{requirement}#{group}#{source}#{git}#{branch})
51
118
  end.join("\n")
52
119
  end
53
120
 
54
- def append_to(gemfile_path)
121
+ def append_to(gemfile_path, new_gem_lines)
55
122
  gemfile_path.open("a") do |f|
56
123
  f.puts
57
- f.puts "# Added at #{Time.now} by #{`whoami`.chomp}:"
58
124
  f.puts new_gem_lines
59
125
  end
60
126
  end
127
+
128
+ # evaluates a gemfile to remove the specified gem
129
+ # from it.
130
+ def remove_deps(gemfile_path)
131
+ initial_gemfile = IO.readlines(gemfile_path)
132
+
133
+ Bundler.ui.info "Removing gems from #{gemfile_path}"
134
+
135
+ # evaluate the Gemfile we have
136
+ builder = Dsl.new
137
+ builder.eval_gemfile(gemfile_path)
138
+
139
+ removed_deps = remove_gems_from_dependencies(builder, @deps, gemfile_path)
140
+
141
+ # abort the operation if no gems were removed
142
+ # no need to operate on gemfile further
143
+ return [] if removed_deps.empty?
144
+
145
+ cleaned_gemfile = remove_gems_from_gemfile(@deps, gemfile_path)
146
+
147
+ SharedHelpers.write_to_gemfile(gemfile_path, cleaned_gemfile)
148
+
149
+ # check for errors
150
+ # including extra gems being removed
151
+ # or some gems not being removed
152
+ # and return the actual removed deps
153
+ cross_check_for_errors(gemfile_path, builder.dependencies, removed_deps, initial_gemfile)
154
+ end
155
+
156
+ # @param [Dsl] builder Dsl object of current Gemfile.
157
+ # @param [Array] gems Array of names of gems to be removed.
158
+ # @param [Pathname] gemfile_path Path of the Gemfile.
159
+ # @return [Array] Array of removed dependencies.
160
+ def remove_gems_from_dependencies(builder, gems, gemfile_path)
161
+ removed_deps = []
162
+
163
+ gems.each do |gem_name|
164
+ deleted_dep = builder.dependencies.find {|d| d.name == gem_name }
165
+
166
+ if deleted_dep.nil?
167
+ raise GemfileError, "`#{gem_name}` is not specified in #{gemfile_path} so it could not be removed."
168
+ end
169
+
170
+ builder.dependencies.delete(deleted_dep)
171
+
172
+ removed_deps << deleted_dep
173
+ end
174
+
175
+ removed_deps
176
+ end
177
+
178
+ # @param [Array] gems Array of names of gems to be removed.
179
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
180
+ def remove_gems_from_gemfile(gems, gemfile_path)
181
+ patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
182
+ new_gemfile = []
183
+ multiline_removal = false
184
+ IO.readlines(gemfile_path).each do |line|
185
+ match_data = line.match(patterns)
186
+ if match_data && is_not_within_comment?(line, match_data)
187
+ multiline_removal = line.rstrip.end_with?(",")
188
+ # skip lines which match the regex
189
+ next
190
+ end
191
+
192
+ # skip followup lines until line does not end with ','
193
+ new_gemfile << line unless multiline_removal
194
+ multiline_removal = line.rstrip.end_with?(",") if multiline_removal
195
+ end
196
+
197
+ # remove line \n and append them with other strings
198
+ new_gemfile.each_with_index do |_line, index|
199
+ if new_gemfile[index + 1] == "\n"
200
+ new_gemfile[index] += new_gemfile[index + 1]
201
+ new_gemfile.delete_at(index + 1)
202
+ end
203
+ end
204
+
205
+ %w[group source env install_if].each {|block| remove_nested_blocks(new_gemfile, block) }
206
+
207
+ new_gemfile.join.chomp
208
+ end
209
+
210
+ # @param [String] line Individual line of gemfile content.
211
+ # @param [MatchData] match_data Data about Regex match.
212
+ def is_not_within_comment?(line, match_data)
213
+ match_start_index = match_data.offset(0).first
214
+ !line[0..match_start_index].include?("#")
215
+ end
216
+
217
+ # @param [Array] gemfile Array of gemfile contents.
218
+ # @param [String] block_name Name of block name to look for.
219
+ def remove_nested_blocks(gemfile, block_name)
220
+ nested_blocks = 0
221
+
222
+ # count number of nested blocks
223
+ gemfile.each_with_index {|line, index| nested_blocks += 1 if !gemfile[index + 1].nil? && gemfile[index + 1].include?(block_name) && line.include?(block_name) }
224
+
225
+ while nested_blocks >= 0
226
+ nested_blocks -= 1
227
+
228
+ gemfile.each_with_index do |line, index|
229
+ next unless !line.nil? && line.strip.start_with?(block_name)
230
+ if gemfile[index + 1] =~ /^\s*end\s*$/
231
+ gemfile[index] = nil
232
+ gemfile[index + 1] = nil
233
+ end
234
+ end
235
+
236
+ gemfile.compact!
237
+ end
238
+ end
239
+
240
+ # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
241
+ # @param [Array] original_deps Array of original dependencies.
242
+ # @param [Array] removed_deps Array of removed dependencies.
243
+ # @param [Array] initial_gemfile Contents of original Gemfile before any operation.
244
+ def cross_check_for_errors(gemfile_path, original_deps, removed_deps, initial_gemfile)
245
+ # evaluate the new gemfile to look for any failure cases
246
+ builder = Dsl.new
247
+ builder.eval_gemfile(gemfile_path)
248
+
249
+ # record gems which were removed but not requested
250
+ extra_removed_gems = original_deps - builder.dependencies
251
+
252
+ # if some extra gems were removed then raise error
253
+ # and revert Gemfile to original
254
+ unless extra_removed_gems.empty?
255
+ SharedHelpers.write_to_gemfile(gemfile_path, initial_gemfile.join)
256
+
257
+ raise InvalidOption, "Gems could not be removed. #{extra_removed_gems.join(", ")} would also have been removed. Bundler cannot continue."
258
+ end
259
+
260
+ # record gems which could not be removed due to some reasons
261
+ errored_deps = builder.dependencies.select {|d| d.gemfile == gemfile_path } & removed_deps.select {|d| d.gemfile == gemfile_path }
262
+
263
+ show_warning "#{errored_deps.map(&:name).join(", ")} could not be removed." unless errored_deps.empty?
264
+
265
+ # return actual removed dependencies
266
+ removed_deps - errored_deps
267
+ end
268
+
269
+ def show_warning(message)
270
+ Bundler.ui.info Bundler.ui.add_color(message, :yellow)
271
+ end
61
272
  end
62
273
  end