bundler-clone 4.0.15

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 (350) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5670 -0
  3. data/LICENSE.md +22 -0
  4. data/README.md +58 -0
  5. data/bundler.gemspec +46 -0
  6. data/exe/bundle +29 -0
  7. data/exe/bundler +4 -0
  8. data/lib/bundler/.document +1 -0
  9. data/lib/bundler/build_metadata.rb +44 -0
  10. data/lib/bundler/capistrano.rb +4 -0
  11. data/lib/bundler/checksum.rb +270 -0
  12. data/lib/bundler/ci_detector.rb +75 -0
  13. data/lib/bundler/cli/add.rb +62 -0
  14. data/lib/bundler/cli/binstubs.rb +57 -0
  15. data/lib/bundler/cli/cache.rb +32 -0
  16. data/lib/bundler/cli/check.rb +40 -0
  17. data/lib/bundler/cli/clean.rb +25 -0
  18. data/lib/bundler/cli/common.rb +161 -0
  19. data/lib/bundler/cli/config.rb +208 -0
  20. data/lib/bundler/cli/console.rb +47 -0
  21. data/lib/bundler/cli/doctor/diagnose.rb +167 -0
  22. data/lib/bundler/cli/doctor/ssl.rb +249 -0
  23. data/lib/bundler/cli/doctor.rb +33 -0
  24. data/lib/bundler/cli/exec.rb +114 -0
  25. data/lib/bundler/cli/fund.rb +36 -0
  26. data/lib/bundler/cli/gem.rb +493 -0
  27. data/lib/bundler/cli/info.rb +83 -0
  28. data/lib/bundler/cli/init.rb +51 -0
  29. data/lib/bundler/cli/install.rb +127 -0
  30. data/lib/bundler/cli/issue.rb +41 -0
  31. data/lib/bundler/cli/list.rb +97 -0
  32. data/lib/bundler/cli/lock.rb +94 -0
  33. data/lib/bundler/cli/open.rb +29 -0
  34. data/lib/bundler/cli/outdated.rb +337 -0
  35. data/lib/bundler/cli/platform.rb +48 -0
  36. data/lib/bundler/cli/plugin.rb +39 -0
  37. data/lib/bundler/cli/pristine.rb +64 -0
  38. data/lib/bundler/cli/remove.rb +17 -0
  39. data/lib/bundler/cli/show.rb +71 -0
  40. data/lib/bundler/cli/update.rb +125 -0
  41. data/lib/bundler/cli.rb +829 -0
  42. data/lib/bundler/compact_index_client/cache.rb +96 -0
  43. data/lib/bundler/compact_index_client/cache_file.rb +148 -0
  44. data/lib/bundler/compact_index_client/parser.rb +87 -0
  45. data/lib/bundler/compact_index_client/updater.rb +105 -0
  46. data/lib/bundler/compact_index_client.rb +92 -0
  47. data/lib/bundler/constants.rb +14 -0
  48. data/lib/bundler/current_ruby.rb +94 -0
  49. data/lib/bundler/definition.rb +1304 -0
  50. data/lib/bundler/dependency.rb +151 -0
  51. data/lib/bundler/deployment.rb +6 -0
  52. data/lib/bundler/deprecate.rb +44 -0
  53. data/lib/bundler/digest.rb +71 -0
  54. data/lib/bundler/dsl.rb +642 -0
  55. data/lib/bundler/endpoint_specification.rb +184 -0
  56. data/lib/bundler/env.rb +148 -0
  57. data/lib/bundler/environment_preserver.rb +69 -0
  58. data/lib/bundler/errors.rb +277 -0
  59. data/lib/bundler/feature_flag.rb +20 -0
  60. data/lib/bundler/fetcher/base.rb +55 -0
  61. data/lib/bundler/fetcher/compact_index.rb +133 -0
  62. data/lib/bundler/fetcher/dependency.rb +85 -0
  63. data/lib/bundler/fetcher/downloader.rb +116 -0
  64. data/lib/bundler/fetcher/gem_remote_fetcher.rb +24 -0
  65. data/lib/bundler/fetcher/index.rb +25 -0
  66. data/lib/bundler/fetcher.rb +365 -0
  67. data/lib/bundler/force_platform.rb +16 -0
  68. data/lib/bundler/friendly_errors.rb +127 -0
  69. data/lib/bundler/gem_helper.rb +237 -0
  70. data/lib/bundler/gem_tasks.rb +7 -0
  71. data/lib/bundler/gem_version_promoter.rb +147 -0
  72. data/lib/bundler/index.rb +203 -0
  73. data/lib/bundler/injector.rb +284 -0
  74. data/lib/bundler/inline.rb +106 -0
  75. data/lib/bundler/installer/gem_installer.rb +88 -0
  76. data/lib/bundler/installer/parallel_installer.rb +280 -0
  77. data/lib/bundler/installer/standalone.rb +113 -0
  78. data/lib/bundler/installer.rb +241 -0
  79. data/lib/bundler/lazy_specification.rb +270 -0
  80. data/lib/bundler/lockfile_generator.rb +119 -0
  81. data/lib/bundler/lockfile_parser.rb +328 -0
  82. data/lib/bundler/man/.document +1 -0
  83. data/lib/bundler/man/bundle-add.1 +79 -0
  84. data/lib/bundler/man/bundle-add.1.ronn +92 -0
  85. data/lib/bundler/man/bundle-binstubs.1 +30 -0
  86. data/lib/bundler/man/bundle-binstubs.1.ronn +42 -0
  87. data/lib/bundler/man/bundle-cache.1 +56 -0
  88. data/lib/bundler/man/bundle-cache.1.ronn +95 -0
  89. data/lib/bundler/man/bundle-check.1 +21 -0
  90. data/lib/bundler/man/bundle-check.1.ronn +26 -0
  91. data/lib/bundler/man/bundle-clean.1 +17 -0
  92. data/lib/bundler/man/bundle-clean.1.ronn +18 -0
  93. data/lib/bundler/man/bundle-config.1 +339 -0
  94. data/lib/bundler/man/bundle-config.1.ronn +455 -0
  95. data/lib/bundler/man/bundle-console.1 +33 -0
  96. data/lib/bundler/man/bundle-console.1.ronn +39 -0
  97. data/lib/bundler/man/bundle-doctor.1 +69 -0
  98. data/lib/bundler/man/bundle-doctor.1.ronn +77 -0
  99. data/lib/bundler/man/bundle-env.1 +9 -0
  100. data/lib/bundler/man/bundle-env.1.ronn +10 -0
  101. data/lib/bundler/man/bundle-exec.1 +104 -0
  102. data/lib/bundler/man/bundle-exec.1.ronn +150 -0
  103. data/lib/bundler/man/bundle-fund.1 +22 -0
  104. data/lib/bundler/man/bundle-fund.1.ronn +25 -0
  105. data/lib/bundler/man/bundle-gem.1 +107 -0
  106. data/lib/bundler/man/bundle-gem.1.ronn +150 -0
  107. data/lib/bundler/man/bundle-help.1 +9 -0
  108. data/lib/bundler/man/bundle-help.1.ronn +12 -0
  109. data/lib/bundler/man/bundle-info.1 +17 -0
  110. data/lib/bundler/man/bundle-info.1.ronn +21 -0
  111. data/lib/bundler/man/bundle-init.1 +20 -0
  112. data/lib/bundler/man/bundle-init.1.ronn +32 -0
  113. data/lib/bundler/man/bundle-install.1 +178 -0
  114. data/lib/bundler/man/bundle-install.1.ronn +314 -0
  115. data/lib/bundler/man/bundle-issue.1 +45 -0
  116. data/lib/bundler/man/bundle-issue.1.ronn +37 -0
  117. data/lib/bundler/man/bundle-licenses.1 +9 -0
  118. data/lib/bundler/man/bundle-licenses.1.ronn +10 -0
  119. data/lib/bundler/man/bundle-list.1 +40 -0
  120. data/lib/bundler/man/bundle-list.1.ronn +41 -0
  121. data/lib/bundler/man/bundle-lock.1 +75 -0
  122. data/lib/bundler/man/bundle-lock.1.ronn +115 -0
  123. data/lib/bundler/man/bundle-open.1 +32 -0
  124. data/lib/bundler/man/bundle-open.1.ronn +28 -0
  125. data/lib/bundler/man/bundle-outdated.1 +106 -0
  126. data/lib/bundler/man/bundle-outdated.1.ronn +117 -0
  127. data/lib/bundler/man/bundle-platform.1 +49 -0
  128. data/lib/bundler/man/bundle-platform.1.ronn +49 -0
  129. data/lib/bundler/man/bundle-plugin.1 +76 -0
  130. data/lib/bundler/man/bundle-plugin.1.ronn +84 -0
  131. data/lib/bundler/man/bundle-pristine.1 +23 -0
  132. data/lib/bundler/man/bundle-pristine.1.ronn +34 -0
  133. data/lib/bundler/man/bundle-remove.1 +15 -0
  134. data/lib/bundler/man/bundle-remove.1.ronn +16 -0
  135. data/lib/bundler/man/bundle-show.1 +16 -0
  136. data/lib/bundler/man/bundle-show.1.ronn +21 -0
  137. data/lib/bundler/man/bundle-update.1 +284 -0
  138. data/lib/bundler/man/bundle-update.1.ronn +367 -0
  139. data/lib/bundler/man/bundle-version.1 +22 -0
  140. data/lib/bundler/man/bundle-version.1.ronn +24 -0
  141. data/lib/bundler/man/bundle.1 +93 -0
  142. data/lib/bundler/man/bundle.1.ronn +107 -0
  143. data/lib/bundler/man/gemfile.5 +503 -0
  144. data/lib/bundler/man/gemfile.5.ronn +586 -0
  145. data/lib/bundler/man/index.txt +31 -0
  146. data/lib/bundler/match_metadata.rb +30 -0
  147. data/lib/bundler/match_platform.rb +42 -0
  148. data/lib/bundler/match_remote_metadata.rb +29 -0
  149. data/lib/bundler/materialization.rb +59 -0
  150. data/lib/bundler/mirror.rb +221 -0
  151. data/lib/bundler/plugin/api/source.rb +330 -0
  152. data/lib/bundler/plugin/api.rb +81 -0
  153. data/lib/bundler/plugin/dsl.rb +53 -0
  154. data/lib/bundler/plugin/events.rb +85 -0
  155. data/lib/bundler/plugin/index.rb +203 -0
  156. data/lib/bundler/plugin/installer/git.rb +34 -0
  157. data/lib/bundler/plugin/installer/path.rb +26 -0
  158. data/lib/bundler/plugin/installer/rubygems.rb +19 -0
  159. data/lib/bundler/plugin/installer.rb +123 -0
  160. data/lib/bundler/plugin/source_list.rb +31 -0
  161. data/lib/bundler/plugin/unloaded_source.rb +25 -0
  162. data/lib/bundler/plugin.rb +387 -0
  163. data/lib/bundler/process_lock.rb +20 -0
  164. data/lib/bundler/remote_specification.rb +126 -0
  165. data/lib/bundler/resolver/base.rb +127 -0
  166. data/lib/bundler/resolver/candidate.rb +85 -0
  167. data/lib/bundler/resolver/incompatibility.rb +15 -0
  168. data/lib/bundler/resolver/package.rb +95 -0
  169. data/lib/bundler/resolver/root.rb +25 -0
  170. data/lib/bundler/resolver/spec_group.rb +74 -0
  171. data/lib/bundler/resolver/strategy.rb +43 -0
  172. data/lib/bundler/resolver.rb +603 -0
  173. data/lib/bundler/retry.rb +92 -0
  174. data/lib/bundler/ruby_dsl.rb +67 -0
  175. data/lib/bundler/ruby_version.rb +135 -0
  176. data/lib/bundler/rubygems_ext.rb +503 -0
  177. data/lib/bundler/rubygems_gem_installer.rb +206 -0
  178. data/lib/bundler/rubygems_integration.rb +456 -0
  179. data/lib/bundler/runtime.rb +331 -0
  180. data/lib/bundler/safe_marshal.rb +31 -0
  181. data/lib/bundler/self_manager.rb +197 -0
  182. data/lib/bundler/settings/validator.rb +86 -0
  183. data/lib/bundler/settings.rb +585 -0
  184. data/lib/bundler/setup.rb +39 -0
  185. data/lib/bundler/shared_helpers.rb +392 -0
  186. data/lib/bundler/source/gemspec.rb +19 -0
  187. data/lib/bundler/source/git/git_proxy.rb +509 -0
  188. data/lib/bundler/source/git.rb +451 -0
  189. data/lib/bundler/source/metadata.rb +67 -0
  190. data/lib/bundler/source/path/installer.rb +53 -0
  191. data/lib/bundler/source/path.rb +256 -0
  192. data/lib/bundler/source/rubygems/remote.rb +86 -0
  193. data/lib/bundler/source/rubygems.rb +606 -0
  194. data/lib/bundler/source/rubygems_aggregate.rb +71 -0
  195. data/lib/bundler/source.rb +120 -0
  196. data/lib/bundler/source_list.rb +240 -0
  197. data/lib/bundler/source_map.rb +72 -0
  198. data/lib/bundler/spec_set.rb +390 -0
  199. data/lib/bundler/stub_specification.rb +147 -0
  200. data/lib/bundler/templates/.document +1 -0
  201. data/lib/bundler/templates/Executable +16 -0
  202. data/lib/bundler/templates/Executable.standalone +14 -0
  203. data/lib/bundler/templates/Gemfile +5 -0
  204. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  205. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +10 -0
  206. data/lib/bundler/templates/newgem/Cargo.toml.tt +13 -0
  207. data/lib/bundler/templates/newgem/Gemfile.tt +24 -0
  208. data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
  209. data/lib/bundler/templates/newgem/README.md.tt +49 -0
  210. data/lib/bundler/templates/newgem/Rakefile.tt +72 -0
  211. data/lib/bundler/templates/newgem/bin/console.tt +11 -0
  212. data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
  213. data/lib/bundler/templates/newgem/circleci/config.yml.tt +37 -0
  214. data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  215. data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +22 -0
  216. data/lib/bundler/templates/newgem/ext/newgem/build.rs.tt +5 -0
  217. data/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
  218. data/lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt +11 -0
  219. data/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  220. data/lib/bundler/templates/newgem/ext/newgem/go.mod.tt +5 -0
  221. data/lib/bundler/templates/newgem/ext/newgem/newgem-go.c.tt +2 -0
  222. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  223. data/lib/bundler/templates/newgem/ext/newgem/newgem.go.tt +31 -0
  224. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  225. data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +23 -0
  226. data/lib/bundler/templates/newgem/github/workflows/build-gems.yml.tt +69 -0
  227. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +48 -0
  228. data/lib/bundler/templates/newgem/gitignore.tt +23 -0
  229. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +27 -0
  230. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +9 -0
  231. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +15 -0
  232. data/lib/bundler/templates/newgem/newgem.gemspec.tt +58 -0
  233. data/lib/bundler/templates/newgem/rspec.tt +3 -0
  234. data/lib/bundler/templates/newgem/rubocop.yml.tt +8 -0
  235. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  236. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +19 -0
  237. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +15 -0
  238. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  239. data/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt +6 -0
  240. data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +19 -0
  241. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  242. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  243. data/lib/bundler/ui/rg_proxy.rb +19 -0
  244. data/lib/bundler/ui/shell.rb +191 -0
  245. data/lib/bundler/ui/silent.rb +96 -0
  246. data/lib/bundler/ui.rb +9 -0
  247. data/lib/bundler/uri_credentials_filter.rb +43 -0
  248. data/lib/bundler/uri_normalizer.rb +23 -0
  249. data/lib/bundler/vendor/.document +1 -0
  250. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  251. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +227 -0
  252. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  253. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +56 -0
  254. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +230 -0
  255. data/lib/bundler/vendor/fileutils/COPYING +56 -0
  256. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +2701 -0
  257. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  258. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +41 -0
  259. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +65 -0
  260. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +80 -0
  261. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1153 -0
  262. data/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  263. data/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  264. data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +169 -0
  265. data/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  266. data/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
  267. data/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  268. data/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  269. data/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  270. data/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  271. data/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +61 -0
  272. data/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
  273. data/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  274. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  275. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
  276. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +423 -0
  277. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +236 -0
  278. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  279. data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  280. data/lib/bundler/vendor/securerandom/COPYING +56 -0
  281. data/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
  282. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  283. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +105 -0
  284. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +61 -0
  285. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +108 -0
  286. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
  287. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +407 -0
  288. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +130 -0
  289. data/lib/bundler/vendor/thor/lib/thor/actions.rb +340 -0
  290. data/lib/bundler/vendor/thor/lib/thor/base.rb +825 -0
  291. data/lib/bundler/vendor/thor/lib/thor/command.rb +151 -0
  292. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +107 -0
  293. data/lib/bundler/vendor/thor/lib/thor/error.rb +106 -0
  294. data/lib/bundler/vendor/thor/lib/thor/group.rb +292 -0
  295. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +178 -0
  296. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
  297. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  298. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
  299. data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
  300. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +86 -0
  301. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +195 -0
  302. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +178 -0
  303. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +294 -0
  304. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  305. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +72 -0
  306. data/lib/bundler/vendor/thor/lib/thor/runner.rb +335 -0
  307. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +384 -0
  308. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +112 -0
  309. data/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
  310. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +81 -0
  311. data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +118 -0
  312. data/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
  313. data/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
  314. data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
  315. data/lib/bundler/vendor/thor/lib/thor/util.rb +285 -0
  316. data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
  317. data/lib/bundler/vendor/thor/lib/thor.rb +674 -0
  318. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  319. data/lib/bundler/vendor/tsort/lib/tsort.rb +455 -0
  320. data/lib/bundler/vendor/uri/COPYING +56 -0
  321. data/lib/bundler/vendor/uri/lib/uri/common.rb +922 -0
  322. data/lib/bundler/vendor/uri/lib/uri/file.rb +100 -0
  323. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
  324. data/lib/bundler/vendor/uri/lib/uri/generic.rb +1592 -0
  325. data/lib/bundler/vendor/uri/lib/uri/http.rb +137 -0
  326. data/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
  327. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
  328. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +22 -0
  329. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +293 -0
  330. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +547 -0
  331. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +206 -0
  332. data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
  333. data/lib/bundler/vendor/uri/lib/uri/ws.rb +83 -0
  334. data/lib/bundler/vendor/uri/lib/uri/wss.rb +23 -0
  335. data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
  336. data/lib/bundler/vendored_fileutils.rb +4 -0
  337. data/lib/bundler/vendored_net_http.rb +23 -0
  338. data/lib/bundler/vendored_persistent.rb +11 -0
  339. data/lib/bundler/vendored_pub_grub.rb +4 -0
  340. data/lib/bundler/vendored_securerandom.rb +12 -0
  341. data/lib/bundler/vendored_thor.rb +8 -0
  342. data/lib/bundler/vendored_timeout.rb +12 -0
  343. data/lib/bundler/vendored_tsort.rb +4 -0
  344. data/lib/bundler/vendored_uri.rb +21 -0
  345. data/lib/bundler/version.rb +21 -0
  346. data/lib/bundler/vlad.rb +4 -0
  347. data/lib/bundler/worker.rb +125 -0
  348. data/lib/bundler/yaml_serializer.rb +98 -0
  349. data/lib/bundler.rb +691 -0
  350. metadata +409 -0
