bundler 2.2.29 → 2.5.16

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 (330) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1129 -4
  3. data/README.md +4 -8
  4. data/bundler.gemspec +11 -11
  5. data/exe/bundle +5 -26
  6. data/exe/bundler +1 -1
  7. data/lib/bundler/.document +1 -0
  8. data/lib/bundler/build_metadata.rb +4 -4
  9. data/lib/bundler/capistrano.rb +1 -1
  10. data/lib/bundler/checksum.rb +254 -0
  11. data/lib/bundler/ci_detector.rb +75 -0
  12. data/lib/bundler/cli/add.rb +4 -4
  13. data/lib/bundler/cli/binstubs.rb +10 -6
  14. data/lib/bundler/cli/cache.rb +1 -1
  15. data/lib/bundler/cli/check.rb +3 -3
  16. data/lib/bundler/cli/common.rb +13 -3
  17. data/lib/bundler/cli/config.rb +18 -8
  18. data/lib/bundler/cli/console.rb +5 -4
  19. data/lib/bundler/cli/doctor.rb +12 -5
  20. data/lib/bundler/cli/exec.rb +1 -1
  21. data/lib/bundler/cli/fund.rb +1 -1
  22. data/lib/bundler/cli/gem.rb +141 -48
  23. data/lib/bundler/cli/info.rb +27 -17
  24. data/lib/bundler/cli/init.rb +6 -2
  25. data/lib/bundler/cli/install.rb +22 -39
  26. data/lib/bundler/cli/issue.rb +5 -4
  27. data/lib/bundler/cli/lock.rb +36 -29
  28. data/lib/bundler/cli/open.rb +9 -9
  29. data/lib/bundler/cli/outdated.rb +19 -12
  30. data/lib/bundler/cli/platform.rb +8 -6
  31. data/lib/bundler/cli/plugin.rb +9 -15
  32. data/lib/bundler/cli/pristine.rb +38 -30
  33. data/lib/bundler/cli/show.rb +3 -3
  34. data/lib/bundler/cli/update.rb +12 -7
  35. data/lib/bundler/cli/viz.rb +1 -1
  36. data/lib/bundler/cli.rb +266 -285
  37. data/lib/bundler/compact_index_client/cache.rb +53 -67
  38. data/lib/bundler/compact_index_client/cache_file.rb +153 -0
  39. data/lib/bundler/compact_index_client/gem_parser.rb +7 -3
  40. data/lib/bundler/compact_index_client/parser.rb +84 -0
  41. data/lib/bundler/compact_index_client/updater.rb +83 -76
  42. data/lib/bundler/compact_index_client.rb +59 -87
  43. data/lib/bundler/constants.rb +9 -2
  44. data/lib/bundler/current_ruby.rb +12 -16
  45. data/lib/bundler/definition.rb +509 -319
  46. data/lib/bundler/dependency.rb +33 -71
  47. data/lib/bundler/digest.rb +71 -0
  48. data/lib/bundler/dsl.rb +88 -69
  49. data/lib/bundler/endpoint_specification.rb +32 -15
  50. data/lib/bundler/env.rb +5 -7
  51. data/lib/bundler/environment_preserver.rb +8 -22
  52. data/lib/bundler/errors.rb +101 -13
  53. data/lib/bundler/feature_flag.rb +0 -2
  54. data/lib/bundler/fetcher/base.rb +11 -11
  55. data/lib/bundler/fetcher/compact_index.rb +32 -52
  56. data/lib/bundler/fetcher/dependency.rb +3 -7
  57. data/lib/bundler/fetcher/downloader.rb +17 -16
  58. data/lib/bundler/fetcher/gem_remote_fetcher.rb +16 -0
  59. data/lib/bundler/fetcher/index.rb +2 -29
  60. data/lib/bundler/fetcher.rb +87 -79
  61. data/lib/bundler/force_platform.rb +18 -0
  62. data/lib/bundler/friendly_errors.rb +29 -40
  63. data/lib/bundler/gem_helper.rb +11 -23
  64. data/lib/bundler/gem_helpers.rb +30 -6
  65. data/lib/bundler/gem_version_promoter.rb +68 -109
  66. data/lib/bundler/graph.rb +9 -9
  67. data/lib/bundler/index.rb +71 -79
  68. data/lib/bundler/injector.rb +23 -11
  69. data/lib/bundler/inline.rb +11 -23
  70. data/lib/bundler/installer/gem_installer.rb +18 -11
  71. data/lib/bundler/installer/parallel_installer.rb +17 -65
  72. data/lib/bundler/installer/standalone.rb +56 -15
  73. data/lib/bundler/installer.rb +35 -61
  74. data/lib/bundler/lazy_specification.rb +92 -61
  75. data/lib/bundler/lockfile_generator.rb +12 -3
  76. data/lib/bundler/lockfile_parser.rb +137 -70
  77. data/lib/bundler/man/bundle-add.1 +19 -26
  78. data/lib/bundler/man/bundle-add.1.ronn +16 -4
  79. data/lib/bundler/man/bundle-binstubs.1 +4 -16
  80. data/lib/bundler/man/bundle-cache.1 +9 -24
  81. data/lib/bundler/man/bundle-cache.1.ronn +9 -2
  82. data/lib/bundler/man/bundle-check.1 +5 -12
  83. data/lib/bundler/man/bundle-check.1.ronn +3 -0
  84. data/lib/bundler/man/bundle-clean.1 +4 -11
  85. data/lib/bundler/man/bundle-clean.1.ronn +1 -1
  86. data/lib/bundler/man/bundle-config.1 +47 -224
  87. data/lib/bundler/man/bundle-config.1.ronn +40 -28
  88. data/lib/bundler/man/bundle-console.1 +35 -0
  89. data/lib/bundler/man/bundle-console.1.ronn +44 -0
  90. data/lib/bundler/man/bundle-doctor.1 +4 -18
  91. data/lib/bundler/man/bundle-exec.1 +16 -77
  92. data/lib/bundler/man/bundle-exec.1.ronn +8 -9
  93. data/lib/bundler/man/bundle-gem.1 +45 -72
  94. data/lib/bundler/man/bundle-gem.1.ronn +32 -5
  95. data/lib/bundler/man/bundle-help.1 +9 -0
  96. data/lib/bundler/man/bundle-help.1.ronn +12 -0
  97. data/lib/bundler/man/bundle-info.1 +5 -11
  98. data/lib/bundler/man/bundle-info.1.ronn +3 -3
  99. data/lib/bundler/man/bundle-init.1 +6 -11
  100. data/lib/bundler/man/bundle-init.1.ronn +2 -0
  101. data/lib/bundler/man/bundle-inject.1 +8 -18
  102. data/lib/bundler/man/bundle-inject.1.ronn +3 -1
  103. data/lib/bundler/man/bundle-install.1 +32 -155
  104. data/lib/bundler/man/bundle-install.1.ronn +11 -33
  105. data/lib/bundler/man/bundle-list.1 +4 -19
  106. data/lib/bundler/man/bundle-lock.1 +5 -29
  107. data/lib/bundler/man/bundle-open.1 +18 -18
  108. data/lib/bundler/man/bundle-open.1.ronn +9 -1
  109. data/lib/bundler/man/bundle-outdated.1 +17 -72
  110. data/lib/bundler/man/bundle-outdated.1.ronn +13 -18
  111. data/lib/bundler/man/bundle-platform.1 +16 -28
  112. data/lib/bundler/man/bundle-platform.1.ronn +14 -7
  113. data/lib/bundler/man/bundle-plugin.1 +58 -0
  114. data/lib/bundler/man/bundle-plugin.1.ronn +63 -0
  115. data/lib/bundler/man/bundle-pristine.1 +5 -16
  116. data/lib/bundler/man/bundle-remove.1 +4 -14
  117. data/lib/bundler/man/bundle-show.1 +3 -10
  118. data/lib/bundler/man/bundle-update.1 +19 -138
  119. data/lib/bundler/man/bundle-update.1.ronn +2 -1
  120. data/lib/bundler/man/bundle-version.1 +22 -0
  121. data/lib/bundler/man/bundle-version.1.ronn +24 -0
  122. data/lib/bundler/man/bundle-viz.1 +6 -15
  123. data/lib/bundler/man/bundle-viz.1.ronn +2 -0
  124. data/lib/bundler/man/bundle.1 +17 -51
  125. data/lib/bundler/man/bundle.1.ronn +12 -7
  126. data/lib/bundler/man/gemfile.5 +130 -346
  127. data/lib/bundler/man/gemfile.5.ronn +121 -86
  128. data/lib/bundler/man/index.txt +4 -0
  129. data/lib/bundler/match_metadata.rb +17 -0
  130. data/lib/bundler/match_platform.rb +1 -2
  131. data/lib/bundler/match_remote_metadata.rb +29 -0
  132. data/lib/bundler/mirror.rb +8 -10
  133. data/lib/bundler/plugin/api/source.rb +9 -13
  134. data/lib/bundler/plugin/index.rb +13 -5
  135. data/lib/bundler/plugin/installer/git.rb +0 -4
  136. data/lib/bundler/plugin/installer/path.rb +18 -0
  137. data/lib/bundler/plugin/installer/rubygems.rb +0 -8
  138. data/lib/bundler/plugin/installer.rb +42 -19
  139. data/lib/bundler/plugin/source_list.rb +4 -4
  140. data/lib/bundler/plugin.rb +16 -7
  141. data/lib/bundler/process_lock.rb +1 -1
  142. data/lib/bundler/remote_specification.rb +11 -5
  143. data/lib/bundler/resolver/base.rb +111 -0
  144. data/lib/bundler/resolver/candidate.rb +82 -0
  145. data/lib/bundler/resolver/incompatibility.rb +15 -0
  146. data/lib/bundler/resolver/package.rb +81 -0
  147. data/lib/bundler/resolver/root.rb +25 -0
  148. data/lib/bundler/resolver/spec_group.rb +53 -66
  149. data/lib/bundler/resolver.rb +419 -307
  150. data/lib/bundler/retry.rb +1 -1
  151. data/lib/bundler/ruby_dsl.rb +42 -7
  152. data/lib/bundler/ruby_version.rb +16 -22
  153. data/lib/bundler/rubygems_ext.rb +250 -64
  154. data/lib/bundler/rubygems_gem_installer.rb +90 -64
  155. data/lib/bundler/rubygems_integration.rb +81 -190
  156. data/lib/bundler/runtime.rb +8 -13
  157. data/lib/bundler/safe_marshal.rb +31 -0
  158. data/lib/bundler/self_manager.rb +206 -0
  159. data/lib/bundler/settings.rb +139 -57
  160. data/lib/bundler/setup.rb +13 -1
  161. data/lib/bundler/shared_helpers.rb +67 -36
  162. data/lib/bundler/source/git/git_proxy.rb +285 -82
  163. data/lib/bundler/source/git.rb +81 -41
  164. data/lib/bundler/source/metadata.rb +17 -16
  165. data/lib/bundler/source/path/installer.rb +1 -22
  166. data/lib/bundler/source/path.rb +13 -25
  167. data/lib/bundler/source/rubygems/remote.rb +1 -1
  168. data/lib/bundler/source/rubygems.rb +164 -234
  169. data/lib/bundler/source/rubygems_aggregate.rb +1 -1
  170. data/lib/bundler/source.rb +7 -6
  171. data/lib/bundler/source_list.rb +40 -32
  172. data/lib/bundler/source_map.rb +15 -2
  173. data/lib/bundler/spec_set.rb +156 -46
  174. data/lib/bundler/stub_specification.rb +18 -5
  175. data/lib/bundler/templates/Executable +3 -5
  176. data/lib/bundler/templates/Executable.bundler +7 -12
  177. data/lib/bundler/templates/Executable.standalone +4 -4
  178. data/lib/bundler/templates/Gemfile +0 -2
  179. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +77 -29
  180. data/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  181. data/lib/bundler/templates/newgem/Gemfile.tt +8 -2
  182. data/lib/bundler/templates/newgem/README.md.tt +7 -11
  183. data/lib/bundler/templates/newgem/Rakefile.tt +28 -4
  184. data/lib/bundler/templates/newgem/bin/console.tt +0 -4
  185. data/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  186. data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  187. data/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
  188. data/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  189. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +1 -1
  190. data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  191. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +13 -3
  192. data/lib/bundler/templates/newgem/gitignore.tt +3 -0
  193. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +13 -4
  194. data/lib/bundler/templates/newgem/newgem.gemspec.tt +25 -17
  195. data/lib/bundler/templates/newgem/rubocop.yml.tt +0 -5
  196. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  197. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  198. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  199. data/lib/bundler/ui/rg_proxy.rb +1 -1
  200. data/lib/bundler/ui/shell.rb +38 -15
  201. data/lib/bundler/ui/silent.rb +21 -5
  202. data/lib/bundler/uri_credentials_filter.rb +2 -2
  203. data/lib/bundler/uri_normalizer.rb +23 -0
  204. data/lib/bundler/vendor/.document +1 -0
  205. data/lib/bundler/vendor/connection_pool/.document +1 -0
  206. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  207. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  208. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  209. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +56 -0
  210. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +92 -78
  211. data/lib/bundler/vendor/fileutils/.document +1 -0
  212. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  213. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1340 -410
  214. data/lib/bundler/vendor/net-http-persistent/.document +1 -0
  215. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  216. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +4 -3
  217. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +23 -11
  218. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +1 -1
  219. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +57 -57
  220. data/lib/bundler/vendor/pub_grub/.document +1 -0
  221. data/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  222. data/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  223. data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  224. data/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  225. data/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
  226. data/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  227. data/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  228. data/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  229. data/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  230. data/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +61 -0
  231. data/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  232. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  233. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
  234. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +411 -0
  235. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +248 -0
  236. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  237. data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  238. data/lib/bundler/vendor/thor/.document +1 -0
  239. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  240. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
  241. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
  242. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +1 -1
  243. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +12 -14
  244. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +16 -6
  245. data/lib/bundler/vendor/thor/lib/thor/actions.rb +21 -17
  246. data/lib/bundler/vendor/thor/lib/thor/base.rb +140 -14
  247. data/lib/bundler/vendor/thor/lib/thor/command.rb +13 -4
  248. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +10 -0
  249. data/lib/bundler/vendor/thor/lib/thor/error.rb +16 -20
  250. data/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
  251. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -1
  252. data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +2 -2
  253. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +20 -1
  254. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +33 -17
  255. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +27 -8
  256. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +63 -7
  257. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +2 -2
  258. data/lib/bundler/vendor/thor/lib/thor/runner.rb +40 -30
  259. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +48 -154
  260. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -46
  261. data/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
  262. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +0 -45
  263. data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +134 -0
  264. data/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
  265. data/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
  266. data/lib/bundler/vendor/thor/lib/thor/shell.rb +2 -2
  267. data/lib/bundler/vendor/thor/lib/thor/util.rb +9 -8
  268. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  269. data/lib/bundler/vendor/thor/lib/thor.rb +155 -8
  270. data/lib/bundler/vendor/tsort/.document +1 -0
  271. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  272. data/lib/bundler/vendor/tsort/lib/tsort.rb +455 -0
  273. data/lib/bundler/vendor/uri/.document +1 -0
  274. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  275. data/lib/bundler/vendor/uri/lib/uri/common.rb +316 -207
  276. data/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
  277. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -2
  278. data/lib/bundler/vendor/uri/lib/uri/generic.rb +33 -13
  279. data/lib/bundler/vendor/uri/lib/uri/http.rb +40 -3
  280. data/lib/bundler/vendor/uri/lib/uri/https.rb +2 -2
  281. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +2 -2
  282. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
  283. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -3
  284. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +16 -23
  285. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +105 -47
  286. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  287. data/lib/bundler/vendor/uri/lib/uri/ws.rb +83 -0
  288. data/lib/bundler/vendor/uri/lib/uri/wss.rb +23 -0
  289. data/lib/bundler/vendor/uri/lib/uri.rb +3 -3
  290. data/lib/bundler/vendored_net_http.rb +23 -0
  291. data/lib/bundler/vendored_persistent.rb +0 -36
  292. data/lib/bundler/{vendored_molinillo.rb → vendored_pub_grub.rb} +1 -1
  293. data/lib/bundler/vendored_timeout.rb +12 -0
  294. data/lib/bundler/{vendored_tmpdir.rb → vendored_tsort.rb} +1 -1
  295. data/lib/bundler/vendored_uri.rb +18 -1
  296. data/lib/bundler/version.rb +5 -1
  297. data/lib/bundler/vlad.rb +1 -1
  298. data/lib/bundler/worker.rb +7 -9
  299. data/lib/bundler/yaml_serializer.rb +21 -12
  300. data/lib/bundler.rb +114 -121
  301. metadata +87 -41
  302. data/lib/bundler/dep_proxy.rb +0 -55
  303. data/lib/bundler/gemdeps.rb +0 -29
  304. data/lib/bundler/psyched_yaml.rb +0 -22
  305. data/lib/bundler/templates/gems.rb +0 -8
  306. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +0 -5
  307. data/lib/bundler/templates/newgem/travis.yml.tt +0 -6
  308. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
  309. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  310. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  311. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  312. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  313. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  314. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  315. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  316. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  317. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  318. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  319. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  320. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  321. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -143
  322. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  323. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  324. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  325. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
  326. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  327. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
  328. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
  329. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
  330. data/lib/bundler/version_ranges.rb +0 -122
