bundler 1.9.0 → 1.17.3

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

Potentially problematic release.


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

Files changed (328) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1157 -6
  3. data/README.md +33 -6
  4. data/bundler.gemspec +51 -18
  5. data/exe/bundle +31 -0
  6. data/{bin → exe}/bundle_ruby +10 -6
  7. data/exe/bundler +4 -0
  8. data/lib/bundler.rb +326 -207
  9. data/lib/bundler/build_metadata.rb +53 -0
  10. data/lib/bundler/capistrano.rb +9 -3
  11. data/lib/bundler/cli.rb +522 -141
  12. data/lib/bundler/cli/add.rb +35 -0
  13. data/lib/bundler/cli/binstubs.rb +22 -11
  14. data/lib/bundler/cli/cache.rb +7 -6
  15. data/lib/bundler/cli/check.rb +11 -8
  16. data/lib/bundler/cli/clean.rb +7 -8
  17. data/lib/bundler/cli/common.rb +53 -7
  18. data/lib/bundler/cli/config.rb +84 -49
  19. data/lib/bundler/cli/console.rb +13 -8
  20. data/lib/bundler/cli/doctor.rb +140 -0
  21. data/lib/bundler/cli/exec.rb +77 -16
  22. data/lib/bundler/cli/gem.rb +120 -52
  23. data/lib/bundler/cli/info.rb +50 -0
  24. data/lib/bundler/cli/init.rb +21 -7
  25. data/lib/bundler/cli/inject.rb +37 -10
  26. data/lib/bundler/cli/install.rb +139 -78
  27. data/lib/bundler/cli/issue.rb +40 -0
  28. data/lib/bundler/cli/list.rb +58 -0
  29. data/lib/bundler/cli/lock.rb +63 -0
  30. data/lib/bundler/cli/open.rb +9 -6
  31. data/lib/bundler/cli/outdated.rb +221 -35
  32. data/lib/bundler/cli/package.rb +11 -7
  33. data/lib/bundler/cli/platform.rb +7 -4
  34. data/lib/bundler/cli/plugin.rb +24 -0
  35. data/lib/bundler/cli/pristine.rb +47 -0
  36. data/lib/bundler/cli/remove.rb +18 -0
  37. data/lib/bundler/cli/show.rb +11 -10
  38. data/lib/bundler/cli/update.rb +47 -29
  39. data/lib/bundler/cli/viz.rb +12 -8
  40. data/lib/bundler/compact_index_client.rb +109 -0
  41. data/lib/bundler/compact_index_client/cache.rb +118 -0
  42. data/lib/bundler/compact_index_client/updater.rb +116 -0
  43. data/lib/bundler/compatibility_guard.rb +14 -0
  44. data/lib/bundler/constants.rb +3 -1
  45. data/lib/bundler/current_ruby.rb +47 -137
  46. data/lib/bundler/definition.rb +599 -230
  47. data/lib/bundler/dep_proxy.rb +15 -10
  48. data/lib/bundler/dependency.rb +54 -25
  49. data/lib/bundler/deployment.rb +12 -2
  50. data/lib/bundler/deprecate.rb +33 -4
  51. data/lib/bundler/dsl.rb +383 -99
  52. data/lib/bundler/endpoint_specification.rb +72 -7
  53. data/lib/bundler/env.rb +121 -41
  54. data/lib/bundler/environment_preserver.rb +59 -0
  55. data/lib/bundler/errors.rb +158 -0
  56. data/lib/bundler/feature_flag.rb +74 -0
  57. data/lib/bundler/fetcher.rb +171 -280
  58. data/lib/bundler/fetcher/base.rb +52 -0
  59. data/lib/bundler/fetcher/compact_index.rb +126 -0
  60. data/lib/bundler/fetcher/dependency.rb +82 -0
  61. data/lib/bundler/fetcher/downloader.rb +84 -0
  62. data/lib/bundler/fetcher/index.rb +52 -0
  63. data/lib/bundler/friendly_errors.rb +113 -58
  64. data/lib/bundler/gem_helper.rb +73 -46
  65. data/lib/bundler/gem_helpers.rb +85 -9
  66. data/lib/bundler/gem_remote_fetcher.rb +43 -0
  67. data/lib/bundler/gem_tasks.rb +6 -1
  68. data/lib/bundler/gem_version_promoter.rb +190 -0
  69. data/lib/bundler/gemdeps.rb +29 -0
  70. data/lib/bundler/graph.rb +32 -49
  71. data/lib/bundler/index.rb +79 -67
  72. data/lib/bundler/injector.rb +219 -30
  73. data/lib/bundler/inline.rb +74 -0
  74. data/lib/bundler/installer.rb +191 -206
  75. data/lib/bundler/installer/gem_installer.rb +85 -0
  76. data/lib/bundler/installer/parallel_installer.rb +233 -0
  77. data/lib/bundler/installer/standalone.rb +53 -0
  78. data/lib/bundler/lazy_specification.rb +53 -13
  79. data/lib/bundler/lockfile_generator.rb +95 -0
  80. data/lib/bundler/lockfile_parser.rb +157 -62
  81. data/lib/bundler/match_platform.rb +15 -4
  82. data/lib/bundler/mirror.rb +223 -0
  83. data/lib/bundler/plugin.rb +292 -0
  84. data/lib/bundler/plugin/api.rb +81 -0
  85. data/lib/bundler/plugin/api/source.rb +306 -0
  86. data/lib/bundler/plugin/dsl.rb +53 -0
  87. data/lib/bundler/plugin/events.rb +61 -0
  88. data/lib/bundler/plugin/index.rb +162 -0
  89. data/lib/bundler/plugin/installer.rb +96 -0
  90. data/lib/bundler/plugin/installer/git.rb +38 -0
  91. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  92. data/lib/bundler/plugin/source_list.rb +27 -0
  93. data/lib/bundler/process_lock.rb +24 -0
  94. data/lib/bundler/psyched_yaml.rb +17 -6
  95. data/lib/bundler/remote_specification.rb +68 -11
  96. data/lib/bundler/resolver.rb +263 -229
  97. data/lib/bundler/resolver/spec_group.rb +106 -0
  98. data/lib/bundler/retry.rb +25 -19
  99. data/lib/bundler/ruby_dsl.rb +9 -2
  100. data/lib/bundler/ruby_version.rb +101 -66
  101. data/lib/bundler/rubygems_ext.rb +77 -37
  102. data/lib/bundler/rubygems_gem_installer.rb +106 -0
  103. data/lib/bundler/rubygems_integration.rb +450 -163
  104. data/lib/bundler/runtime.rb +133 -103
  105. data/lib/bundler/settings.rb +344 -83
  106. data/lib/bundler/settings/validator.rb +102 -0
  107. data/lib/bundler/setup.rb +7 -3
  108. data/lib/bundler/shared_helpers.rb +284 -54
  109. data/lib/bundler/similarity_detector.rb +21 -21
  110. data/lib/bundler/source.rb +68 -15
  111. data/lib/bundler/source/gemspec.rb +18 -0
  112. data/lib/bundler/source/git.rb +90 -55
  113. data/lib/bundler/source/git/git_proxy.rb +135 -35
  114. data/lib/bundler/source/metadata.rb +62 -0
  115. data/lib/bundler/source/path.rb +84 -61
  116. data/lib/bundler/source/path/installer.rb +53 -17
  117. data/lib/bundler/source/rubygems.rb +282 -122
  118. data/lib/bundler/source/rubygems/remote.rb +69 -0
  119. data/lib/bundler/source_list.rb +107 -22
  120. data/lib/bundler/spec_set.rb +83 -45
  121. data/lib/bundler/ssl_certs/certificate_manager.rb +8 -7
  122. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  123. data/lib/bundler/ssl_certs/{DigiCertHighAssuranceEVRootCA.pem → rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem} +0 -0
  124. data/lib/bundler/ssl_certs/{AddTrustExternalCARoot-2048.pem → rubygems.org/AddTrustExternalCARoot.pem} +0 -0
  125. data/lib/bundler/stub_specification.rb +108 -0
  126. data/lib/bundler/templates/.document +1 -0
  127. data/lib/bundler/templates/Executable +19 -6
  128. data/lib/bundler/templates/Executable.bundler +105 -0
  129. data/lib/bundler/templates/Executable.standalone +6 -4
  130. data/lib/bundler/templates/Gemfile +4 -1
  131. data/lib/bundler/templates/gems.rb +8 -0
  132. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +68 -7
  133. data/lib/bundler/templates/newgem/Gemfile.tt +4 -2
  134. data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
  135. data/lib/bundler/templates/newgem/README.md.tt +19 -11
  136. data/lib/bundler/templates/newgem/Rakefile.tt +10 -6
  137. data/lib/bundler/templates/newgem/bin/console.tt +1 -1
  138. data/lib/bundler/templates/newgem/bin/setup.tt +2 -1
  139. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
  140. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
  141. data/lib/bundler/templates/newgem/gitignore.tt +5 -1
  142. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +7 -6
  143. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +4 -4
  144. data/lib/bundler/templates/newgem/newgem.gemspec.tt +31 -15
  145. data/lib/bundler/templates/newgem/rspec.tt +1 -0
  146. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +3 -5
  147. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -2
  148. data/lib/bundler/templates/newgem/test/{test_newgem.rb.tt → newgem_test.rb.tt} +2 -2
  149. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +4 -0
  150. data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
  151. data/lib/bundler/ui.rb +5 -3
  152. data/lib/bundler/ui/rg_proxy.rb +5 -7
  153. data/lib/bundler/ui/shell.rb +69 -18
  154. data/lib/bundler/ui/silent.rb +26 -1
  155. data/lib/bundler/uri_credentials_filter.rb +37 -0
  156. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
  157. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
  158. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
  159. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  160. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
  161. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
  162. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
  163. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
  164. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
  165. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  166. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
  167. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
  169. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
  173. data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/modules/specification_provider.rb +11 -0
  174. data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/modules/ui.rb +6 -2
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
  176. data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/resolver.rb +6 -3
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
  178. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/faster.rb +1 -0
  179. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +27 -24
  180. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent/ssl_reuse.rb +2 -1
  181. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor.rb +47 -22
  182. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions.rb +31 -29
  183. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/create_file.rb +3 -2
  184. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/create_link.rb +3 -2
  185. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/directory.rb +3 -3
  186. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/empty_directory.rb +16 -8
  187. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/file_manipulation.rb +66 -18
  188. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/inject_into_file.rb +18 -16
  189. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/base.rb +67 -44
  190. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/command.rb +13 -11
  191. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/core_ext/hash_with_indifferent_access.rb +21 -1
  192. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
  193. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
  194. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/error.rb +3 -3
  195. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/group.rb +14 -14
  196. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/invocation.rb +4 -5
  197. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor.rb +2 -2
  198. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor/basic.rb +2 -0
  199. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor/readline.rb +0 -0
  200. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  201. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/argument.rb +4 -7
  202. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/arguments.rb +16 -16
  203. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/option.rb +42 -21
  204. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/options.rb +13 -10
  205. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/rake_compat.rb +1 -1
  206. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/runner.rb +35 -33
  207. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell.rb +4 -4
  208. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/basic.rb +49 -33
  209. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/color.rb +2 -2
  210. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/html.rb +5 -5
  211. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/util.rb +8 -7
  212. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/version.rb +1 -1
  213. data/lib/bundler/vendored_fileutils.rb +9 -0
  214. data/lib/bundler/vendored_molinillo.rb +4 -5
  215. data/lib/bundler/vendored_persistent.rb +45 -4
  216. data/lib/bundler/vendored_thor.rb +8 -5
  217. data/lib/bundler/version.rb +23 -1
  218. data/lib/bundler/version_ranges.rb +76 -0
  219. data/lib/bundler/vlad.rb +8 -2
  220. data/lib/bundler/worker.rb +39 -6
  221. data/lib/bundler/yaml_serializer.rb +90 -0
  222. data/man/bundle-add.1 +58 -0
  223. data/man/bundle-add.1.txt +52 -0
  224. data/man/bundle-add.ronn +40 -0
  225. data/man/bundle-binstubs.1 +40 -0
  226. data/man/bundle-binstubs.1.txt +48 -0
  227. data/man/bundle-binstubs.ronn +43 -0
  228. data/man/bundle-check.1 +31 -0
  229. data/man/bundle-check.1.txt +33 -0
  230. data/man/bundle-check.ronn +26 -0
  231. data/man/bundle-clean.1 +24 -0
  232. data/man/bundle-clean.1.txt +26 -0
  233. data/man/bundle-clean.ronn +18 -0
  234. data/man/bundle-config.1 +497 -0
  235. data/man/bundle-config.1.txt +529 -0
  236. data/man/bundle-config.ronn +256 -31
  237. data/man/bundle-doctor.1 +44 -0
  238. data/man/bundle-doctor.1.txt +44 -0
  239. data/man/bundle-doctor.ronn +33 -0
  240. data/man/bundle-exec.1 +165 -0
  241. data/man/bundle-exec.1.txt +178 -0
  242. data/man/bundle-exec.ronn +19 -3
  243. data/man/bundle-gem.1 +80 -0
  244. data/man/bundle-gem.1.txt +91 -0
  245. data/man/bundle-gem.ronn +78 -0
  246. data/man/bundle-info.1 +20 -0
  247. data/man/bundle-info.1.txt +21 -0
  248. data/man/bundle-info.ronn +17 -0
  249. data/man/bundle-init.1 +25 -0
  250. data/man/bundle-init.1.txt +34 -0
  251. data/man/bundle-init.ronn +29 -0
  252. data/man/bundle-inject.1 +33 -0
  253. data/man/bundle-inject.1.txt +32 -0
  254. data/man/bundle-inject.ronn +22 -0
  255. data/man/bundle-install.1 +308 -0
  256. data/man/bundle-install.1.txt +396 -0
  257. data/man/bundle-install.ronn +64 -67
  258. data/man/bundle-list.1 +50 -0
  259. data/man/bundle-list.1.txt +43 -0
  260. data/man/bundle-list.ronn +33 -0
  261. data/man/bundle-lock.1 +84 -0
  262. data/man/bundle-lock.1.txt +93 -0
  263. data/man/bundle-lock.ronn +94 -0
  264. data/man/bundle-open.1 +32 -0
  265. data/man/bundle-open.1.txt +29 -0
  266. data/man/bundle-open.ronn +19 -0
  267. data/man/bundle-outdated.1 +155 -0
  268. data/man/bundle-outdated.1.txt +131 -0
  269. data/man/bundle-outdated.ronn +111 -0
  270. data/man/bundle-package.1 +55 -0
  271. data/man/bundle-package.1.txt +79 -0
  272. data/man/bundle-package.ronn +14 -8
  273. data/man/bundle-platform.1 +61 -0
  274. data/man/bundle-platform.1.txt +57 -0
  275. data/man/bundle-platform.ronn +1 -1
  276. data/man/bundle-pristine.1 +34 -0
  277. data/man/bundle-pristine.1.txt +44 -0
  278. data/man/bundle-pristine.ronn +34 -0
  279. data/man/bundle-remove.1 +31 -0
  280. data/man/bundle-remove.1.txt +34 -0
  281. data/man/bundle-remove.ronn +23 -0
  282. data/man/bundle-show.1 +23 -0
  283. data/man/bundle-show.1.txt +27 -0
  284. data/man/bundle-show.ronn +21 -0
  285. data/man/bundle-update.1 +394 -0
  286. data/man/bundle-update.1.txt +391 -0
  287. data/man/bundle-update.ronn +180 -18
  288. data/man/bundle-viz.1 +39 -0
  289. data/man/bundle-viz.1.txt +39 -0
  290. data/man/bundle-viz.ronn +30 -0
  291. data/man/bundle.1 +136 -0
  292. data/man/bundle.1.txt +116 -0
  293. data/man/bundle.ronn +46 -33
  294. data/man/gemfile.5 +689 -0
  295. data/man/gemfile.5.ronn +127 -79
  296. data/man/gemfile.5.txt +653 -0
  297. data/man/index.txt +25 -7
  298. metadata +242 -95
  299. data/.gitignore +0 -16
  300. data/.rspec +0 -3
  301. data/.travis.yml +0 -110
  302. data/CODE_OF_CONDUCT.md +0 -40
  303. data/CONTRIBUTING.md +0 -32
  304. data/DEVELOPMENT.md +0 -119
  305. data/ISSUES.md +0 -96
  306. data/Rakefile +0 -302
  307. data/UPGRADING.md +0 -103
  308. data/bin/bundle +0 -21
  309. data/bin/bundler +0 -21
  310. data/lib/bundler/anonymizable_uri.rb +0 -32
  311. data/lib/bundler/environment.rb +0 -42
  312. data/lib/bundler/gem_installer.rb +0 -9
  313. data/lib/bundler/gem_path_manipulation.rb +0 -8
  314. data/lib/bundler/ssl_certs/AddTrustExternalCARoot.pem +0 -32
  315. data/lib/bundler/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  316. data/lib/bundler/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  317. data/lib/bundler/ssl_certs/GeoTrustGlobalCA.pem +0 -20
  318. data/lib/bundler/templates/newgem/.travis.yml.tt +0 -3
  319. data/lib/bundler/templates/newgem/test/minitest_helper.rb.tt +0 -4
  320. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo.rb +0 -5
  321. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/dependency_graph.rb +0 -266
  322. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/errors.rb +0 -69
  323. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/gem_metadata.rb +0 -3
  324. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/resolution.rb +0 -412
  325. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/state.rb +0 -43
  326. data/lib/bundler/vendor/thor-0.19.1/lib/thor/core_ext/io_binary_read.rb +0 -10
  327. data/lib/bundler/vendor/thor-0.19.1/lib/thor/core_ext/ordered_hash.rb +0 -98
  328. data/lib/bundler/vendor/thor-0.19.1/lib/thor/parser.rb +0 -4
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class ProcessLock
5
+ def self.lock(bundle_path = Bundler.bundle_path)
6
+ lock_file_path = File.join(bundle_path, "bundler.lock")
7
+ has_lock = false
8
+
9
+ File.open(lock_file_path, "w") do |f|
10
+ f.flock(File::LOCK_EX)
11
+ has_lock = true
12
+ yield
13
+ f.flock(File::LOCK_UN)
14
+ end
15
+ rescue Errno::EACCES, Errno::ENOLCK, *[SharedHelpers.const_get_safely(:ENOTSUP, Errno)].compact
16
+ # In the case the user does not have access to
17
+ # create the lock file or is using NFS where
18
+ # locks are not available we skip locking.
19
+ yield
20
+ ensure
21
+ FileUtils.rm_f(lock_file_path) if has_lock
22
+ end
23
+ end
24
+ end
@@ -1,26 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Psych could be a gem, so try to ask for it
2
4
  begin