@@ -0,0 +1,1304 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lockfile_parser"
4
+ require_relative "worker"
5
+
6
+ module Bundler
7
+ class Definition
8
+ class << self
9
+ # Do not create or modify a lockfile (Makes #lock a noop)
10
+ attr_accessor :no_lock
11
+ end
12
+
13
+ attr_writer :lockfile
14
+
15
+ attr_reader(
16
+ :dependencies,
17
+ :locked_checksums,
18
+ :locked_deps,
19
+ :locked_gems,
20
+ :platforms,
21
+ :ruby_version,
22
+ :lockfile,
23
+ :gemfiles,
24
+ :sources
25
+ )
26
+
27
+ # Given a gemfile and lockfile creates a Bundler definition
28
+ #
29
+ # @param gemfile [Pathname] Path to Gemfile
30
+ # @param lockfile [Pathname,nil] Path to Gemfile.lock
31
+ # @param unlock [Hash, Boolean, nil] Gems that have been requested
32
+ # to be updated or true if all gems should be updated
33
+ # @return [Bundler::Definition]
34
+ def self.build(gemfile, lockfile, unlock)
35
+ unlock ||= {}
36
+ gemfile = Pathname.new(gemfile).expand_path
37
+
38
+ raise GemfileNotFound, "#{gemfile} not found" unless gemfile.file?
39
+
40
+ Dsl.evaluate(gemfile, lockfile, unlock)
41
+ end
42
+
43
+ #
44
+ # How does the new system work?
45
+ #
46
+ # * Load information from Gemfile and Lockfile
47
+ # * Invalidate stale locked specs
48
+ # * All specs from stale source are stale
49
+ # * All specs that are reachable only through a stale
50
+ # dependency are stale.
51
+ # * If all fresh dependencies are satisfied by the locked
52
+ # specs, then we can try to resolve locally.
53
+ #
54
+ # @param lockfile [Pathname] Path to Gemfile.lock
55
+ # @param dependencies [Array(Bundler::Dependency)] array of dependencies from Gemfile
56
+ # @param sources [Bundler::SourceList]
57
+ # @param unlock [Hash, Boolean, nil] Gems that have been requested
58
+ # to be updated or true if all gems should be updated
59
+ # @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
60
+ # @param optional_groups [Array(String)] A list of optional groups
61
+ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = [])
62
+ unlock ||= {}
63
+
64
+ if unlock == true
65
+ @unlocking_all = true
66
+ strict = false
67
+ @unlocking_bundler = false
68
+ @unlocking = unlock
69
+ @sources_to_unlock = []
70
+ @unlocking_ruby = false
71
+ @explicit_unlocks = []
72
+ conservative = false
73
+ else
74
+ @unlocking_all = false
75
+ strict = unlock.delete(:strict)
76
+ @unlocking_bundler = unlock.delete(:bundler)
77
+ @unlocking = unlock.any? {|_k, v| !Array(v).empty? }
78
+ @sources_to_unlock = unlock.delete(:sources) || []
79
+ @unlocking_ruby = unlock.delete(:ruby)
80
+ @explicit_unlocks = unlock.delete(:gems) || []
81
+ conservative = unlock.delete(:conservative)
82
+ end
83
+
84
+ @dependencies = dependencies
85
+ @sources = sources
86
+ @optional_groups = optional_groups
87
+ @prefer_local = false
88
+ @specs = nil
89
+ @ruby_version = ruby_version
90
+ @gemfiles = gemfiles
91
+
92
+ @lockfile = lockfile
93
+ @lockfile_contents = String.new
94
+
95
+ @locked_bundler_version = nil
96
+ @resolved_bundler_version = nil
97
+
98
+ @locked_ruby_version = nil
99
+ @new_platforms = []
100
+ @removed_platforms = []
101
+ @originally_invalid_platforms = []
102
+
103
+ if lockfile_exists?
104
+ @lockfile_contents = Bundler.read_file(lockfile)
105
+ @locked_gems = LockfileParser.new(@lockfile_contents, strict: strict)
106
+ @locked_platforms = @locked_gems.platforms
107
+ @most_specific_locked_platform = @locked_gems.most_specific_locked_platform
108
+ @platforms = @locked_platforms.dup
109
+ @locked_bundler_version = @locked_gems.bundler_version
110
+ @locked_ruby_version = @locked_gems.ruby_version
111
+ @locked_deps = @locked_gems.dependencies
112
+ @originally_locked_specs = SpecSet.new(@locked_gems.specs)
113
+ @originally_locked_sources = @locked_gems.sources
114
+ @locked_checksums = @locked_gems.checksums
115
+
116
+ if @unlocking_all
117
+ @locked_specs = SpecSet.new([])
118
+ @locked_sources = []
119
+ else
120
+ @locked_specs = @originally_locked_specs
121
+ @locked_sources = @originally_locked_sources
122
+ end
123
+
124
+ locked_gem_sources = @originally_locked_sources.select {|s| s.is_a?(Source::Rubygems) }
125
+ multisource_lockfile = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes?
126
+
127
+ if multisource_lockfile
128
+ msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
129
+
130
+ Bundler::SharedHelpers.feature_removed! msg
131
+ end
132
+ else
133
+ @locked_gems = nil
134
+ @locked_platforms = []
135
+ @most_specific_locked_platform = nil
136
+ @platforms = []
137
+ @locked_deps = {}
138
+ @locked_specs = SpecSet.new([])
139
+ @locked_sources = []
140
+ @originally_locked_specs = @locked_specs
141
+ @originally_locked_sources = @locked_sources
142
+ @locked_checksums = Bundler.settings[:lockfile_checksums]
143
+ end
144
+
145
+ @unlocking_ruby ||= if @ruby_version && locked_ruby_version_object
146
+ @ruby_version.diff(locked_ruby_version_object)
147
+ end
148
+ @unlocking ||= @unlocking_ruby ||= (!@locked_ruby_version ^ !@ruby_version)
149
+
150
+ @current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
151
+
152
+ @source_changes = converge_sources
153
+ @path_changes = converge_paths
154
+
155
+ if conservative
156
+ @gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
157
+ else
158
+ eager_unlock = @explicit_unlocks.map {|name| Dependency.new(name, ">= 0") }
159
+ @gems_to_unlock = @locked_specs.for(eager_unlock, platforms).map(&:name).uniq
160
+ end
161
+
162
+ @dependency_changes = converge_dependencies
163
+ @local_changes = converge_locals
164
+
165
+ check_lockfile
166
+ end
167
+
168
+ def gem_version_promoter
169
+ @gem_version_promoter ||= GemVersionPromoter.new
170
+ end
171
+
172
+ def check!
173
+ # If dependencies have changed, we need to resolve remotely. Otherwise,
174
+ # since we'll be resolving with a single local source, we may end up
175
+ # locking gems under the wrong source in the lockfile, and missing lockfile
176
+ # checksums
177
+ resolve_remotely! if @dependency_changes
178
+
179
+ # Now do a local only resolve, to verify if any gems are missing locally
180
+ sources.local_only!
181
+ resolve
182
+ end
183
+
184
+ #
185
+ # Setup sources according to the given options and the state of the
186
+ # definition.
187
+ #
188
+ # @return [Boolean] Whether fetching remote information will be necessary or not
189
+ #
190
+ def setup_domain!(options = {})
191
+ prefer_local! if options[:"prefer-local"]
192
+
193
+ sources.cached!
194
+
195
+ if options[:add_checksums] || (!options[:local] && install_needed?)
196
+ sources.remote!
197
+ true
198
+ else
199
+ Bundler.settings.set_command_option(:jobs, 1) unless install_needed? # to avoid the overhead of Bundler::Worker
200
+ sources.local!
201
+ false
202
+ end
203
+ end
204
+
205
+ def resolve_with_cache!
206
+ with_cache!
207
+
208
+ resolve
209
+ end
210
+
211
+ def with_cache!
212
+ sources.local!
213
+ sources.cached!
214
+ end
215
+
216
+ def resolve_remotely!
217
+ remotely!
218
+
219
+ resolve
220
+ end
221
+
222
+ def remotely!
223
+ sources.cached!
224
+ sources.remote!
225
+ end
226
+
227
+ def prefer_local!
228
+ @prefer_local = true
229
+
230
+ sources.prefer_local!
231
+ end
232
+
233
+ # Releases memory only needed during resolution, such as remote spec
234
+ # indexes and resolver state. Only safe to call once resolution is
235
+ # complete and the result has been materialized, since any further
236
+ # resolution will need to refetch remote specs.
237
+ def release_resolution_memory!
238
+ @resolver = nil
239
+ @resolution_base = nil
240
+ sources.release_resolution_memory!
241
+ end
242
+
243
+ # For given dependency list returns a SpecSet with Gemspec of all the required
244
+ # dependencies.
245
+ # 1. The method first resolves the dependencies specified in Gemfile
246
+ # 2. After that it tries and fetches gemspec of resolved dependencies
247
+ #
248
+ # @return [Bundler::SpecSet]
249
+ def specs
250
+ @specs ||= materialize(requested_dependencies)
251
+ end
252
+
253
+ def new_specs
254
+ specs - @locked_specs
255
+ end
256
+
257
+ def removed_specs
258
+ @locked_specs - specs
259
+ end
260
+
261
+ def missing_specs
262
+ preload_git_sources
263
+ resolve.missing_specs_for(requested_dependencies)
264
+ end
265
+
266
+ def missing_specs?
267
+ missing = missing_specs
268
+ return false if missing.empty?
269
+ Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
270
+ true
271
+ rescue BundlerError => e
272
+ @resolve = nil
273
+ @resolver = nil
274
+ @resolution_base = nil
275
+ @source_requirements = nil
276
+ @specs = nil
277
+
278
+ Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
279
+ true
280
+ end
281
+
282
+ def requested_specs
283
+ specs_for(requested_groups)
284
+ end
285
+
286
+ def requested_dependencies
287
+ dependencies_for(requested_groups)
288
+ end
289
+
290
+ def current_dependencies
291
+ filter_relevant(dependencies)
292
+ end
293
+
294
+ def current_locked_dependencies
295
+ filter_relevant(locked_dependencies)
296
+ end
297
+
298
+ def filter_relevant(dependencies)
299
+ dependencies.select do |d|
300
+ relevant_deps?(d)
301
+ end
302
+ end
303
+
304
+ def relevant_deps?(dep)
305
+ platforms_array = [Bundler.generic_local_platform].freeze
306
+
307
+ dep.should_include? && !dep.gem_platforms(platforms_array).empty?
308
+ end
309
+
310
+ def locked_dependencies
311
+ @locked_deps.values
312
+ end
313
+
314
+ def new_deps
315
+ @new_deps ||= @dependencies - locked_dependencies
316
+ end
317
+
318
+ def deleted_deps
319
+ @deleted_deps ||= locked_dependencies - @dependencies
320
+ end
321
+
322
+ def specs_for(groups)
323
+ return specs if groups.empty?
324
+ deps = dependencies_for(groups)
325
+ materialize(deps)
326
+ end
327
+
328
+ def dependencies_for(groups)
329
+ groups.map!(&:to_sym)
330
+ deps = current_dependencies # always returns a new array
331
+ deps.select! do |d|
332
+ d.groups.intersect?(groups)
333
+ end
334
+ deps
335
+ end
336
+
337
+ # Resolve all the dependencies specified in Gemfile. It ensures that
338
+ # dependencies that have been already resolved via locked file and are fresh
339
+ # are reused when resolving dependencies
340
+ #
341
+ # @return [SpecSet] resolved dependencies
342
+ def resolve
343
+ @resolve ||= if Bundler.frozen_bundle?
344
+ Bundler.ui.debug "Frozen, using resolution from the lockfile"
345
+ @locked_specs
346
+ elsif no_resolve_needed?
347
+ if deleted_deps.any?
348
+ Bundler.ui.debug "Some dependencies were deleted, using a subset of the resolution from the lockfile"
349
+ SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
350
+ else
351
+ Bundler.ui.debug "Found no changes, using resolution from the lockfile"
352
+ if @removed_platforms.any? || @locked_gems.may_include_redundant_platform_specific_gems?
353
+ SpecSet.new(filter_specs(@locked_specs, @dependencies))
354
+ else
355
+ @locked_specs
356
+ end
357
+ end
358
+ else
359
+ Bundler.ui.debug resolve_needed_reason
360
+
361
+ start_resolution
362
+ end
363
+ end
364
+
365
+ def spec_git_paths
366
+ sources.git_sources.filter_map {|s| File.realpath(s.path) if File.exist?(s.path) }
367
+ end
368
+
369
+ def groups
370
+ dependencies.flat_map(&:groups).uniq
371
+ end
372
+
373
+ def lock(file_or_preserve_unknown_sections = false, preserve_unknown_sections_or_unused = false)
374
+ if [true, false, nil].include?(file_or_preserve_unknown_sections)
375
+ target_lockfile = lockfile
376
+ preserve_unknown_sections = file_or_preserve_unknown_sections
377
+ else
378
+ target_lockfile = file_or_preserve_unknown_sections
379
+ preserve_unknown_sections = preserve_unknown_sections_or_unused
380
+
381
+ suggestion = if target_lockfile == lockfile
382
+ "To fix this warning, remove it from the `Definition#lock` call."
383
+ else
384
+ "Instead, instantiate a new definition passing `#{target_lockfile}`, and call `lock` without a file argument on that definition"
385
+ end
386
+
387
+ msg = "`Definition#lock` was passed a target file argument. #{suggestion}"
388
+
389
+ Bundler::SharedHelpers.feature_removed! msg
390
+ end
391
+
392
+ write_lock(target_lockfile, preserve_unknown_sections)
393
+ end
394
+
395
+ def write_lock(file, preserve_unknown_sections)
396
+ return if Definition.no_lock || !lockfile || file.nil?
397
+
398
+ contents = to_lock
399
+
400
+ # Convert to \r\n if the existing lock has them
401
+ # i.e., Windows with `git config core.autocrlf=true`
402
+ contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
403
+
404
+ if @locked_bundler_version
405
+ locked_major = @locked_bundler_version.segments.first
406
+ current_major = bundler_version_to_lock.segments.first
407
+
408
+ updating_major = locked_major < current_major
409
+ end
410
+
411
+ preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
412
+
413
+ if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
414
+ return if Bundler.frozen_bundle?
415
+ SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
416
+ return
417
+ end
418
+
419
+ if Bundler.frozen_bundle?
420
+ Bundler.ui.error "Cannot write a changed lockfile while frozen."
421
+ return
422
+ end
423
+
424
+ begin
425
+ SharedHelpers.filesystem_access(file) do |p|
426
+ File.open(p, "wb") {|f| f.puts(contents) }
427
+ end
428
+ rescue ReadOnlyFileSystemError
429
+ raise ProductionError, lockfile_changes_summary("file system is read-only")
430
+ end
431
+ end
432
+
433
+ def locked_ruby_version
434
+ return unless ruby_version
435
+ if @unlocking_ruby || !@locked_ruby_version
436
+ Bundler::RubyVersion.system
437
+ else
438
+ @locked_ruby_version
439
+ end
440
+ end
441
+
442
+ def locked_ruby_version_object
443
+ return unless @locked_ruby_version
444
+ @locked_ruby_version_object ||= begin
445
+ unless version = RubyVersion.from_string(@locked_ruby_version)
446
+ raise LockfileError, "The Ruby version #{@locked_ruby_version} from " \
447
+ "#{@lockfile} could not be parsed. " \
448
+ "Try running bundle update --ruby to resolve this."
449
+ end
450
+ version
451
+ end
452
+ end
453
+
454
+ def bundler_version_to_lock
455
+ @resolved_bundler_version || Bundler.gem_version
456
+ end
457
+
458
+ def to_lock
459
+ require_relative "lockfile_generator"
460
+ LockfileGenerator.generate(self)
461
+ end
462
+
463
+ def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
464
+ return unless Bundler.frozen_bundle?
465
+
466
+ raise ProductionError, "Frozen mode is set, but there's no lockfile" unless lockfile_exists?
467
+
468
+ msg = lockfile_changes_summary("frozen mode is set")
469
+ return unless msg
470
+
471
+ unless explicit_flag
472
+ suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
473
+ "bundle config set frozen false"
474
+ end
475
+ msg << "\n\nIf this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} " \
476
+ "freeze by running `#{suggested_command}`." if suggested_command
477
+ end
478
+
479
+ raise ProductionError, msg
480
+ end
481
+
482
+ def validate_runtime!
483
+ validate_ruby!
484
+ validate_platforms!
485
+ end
486
+
487
+ def validate_ruby!
488
+ return unless ruby_version
489
+
490
+ if diff = ruby_version.diff(Bundler::RubyVersion.system)
491
+ problem, expected, actual = diff
492
+
493
+ msg = case problem
494
+ when :engine
495
+ "Your Ruby engine is #{actual}, but your Gemfile specified #{expected}"
496
+ when :version
497
+ "Your Ruby version is #{actual}, but your Gemfile specified #{expected}"
498
+ when :engine_version
499
+ "Your #{Bundler::RubyVersion.system.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}"
500
+ when :patchlevel
501
+ if !expected.is_a?(String)
502
+ "The Ruby patchlevel in your Gemfile must be a string"
503
+ else
504
+ "Your Ruby patchlevel is #{actual}, but your Gemfile specified #{expected}"
505
+ end
506
+ end
507
+
508
+ raise RubyVersionMismatch, msg
509
+ end
510
+ end
511
+
512
+ def validate_platforms!
513
+ return if current_platform_locked? || @platforms.include?(Gem::Platform::RUBY)
514
+
515
+ raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
516
+ "but your local platform is #{Bundler.local_platform}. " \
517
+ "Add the current platform to the lockfile with\n`bundle lock --add-platform #{Bundler.local_platform}` and try again."
518
+ end
519
+
520
+ def normalize_platforms
521
+ resolve.normalize_platforms!(current_dependencies, platforms)
522
+
523
+ @resolve = SpecSet.new(resolve.for(current_dependencies, @platforms))
524
+ end
525
+
526
+ def add_platform(platform)
527
+ return if @platforms.include?(platform)
528
+
529
+ @new_platforms << platform
530
+ @platforms << platform
531
+ end
532
+
533
+ def remove_platform(platform)
534
+ raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}" unless @platforms.include?(platform)
535
+
536
+ @removed_platforms << platform
537
+ @platforms.delete(platform)
538
+ end
539
+
540
+ def nothing_changed?
541
+ !something_changed?
542
+ end
543
+
544
+ def no_resolve_needed?
545
+ !resolve_needed?
546
+ end
547
+
548
+ def unlocking?
549
+ @unlocking
550
+ end
551
+
552
+ def add_checksums
553
+ require "rubygems/package"
554
+
555
+ @locked_checksums = true
556
+
557
+ setup_domain!(add_checksums: true)
558
+
559
+ # force materialization to real specifications, so that checksums are fetched
560
+ specs.each do |spec|
561
+ next unless spec.source.is_a?(Bundler::Source::Rubygems)
562
+ # Checksum was fetched from the compact index API.
563
+ next if !spec.source.checksum_store.missing?(spec) && !spec.source.checksum_store.empty?(spec)
564
+ # The gem isn't installed, can't compute the checksum.
565
+ next unless spec.loaded_from
566
+
567
+ package = Gem::Package.new(spec.source.cached_built_in_gem(spec))
568
+ checksum = Checksum.from_gem_package(package)
569
+ spec.source.checksum_store.register(spec, checksum)
570
+ end
571
+ end
572
+
573
+ private
574
+
575
+ def lockfile_changes_summary(update_refused_reason)
576
+ added = []
577
+ deleted = []
578
+ changed = []
579
+
580
+ added.concat @new_platforms.map {|p| "* platform: #{p}" }
581
+ deleted.concat @removed_platforms.map {|p| "* platform: #{p}" }
582
+
583
+ added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
584
+ deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
585
+
586
+ both_sources = Hash.new {|h, k| h[k] = [] }
587
+ current_dependencies.each {|d| both_sources[d.name][0] = d }
588
+ current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
589
+
590
+ both_sources.each do |name, (dep, lock_dep)|
591
+ next if dep.nil? || lock_dep.nil?
592
+
593
+ gemfile_source = dep.source || default_source
594
+ lock_source = lock_dep.source || default_source
595
+ next if lock_source.include?(gemfile_source)
596
+
597
+ gemfile_source_name = dep.source ? gemfile_source.to_gemfile : "no specified source"
598
+ lockfile_source_name = lock_dep.source ? lock_source.to_gemfile : "no specified source"
599
+ changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
600
+ end
601
+
602
+ return unless added.any? || deleted.any? || changed.any? || resolve_needed?
603
+
604
+ msg = String.new("#{change_reason[0].upcase}#{change_reason[1..-1].strip}, but ")
605
+ msg << "the lockfile " unless msg.start_with?("Your lockfile")
606
+ msg << "can't be updated because #{update_refused_reason}"
607
+ msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
608
+ msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
609
+ msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
610
+ msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_lockfile_path} to version control.\n" unless unlocking?
611
+ msg
612
+ end
613
+
614
+ def install_needed?
615
+ resolve_needed? || missing_specs?
616
+ end
617
+
618
+ def something_changed?
619
+ return true unless lockfile_exists?
620
+
621
+ @source_changes ||
622
+ @dependency_changes ||
623
+ @current_platform_missing ||
624
+ @new_platforms.any? ||
625
+ @path_changes ||
626
+ @local_changes ||
627
+ @missing_lockfile_dep ||
628
+ @unlocking_bundler ||
629
+ @locked_spec_with_missing_checksums ||
630
+ @locked_spec_with_empty_checksums ||
631
+ @locked_spec_with_missing_deps ||
632
+ @locked_spec_with_invalid_deps
633
+ end
634
+
635
+ def resolve_needed?
636
+ unlocking? || something_changed?
637
+ end
638
+
639
+ def should_add_extra_platforms?
640
+ !lockfile_exists? && Bundler::MatchPlatform.generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
641
+ end
642
+
643
+ def lockfile_exists?
644
+ lockfile && File.exist?(lockfile)
645
+ end
646
+
647
+ def resolver
648
+ @resolver ||= new_resolver(resolution_base)
649
+ end
650
+
651
+ def expanded_dependencies
652
+ dependencies_with_bundler + metadata_dependencies
653
+ end
654
+
655
+ def dependencies_with_bundler
656
+ return dependencies unless @unlocking_bundler
657
+ return dependencies if dependencies.any? {|d| d.name == "bundler" }
658
+
659
+ [Dependency.new("bundler", @unlocking_bundler)] + dependencies
660
+ end
661
+
662
+ def resolution_base
663
+ @resolution_base ||= begin
664
+ last_resolve = converge_locked_specs
665
+ remove_invalid_platforms!
666
+ base = new_resolution_base(last_resolve: last_resolve, unlock: @unlocking_all || @gems_to_unlock)
667
+ base = additional_base_requirements_to_prevent_downgrades(base)
668
+ base = additional_base_requirements_to_force_updates(base)
669
+ base
670
+ end
671
+ end
672
+
673
+ def filter_specs(specs, deps, skips: [])
674
+ SpecSet.new(specs).for(deps, platforms, skips: skips)
675
+ end
676
+
677
+ def materialize(dependencies)
678
+ specs = begin
679
+ resolve.materialize(dependencies)
680
+ rescue IncorrectLockfileDependencies => e
681
+ raise if Bundler.frozen_bundle?
682
+
683
+ reresolve_without([e.spec])
684
+ retry
685
+ end
686
+
687
+ missing_specs = resolve.missing_specs
688
+
689
+ if missing_specs.any?
690
+ missing_specs.each do |s|
691
+ locked_gem = @locked_specs[s.name].last
692
+ next if locked_gem.nil? || locked_gem.version != s.version || sources.local_mode?
693
+
694
+ message = if sources.implicit_global_source?
695
+ "Because your Gemfile specifies no global remote source, your bundle is locked to " \
696
+ "#{locked_gem} from #{locked_gem.source}. However, #{locked_gem} is not installed. You'll " \
697
+ "need to either add a global remote source to your Gemfile or make sure #{locked_gem} is " \
698
+ "available locally before rerunning Bundler."
699
+ else
700
+ "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
701
+ "no longer be found in that source. That means either the author of #{locked_gem} has removed it, " \
702
+ "or you no longer have access to that source. You'll need to update your bundle to a version other " \
703
+ "than #{locked_gem} that hasn't been removed, or check your credentials and access rights for " \
704
+ "#{locked_gem.source}, in order to install."
705
+ end
706
+
707
+ raise GemNotFound, message
708
+ end
709
+
710
+ missing_specs_list = missing_specs.group_by(&:source).map do |source, missing_specs_for_source|
711
+ "#{missing_specs_for_source.map(&:full_name).join(", ")} in #{source}"
712
+ end
713
+
714
+ raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
715
+ end
716
+
717
+ partially_missing_specs = resolve.partially_missing_specs
718
+
719
+ if partially_missing_specs.any? && !sources.local_mode?
720
+ Bundler.ui.warn "Some locked specs have possibly been yanked (#{partially_missing_specs.map(&:full_name).join(", ")}). Ignoring them..."
721
+
722
+ resolve.delete(partially_missing_specs)
723
+ end
724
+
725
+ incomplete_specs = resolve.incomplete_specs
726
+ loop do
727
+ break if incomplete_specs.empty?
728
+
729
+ Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
730
+ sources.remote!
731
+ reresolve_without(incomplete_specs)
732
+ specs = resolve.materialize(dependencies)
733
+
734
+ still_incomplete_specs = resolve.incomplete_specs
735
+
736
+ if still_incomplete_specs == incomplete_specs
737
+ resolver.raise_incomplete! incomplete_specs
738
+ end
739
+
740
+ incomplete_specs = still_incomplete_specs
741
+ end
742
+
743
+ insecurely_materialized_specs = resolve.insecurely_materialized_specs
744
+
745
+ if insecurely_materialized_specs.any?
746
+ Bundler.ui.warn "The following platform specific gems are getting installed, yet the lockfile includes only their generic ruby version:\n" \
747
+ " * #{insecurely_materialized_specs.map(&:full_name).join("\n * ")}\n" \
748
+ "Please run `bundle lock --normalize-platforms` and commit the resulting lockfile.\n" \
749
+ "Alternatively, you may run `bundle lock --add-platform <list-of-platforms-that-you-want-to-support>`"
750
+ end
751
+
752
+ bundler = sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
753
+ specs["bundler"] = bundler
754
+
755
+ specs
756
+ end
757
+
758
+ def reresolve_without(incomplete_specs)
759
+ resolution_base.delete(incomplete_specs)
760
+ @resolve = start_resolution
761
+ end
762
+
763
+ def start_resolution
764
+ local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && !@platforms.include?(Bundler.local_platform)
765
+ @platforms << Bundler.local_platform if local_platform_needed_for_resolvability
766
+
767
+ result = SpecSet.new(resolver.start)
768
+
769
+ @resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
770
+
771
+ @new_platforms.each do |platform|
772
+ incomplete_specs = result.incomplete_specs_for_platform(current_dependencies, platform)
773
+
774
+ if incomplete_specs.any?
775
+ resolver.raise_incomplete! incomplete_specs
776
+ end
777
+ end
778
+
779
+ if @most_specific_non_local_locked_platform
780
+ if result.incomplete_for_platform?(current_dependencies, @most_specific_non_local_locked_platform)
781
+ @platforms.delete(@most_specific_non_local_locked_platform)
782
+ elsif local_platform_needed_for_resolvability
783
+ @platforms.delete(Bundler.local_platform)
784
+ end
785
+ end
786
+
787
+ if should_add_extra_platforms?
788
+ result.add_extra_platforms!(platforms)
789
+ elsif @originally_invalid_platforms.any?
790
+ result.add_originally_invalid_platforms!(platforms, @originally_invalid_platforms)
791
+ end
792
+
793
+ SpecSet.new(result.for(dependencies, @platforms | [Gem::Platform::RUBY]))
794
+ end
795
+
796
+ def precompute_source_requirements_for_indirect_dependencies?
797
+ if sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
798
+ true
799
+ else
800
+ non_dependency_api_warning
801
+ false
802
+ end
803
+ end
804
+
805
+ def non_dependency_api_warning
806
+ non_api_sources = sources.non_global_rubygems_sources.reject(&:dependency_api_available?)
807
+ non_api_source_names = non_api_sources.map {|d| " * #{d}" }.join("\n")
808
+
809
+ msg = String.new
810
+ msg << "Your Gemfile contains scoped sources that don't implement a dependency API, namely:\n\n"
811
+ msg << non_api_source_names
812
+ msg << "\n\nUsing the above gem servers may result in installing unexpected gems. " \
813
+ "To resolve this warning, make sure you use gem servers that implement dependency APIs, " \
814
+ "such as gemstash or geminabox gem servers."
815
+ Bundler.ui.warn msg
816
+ end
817
+
818
+ def current_platform_locked?
819
+ @platforms.any? do |bundle_platform|
820
+ Bundler.generic_local_platform == bundle_platform || Bundler.local_platform === bundle_platform
821
+ end
822
+ end
823
+
824
+ def add_current_platform
825
+ return if @platforms.include?(Bundler.local_platform)
826
+
827
+ @most_specific_non_local_locked_platform = find_most_specific_locked_platform
828
+ return if @most_specific_non_local_locked_platform
829
+
830
+ @platforms << Bundler.local_platform
831
+ true
832
+ end
833
+
834
+ def find_most_specific_locked_platform
835
+ return unless current_platform_locked?
836
+
837
+ @most_specific_locked_platform
838
+ end
839
+
840
+ def resolve_needed_reason
841
+ if lockfile_exists?
842
+ if unlocking?
843
+ "Re-resolving dependencies because #{unlocking_reason}"
844
+ else
845
+ "Found changes from the lockfile, re-resolving dependencies because #{lockfile_changed_reason}"
846
+ end
847
+ else
848
+ "Resolving dependencies because there's no lockfile"
849
+ end
850
+ end
851
+
852
+ def change_reason
853
+ if resolve_needed?
854
+ if unlocking?
855
+ unlocking_reason
856
+ else
857
+ lockfile_changed_reason
858
+ end
859
+ else
860
+ "some dependencies were deleted from your gemfile"
861
+ end
862
+ end
863
+
864
+ def unlocking_reason
865
+ unlock_targets = if @gems_to_unlock.any?
866
+ ["gems", @gems_to_unlock]
867
+ elsif @sources_to_unlock.any?
868
+ ["sources", @sources_to_unlock]
869
+ end
870
+
871
+ unlock_reason = if unlock_targets
872
+ "#{unlock_targets.first}: (#{unlock_targets.last.join(", ")})"
873
+ else
874
+ @unlocking_ruby ? "ruby" : ""
875
+ end
876
+
877
+ "bundler is unlocking #{unlock_reason}"
878
+ end
879
+
880
+ def lockfile_changed_reason
881
+ [
882
+ [@source_changes, "the list of sources changed"],
883
+ [@dependency_changes, "the dependencies in your gemfile changed"],
884
+ [@current_platform_missing, "your lockfile is missing the current platform"],
885
+ [@new_platforms.any?, "you are adding a new platform to your lockfile"],
886
+ [@path_changes, "the gemspecs for path gems changed"],
887
+ [@local_changes, "the gemspecs for git local gems changed"],
888
+ [@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
889
+ [@unlocking_bundler, "an update to the version of Bundler itself was requested"],
890
+ [@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
891
+ [@locked_spec_with_empty_checksums, "your lockfile has an empty CHECKSUMS entry for \"#{@locked_spec_with_empty_checksums}\""],
892
+ [@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
893
+ [@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
894
+ ].select(&:first).map(&:last).join(", ")
895
+ end
896
+
897
+ def pretty_dep(dep)
898
+ SharedHelpers.pretty_dependency(dep)
899
+ end
900
+
901
+ # Check if the specs of the given source changed
902
+ # according to the locked source.
903
+ def specs_changed?(source)
904
+ locked = @locked_sources.find {|s| s == source }
905
+
906
+ !locked || dependencies_for_source_changed?(source, locked) || specs_for_source_changed?(source)
907
+ end
908
+
909
+ def dependencies_for_source_changed?(source, locked_source)
910
+ deps_for_source = @dependencies.select {|dep| dep.source == source }
911
+ locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
912
+
913
+ deps_for_source.uniq.sort != locked_deps_for_source.sort
914
+ end
915
+
916
+ def specs_for_source_changed?(source)
917
+ locked_index = Index.new
918
+ locked_index.use(@locked_specs.select {|s| s.replace_source_with!(source) })
919
+
920
+ !locked_index.subset?(source.specs)
921
+ rescue PathError, GitError => e
922
+ Bundler.ui.debug "Assuming that #{source} has not changed since fetching its specs errored (#{e})"
923
+ false
924
+ end
925
+
926
+ # Get all locals and override their matching sources.
927
+ # Return true if any of the locals changed (for example,
928
+ # they point to a new revision) or depend on new specs.
929
+ def converge_locals
930
+ locals = []
931
+
932
+ Bundler.settings.local_overrides.map do |k, v|
933
+ spec = @dependencies.find {|s| s.name == k }
934
+ source = spec&.source
935
+ if source&.respond_to?(:local_override!)
936
+ source.unlock! if @gems_to_unlock.include?(spec.name)
937
+ locals << [source, source.local_override!(v)]
938
+ end
939
+ end
940
+
941
+ sources_with_changes = locals.select do |source, changed|
942
+ changed || specs_changed?(source)
943
+ end.map(&:first)
944
+ !sources_with_changes.each {|source| @sources_to_unlock << source.name }.empty?
945
+ end
946
+
947
+ def check_lockfile
948
+ @locked_spec_with_invalid_deps = nil
949
+ @locked_spec_with_missing_deps = nil
950
+ @locked_spec_with_missing_checksums = nil
951
+ @locked_spec_with_empty_checksums = nil
952
+
953
+ missing_deps = []
954
+ missing_checksums = []
955
+ empty_checksums = []
956
+ invalid = []
957
+
958
+ @locked_specs.each do |s|
959
+ if @locked_checksums
960
+ checksum_store = s.source.checksum_store
961
+
962
+ if checksum_store.missing?(s)
963
+ missing_checksums << s
964
+ elsif checksum_store.empty?(s)
965
+ empty_checksums << s
966
+ end
967
+ end
968
+
969
+ validation = @locked_specs.validate_deps(s)
970
+
971
+ missing_deps << s if validation == :missing
972
+ invalid << s if validation == :invalid
973
+ end
974
+
975
+ @locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
976
+ @locked_spec_with_empty_checksums = empty_checksums.first.name if empty_checksums.any?
977
+
978
+ if missing_deps.any?
979
+ @locked_specs.delete(missing_deps)
980
+
981
+ @locked_spec_with_missing_deps = missing_deps.first.name
982
+ end
983
+
984
+ if invalid.any?
985
+ @locked_specs.delete(invalid)
986
+
987
+ @locked_spec_with_invalid_deps = invalid.first.name
988
+ end
989
+ end
990
+
991
+ def converge_paths
992
+ sources.path_sources.any? do |source|
993
+ specs_changed?(source)
994
+ end
995
+ end
996
+
997
+ def converge_sources
998
+ # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
999
+ # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
1000
+ # source in the Gemfile.lock, use the one from the Gemfile.
1001
+ changes = sources.replace_sources!(@locked_sources)
1002
+
1003
+ sources.all_sources.each do |source|
1004
+ # has to be done separately, because we want to keep the locked checksum
1005
+ # store for a source, even when doing a full update
1006
+ if @locked_checksums && @locked_gems && locked_source = @originally_locked_sources.find {|s| s == source && !s.equal?(source) }
1007
+ source.checksum_store.merge!(locked_source.checksum_store)
1008
+ end
1009
+ # If the source is unlockable and the current command allows an unlock of
1010
+ # the source (for example, you are doing a `bundle update <foo>` of a git-pinned
1011
+ # gem), unlock it. For git sources, this means to unlock the revision, which
1012
+ # will cause the `ref` used to be the most recent for the branch (or master) if
1013
+ # an explicit `ref` is not used.
1014
+ if source.respond_to?(:unlock!) && @sources_to_unlock.include?(source.name)
1015
+ source.unlock!
1016
+ changes = true
1017
+ end
1018
+ end
1019
+
1020
+ sources.metadata_source.checksum_store.merge!(@locked_gems.metadata_source.checksum_store) if @locked_gems
1021
+
1022
+ changes
1023
+ end
1024
+
1025
+ def converge_dependencies
1026
+ @missing_lockfile_dep = nil
1027
+ @changed_dependencies = []
1028
+
1029
+ @dependencies.each do |dep|
1030
+ if dep.source
1031
+ dep.source = sources.get(dep.source)
1032
+ end
1033
+ next unless relevant_deps?(dep)
1034
+
1035
+ name = dep.name
1036
+
1037
+ dep_changed = @locked_deps[name].nil?
1038
+
1039
+ unless name == "bundler"
1040
+ locked_specs = @originally_locked_specs[name]
1041
+
1042
+ if locked_specs.empty?
1043
+ @missing_lockfile_dep = name if dep_changed == false
1044
+ else
1045
+ if locked_specs.map(&:source).uniq.size > 1
1046
+ @locked_specs.delete(locked_specs.select {|s| s.source != dep.source })
1047
+ end
1048
+
1049
+ unless dep.matches_spec?(locked_specs.first)
1050
+ @gems_to_unlock << name
1051
+ dep_changed = true
1052
+ end
1053
+ end
1054
+ end
1055
+
1056
+ @changed_dependencies << name if dep_changed
1057
+ end
1058
+
1059
+ @changed_dependencies.any?
1060
+ end
1061
+
1062
+ # Remove elements from the locked specs that are expired. This will most
1063
+ # commonly happen if the Gemfile has changed since the lockfile was last
1064
+ # generated
1065
+ def converge_locked_specs
1066
+ converged = converge_specs(@locked_specs)
1067
+
1068
+ resolve = SpecSet.new(converged)
1069
+
1070
+ diff = nil
1071
+
1072
+ # Now, we unlock any sources that do not have anymore gems pinned to it
1073
+ sources.all_sources.each do |source|
1074
+ next unless source.respond_to?(:unlock!)
1075
+
1076
+ unless resolve.any? {|s| s.source == source }
1077
+ diff ||= @locked_specs.to_a - resolve.to_a
1078
+ source.unlock! if diff.any? {|s| s.source == source }
1079
+ end
1080
+ end
1081
+
1082
+ resolve
1083
+ end
1084
+
1085
+ def converge_specs(specs)
1086
+ converged = []
1087
+ deps = []
1088
+
1089
+ specs.each do |s|
1090
+ name = s.name
1091
+ next if @gems_to_unlock.include?(name)
1092
+
1093
+ dep = @dependencies.find {|d| s.satisfies?(d) }
1094
+ lockfile_source = s.source
1095
+
1096
+ if dep
1097
+ replacement_source = dep.source
1098
+
1099
+ deps << dep if !replacement_source || lockfile_source.include?(replacement_source) || new_deps.include?(dep)
1100
+ else
1101
+ parent_dep = @dependencies.find do |d|
1102
+ next unless d.source && d.source != lockfile_source
1103
+ next if d.source.is_a?(Source::Gemspec)
1104
+
1105
+ parent_locked_specs = @originally_locked_specs[d.name]
1106
+
1107
+ parent_locked_specs.any? do |parent_spec|
1108
+ parent_spec.runtime_dependencies.any? {|rd| rd.name == s.name }
1109
+ end
1110
+ end
1111
+
1112
+ if parent_dep && parent_dep.source.is_a?(Source::Path) && parent_dep.source.specs[s]&.any?
1113
+ replacement_source = parent_dep.source
1114
+ else
1115
+ replacement_source = sources.get(lockfile_source)
1116
+ end
1117
+ end
1118
+
1119
+ # Replace the locked dependency's source with the equivalent source from the Gemfile
1120
+ s.source = replacement_source || default_source
1121
+ next if s.source_changed?
1122
+
1123
+ source = s.source
1124
+ next if @sources_to_unlock.include?(source.name)
1125
+
1126
+ # Path sources have special logic
1127
+ if source.is_a?(Source::Path)
1128
+ new_spec = source.specs[s].first
1129
+ if new_spec
1130
+ s.runtime_dependencies.replace(new_spec.runtime_dependencies)
1131
+ else
1132
+ # If the spec is no longer in the path source, unlock it. This
1133
+ # commonly happens if the version changed in the gemspec
1134
+ @gems_to_unlock << name
1135
+ end
1136
+ end
1137
+
1138
+ converged << s
1139
+ end
1140
+
1141
+ filter_specs(converged, deps, skips: @gems_to_unlock)
1142
+ end
1143
+
1144
+ def metadata_dependencies
1145
+ @metadata_dependencies ||= [
1146
+ Dependency.new("Ruby\0", Bundler::RubyVersion.system.gem_version),
1147
+ Dependency.new("RubyGems\0", Gem::VERSION),
1148
+ ]
1149
+ end
1150
+
1151
+ def source_requirements
1152
+ @source_requirements ||= find_source_requirements
1153
+ end
1154
+
1155
+ def preload_git_source_worker
1156
+ workers = Bundler.settings.installation_parallelization
1157
+
1158
+ @preload_git_source_worker ||= Bundler::Worker.new(workers, "Git source preloading", ->(source, _) { source.specs })
1159
+ end
1160
+
1161
+ def preload_git_sources
1162
+ if Gem.ruby_version < Gem::Version.new("3.3")
1163
+ # Ruby 3.2 has a bug that incorrectly triggers a circular dependency warning. This version will continue to
1164
+ # fetch git repositories one by one.
1165
+ return
1166
+ end
1167
+
1168
+ begin
1169
+ needed_git_sources.each {|source| preload_git_source_worker.enq(source) }
1170
+ ensure
1171
+ preload_git_source_worker.stop
1172
+ end
1173
+ end
1174
+
1175
+ # Git sources needed for the requested groups (excludes sources only used by --without groups)
1176
+ def needed_git_sources
1177
+ needed_deps = dependencies_for(requested_groups)
1178
+ sources.git_sources.select do |source|
1179
+ needed_deps.any? {|d| d.source == source }
1180
+ end
1181
+ end
1182
+
1183
+ # Git sources that should be excluded (only used by --without groups)
1184
+ def excluded_git_sources
1185
+ sources.git_sources - needed_git_sources
1186
+ end
1187
+
1188
+ def find_source_requirements
1189
+ preload_git_sources
1190
+
1191
+ # Only safe to exclude when locked_requirements (merged below) backfills the gap.
1192
+ nothing_changed = nothing_changed?
1193
+ excluded = nothing_changed ? excluded_git_sources : []
1194
+
1195
+ # Record the specs available in each gem's source, so that those
1196
+ # specs will be available later when the resolver knows where to
1197
+ # look for that gemspec (or its dependencies)
1198
+ source_requirements = if precompute_source_requirements_for_indirect_dependencies?
1199
+ all_requirements = source_map.all_requirements(excluded)
1200
+ { default: default_source }.merge(all_requirements)
1201
+ else
1202
+ { default: Source::RubygemsAggregate.new(sources, source_map, excluded) }.merge(source_map.direct_requirements)
1203
+ end
1204
+ source_requirements.merge!(source_map.locked_requirements) if nothing_changed
1205
+ metadata_dependencies.each do |dep|
1206
+ source_requirements[dep.name] = sources.metadata_source
1207
+ end
1208
+
1209
+ default_bundler_source = source_requirements["bundler"] || default_source
1210
+
1211
+ if @unlocking_bundler
1212
+ default_bundler_source.add_dependency_names("bundler")
1213
+ else
1214
+ source_requirements[:default_bundler] = default_bundler_source
1215
+ source_requirements["bundler"] = sources.metadata_source # needs to come last to override
1216
+ end
1217
+
1218
+ source_requirements
1219
+ end
1220
+
1221
+ def default_source
1222
+ sources.default_source
1223
+ end
1224
+
1225
+ def requested_groups
1226
+ values = groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
1227
+ values &= Bundler.settings[:only] unless Bundler.settings[:only].empty?
1228
+ values
1229
+ end
1230
+
1231
+ def lockfiles_equal?(current, proposed, preserve_unknown_sections)
1232
+ if preserve_unknown_sections
1233
+ sections_to_ignore = LockfileParser.sections_to_ignore(@locked_bundler_version)
1234
+ sections_to_ignore += LockfileParser.unknown_sections_in_lockfile(current)
1235
+ sections_to_ignore << LockfileParser::RUBY
1236
+ sections_to_ignore << LockfileParser::BUNDLED unless @unlocking_bundler
1237
+ pattern = /#{Regexp.union(sections_to_ignore)}\n(\s{2,}.*\n)+/
1238
+ whitespace_cleanup = /\n{2,}/
1239
+ current = current.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip
1240
+ proposed = proposed.gsub(pattern, "\n").gsub(whitespace_cleanup, "\n\n").strip
1241
+ end
1242
+ current == proposed
1243
+ end
1244
+
1245
+ def additional_base_requirements_to_prevent_downgrades(resolution_base)
1246
+ return resolution_base unless @locked_gems
1247
+ @originally_locked_specs.each do |locked_spec|
1248
+ next if locked_spec.source.is_a?(Source::Path) || locked_spec.source_changed?
1249
+
1250
+ name = locked_spec.name
1251
+ next if @changed_dependencies.include?(name)
1252
+
1253
+ resolution_base.base_requirements[name] = Gem::Requirement.new(">= #{locked_spec.version}")
1254
+ end
1255
+ resolution_base
1256
+ end
1257
+
1258
+ def additional_base_requirements_to_force_updates(resolution_base)
1259
+ return resolution_base if @explicit_unlocks.empty?
1260
+ full_update = SpecSet.new(new_resolver_for_full_update.start)
1261
+ @explicit_unlocks.each do |name|
1262
+ version = full_update.version_for(name)
1263
+ resolution_base.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
1264
+ end
1265
+ resolution_base
1266
+ end
1267
+
1268
+ def remove_invalid_platforms!
1269
+ return if Bundler.frozen_bundle?
1270
+
1271
+ skips = (@new_platforms + [Bundler.local_platform]).uniq
1272
+
1273
+ # We should probably avoid removing non-ruby platforms, since that means
1274
+ # lockfile will no longer install on those platforms, so a error to give
1275
+ # heads up to the user may be better. However, we have tests expecting
1276
+ # non ruby platform autoremoval to work, so leaving that in place for
1277
+ # now.
1278
+ skips |= platforms - [Gem::Platform::RUBY] if @dependency_changes
1279
+
1280
+ @originally_invalid_platforms = @originally_locked_specs.remove_invalid_platforms!(current_dependencies, platforms, skips: skips)
1281
+ end
1282
+
1283
+ def source_map
1284
+ @source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
1285
+ end
1286
+
1287
+ def new_resolver_for_full_update
1288
+ new_resolver(unlocked_resolution_base)
1289
+ end
1290
+
1291
+ def unlocked_resolution_base
1292
+ new_resolution_base(last_resolve: SpecSet.new([]), unlock: true)
1293
+ end
1294
+
1295
+ def new_resolution_base(last_resolve:, unlock:)
1296
+ new_resolution_platforms = @current_platform_missing ? @new_platforms + [Bundler.local_platform] : @new_platforms
1297
+ Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms, explicit_unlocks: @explicit_unlocks)
1298
+ end
1299
+
1300
+ def new_resolver(base)
1301
+ Resolver.new(base, gem_version_promoter, @most_specific_locked_platform)
1302
+ end
1303
+ end
1304
+ end