@@ -6,15 +6,20 @@ module Bundler
6
6
  class Definition
7
7
  include GemHelpers
8
8
 
9
+ class << self
10
+ # Do not create or modify a lockfile (Makes #lock a noop)
11
+ attr_accessor :no_lock
12
+ end
13
+
9
14
  attr_reader(
10
15
  :dependencies,
11
16
  :locked_deps,
12
17
  :locked_gems,
13
18
  :platforms,
14
- :requires,
15
19
  :ruby_version,
16
20
  :lockfile,
17
- :gemfiles
21
+ :gemfiles,
22
+ :locked_checksums
18
23
  )
19
24
 
20
25
  # Given a gemfile and lockfile creates a Bundler definition
@@ -64,29 +69,35 @@ module Bundler
64
69
  @sources = sources
65
70
  @unlock = unlock
66
71
  @optional_groups = optional_groups
67
- @remote = false
72
+ @prefer_local = false
68
73
  @specs = nil
69
74
  @ruby_version = ruby_version
70
75
  @gemfiles = gemfiles
71
76
 
72
77
  @lockfile = lockfile
73
78
  @lockfile_contents = String.new
79
+
74
80
  @locked_bundler_version = nil
75
- @locked_ruby_version = nil
76
- @locked_specs_incomplete_for_platform = false
77
- @new_platform = nil
81
+ @resolved_bundler_version = nil
78
82
 