3
- gem 'psych'
5
+ gem "psych"
4
6
  rescue LoadError
5
7
  end if defined?(gem)
6
8
 
7
- # Psych could just be in the stdlib
9
+ # Psych could be in the stdlib
8
10
  # but it's too late if Syck is already loaded
9
11
  begin
10
- require 'psych' unless defined?(Syck)
12
+ require "psych" unless defined?(Syck)
11
13
  rescue LoadError
12
14
  # Apparently Psych wasn't available. Oh well.
13
15
  end
14
16
 
15
17
  # At least load the YAML stdlib, whatever that may be
16
- require 'yaml' unless defined?(YAML.dump)
18
+ require "yaml" unless defined?(YAML.dump)
17
19
 
18
20
  module Bundler
19
21
  # On encountering invalid YAML,
20
22
  # Psych raises Psych::SyntaxError
21
23
  if defined?(::Psych::SyntaxError)
22
- YamlSyntaxError = ::Psych::SyntaxError
24
+ YamlLibrarySyntaxError = ::Psych::SyntaxError
23
25
  else # Syck raises ArgumentError
24
- YamlSyntaxError = ::ArgumentError
26
+ YamlLibrarySyntaxError = ::ArgumentError
27
+ end
28
+ end
29
+
30
+ require "bundler/deprecate"
31
+ begin
32
+ Bundler::Deprecate.skip_during do
33
+ require "rubygems/safe_yaml"
25
34
  end