79
- if lockfile && File.exist?(lockfile)
83
+ @locked_ruby_version = nil
84
+ @new_platforms = []
85
+ @removed_platform = nil
86
+
87
+ if lockfile_exists?
80
88
  @lockfile_contents = Bundler.read_file(lockfile)
81
89
  @locked_gems = LockfileParser.new(@lockfile_contents)
82
90
  @locked_platforms = @locked_gems.platforms
83
91
  @platforms = @locked_platforms.dup
84
92
  @locked_bundler_version = @locked_gems.bundler_version
85
93
  @locked_ruby_version = @locked_gems.ruby_version
94
+ @originally_locked_deps = @locked_gems.dependencies
95
+ @originally_locked_specs = SpecSet.new(@locked_gems.specs)
96
+ @locked_checksums = @locked_gems.checksums
86
97
 
87
98
  if unlock != true
88
- @locked_deps = @locked_gems.dependencies
89
- @locked_specs = SpecSet.new(@locked_gems.specs)
99
+ @locked_deps = @originally_locked_deps
100
+ @locked_specs = @originally_locked_specs
90
101
  @locked_sources = @locked_gems.sources
91
102
  else
92
103
  @unlock = {}
@@ -100,8 +111,11 @@ module Bundler
100
111
  @locked_gems = nil
101
112
  @locked_deps = {}
102
113
  @locked_specs = SpecSet.new([])
114
+ @originally_locked_deps = {}
115
+ @originally_locked_specs = @locked_specs
103
116
  @locked_sources = []
104
117
  @locked_platforms = []
118
+ @locked_checksums = nil
105
119
  end
106
120
 
107
121
  locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@@ -117,67 +131,58 @@ module Bundler
117
131
  @sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
118
132
  end
119
133
 
120
- @unlock[:sources] ||= []
134
+ @sources_to_unlock = @unlock.delete(:sources) || []
121
135
  @unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
122
136
  @ruby_version.diff(locked_ruby_version_object)
123
137
  end
124
138
  @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
125
139
 
126
- add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle?
140
+ add_current_platform unless Bundler.frozen_bundle?
127
141
 
128
142
  converge_path_sources_to_gemspec_sources
129
143
  @path_changes = converge_paths
130
144
  @source_changes = converge_sources
131
145
 
146
+ @explicit_unlocks = @unlock.delete(:gems) || []
147
+
132
148
  if @unlock[:conservative]
133
- @unlock[:gems] ||= @dependencies.map(&:name)
149
+ @gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
134
150
  else
135
- eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
136
- @unlock[:gems] = @locked_specs.for(eager_unlock, false, false).map(&:name)
151
+ eager_unlock = @explicit_unlocks.map {|name| Dependency.new(name, ">= 0") }
152
+ @gems_to_unlock = @locked_specs.for(eager_unlock, false, platforms).map(&:name).uniq
137
153
  end
138
154
 
139
155
  @dependency_changes = converge_dependencies
140
156
  @local_changes = converge_locals
141
157
 
142
- @requires = compute_requires
158
+ check_lockfile
143
159
  end
144
160
 
145
161
  def gem_version_promoter
146
- @gem_version_promoter ||= begin
147
- locked_specs =
148
- if unlocking? && @locked_specs.empty? && !@lockfile_contents.empty?
149
- # Definition uses an empty set of locked_specs to indicate all gems
150
- # are unlocked, but GemVersionPromoter needs the locked_specs
151
- # for conservative comparison.
152
- Bundler::SpecSet.new(@locked_gems.specs)
153
- else
154
- @locked_specs
155
- end
156
- GemVersionPromoter.new(locked_specs, @unlock[:gems])
157
- end
158
- end
159
-
160
- def multisource_allowed?
161
- @multisource_allowed
162
+ @gem_version_promoter ||= GemVersionPromoter.new
162
163
  end
163
164
 
164
165
  def resolve_only_locally!
165
- @remote = false
166
166
  sources.local_only!
167
167
  resolve
168
168
  end
169
169
 
170
170
  def resolve_with_cache!
171
+ sources.local!
171
172
  sources.cached!
172
173
  resolve
173
174
  end
174
175
 
175
176
  def resolve_remotely!
176
- @remote = true
177
+ sources.cached!
177
178
  sources.remote!
178
179
  resolve
179
180
  end
180
181
 
182
+ def prefer_local!
183
+ @prefer_local = true
184
+ end
185
+
181
186
  # For given dependency list returns a SpecSet with Gemspec of all the required
182
187
  # dependencies.
183
188
  # 1. The method first resolves the dependencies specified in Gemfile
@@ -207,8 +212,9 @@ module Bundler
207
212
  true
208
213
  rescue BundlerError => e
209
214
  @resolve = nil
215
+ @resolver = nil
216
+ @resolution_packages = nil
210
217
  @specs = nil
211
- @gem_version_promoter = nil
212
218
 
213
219
  Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
214
220
  true
@@ -223,22 +229,49 @@ module Bundler
223
229
  end
224
230
 
225
231
  def current_dependencies
232
+ filter_relevant(dependencies)
233
+ end
234
+
235
+ def current_locked_dependencies
236
+ filter_relevant(locked_dependencies)
237
+ end
238
+
239
+ def filter_relevant(dependencies)
240
+ platforms_array = [generic_local_platform].freeze
226
241
  dependencies.select do |d|
227
- d.should_include? && !d.gem_platforms(@platforms).empty?
242
+ d.should_include? && !d.gem_platforms(platforms_array).empty?
228
243
  end
229
244
  end
230
245
 
246
+ def locked_dependencies
247
+ @locked_deps.values
248
+ end
249
+
250
+ def new_deps
251
+ @new_deps ||= @dependencies - locked_dependencies
252
+ end
253
+
254
+ def deleted_deps
255
+ @deleted_deps ||= locked_dependencies - @dependencies
256
+ end
257
+
231
258
  def specs_for(groups)
232
- groups = requested_groups if groups.empty?
259
+ return specs if groups.empty?
233
260
  deps = dependencies_for(groups)
234
- materialize(expand_dependencies(deps))
261
+ materialize(deps)
235
262
  end
236
263
 
237
264
  def dependencies_for(groups)
238
265
  groups.map!(&:to_sym)
239
- current_dependencies.reject do |d|
240
- (d.groups & groups).empty?
266
+ deps = current_dependencies # always returns a new array
267
+ deps.select! do |d|
268
+ if RUBY_VERSION >= "3.1"
269
+ d.groups.intersect?(groups)
270
+ else
271
+ !(d.groups & groups).empty?
272
+ end
241
273
  end
274
+ deps
242
275
  end
243
276
 
244
277
  # Resolve all the dependencies specified in Gemfile. It ensures that
@@ -247,20 +280,29 @@ module Bundler
247
280
  #
248
281
  # @return [SpecSet] resolved dependencies
249
282
  def resolve
250
- @resolve ||= begin
251
- last_resolve = converge_locked_specs
252
- if Bundler.frozen_bundle?
253
- Bundler.ui.debug "Frozen, using resolution from the lockfile"
254
- last_resolve
255
- elsif !unlocking? && nothing_changed?
256
- Bundler.ui.debug("Found no changes, using resolution from the lockfile")
257
- last_resolve
283
+ @resolve ||= if Bundler.frozen_bundle?
284
+ Bundler.ui.debug "Frozen, using resolution from the lockfile"
285
+ @locked_specs
286
+ elsif no_resolve_needed?
287
+ if deleted_deps.any?
288
+ Bundler.ui.debug "Some dependencies were deleted, using a subset of the resolution from the lockfile"
289
+ SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
258
290
  else
259
- # Run a resolve against the locally available gems
260
- Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
261
- expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
262
- Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
291
+ Bundler.ui.debug "Found no changes, using resolution from the lockfile"
292
+ if @removed_platform || @locked_gems.may_include_redundant_platform_specific_gems?
293
+ SpecSet.new(filter_specs(@locked_specs, @dependencies))
294
+ else
295
+ @locked_specs
296
+ end
263
297
  end
298
+ else
299
+ if lockfile_exists?
300
+ Bundler.ui.debug "Found changes from the lockfile, re-resolving dependencies because #{change_reason}"
301
+ else
302
+ Bundler.ui.debug "Resolving dependencies because there's no lockfile"
303
+ end
304
+
305
+ start_resolution
264
306
  end
265
307
  end
266
308
 
@@ -272,43 +314,26 @@ module Bundler
272
314
  dependencies.map(&:groups).flatten.uniq
273
315
  end
274
316
 
275
- def lock(file, preserve_unknown_sections = false)
276
- contents = to_lock
277
-
278
- # Convert to \r\n if the existing lock has them
279
- # i.e., Windows with `git config core.autocrlf=true`
280
- contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
281
-
282
- if @locked_bundler_version
283
- locked_major = @locked_bundler_version.segments.first
284
- current_major = Gem::Version.create(Bundler::VERSION).segments.first
317
+ def lock(file_or_preserve_unknown_sections = false, preserve_unknown_sections_or_unused = false)
318
+ if [true, false, nil].include?(file_or_preserve_unknown_sections)
319
+ target_lockfile = lockfile || Bundler.default_lockfile
320
+ preserve_unknown_sections = file_or_preserve_unknown_sections
321
+ else
322
+ target_lockfile = file_or_preserve_unknown_sections
323
+ preserve_unknown_sections = preserve_unknown_sections_or_unused
285
324
 
286
- if updating_major = locked_major < current_major
287
- Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
288
- "after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
325
+ suggestion = if target_lockfile == lockfile
326
+ "To fix this warning, remove it from the `Definition#lock` call."
327
+ else
328
+ "Instead, instantiate a new definition passing `#{target_lockfile}`, and call `lock` without a file argument on that definition"
289
329
  end
290
- end
291
-
292
- preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
293
-
294
- return if file && File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
295
-
296
- if Bundler.frozen_bundle?
297
- Bundler.ui.error "Cannot write a changed lockfile while frozen."
298
- return
299
- end
300
330
 
301
- SharedHelpers.filesystem_access(file) do |p|
302
- File.open(p, "wb") {|f| f.puts(contents) }
303
- end
304
- end
331
+ msg = "`Definition#lock` was passed a target file argument. #{suggestion}"
305
332
 
306
- def locked_bundler_version
307
- if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
308
- new_version = Bundler::VERSION
333
+ Bundler::SharedHelpers.major_deprecation 2, msg
309
334
  end
310
335
 
311
- new_version || @locked_bundler_version || Bundler::VERSION
336
+ write_lock(target_lockfile, preserve_unknown_sections)
312
337
  end
313
338
 
314
339
  def locked_ruby_version
@@ -332,26 +357,19 @@ module Bundler
332
357
  end
333
358
  end
334
359
 
360
+ def bundler_version_to_lock
361
+ @resolved_bundler_version || Bundler.gem_version
362
+ end
363
+
335
364
  def to_lock
336
365
  require_relative "lockfile_generator"
337
366
  LockfileGenerator.generate(self)
338
367
  end
339
368
 
340
369
  def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
341
- msg = String.new
342
- msg << "You are trying to install in deployment mode after changing\n" \
343
- "your Gemfile. Run `bundle install` elsewhere and add the\n" \
344
- "updated #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control."
370
+ return unless Bundler.frozen_bundle?
345
371
 
346
- unless explicit_flag
347
- suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any?
348
- "bundle config unset frozen"
349
- elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
350
- "bundle config unset deployment"
351
- end
352
- msg << "\n\nIf this is a development machine, remove the #{Bundler.default_gemfile} " \
353
- "freeze \nby running `#{suggested_command}`."
354
- end
372
+ raise ProductionError, "Frozen mode is set, but there's no lockfile" unless lockfile_exists?
355
373
 
356
374
  added = []
357
375
  deleted = []
@@ -362,52 +380,40 @@ module Bundler
362
380
  added.concat new_platforms.map {|p| "* platform: #{p}" }
363
381
  deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
364
382
 
365
- gemfile_sources = sources.lock_sources
366
-
367
- new_sources = gemfile_sources - @locked_sources
368
- deleted_sources = @locked_sources - gemfile_sources
369
-
370
- new_deps = @dependencies - @locked_deps.values
371
- deleted_deps = @locked_deps.values - @dependencies
372
-
373
- # Check if it is possible that the source is only changed thing
374
- if (new_deps.empty? && deleted_deps.empty?) && (!new_sources.empty? && !deleted_sources.empty?)
375
- new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
376
- deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
377
- end
378
-
379
- if @locked_sources != gemfile_sources
380
- if new_sources.any?
381
- added.concat new_sources.map {|source| "* source: #{source}" }
382
- end
383
-
384
- if deleted_sources.any?
385
- deleted.concat deleted_sources.map {|source| "* source: #{source}" }
386
- end
387
- end
388
-
389
383
  added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
390
- if deleted_deps.any?
391
- deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
392
- end
384
+ deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
393
385
 
394
386
  both_sources = Hash.new {|h, k| h[k] = [] }