35
+ rescue LoadError
36
+ # it's OK if the file isn't there
26
37
  end
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "uri"
2
- require "rubygems/spec_fetcher"
3
4
 
4
5
  module Bundler
5
6
  # Represents a lazily loaded gem specification, where the full specification
@@ -8,15 +9,18 @@ module Bundler
8
9
  # full specification will only be fetched when necessary.
9
10
  class RemoteSpecification
10
11
  include MatchPlatform
12
+ include Comparable
11
13
 
12
14
  attr_reader :name, :version, :platform
13
- attr_accessor :source, :source_uri
15
+ attr_writer :dependencies
16
+ attr_accessor :source, :remote
14
17
 
15
18
  def initialize(name, version, platform, spec_fetcher)
16
19
  @name = name
17
- @version = version
20
+ @version = Gem::Version.create version
18
21
  @platform = platform
19
22
  @spec_fetcher = spec_fetcher
23
+ @dependencies = nil
20
24
  end
21
25
 
22
26
  # Needed before installs, since the arch matters then and quick
@@ -26,32 +30,85 @@ module Bundler
26
30
  end
27
31
 
28
32
  def full_name
29
- if platform == Gem::Platform::RUBY or platform.nil? then
33
+ if platform == Gem::Platform::RUBY || platform.nil?
30
34
  "#{@name}-#{@version}"
31
35
  else
32
36
  "#{@name}-#{@version}-#{platform}"
33
37
  end
34
38
  end
35
39
 
40
+ # Compare this specification against another object. Using sort_obj
41
+ # is compatible with Gem::Specification and other Bundler or RubyGems
42
+ # objects. Otherwise, use the default Object comparison.
43
+ def <=>(other)
44
+ if other.respond_to?(:sort_obj)
45
+ sort_obj <=> other.sort_obj
46
+ else
47
+ super
48
+ end
49
+ end
50
+
36
51
  # Because Rubyforge cannot be trusted to provide valid specifications
37
52
  # once the remote gem is downloaded, the backend specification will
38
53
  # be swapped out.
39
54
  def __swap__(spec)
40
- @specification = spec
55
+ SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
56
+ @_remote_specification = spec
57
+ end
58
+
59
+ # Create a delegate used for sorting. This strategy is copied from
60
+ # RubyGems 2.23 and ensures that Bundler's specifications can be
61
+ # compared and sorted with RubyGems' own specifications.
62
+ #
63
+ # @see #<=>
64
+ # @see Gem::Specification#sort_obj
65
+ #
66
+ # @return [Array] an object you can use to compare and sort this
67
+ # specification against other specifications
68
+ def sort_obj
69
+ [@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1]
70
+ end
71
+
72
+ def to_s
73
+ "#<#{self.class} name=#{name} version=#{version} platform=#{platform}>"
74
+ end
75
+
76
+ def dependencies
77
+ @dependencies ||= begin
78
+ deps = method_missing(:dependencies)
79
+
80
+ # allow us to handle when the specs dependencies are an array of array of string
81
+ # see https://github.com/bundler/bundler/issues/5797
82
+ deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) }
83
+
84
+ deps
85
+ end
86
+ end
87
+
88
+ def git_version
89
+ return unless loaded_from && source.is_a?(Bundler::Source::Git)
90
+ " #{source.revision[0..6]}"
41
91
  end