395
- @dependencies.each {|d| both_sources[d.name][0] = d }
396
- @locked_deps.each {|name, d| both_sources[name][1] = d.source }
387
+ current_dependencies.each {|d| both_sources[d.name][0] = d }
388
+ current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
389
+
390
+ both_sources.each do |name, (dep, lock_dep)|
391
+ next if dep.nil? || lock_dep.nil?
397
392
 
398
- both_sources.each do |name, (dep, lock_source)|
399
- next if lock_source.nil? || (dep && lock_source.can_lock?(dep))
400
- gemfile_source_name = (dep && dep.source) || "no specified source"
401
- lockfile_source_name = lock_source
402
- changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
393
+ gemfile_source = dep.source || default_source
394
+ lock_source = lock_dep.source || default_source
395
+ next if lock_source.include?(gemfile_source)
396
+
397
+ gemfile_source_name = dep.source ? gemfile_source.to_gemfile : "no specified source"
398
+ lockfile_source_name = lock_dep.source ? lock_source.to_gemfile : "no specified source"
399
+ changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
403
400
  end
404
401
 
405
- reason = change_reason
406
- msg << "\n\n#{reason.split(", ").map(&:capitalize).join("\n")}" unless reason.strip.empty?
402
+ reason = nothing_changed? ? "some dependencies were deleted from your gemfile" : change_reason
403
+ msg = String.new
404
+ msg << "#{reason.capitalize.strip}, but the lockfile can't be updated because frozen mode is set"
407
405
  msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
408
406
  msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
409
407
  msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
410
- msg << "\n"
408
+ msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_gemfile_path} to version control.\n"
409
+
410
+ unless explicit_flag
411
+ suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
412
+ "bundle config set frozen false"
413
+ end
414
+ msg << "If this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} " \
415
+ "freeze by running `#{suggested_command}`." if suggested_command
416
+ end
411
417
 
412
418
  raise ProductionError, msg if added.any? || deleted.any? || changed.any? || !nothing_changed?
413
419
  end
@@ -446,17 +452,21 @@ module Bundler
446
452
  return if current_platform_locked?
447
453
 
448
454
  raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
449
- "but your local platform is #{Bundler.local_platform}. " \
450
- "Add the current platform to the lockfile with `bundle lock --add-platform #{Bundler.local_platform}` and try again."
455
+ "but your local platform is #{local_platform}. " \
456
+ "Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again."
451
457
  end
452
458
 
453
459
  def add_platform(platform)
454
- @new_platform ||= !@platforms.include?(platform)
455
- @platforms |= [platform]
460
+ return if @platforms.include?(platform)
461
+
462
+ @new_platforms << platform
463
+ @platforms << platform
456
464
  end
457
465
 
458
466
  def remove_platform(platform)
459
- return if @platforms.delete(Gem::Platform.new(platform))
467
+ removed_platform = @platforms.delete(Gem::Platform.new(platform))
468
+ @removed_platform ||= removed_platform
469
+ return if removed_platform
460
470
  raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
461
471
  end
462
472
 
@@ -470,7 +480,21 @@ module Bundler
470
480
  private :sources
471
481
 
472
482
  def nothing_changed?
473
- !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
483
+ return false unless lockfile_exists?
484
+
485
+ !@source_changes &&
486
+ !@dependency_changes &&
487
+ @new_platforms.empty? &&
488
+ !@path_changes &&
489
+ !@local_changes &&
490
+ !@missing_lockfile_dep &&
491
+ !@unlocking_bundler &&
492
+ !@locked_spec_with_missing_deps &&
493
+ !@locked_spec_with_invalid_deps
494
+ end
495
+
496
+ def no_resolve_needed?
497
+ !unlocking? && nothing_changed?
474
498
  end
475
499
 
476
500
  def unlocking?
@@ -479,6 +503,82 @@ module Bundler
479
503
 
480
504
  private
481
505
 
506
+ def should_add_extra_platforms?
507
+ !lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
508
+ end
509
+
510
+ def lockfile_exists?
511
+ file_exists?(lockfile)
512
+ end
513
+
514
+ def file_exists?(file)
515
+ file && File.exist?(file)
516
+ end
517
+
518
+ def write_lock(file, preserve_unknown_sections)
519
+ return if Definition.no_lock
520
+
521
+ contents = to_lock
522
+
523
+ # Convert to \r\n if the existing lock has them
524
+ # i.e., Windows with `git config core.autocrlf=true`
525
+ contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
526
+
527
+ if @locked_bundler_version
528
+ locked_major = @locked_bundler_version.segments.first
529
+ current_major = bundler_version_to_lock.segments.first
530
+
531
+ updating_major = locked_major < current_major
532
+ end
533
+
534
+ preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
535
+
536
+ if file_exists?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
537
+ return if Bundler.frozen_bundle?
538
+ SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
539
+ return
540
+ end
541
+
542
+ if Bundler.frozen_bundle?
543
+ Bundler.ui.error "Cannot write a changed lockfile while frozen."
544
+ return
545
+ end
546
+
547
+ SharedHelpers.filesystem_access(file) do |p|
548
+ File.open(p, "wb") {|f| f.puts(contents) }
549
+ end
550
+ end
551
+
552
+ def resolver
553
+ @resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
554
+ end
555
+
556
+ def expanded_dependencies
557
+ dependencies_with_bundler + metadata_dependencies
558
+ end
559
+
560
+ def dependencies_with_bundler
561
+ return dependencies unless @unlocking_bundler
562
+ return dependencies if dependencies.map(&:name).include?("bundler")
563
+
564
+ [Dependency.new("bundler", @unlocking_bundler)] + dependencies
565
+ end
566
+
567
+ def resolution_packages
568
+ @resolution_packages ||= begin
569
+ last_resolve = converge_locked_specs
570
+ remove_invalid_platforms!
571
+ packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @gems_to_unlock, prerelease: gem_version_promoter.pre?)
572
+ packages = additional_base_requirements_to_prevent_downgrades(packages, last_resolve)
573
+ packages = additional_base_requirements_to_force_updates(packages)
574
+ packages
575
+ end
576
+ end
577
+
578
+ def filter_specs(specs, deps)
579
+ SpecSet.new(specs).for(deps, false, platforms)
580
+ end
581
+
482
582
  def materialize(dependencies)
483
583
  specs = resolve.materialize(dependencies)
484
584
  missing_specs = specs.missing_specs
@@ -486,68 +586,137 @@ module Bundler
486
586
  if missing_specs.any?
487
587
  missing_specs.each do |s|
488
588
  locked_gem = @locked_specs[s.name].last
489
- next if locked_gem.nil? || locked_gem.version != s.version || !@remote
589
+ next if locked_gem.nil? || locked_gem.version != s.version || sources.local_mode?
490
590
  raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
491
591
  "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
492
592
  "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
493
593
  "removed in order to install."
494
594
  end
495
595
 
496
- raise GemNotFound, "Could not find #{missing_specs.map(&:full_name).join(", ")} in any of the sources"
596
+ missing_specs_list = missing_specs.group_by(&:source).map do |source, missing_specs_for_source|
597
+ "#{missing_specs_for_source.map(&:full_name).join(", ")} in #{source}"
598
+ end
599
+
600
+ raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
497
601
  end
498
602
 
499
- unless specs["bundler"].any?
500
- bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
501
- specs["bundler"] = bundler
603
+ incomplete_specs = specs.incomplete_specs
604
+ loop do
605
+ break if incomplete_specs.empty?
606
+
607
+ Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
608
+ sources.remote!
609
+ resolution_packages.delete(incomplete_specs)
610
+ @resolve = start_resolution
611
+ specs = resolve.materialize(dependencies)
612
+
613
+ still_incomplete_specs = specs.incomplete_specs
614
+
615
+ if still_incomplete_specs == incomplete_specs
616
+ package = resolution_packages.get_package(incomplete_specs.first.name)
617
+ resolver.raise_not_found! package
618
+ end
619
+
620
+ incomplete_specs = still_incomplete_specs
502
621
  end
503
622
 
623
+ bundler = sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
624
+ specs["bundler"] = bundler
625
+
504
626
  specs
505
627
  end
506
628
 