42
92
 
43
93
  private
44
94
 
95
+ def to_ary
96
+ nil
97
+ end
98
+
45
99
  def _remote_specification
46
- @specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
100
+ @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
101
+ @_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \
102
+ " missing from the server! Try installing with `--full-index` as a workaround.")
47
103
  end
48
104
 
49
105
  def method_missing(method, *args, &blk)
50
- if Gem::Specification.new.respond_to?(method)
51
- _remote_specification.send(method, *args, &blk)
52
- else
53
- super
54
- end
106
+ _remote_specification.send(method, *args, &blk)
107
+ end
108
+
109
+ def respond_to?(method, include_all = false)
110
+ super || _remote_specification.respond_to?(method, include_all)
55
111
  end
112
+ public :respond_to?
56
113
  end
57
114
  end
@@ -1,170 +1,9 @@
1
- require 'set'
2
-
3
- # This is the latest iteration of the gem dependency resolving algorithm. As of now,
4
- # it can resolve (as a success or failure) any set of gem dependencies we throw at it
5
- # in a reasonable amount of time. The most iterations I've seen it take is about 150.
6
- # The actual implementation of the algorithm is not as good as it could be yet, but that
7
- # can come later.
1
+ # frozen_string_literal: true
8
2
 
9
3
  module Bundler
10
4
  class Resolver
11
-
12
- require 'bundler/vendored_molinillo'
13
-
14
- class Molinillo::VersionConflict
15
- def clean_req(req)
16
- if req.to_s.include?(">= 0")
17
- req.to_s.gsub(/ \(.*?\)$/, '')
18
- else
19
- req.to_s.gsub(/\, (runtime|development)\)$/, ')')
20
- end
21
- end
22
-
23
- def message
24
- conflicts.values.flatten.reduce('') do |o, conflict|
25
- o << %(Bundler could not find compatible versions for gem "#{conflict.requirement.name}":\n)
26
- if conflict.locked_requirement
27
- o << %( In snapshot (Gemfile.lock):\n)
28
- o << %( #{clean_req conflict.locked_requirement}\n)
29
- o << %(\n)
30
- end
31
- o << %( In Gemfile:\n)
32
- o << conflict.requirement_trees.map do |tree|
33
- t = ''
34
- depth = 2
35
- tree.each do |req|
36
- t << ' ' * depth << %(#{clean_req req})
37
- t << %( depends on) unless tree[-1] == req
38
- t << %(\n)
39
- depth += 1
40
- end
41
- t
42
- end.join("\n")
43
-
44
- if conflict.requirement.name == 'bundler'
45
- o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
46
- other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
47
- end
48
-
49
- if conflict.requirement.name == "bundler" && other_bundler_required
50
- o << "\n"
51
- o << "This Gemfile requires a different version of Bundler.\n"
52
- o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
53
- end
54
- if conflict.locked_requirement
55
- o << "\n"
56
- o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
57
- o << %(the gems in your Gemfile, which may resolve the conflict.\n)
58
- elsif !conflict.existing
59
- if conflict.requirement_trees.first.size > 1
60
- o << "Could not find gem '#{clean_req(conflict.requirement)}', which is required by "
61
- o << "gem '#{clean_req(conflict.requirement_trees.first[-2])}', in any of the sources."
62
- else
63
- o << "Could not find gem '#{clean_req(conflict.requirement)} in any of the sources\n"
64
- end
65
- end
66
- o
67
- end
68
- end
69
- end
70
-
71
- ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze
72
-
73
- class SpecGroup < Array
74
- include GemHelpers
75
-
76
- attr_reader :activated, :required_by
77
-
78
- def initialize(a)
79
- super
80
- @required_by = []
81
- @activated = []
82
- @dependencies = nil
83
- @specs = {}
84
-
85
- ALL.each do |p|
86
- @specs[p] = reverse.find { |s| s.match_platform(p) }
87
- end
88
- end
89
-
90
- def initialize_copy(o)
91
- super
92
- @required_by = o.required_by.dup
93
- @activated = o.activated.dup
94
- end
95
-
96
- def to_specs
97
- specs = {}
98
-
99
- @activated.each do |p|
100
- if s = @specs[p]
101
- platform = generic(Gem::Platform.new(s.platform))
102
- next if specs[platform]
103
-
104
- lazy_spec = LazySpecification.new(name, version, platform, source)
105
- lazy_spec.dependencies.replace s.dependencies
106
- specs[platform] = lazy_spec
107
- end
108
- end
109
- specs.values
110
- end
111
-
112
- def activate_platform(platform)
113
- unless @activated.include?(platform)
114
- if for?(platform)
115
- @activated << platform
116
- return __dependencies[platform] || []
117
- end
118
- end
119
- []
120
- end
121
-
122
- def name
123
- @name ||= first.name
124
- end
125
-
126
- def version
127
- @version ||= first.version
128
- end
129
-
130
- def source
131
- @source ||= first.source
132
- end
133
-
134
- def for?(platform)
135
- @specs[platform]
136
- end
137
-
138
- def to_s
139
- "#{name} (#{version})"
140
- end
141
-
142
- def dependencies_for_activated_platforms
143
- @activated.map { |p| __dependencies[p] }.flatten
144
- end
145
-
146
- def platforms_for_dependency_named(dependency)
147
- __dependencies.select { |p, deps| deps.map(&:name).include? dependency }.keys
148
- end
149
-
150
- private
151
-
152
- def __dependencies
153
- @dependencies ||= begin
154
- dependencies = {}
155
- ALL.each do |p|
156
- if spec = @specs[p]
157
- dependencies[p] = []
158
- spec.dependencies.each do |dep|
159
- next if dep.type == :development
160
- dependencies[p] << DepProxy.new(dep, p)
161
- end
162
- end
163
- end
164
- dependencies
165
- end
166
- end
167
- end
5
+ require "bundler/vendored_molinillo"
6
+ require "bundler/resolver/spec_group"
168
7
 
169
8
  # Figures out the best possible configuration of gems that satisfies
170
9
  # the list of passed dependencies and any child dependencies without
@@ -176,36 +15,50 @@ module Bundler
176
15
  # ==== Returns
177
16
  # <GemBundle>,nil:: If the list of dependencies can be resolved, a
178
17
  # collection of gemspecs is returned. Otherwise, nil is returned.
179
- def self.resolve(requirements, index, source_requirements = {}, base = [])
18
+ def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
19
+ platforms = Set.new(platforms) if platforms
180
20
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
181
- resolver = new(index, source_requirements, base)
21
+ resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
182
22
  result = resolver.start(requirements)
183
23
  SpecSet.new(result)
184
24
  end
185
25
 
186
-
187
- def initialize(index, source_requirements, base)
26
+ def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
188
27
  @index = index
189
28
  @source_requirements = source_requirements
190
29
  @base = base
191
30
  @resolver = Molinillo::Resolver.new(self, self)
192
31
  @search_for = {}
193
- @prereleases_cache = Hash.new { |h,k| h[k] = k.prerelease? }
194
32
  @base_dg = Molinillo::DependencyGraph.new
195
- @base.each { |ls| @base_dg.add_root_vertex ls.name, Dependency.new(ls.name, ls.version) }
33
+ @base.each do |ls|
34
+ dep = Dependency.new(ls.name, ls.version)
35
+ @base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
36
+ end
37
+ additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
38
+ @platforms = platforms
39
+ @gem_version_promoter = gem_version_promoter
40
+ @allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
41
+ @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
42
+ @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
196
43
  end
197
44
 
198
45
  def start(requirements)
46
+ @gem_version_promoter.prerelease_specified = @prerelease_specified = {}
47
+ requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
48
+
199
49
  verify_gemfile_dependencies_are_found!(requirements)
200
50
  dg = @resolver.resolve(requirements, @base_dg)
201
- dg.map(&:payload).map(&:to_specs).flatten
51
+ dg.map(&:payload).
52
+ reject {|sg| sg.name.end_with?("\0") }.
53
+ map(&:to_specs).flatten
202
54
  rescue Molinillo::VersionConflict => e
203
- raise VersionConflict.new(e.conflicts.keys.uniq, e.message)
55
+ message = version_conflict_message(e)
56
+ raise VersionConflict.new(e.conflicts.keys.uniq, message)
204
57
  rescue Molinillo::CircularDependencyError => e
205
- names = e.dependencies.sort_by(&:name).map { |d| "gem '#{d.name}'"}
206
- raise CyclicDependencyError, "Your Gemfile requires gems that depend" \
58
+ names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
59
+ raise CyclicDependencyError, "Your bundle requires gems that depend" \
207
60
  " on each other, creating an infinite loop. Please remove" \
208
- " #{names.count > 1 ? 'either ' : '' }#{names.join(' or ')}" \
61
+ " #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \
209
62
  " and try again."
210
63
  end
211
64
 
@@ -216,31 +69,29 @@ module Bundler
216
69
  # @param [Integer] depth the current depth of the resolution process.
217
70
  # @return [void]
218
71
  def debug(depth = 0)
219
- if debug?
220
- debug_info = yield
221
- debug_info = debug_info.inspect unless debug_info.is_a?(String)
222
- STDERR.puts debug_info.split("\n").map { |s| ' ' * depth + s }
223
- end
72
+ return unless debug?
73
+ debug_info = yield
74
+ debug_info = debug_info.inspect unless debug_info.is_a?(String)
75
+ STDERR.puts debug_info.split("\n").map {|s| " " * depth + s }
224
76
  end
225
77
 
226
78
  def debug?
227
- ENV['DEBUG_RESOLVER'] || ENV['DEBUG_RESOLVER_TREE']
79
+ return @debug_mode if defined?(@debug_mode)
80
+ @debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
228
81
  end
229
82
 
230
83
  def before_resolution
231
- Bundler.ui.info 'Resolving dependencies...', false
84
+ Bundler.ui.info "Resolving dependencies...", debug?
232
85
  end
233
86
 
234
87
  def after_resolution
235
- Bundler.ui.info ''
88
+ Bundler.ui.info ""
236
89
  end
237
90
 
238
91
  def indicate_progress
239
- Bundler.ui.info '.', false
92
+ Bundler.ui.info ".", false unless debug?
240
93
  end
241
94
 
242
- private
243
-
244
95
  include Molinillo::SpecificationProvider
245
96
 
246
97
  def dependencies_for(specification)
@@ -251,28 +102,65 @@ module Bundler
251
102
  platform = dependency.__platform
252
103
  dependency = dependency.dep unless dependency.is_a? Gem::Dependency
253
104
  search = @search_for[dependency] ||= begin
254
- index = @source_requirements[dependency.name] || @index
105
+ index = index_for(dependency)
255
106
  results = index.search(dependency, @base[dependency.name])
107
+
256
108
  if vertex = @base_dg.vertex_named(dependency.name)
257
109
  locked_requirement = vertex.payload.requirement
258
110
  end
259
- if results.any?
260
- version = results.first.version
261
- nested = [[]]
111
+
112
+ if !@prerelease_specified[dependency.name] && (!@use_gvp || locked_requirement.nil?)
113
+ # Move prereleases to the beginning of the list, so they're considered
114
+ # last during resolution.
115
+ pre, results = results.partition {|spec| spec.version.prerelease? }
116
+ results = pre + results
117
+ end
118
+
119
+ spec_groups = if results.any?
120
+ nested = []
262
121
  results.each do |spec|
263
- if spec.version != version
264
- nested << []
265
- version = spec.version
122
+ version, specs = nested.last
123
+ if version == spec.version
124
+ specs << spec
125
+ else
126
+ nested << [spec.version, [spec]]
266
127
  end
267
- nested.last << spec
268
128
  end
269
- groups = nested.map { |a| SpecGroup.new(a) }
270
- !locked_requirement ? groups : groups.select { |sg| locked_requirement.satisfied_by? sg.version }
129
+ nested.reduce([]) do |groups, (version, specs)|
130
+ next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
131
+ spec_group = SpecGroup.new(specs)
132
+ spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
133
+ groups << spec_group
134
+ end
271
135
  else
272
136
  []
273
137
  end
138
+ # GVP handles major itself, but it's still a bit risky to trust it with it
139
+ # until we get it settled with new behavior. For 2.x it can take over all cases.
140
+ if !@use_gvp
141
+ spec_groups
142
+ else
143
+ @gem_version_promoter.sort_versions(dependency, spec_groups)
144
+ end
145
+ end
146
+ search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
147
+ end
148
+
149
+ def index_for(dependency)
150
+ source = @source_requirements[dependency.name]
151
+ if source
152
+ source.specs
153
+ elsif @lockfile_uses_separate_rubygems_sources
154
+ Index.build do |idx|
155
+ if dependency.all_sources
156
+ dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
157
+ else
158
+ idx.add_source @source_requirements[:default].specs
159
+ end
160
+ end
161
+ else
162
+ @index
274
163
  end
275
- search.select { |sg| sg.for?(platform) }.each { |sg| sg.activate_platform(platform) }
276
164
  end
277
165
 
278
166
  def name_for(dependency)
@@ -280,60 +168,206 @@ module Bundler
280
168
  end
281
169
 
282
170
  def name_for_explicit_dependency_source
283
- 'Gemfile'
171
+ Bundler.default_gemfile.basename.to_s
172
+ rescue
173
+ "Gemfile"
284
174
  end
285
175
 
286
176
  def name_for_locking_dependency_source
287
- 'Gemfile.lock'
177
+ Bundler.default_lockfile.basename.to_s
178
+ rescue
179
+ "Gemfile.lock"
288
180
  end
289
181
 
290
182
  def requirement_satisfied_by?(requirement, activated, spec)
291
- requirement.matches_spec?(spec)
183
+ return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
184
+ spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
185
+ true
186
+ end
187
+
188
+ def relevant_sources_for_vertex(vertex)
189
+ if vertex.root?
190
+ [@source_requirements[vertex.name]]
191
+ elsif @lockfile_uses_separate_rubygems_sources
192
+ vertex.recursive_predecessors.map do |v|
193
+ @source_requirements[v.name]
194
+ end << @source_requirements[:default]
195
+ end
292
196
  end
293
197
 
294
198
  def sort_dependencies(dependencies, activated, conflicts)
295
199
  dependencies.sort_by do |dependency|
200
+ dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
296
201
  name = name_for(dependency)
202
+ vertex = activated.vertex_named(name)
297
203
  [
298
- activated.vertex_named(name).payload ? 0 : 1,
299
- @prereleases_cache[dependency.requirement] ? 0 : 1,
204
+ @base_dg.vertex_named(name) ? 0 : 1,
205
+ vertex.payload ? 0 : 1,
206
+ vertex.root? ? 0 : 1,
207
+ amount_constrained(dependency),
300
208
  conflicts[name] ? 0 : 1,
301
- activated.vertex_named(name).payload ? 0 : search_for(dependency).count,
209
+ vertex.payload ? 0 : search_for(dependency).count,
210
+ self.class.platform_sort_key(dependency.__platform),
302
211
  ]
303
212
  end
304
213
  end
305
214
 
306
- def verify_gemfile_dependencies_are_found!(requirements)
307
- requirements.each do |requirement|
308
- next if requirement.name == 'bundler'
309
- if search_for(requirement).empty?
310
- if base = @base[requirement.name] and !base.empty?
311
- version = base.first.version
312
- message = "You have requested:\n" \
313
- " #{requirement.name} #{requirement.requirement}\n\n" \
314
- "The bundle currently has #{requirement.name} locked at #{version}.\n" \
315
- "Try running `bundle update #{requirement.name}`"
316
- elsif requirement.source
317
- name = requirement.name
318
- versions = @source_requirements[name][name].map { |s| s.version }
319
- message = "Could not find gem '#{requirement}' in #{requirement.source}.\n"
320
- if versions.any?
321
- message << "Source contains '#{name}' at: #{versions.join(', ')}"
322
- else
323
- message << "Source does not contain any versions of '#{requirement}'"
324
- end
215
+ # Sort platforms from most general to most specific
216
+ def self.sort_platforms(platforms)
217
+ platforms.sort_by do |platform|
218
+ platform_sort_key(platform)
219
+ end
220
+ end
221
+
222
+ def self.platform_sort_key(platform)
223
+ return ["", "", ""] if Gem::Platform::RUBY == platform
224
+ platform.to_a.map {|part| part || "" }
225
+ end
226
+
227
+ private
228
+
229
+ # returns an integer \in (-\infty, 0]
230
+ # a number closer to 0 means the dependency is less constraining
231
+ #
232
+ # dependencies w/ 0 or 1 possibilities (ignoring version requirements)
233
+ # are given very negative values, so they _always_ sort first,
234
+ # before dependencies that are unconstrained
235
+ def amount_constrained(dependency)
236
+ @amount_constrained ||= {}
237
+ @amount_constrained[dependency.name] ||= begin
238
+ if (base = @base[dependency.name]) && !base.empty?
239
+ dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
240
+ else
241
+ all = index_for(dependency).search(dependency.name).size
242
+
243
+ if all <= 1
244
+ all - 1_000_000
325
245
  else
326
- message = "Could not find gem '#{requirement}' "
327
- if @index.source_types.include?(Bundler::Source::Rubygems)
328
- message << "in any of the gem sources listed in your Gemfile."
329
- else
330
- message << "in the gems available on this machine."
331
- end
246
+ search = search_for(dependency)
247
+ search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
248
+ search - all
332
249
  end
333
- raise GemNotFound, message
334
250
  end
335
251
  end
336
252
  end
337
253
 
254
+ def verify_gemfile_dependencies_are_found!(requirements)
255
+ requirements.each do |requirement|
256
+ name = requirement.name
257
+ next if name == "bundler"
258
+ next unless search_for(requirement).empty?
259
+
260
+ cache_message = begin
261
+ " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
262
+ rescue GemfileNotFound
263
+ nil
264
+ end
265
+
266
+ if (base = @base[name]) && !base.empty?
267
+ version = base.first.version
268
+ message = "You have requested:\n" \
269
+ " #{name} #{requirement.requirement}\n\n" \
270
+ "The bundle currently has #{name} locked at #{version}.\n" \
271
+ "Try running `bundle update #{name}`\n\n" \
272
+ "If you are updating multiple gems in your Gemfile at once,\n" \
273
+ "try passing them all to `bundle update`"
274
+ elsif source = @source_requirements[name]
275
+ specs = source.specs[name]
276
+ versions_with_platforms = specs.map {|s| [s.version, s.platform] }
277
+ message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
278
+ message << if versions_with_platforms.any?
279
+ "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
280
+ else
281
+ "The source does not contain any versions of '#{name}'"
282
+ end
283
+ else
284
+ message = "Could not find gem '#{requirement}' in any of the gem sources " \
285
+ "listed in your Gemfile#{cache_message}."
286
+ end
287
+ raise GemNotFound, message
288
+ end
289
+ end
290
+
291
+ def formatted_versions_with_platforms(versions_with_platforms)
292
+ version_platform_strs = versions_with_platforms.map do |vwp|
293
+ version = vwp.first
294
+ platform = vwp.last
295
+ version_platform_str = String.new(version.to_s)
296
+ version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
297
+ version_platform_str
298
+ end
299
+ version_platform_strs.join(", ")
300
+ end
301
+
302
+ def version_conflict_message(e)
303
+ e.message_with_trees(
304
+ :solver_name => "Bundler",
305
+ :possibility_type => "gem",
306
+ :reduce_trees => lambda do |trees|
307
+ # called first, because we want to reduce the amount of work required to find maximal empty sets
308
+ trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
309
+
310
+ # bail out if tree size is too big for Array#combination to make any sense
311
+ return trees if trees.size > 15
312
+ maximal = 1.upto(trees.size).map do |size|
313
+ trees.map(&:last).flatten(1).combination(size).to_a
314
+ end.flatten(1).select do |deps|
315
+ Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
316
+ end.min_by(&:size)
317
+ trees.reject! {|t| !maximal.include?(t.last) } if maximal
318
+
319
+ trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
320
+ trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
321
+
322
+ trees.sort_by {|t| t.reverse.map(&:name) }
323
+ end,
324
+ :printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
325
+ :additional_message_for_conflict => lambda do |o, name, conflict|
326
+ if name == "bundler"
327
+ o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
328
+ other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
329
+ end
330
+
331
+ if name == "bundler" && other_bundler_required
332
+ o << "\n"
333
+ o << "This Gemfile requires a different version of Bundler.\n"
334
+ o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
335
+ end
336
+ if conflict.locked_requirement
337
+ o << "\n"
338
+ o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
339
+ o << %(the gems in your Gemfile, which may resolve the conflict.\n)
340
+ elsif !conflict.existing
341
+ o << "\n"
342
+
343
+ relevant_sources = if conflict.requirement.source
344
+ [conflict.requirement.source]
345
+ elsif conflict.requirement.all_sources
346
+ conflict.requirement.all_sources
347
+ elsif @lockfile_uses_separate_rubygems_sources
348
+ # every conflict should have an explicit group of sources when we
349
+ # enforce strict pinning
350
+ raise "no source set for #{conflict}"
351
+ else
352
+ []
353
+ end.compact.map(&:to_s).uniq.sort
354
+
355
+ o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
356
+ if conflict.requirement_trees.first.size > 1
357
+ o << ", which is required by "
358
+ o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
359
+ end
360
+ o << " "
361
+
362
+ o << if relevant_sources.empty?
363
+ "in any of the sources.\n"
364
+ else
365
+ "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
366
+ end
367
+ end
368
+ end,
369
+ :version_for_spec => lambda {|spec| spec.version }
370
+ )
371
+ end
338
372
  end
339
373
  end