629
+ def start_resolution
630
+ local_platform_needed_for_resolvability = @most_specific_non_local_locked_ruby_platform && !@platforms.include?(local_platform)
631
+ @platforms << local_platform if local_platform_needed_for_resolvability
632
+
633
+ result = SpecSet.new(resolver.start)
634
+
635
+ @resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
636
+
637
+ if @most_specific_non_local_locked_ruby_platform
638
+ if spec_set_incomplete_for_platform?(result, @most_specific_non_local_locked_ruby_platform)
639
+ @platforms.delete(@most_specific_non_local_locked_ruby_platform)
640
+ elsif local_platform_needed_for_resolvability
641
+ @platforms.delete(local_platform)
642
+ end
643
+ end
644
+
645
+ @platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
646
+
647
+ SpecSet.new(result.for(dependencies, false, @platforms))
648
+ end
649
+
507
650
  def precompute_source_requirements_for_indirect_dependencies?
508
- @remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
651
+ sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
509
652
  end
510
653
 
511
- def current_ruby_platform_locked?
512
- return false unless generic_local_platform == Gem::Platform::RUBY
654
+ def pin_locally_available_names(source_requirements)
655
+ source_requirements.each_with_object({}) do |(name, original_source), new_source_requirements|
656
+ local_source = original_source.dup
657
+ local_source.local_only!
513
658
 
514
- current_platform_locked?
659
+ new_source_requirements[name] = if local_source.specs.search(name).any?
660
+ local_source
661
+ else
662
+ original_source
663
+ end
664
+ end
515
665
  end
516
666
 
517
667
  def current_platform_locked?
518
668
  @platforms.any? do |bundle_platform|
519
- MatchPlatform.platforms_match?(bundle_platform, Bundler.local_platform)
669
+ MatchPlatform.platforms_match?(bundle_platform, local_platform)
520
670
  end
521
671
  end
522
672
 
523
673
  def add_current_platform
674
+ @most_specific_non_local_locked_ruby_platform = find_most_specific_non_local_locked_ruby_platform
675
+ return if @most_specific_non_local_locked_ruby_platform
676
+
524
677
  add_platform(local_platform)
525
678
  end
526
679
 
680
+ def find_most_specific_non_local_locked_ruby_platform
681
+ return unless generic_local_platform_is_ruby? && current_platform_locked?
682
+
683
+ most_specific_locked_ruby_platform = most_specific_locked_platform
684
+ return unless most_specific_locked_ruby_platform != local_platform
685
+
686
+ most_specific_locked_ruby_platform
687
+ end
688
+
527
689
  def change_reason
528
690
  if unlocking?
529
- unlock_reason = @unlock.reject {|_k, v| Array(v).empty? }.map do |k, v|
530
- if v == true
531
- k.to_s
532
- else
533
- v = Array(v)
534
- "#{k}: (#{v.join(", ")})"
535
- end
536
- end.join(", ")
691
+ unlock_targets = if @gems_to_unlock.any?
692
+ ["gems", @gems_to_unlock]
693
+ elsif @sources_to_unlock.any?
694
+ ["sources", @sources_to_unlock]
695
+ end
696
+
697
+ unlock_reason = if unlock_targets
698
+ "#{unlock_targets.first}: (#{unlock_targets.last.join(", ")})"
699
+ else
700
+ @unlock[:ruby] ? "ruby" : ""
701
+ end
702
+
537
703
  return "bundler is unlocking #{unlock_reason}"
538
704
  end
539
705
  [
540
706
  [@source_changes, "the list of sources changed"],
541
707
  [@dependency_changes, "the dependencies in your gemfile changed"],
542
- [@new_platform, "you added a new platform to your gemfile"],
708
+ [@new_platforms.any?, "you added a new platform to your gemfile"],
543
709
  [@path_changes, "the gemspecs for path gems changed"],
544
710
  [@local_changes, "the gemspecs for git local gems changed"],
545
- [@locked_specs_incomplete_for_platform, "the lockfile does not have all gems needed for the current platform"],
711
+ [@missing_lockfile_dep, "your lock file is missing \"#{@missing_lockfile_dep}\""],
712
+ [@unlocking_bundler, "an update to the version of Bundler itself was requested"],
713
+ [@locked_spec_with_missing_deps, "your lock file includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
714
+ [@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
546
715
  ].select(&:first).map(&:last).join(", ")
547
716
  end
548
717
 
549
- def pretty_dep(dep, source = false)
550
- SharedHelpers.pretty_dependency(dep, source)
718
+ def pretty_dep(dep)
719
+ SharedHelpers.pretty_dependency(dep)
551
720
  end
552
721
 
553
722
  # Check if the specs of the given source changed
@@ -560,7 +729,7 @@ module Bundler
560
729
 
561
730
  def dependencies_for_source_changed?(source, locked_source = source)
562
731
  deps_for_source = @dependencies.select {|s| s.source == source }
563
- locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
732
+ locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
564
733
 
565
734
  deps_for_source.uniq.sort != locked_deps_for_source.sort
566
735
  end
@@ -569,8 +738,7 @@ module Bundler
569
738
  locked_index = Index.new
570
739
  locked_index.use(@locked_specs.select {|s| source.can_lock?(s) })
571
740
 
572
- # order here matters, since Index#== is checking source.specs.include?(locked_index)
573
- locked_index != source.specs
741
+ !locked_index.subset?(source.specs)
574
742
  rescue PathError, GitError => e
575
743
  Bundler.ui.debug "Assuming that #{source} has not changed since fetching its specs errored (#{e})"
576
744
  false
@@ -584,9 +752,9 @@ module Bundler
584
752
 
585
753
  Bundler.settings.local_overrides.map do |k, v|
586
754
  spec = @dependencies.find {|s| s.name == k }
587
- source = spec && spec.source
588
- if source && source.respond_to?(:local_override!)
589
- source.unlock! if @unlock[:gems].include?(spec.name)
755
+ source = spec&.source
756
+ if source&.respond_to?(:local_override!)
757
+ source.unlock! if @gems_to_unlock.include?(spec.name)
590
758
  locals << [source, source.local_override!(v)]
591
759
  end
592
760
  end
@@ -594,7 +762,40 @@ module Bundler
594
762
  sources_with_changes = locals.select do |source, changed|
595
763
  changed || specs_changed?(source)
596
764
  end.map(&:first)
597
- !sources_with_changes.each {|source| @unlock[:sources] << source.name }.empty?
765
+ !sources_with_changes.each {|source| @sources_to_unlock << source.name }.empty?
766
+ end
767
+
768
+ def check_lockfile
769
+ @missing_lockfile_dep = nil
770
+
771
+ @locked_spec_with_invalid_deps = nil
772
+ @locked_spec_with_missing_deps = nil
773
+
774
+ missing = []
775
+ invalid = []
776
+
777
+ @locked_specs.each do |s|
778
+ validation = @locked_specs.validate_deps(s)
779
+
780
+ missing << s if validation == :missing
781
+ invalid << s if validation == :invalid
782
+ end
783
+
784
+ if missing.any?
785
+ @locked_specs.delete(missing)
786
+
787
+ @locked_spec_with_missing_deps = missing.first.name
788
+ elsif !@dependency_changes
789
+ @missing_lockfile_dep = current_dependencies.find do |d|
790
+ @locked_specs[d.name].empty? && d.name != "bundler"
791
+ end&.name
792
+ end
793
+
794
+ if invalid.any?
795
+ @locked_specs.delete(invalid)
796
+
797
+ @locked_spec_with_invalid_deps = invalid.first.name
798
+ end
598
799
  end
599
800
 
600
801
  def converge_paths
@@ -628,12 +829,17 @@ module Bundler
628
829
  changes = sources.replace_sources!(@locked_sources)
629
830
 
630
831
  sources.all_sources.each do |source|
832
+ # has to be done separately, because we want to keep the locked checksum
833
+ # store for a source, even when doing a full update
834
+ if @locked_checksums && @locked_gems && locked_source = @locked_gems.sources.find {|s| s == source && !s.equal?(source) }
835
+ source.checksum_store.merge!(locked_source.checksum_store)
836
+ end
631
837
  # If the source is unlockable and the current command allows an unlock of
632
838
  # the source (for example, you are doing a `bundle update <foo>` of a git-pinned
633
839
  # gem), unlock it. For git sources, this means to unlock the revision, which
634
840
  # will cause the `ref` used to be the most recent for the branch (or master) if
635
841
  # an explicit `ref` is not used.
636
- if source.respond_to?(:unlock!) && @unlock[:sources].include?(source.name)
842
+ if source.respond_to?(:unlock!) && @sources_to_unlock.include?(source.name)
637
843
  source.unlock!
638
844
  changes = true
639
845
  end
@@ -643,25 +849,14 @@ module Bundler
643
849
  end
644
850
 
645
851
  def converge_dependencies
646
- frozen = Bundler.frozen_bundle?
647
- (@dependencies + @locked_deps.values).each do |dep|
648
- locked_source = @locked_deps[dep.name]
649
- # This is to make sure that if bundler is installing in deployment mode and
650
- # after locked_source and sources don't match, we still use locked_source.
651
- if frozen && !locked_source.nil? &&
652
- locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
653
- dep.source = locked_source.source
654
- elsif dep.source
852
+ changes = false
853
+
854
+ @dependencies.each do |dep|
855
+ if dep.source
655
856
  dep.source = sources.get(dep.source)
656
857
  end
657
- end
658
858
 
659
- changes = false
660
- # We want to know if all match, but don't want to check all entries
661
- # This means we need to return false if any dependency doesn't match
662
- # the lock or doesn't exist in the lock.
663
- @dependencies.each do |dependency|
664
- unless locked_dep = @locked_deps[dependency.name]
859
+ unless locked_dep = @originally_locked_deps[dep.name]
665
860
  changes = true
666
861
  next
667
862
  end
@@ -672,11 +867,11 @@ module Bundler
672
867
  # directive, the lockfile dependencies and resolved dependencies end up
673
868
  # with a mismatch on #type. Work around that by setting the type on the
674
869
  # dep from the lockfile.
675
- locked_dep.instance_variable_set(:@type, dependency.type)
870
+ locked_dep.instance_variable_set(:@type, dep.type)
676
871
 
677
872
  # We already know the name matches from the hash lookup
678
873
  # so we only need to check the requirement now
679
- changes ||= dependency.requirement != locked_dep.requirement
874
+ changes ||= dep.requirement != locked_dep.requirement
680
875
  end
681
876
 
682
877
  changes
@@ -686,140 +881,91 @@ module Bundler
686
881
  # commonly happen if the Gemfile has changed since the lockfile was last
687
882
  # generated
688
883
  def converge_locked_specs
689
- deps = []
884
+ converged = converge_specs(@locked_specs)
690
885
 
691
- # Build a list of dependencies that are the same in the Gemfile
692
- # and Gemfile.lock. If the Gemfile modified a dependency, but
693
- # the gem in the Gemfile.lock still satisfies it, this is fine
694
- # too.
695
- @dependencies.each do |dep|
696
- locked_dep = @locked_deps[dep.name]
886
+ resolve = SpecSet.new(converged.reject {|s| @gems_to_unlock.include?(s.name) })
697
887
 
698
- # If the locked_dep doesn't match the dependency we're looking for then we ignore the locked_dep
699
- locked_dep = nil unless locked_dep == dep
888
+ diff = nil
700
889
 
701
- if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
702
- deps << dep
703
- elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source)
704
- @locked_specs.each do |s|
705
- @unlock[:gems] << s.name if s.source == dep.source
706
- end
890
+ # Now, we unlock any sources that do not have anymore gems pinned to it
891
+ sources.all_sources.each do |source|
892
+ next unless source.respond_to?(:unlock!)
707
893
 
708
- dep.source.unlock! if dep.source.respond_to?(:unlock!)
709
- dep.source.specs.each {|s| @unlock[:gems] << s.name }
894
+ unless resolve.any? {|s| s.source == source }
895
+ diff ||= @locked_specs.to_a - resolve.to_a
896
+ source.unlock! if diff.any? {|s| s.source == source }
710
897
  end
711
898
  end
712
899
 
900
+ resolve
901
+ end
902
+
903
+ def converge_specs(specs)
713
904
  converged = []
714
- @locked_specs.each do |s|
715
- # Replace the locked dependency's source with the equivalent source from the Gemfile
905
+ deps = []
906
+
907
+ @specs_that_changed_sources = []
908
+
909
+ specs.each do |s|
910
+ name = s.name
716
911
  dep = @dependencies.find {|d| s.satisfies?(d) }
717
- s.source = (dep && dep.source) || sources.get(s.source) unless multisource_allowed?
912
+ lockfile_source = s.source
718
913
 
719
- # Don't add a spec to the list if its source is expired. For example,
720
- # if you change a Git gem to RubyGems.
721
- next if s.source.nil?
722
- next if @unlock[:sources].include?(s.source.name)
914
+ if dep
915
+ gemfile_source = dep.source || default_source
916
+
917
+ @specs_that_changed_sources << s if gemfile_source != lockfile_source
918
+ deps << dep if !dep.source || lockfile_source.include?(dep.source)
919
+ @gems_to_unlock << name if lockfile_source.include?(dep.source) && lockfile_source != gemfile_source
920
+
921
+ # Replace the locked dependency's source with the equivalent source from the Gemfile
922
+ s.source = gemfile_source
923
+ else
924
+ # Replace the locked dependency's source with the default source, if the locked source is no longer in the Gemfile
925
+ s.source = default_source unless sources.get(lockfile_source)
926
+ end
723
927
 
724
- # If the spec is from a path source and it doesn't exist anymore
725
- # then we unlock it.
928
+ next if @sources_to_unlock.include?(s.source.name)
726
929
 
727
930
  # Path sources have special logic
728
931
  if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
729
932
  new_specs = begin
730
933
  s.source.specs
731
- rescue PathError, GitError
934
+ rescue PathError
732
935
  # if we won't need the source (according to the lockfile),
733
- # don't error if the path/git source isn't available
734
- next if @locked_specs.
735
- for(requested_dependencies, false, true).
936
+ # don't error if the path source isn't available
937
+ next if specs.
938
+ for(requested_dependencies, false).
736
939
  none? {|locked_spec| locked_spec.source == s.source }
737
940
 
738
941
  raise
739
942
  end
740
943
 
741
944
  new_spec = new_specs[s].first
742
-
743
- # If the spec is no longer in the path source, unlock it. This
744
- # commonly happens if the version changed in the gemspec
745
- next unless new_spec
746
-
747
- s.dependencies.replace(new_spec.dependencies)
945
+ if new_spec
946
+ s.dependencies.replace(new_spec.dependencies)
947
+ else
948
+ # If the spec is no longer in the path source, unlock it. This
949
+ # commonly happens if the version changed in the gemspec
950
+ @gems_to_unlock << name
951
+ end
748
952
  end
749
953
 
750
- converged << s
751
- end
752
-
753
- resolve = SpecSet.new(converged)
754
- @locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), true, true)
755
- resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
756
- diff = nil
757
-
758
- # Now, we unlock any sources that do not have anymore gems pinned to it
759
- sources.all_sources.each do |source|
760
- next unless source.respond_to?(:unlock!)
761
-
762
- unless resolve.any? {|s| s.source == source }
763
- diff ||= @locked_specs.to_a - resolve.to_a
764
- source.unlock! if diff.any? {|s| s.source == source }
954
+ if dep.nil? && requested_dependencies.find {|d| name == d.name }
955
+ @gems_to_unlock << s.name
956
+ else
957
+ converged << s
765
958
  end
766
959
  end
767
960
 
768
- resolve
769
- end
770
-
771
- def in_locked_deps?(dep, locked_dep)
772
- # Because the lockfile can't link a dep to a specific remote, we need to
773
- # treat sources as equivalent anytime the locked dep has all the remotes
774
- # that the Gemfile dep does.
775
- locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
776
- end
777
-
778
- def satisfies_locked_spec?(dep)
779
- @locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
961
+ filter_specs(converged, deps)
780
962
  end
781
963
 
782
964
  def metadata_dependencies
783
- @metadata_dependencies ||= begin
784
- ruby_versions = ruby_version_requirements(@ruby_version)
785
- [
786
- Dependency.new("Ruby\0", ruby_versions),
787
- Dependency.new("RubyGems\0", Gem::VERSION),
788
- ]
789
- end
790
- end
791
-
792
- def ruby_version_requirements(ruby_version)
793
- return [] unless ruby_version
794
- if ruby_version.patchlevel
795
- [ruby_version.to_gem_version_with_patchlevel]
796
- else
797
- ruby_version.versions.map do |version|
798
- requirement = Gem::Requirement.new(version)
799
- if requirement.exact?
800
- "~> #{version}.0"
801
- else
802
- requirement
803
- end
804
- end
805
- end
806
- end
807
-
808
- def expand_dependencies(dependencies, remote = false)
809
- deps = []
810
- dependencies.each do |dep|
811
- dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
812
- next unless remote || dep.current_platform?
813
- target_platforms = dep.gem_platforms(remote ? @platforms : [generic_local_platform])
814
- deps += expand_dependency_with_platforms(dep, target_platforms)
815
- end
816
- deps
817
- end
818
-
819
- def expand_dependency_with_platforms(dep, platforms)
820
- platforms.map do |p|
821
- DepProxy.get_proxy(dep, p)
822
- end
965
+ @metadata_dependencies ||= [
966
+ Dependency.new("Ruby\0", Bundler::RubyVersion.system.gem_version),
967
+ Dependency.new("RubyGems\0", Gem::VERSION),
968
+ ]
823
969
  end
824
970
 
825
971
  def source_requirements
@@ -827,27 +973,54 @@ module Bundler
827
973
  # specs will be available later when the resolver knows where to
828
974
  # look for that gemspec (or its dependencies)
829
975
  source_requirements = if precompute_source_requirements_for_indirect_dependencies?
830
- { :default => sources.default_source }.merge(source_map.all_requirements)
976
+ all_requirements = source_map.all_requirements
977
+ all_requirements = pin_locally_available_names(all_requirements) if @prefer_local
978
+ { default: default_source }.merge(all_requirements)
831
979
  else
832
- { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
980
+ { default: Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
833
981
  end
982
+ source_requirements.merge!(source_map.locked_requirements) if nothing_changed?
834
983
  metadata_dependencies.each do |dep|
835
984
  source_requirements[dep.name] = sources.metadata_source
836
985
  end
837
- source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
838
- source_requirements["bundler"] = sources.metadata_source # needs to come last to override
986
+
987
+ default_bundler_source = source_requirements["bundler"] || default_source
988
+
989
+ if @unlocking_bundler
990
+ default_bundler_source.add_dependency_names("bundler")
991
+ else
992
+ source_requirements[:default_bundler] = default_bundler_source
993
+ source_requirements["bundler"] = sources.metadata_source # needs to come last to override
994
+ end
995
+
996
+ verify_changed_sources!
839
997
  source_requirements
840
998
  end
841
999
 
1000
+ def default_source
1001
+ sources.default_source
1002
+ end
1003
+
1004
+ def verify_changed_sources!
1005
+ @specs_that_changed_sources.each do |s|
1006
+ if s.source.specs.search(s.name).empty?
1007
+ raise GemNotFound, "Could not find gem '#{s.name}' in #{s.source}"
1008
+ end
1009
+ end
1010
+ end
1011
+
842
1012
  def requested_groups
843
- groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
1013
+ values = groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
1014
+ values &= Bundler.settings[:only] unless Bundler.settings[:only].empty?
1015
+ values
844
1016
  end
845
1017
 
846
1018
  def lockfiles_equal?(current, proposed, preserve_unknown_sections)
847
1019
  if preserve_unknown_sections
848
1020
  sections_to_ignore = LockfileParser.sections_to_ignore(@locked_bundler_version)
849
1021
  sections_to_ignore += LockfileParser.unknown_sections_in_lockfile(current)
850
- sections_to_ignore += LockfileParser::ENVIRONMENT_VERSION_SECTIONS
1022
+ sections_to_ignore << LockfileParser::RUBY
1023
+ sections_to_ignore << LockfileParser::BUNDLED unless @unlocking_bundler
851
1024
  pattern = /#{Regexp.union(sections_to_ignore)}\n(\s{2,}.*\n)+/
852
1025
  whitespace_cleanup = /\n{2,}/
853
1026
  current = current.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip
@@ -856,39 +1029,56 @@ module Bundler
856
1029
  current == proposed
857
1030
  end
858
1031
 
859
- def compute_requires
860
- dependencies.reduce({}) do |requires, dep|
861
- next requires unless dep.should_include?
862
- requires[dep.name] = Array(dep.autorequire || dep.name).map do |file|
863
- # Allow `require: true` as an alias for `require: <name>`
864
- file == true ? dep.name : file
865
- end
866
- requires
1032
+ def additional_base_requirements_to_prevent_downgrades(resolution_packages, last_resolve)
1033
+ return resolution_packages unless @locked_gems && !sources.expired_sources?(@locked_gems.sources)
1034
+ converge_specs(@originally_locked_specs - last_resolve).each do |locked_spec|
1035
+ next if locked_spec.source.is_a?(Source::Path)
1036
+ resolution_packages.base_requirements[locked_spec.name] = Gem::Requirement.new(">= #{locked_spec.version}")
867
1037
  end
1038
+ resolution_packages
868
1039
  end
869
1040
 
870
- def additional_base_requirements_for_resolve
871
- return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
872
- dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
873
- @locked_gems.specs.reduce({}) do |requirements, locked_spec|
874
- name = locked_spec.name
875
- dependency = dependencies_by_name[name]
876
- next requirements if @locked_gems.dependencies[name] != dependency
877
- next requirements if dependency && dependency.source.is_a?(Source::Path)
878
- dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
879
- requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
880
- requirements
881
- end.values
1041
+ def additional_base_requirements_to_force_updates(resolution_packages)
1042
+ return resolution_packages if @explicit_unlocks.empty?
1043
+ full_update = dup_for_full_unlock.resolve
1044
+ @explicit_unlocks.each do |name|
1045
+ version = full_update[name].first&.version
1046
+ resolution_packages.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
1047
+ end
1048
+ resolution_packages
1049
+ end
1050
+
1051
+ def dup_for_full_unlock
1052
+ unlocked_definition = self.class.new(@lockfile, @dependencies, @sources, true, @ruby_version, @optional_groups, @gemfiles)
1053
+ unlocked_definition.gem_version_promoter.tap do |gvp|
1054
+ gvp.level = gem_version_promoter.level
1055
+ gvp.strict = gem_version_promoter.strict
1056
+ gvp.pre = gem_version_promoter.pre
1057
+ end
1058
+ unlocked_definition
882
1059
  end
883
1060
 
884
- def equivalent_rubygems_remotes?(source)
885
- return false unless source.is_a?(Source::Rubygems)
1061
+ def remove_invalid_platforms!
1062
+ return if Bundler.frozen_bundle?
1063
+
1064
+ platforms.reverse_each do |platform|
1065
+ next if local_platform == platform ||
1066
+ @new_platforms.include?(platform) ||
1067
+ @path_changes ||
1068
+ @dependency_changes ||
1069
+ @locked_spec_with_invalid_deps ||
1070
+ !spec_set_incomplete_for_platform?(@originally_locked_specs, platform)
1071
+
1072
+ remove_platform(platform)
1073
+ end
1074
+ end
886
1075
 
887
- Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
1076
+ def spec_set_incomplete_for_platform?(spec_set, platform)
1077
+ spec_set.incomplete_for_platform?(current_dependencies, platform)
888
1078
  end
889
1079
 
890
1080
  def source_map
891
- @source_map ||= SourceMap.new(sources, dependencies)
1081
+ @source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
892
1082
  end
893
1083
  end
894
1084
  end