bundler 1.13.6 → 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 (323) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +554 -9
  3. data/README.md +28 -5
  4. data/bundler.gemspec +40 -11
  5. data/exe/bundle +4 -8
  6. data/exe/bundle_ruby +4 -3
  7. data/lib/bundler.rb +162 -68
  8. data/lib/bundler/build_metadata.rb +53 -0
  9. data/lib/bundler/capistrano.rb +5 -0
  10. data/lib/bundler/cli.rb +360 -118
  11. data/lib/bundler/cli/add.rb +35 -0
  12. data/lib/bundler/cli/binstubs.rb +18 -10
  13. data/lib/bundler/cli/cache.rb +6 -5
  14. data/lib/bundler/cli/check.rb +4 -6
  15. data/lib/bundler/cli/clean.rb +6 -7
  16. data/lib/bundler/cli/common.rb +47 -1
  17. data/lib/bundler/cli/config.rb +26 -7
  18. data/lib/bundler/cli/console.rb +2 -1
  19. data/lib/bundler/cli/doctor.rb +63 -18
  20. data/lib/bundler/cli/exec.rb +12 -5
  21. data/lib/bundler/cli/gem.rb +59 -21
  22. data/lib/bundler/cli/info.rb +50 -0
  23. data/lib/bundler/cli/init.rb +21 -7
  24. data/lib/bundler/cli/inject.rb +13 -4
  25. data/lib/bundler/cli/install.rb +72 -101
  26. data/lib/bundler/cli/issue.rb +40 -0
  27. data/lib/bundler/cli/list.rb +58 -0
  28. data/lib/bundler/cli/lock.rb +9 -6
  29. data/lib/bundler/cli/open.rb +4 -3
  30. data/lib/bundler/cli/outdated.rb +175 -60
  31. data/lib/bundler/cli/package.rb +9 -6
  32. data/lib/bundler/cli/platform.rb +2 -1
  33. data/lib/bundler/cli/plugin.rb +1 -0
  34. data/lib/bundler/cli/pristine.rb +47 -0
  35. data/lib/bundler/cli/remove.rb +18 -0
  36. data/lib/bundler/cli/show.rb +2 -2
  37. data/lib/bundler/cli/update.rb +44 -34
  38. data/lib/bundler/cli/viz.rb +5 -1
  39. data/lib/bundler/compact_index_client.rb +109 -0
  40. data/lib/bundler/compact_index_client/cache.rb +118 -0
  41. data/lib/bundler/compact_index_client/updater.rb +116 -0
  42. data/lib/bundler/compatibility_guard.rb +14 -0
  43. data/lib/bundler/constants.rb +1 -0
  44. data/lib/bundler/current_ruby.rb +17 -8
  45. data/lib/bundler/definition.rb +353 -182
  46. data/lib/bundler/dep_proxy.rb +3 -1
  47. data/lib/bundler/dependency.rb +22 -10
  48. data/lib/bundler/deployment.rb +1 -1
  49. data/lib/bundler/deprecate.rb +15 -3
  50. data/lib/bundler/dsl.rb +122 -64
  51. data/lib/bundler/endpoint_specification.rb +13 -3
  52. data/lib/bundler/env.rb +110 -38
  53. data/lib/bundler/environment_preserver.rb +27 -6
  54. data/lib/bundler/errors.rb +24 -0
  55. data/lib/bundler/feature_flag.rb +74 -0
  56. data/lib/bundler/fetcher.rb +18 -11
  57. data/lib/bundler/fetcher/base.rb +1 -0
  58. data/lib/bundler/fetcher/compact_index.rb +7 -5
  59. data/lib/bundler/fetcher/dependency.rb +3 -2
  60. data/lib/bundler/fetcher/downloader.rb +25 -7
  61. data/lib/bundler/fetcher/index.rb +3 -2
  62. data/lib/bundler/friendly_errors.rb +33 -7
  63. data/lib/bundler/gem_helper.rb +25 -11
  64. data/lib/bundler/gem_helpers.rb +70 -1
  65. data/lib/bundler/gem_remote_fetcher.rb +1 -0
  66. data/lib/bundler/gem_tasks.rb +1 -0
  67. data/lib/bundler/gem_version_promoter.rb +17 -2
  68. data/lib/bundler/gemdeps.rb +29 -0
  69. data/lib/bundler/graph.rb +1 -0
  70. data/lib/bundler/index.rb +28 -15
  71. data/lib/bundler/injector.rb +216 -33
  72. data/lib/bundler/inline.rb +12 -12
  73. data/lib/bundler/installer.rb +139 -53
  74. data/lib/bundler/installer/gem_installer.rb +15 -5
  75. data/lib/bundler/installer/parallel_installer.rb +113 -28
  76. data/lib/bundler/installer/standalone.rb +1 -0
  77. data/lib/bundler/lazy_specification.rb +31 -3
  78. data/lib/bundler/lockfile_generator.rb +95 -0
  79. data/lib/bundler/lockfile_parser.rb +50 -37
  80. data/lib/bundler/match_platform.rb +13 -3
  81. data/lib/bundler/mirror.rb +10 -5
  82. data/lib/bundler/plugin.rb +22 -8
  83. data/lib/bundler/plugin/api.rb +2 -1
  84. data/lib/bundler/plugin/api/source.rb +17 -4
  85. data/lib/bundler/plugin/events.rb +61 -0
  86. data/lib/bundler/plugin/index.rb +9 -2
  87. data/lib/bundler/plugin/installer.rb +7 -6
  88. data/lib/bundler/plugin/source_list.rb +7 -8
  89. data/lib/bundler/process_lock.rb +24 -0
  90. data/lib/bundler/psyched_yaml.rb +10 -0
  91. data/lib/bundler/remote_specification.rb +30 -1
  92. data/lib/bundler/resolver.rb +187 -194
  93. data/lib/bundler/resolver/spec_group.rb +106 -0
  94. data/lib/bundler/retry.rb +5 -1
  95. data/lib/bundler/ruby_dsl.rb +1 -0
  96. data/lib/bundler/ruby_version.rb +12 -2
  97. data/lib/bundler/rubygems_ext.rb +23 -8
  98. data/lib/bundler/rubygems_gem_installer.rb +90 -0
  99. data/lib/bundler/rubygems_integration.rb +193 -70
  100. data/lib/bundler/runtime.rb +39 -22
  101. data/lib/bundler/settings.rb +245 -85
  102. data/lib/bundler/settings/validator.rb +102 -0
  103. data/lib/bundler/setup.rb +4 -7
  104. data/lib/bundler/shared_helpers.rb +183 -40
  105. data/lib/bundler/similarity_detector.rb +1 -0
  106. data/lib/bundler/source.rb +58 -1
  107. data/lib/bundler/source/gemspec.rb +1 -0
  108. data/lib/bundler/source/git.rb +52 -23
  109. data/lib/bundler/source/git/git_proxy.rb +30 -14
  110. data/lib/bundler/source/metadata.rb +62 -0
  111. data/lib/bundler/source/path.rb +42 -16
  112. data/lib/bundler/source/path/installer.rb +4 -2
  113. data/lib/bundler/source/rubygems.rb +171 -82
  114. data/lib/bundler/source/rubygems/remote.rb +12 -2
  115. data/lib/bundler/source_list.rb +75 -15
  116. data/lib/bundler/spec_set.rb +67 -32
  117. data/lib/bundler/ssl_certs/certificate_manager.rb +2 -1
  118. data/lib/bundler/stub_specification.rb +86 -2
  119. data/lib/bundler/templates/.document +1 -0
  120. data/lib/bundler/templates/Executable +13 -1
  121. data/lib/bundler/templates/Executable.bundler +105 -0
  122. data/lib/bundler/templates/Executable.standalone +5 -5
  123. data/lib/bundler/templates/Gemfile +3 -0
  124. data/lib/bundler/templates/gems.rb +8 -0
  125. data/lib/bundler/templates/newgem/Gemfile.tt +4 -2
  126. data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
  127. data/lib/bundler/templates/newgem/README.md.tt +14 -8
  128. data/lib/bundler/templates/newgem/Rakefile.tt +5 -5
  129. data/lib/bundler/templates/newgem/bin/console.tt +1 -1
  130. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
  131. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
  132. data/lib/bundler/templates/newgem/gitignore.tt +5 -1
  133. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +7 -6
  134. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +4 -4
  135. data/lib/bundler/templates/newgem/newgem.gemspec.tt +21 -12
  136. data/lib/bundler/templates/newgem/rspec.tt +1 -0
  137. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -3
  138. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +13 -1
  139. data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +1 -1
  140. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +3 -3
  141. data/lib/bundler/templates/newgem/{.travis.yml.tt → travis.yml.tt} +2 -0
  142. data/lib/bundler/ui.rb +1 -0
  143. data/lib/bundler/ui/rg_proxy.rb +1 -0
  144. data/lib/bundler/ui/shell.rb +30 -10
  145. data/lib/bundler/ui/silent.rb +21 -1
  146. data/lib/bundler/uri_credentials_filter.rb +1 -0
  147. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
  148. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +2 -0
  149. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
  150. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +7 -0
  151. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +1 -0
  152. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +26 -6
  153. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +2 -1
  154. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +12 -4
  155. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +3 -2
  156. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  157. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +11 -3
  158. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +13 -1
  159. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +3 -2
  160. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +3 -2
  161. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +18 -5
  162. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +75 -7
  163. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
  164. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -0
  165. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +3 -1
  166. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +499 -128
  167. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +1 -0
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +8 -4
  169. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/faster.rb +1 -0
  170. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +27 -24
  171. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent/ssl_reuse.rb +2 -1
  172. data/lib/bundler/vendor/thor/lib/thor.rb +46 -21
  173. data/lib/bundler/vendor/thor/lib/thor/actions.rb +24 -22
  174. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +2 -1
  175. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  176. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +2 -2
  177. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +16 -8
  178. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +66 -18
  179. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +17 -15
  180. data/lib/bundler/vendor/thor/lib/thor/base.rb +55 -32
  181. data/lib/bundler/vendor/thor/lib/thor/command.rb +13 -11
  182. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +21 -1
  183. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +7 -5
  184. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +94 -63
  185. data/lib/bundler/vendor/thor/lib/thor/error.rb +3 -3
  186. data/lib/bundler/vendor/thor/lib/thor/group.rb +13 -13
  187. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +4 -5
  188. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +2 -0
  189. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +4 -7
  190. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +16 -16
  191. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +42 -21
  192. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +13 -10
  193. data/lib/bundler/vendor/thor/lib/thor/runner.rb +31 -29
  194. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  195. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +49 -33
  196. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
  197. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +4 -4
  198. data/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
  199. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  200. data/lib/bundler/vendored_fileutils.rb +9 -0
  201. data/lib/bundler/vendored_molinillo.rb +1 -0
  202. data/lib/bundler/vendored_persistent.rb +43 -3
  203. data/lib/bundler/vendored_thor.rb +6 -2
  204. data/lib/bundler/version.rb +19 -2
  205. data/lib/bundler/version_ranges.rb +76 -0
  206. data/lib/bundler/vlad.rb +5 -0
  207. data/lib/bundler/worker.rb +30 -6
  208. data/lib/bundler/yaml_serializer.rb +4 -4
  209. data/man/bundle-add.1 +58 -0
  210. data/man/bundle-add.1.txt +52 -0
  211. data/man/bundle-add.ronn +40 -0
  212. data/{lib/bundler/man/bundle-binstubs → man/bundle-binstubs.1} +11 -1
  213. data/man/bundle-binstubs.1.txt +48 -0
  214. data/man/bundle-binstubs.ronn +15 -1
  215. data/man/bundle-check.1 +31 -0
  216. data/man/bundle-check.1.txt +33 -0
  217. data/man/bundle-check.ronn +26 -0
  218. data/man/bundle-clean.1 +24 -0
  219. data/man/bundle-clean.1.txt +26 -0
  220. data/man/bundle-clean.ronn +18 -0
  221. data/man/bundle-config.1 +497 -0
  222. data/man/bundle-config.1.txt +529 -0
  223. data/man/bundle-config.ronn +233 -61
  224. data/man/bundle-doctor.1 +44 -0
  225. data/man/bundle-doctor.1.txt +44 -0
  226. data/man/bundle-doctor.ronn +33 -0
  227. data/{lib/bundler/man/bundle-exec → man/bundle-exec.1} +6 -3
  228. data/man/bundle-exec.1.txt +178 -0
  229. data/man/bundle-exec.ronn +10 -3
  230. data/{lib/bundler/man/bundle-gem → man/bundle-gem.1} +4 -4
  231. data/man/bundle-gem.1.txt +91 -0
  232. data/man/bundle-gem.ronn +3 -2
  233. data/man/bundle-info.1 +20 -0
  234. data/man/bundle-info.1.txt +21 -0
  235. data/man/bundle-info.ronn +17 -0
  236. data/man/bundle-init.1 +25 -0
  237. data/man/bundle-init.1.txt +34 -0
  238. data/man/bundle-init.ronn +29 -0
  239. data/man/bundle-inject.1 +33 -0
  240. data/man/bundle-inject.1.txt +32 -0
  241. data/man/bundle-inject.ronn +22 -0
  242. data/{lib/bundler/man/bundle-install → man/bundle-install.1} +32 -29
  243. data/man/bundle-install.1.txt +396 -0
  244. data/man/bundle-install.ronn +45 -36
  245. data/man/bundle-list.1 +50 -0
  246. data/man/bundle-list.1.txt +43 -0
  247. data/man/bundle-list.ronn +33 -0
  248. data/{lib/bundler/man/bundle-lock → man/bundle-lock.1} +43 -2
  249. data/man/bundle-lock.1.txt +93 -0
  250. data/man/bundle-lock.ronn +47 -0
  251. data/man/bundle-open.1 +32 -0
  252. data/man/bundle-open.1.txt +29 -0
  253. data/man/bundle-open.ronn +19 -0
  254. data/man/bundle-outdated.1 +155 -0
  255. data/man/bundle-outdated.1.txt +131 -0
  256. data/man/bundle-outdated.ronn +111 -0
  257. data/{lib/bundler/man/bundle-package → man/bundle-package.1} +6 -3
  258. data/man/bundle-package.1.txt +79 -0
  259. data/man/bundle-package.ronn +7 -2
  260. data/{lib/bundler/man/bundle-platform → man/bundle-platform.1} +1 -1
  261. data/man/bundle-platform.1.txt +57 -0
  262. data/man/bundle-pristine.1 +34 -0
  263. data/man/bundle-pristine.1.txt +44 -0
  264. data/man/bundle-pristine.ronn +34 -0
  265. data/man/bundle-remove.1 +31 -0
  266. data/man/bundle-remove.1.txt +34 -0
  267. data/man/bundle-remove.ronn +23 -0
  268. data/man/bundle-show.1 +23 -0
  269. data/man/bundle-show.1.txt +27 -0
  270. data/man/bundle-show.ronn +21 -0
  271. data/man/bundle-update.1 +394 -0
  272. data/man/bundle-update.1.txt +391 -0
  273. data/man/bundle-update.ronn +172 -16
  274. data/man/bundle-viz.1 +39 -0
  275. data/man/bundle-viz.1.txt +39 -0
  276. data/man/bundle-viz.ronn +30 -0
  277. data/{lib/bundler/man/bundle → man/bundle.1} +44 -28
  278. data/man/bundle.1.txt +116 -0
  279. data/man/bundle.ronn +39 -27
  280. data/{lib/bundler/man → man}/gemfile.5 +67 -84
  281. data/man/gemfile.5.ronn +77 -55
  282. data/man/gemfile.5.txt +653 -0
  283. data/man/index.txt +25 -8
  284. metadata +118 -58
  285. data/.codeclimate.yml +0 -25
  286. data/.gitignore +0 -16
  287. data/.rspec +0 -3
  288. data/.rubocop.yml +0 -128
  289. data/.rubocop_todo.yml +0 -248
  290. data/.travis.yml +0 -108
  291. data/CODE_OF_CONDUCT.md +0 -42
  292. data/CONTRIBUTING.md +0 -36
  293. data/DEVELOPMENT.md +0 -148
  294. data/ISSUES.md +0 -100
  295. data/Rakefile +0 -333
  296. data/bin/rake +0 -19
  297. data/bin/rspec +0 -15
  298. data/bin/rubocop +0 -17
  299. data/bin/with_rubygems +0 -39
  300. data/lib/bundler/man/bundle-binstubs.txt +0 -33
  301. data/lib/bundler/man/bundle-config +0 -254
  302. data/lib/bundler/man/bundle-config.txt +0 -282
  303. data/lib/bundler/man/bundle-exec.txt +0 -171
  304. data/lib/bundler/man/bundle-gem.txt +0 -90
  305. data/lib/bundler/man/bundle-install.txt +0 -385
  306. data/lib/bundler/man/bundle-lock.txt +0 -52
  307. data/lib/bundler/man/bundle-package.txt +0 -74
  308. data/lib/bundler/man/bundle-platform.txt +0 -57
  309. data/lib/bundler/man/bundle-update +0 -221
  310. data/lib/bundler/man/bundle-update.txt +0 -227
  311. data/lib/bundler/man/bundle.txt +0 -104
  312. data/lib/bundler/man/gemfile.5.txt +0 -636
  313. data/lib/bundler/postit_trampoline.rb +0 -68
  314. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +0 -79
  315. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/cache.rb +0 -112
  316. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +0 -80
  317. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/version.rb +0 -4
  318. data/lib/bundler/vendor/postit/lib/postit.rb +0 -15
  319. data/lib/bundler/vendor/postit/lib/postit/environment.rb +0 -44
  320. data/lib/bundler/vendor/postit/lib/postit/installer.rb +0 -28
  321. data/lib/bundler/vendor/postit/lib/postit/parser.rb +0 -21
  322. data/lib/bundler/vendor/postit/lib/postit/setup.rb +0 -12
  323. data/lib/bundler/vendor/postit/lib/postit/version.rb +0 -3
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require "bundler/plugin/api/source"
3
2
 
4
3
  module Bundler
5
4
  # This is the interfacing class represents the API that we intend to provide
@@ -24,6 +23,8 @@ module Bundler
24
23
  # and hooks).
25
24
  module Plugin
26
25
  class API
26
+ autoload :Source, "bundler/plugin/api/source"
27
+
27
28
  # The plugins should declare that they handle a command through this helper.
28
29
  #
29
30
  # @param [String] command being handled by them
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "uri"
3
- require "digest/sha1"
4
4
 
5
5
  module Bundler
6
6
  module Plugin
7
7
  class API
8
8
  # This class provides the base to build source plugins
9
- # All the method here are require to build a source plugin (except
9
+ # All the method here are required to build a source plugin (except
10
10
  # `uri_hash`, `gem_install_dir`; they are helpers).
11
11
  #
12
12
  # Defaults for methods, where ever possible are provided which is
@@ -93,7 +93,7 @@ module Bundler
93
93
  # It should be called in `install` after the plugin is done placing the
94
94
  # gem at correct install location.
95
95
  #
96
- # It also runs Gem hooks `post_install`, `post_build` and `post_install`
96
+ # It also runs Gem hooks `pre_install`, `post_build` and `post_install`
97
97
  #
98
98
  # Note: Do not override if you don't know what you are doing.
99
99
  def post_install(spec, disable_exts = false)
@@ -271,7 +271,7 @@ module Bundler
271
271
  end
272
272
 
273
273
  def uri_hash
274
- Digest::SHA1.hexdigest(uri)
274
+ SharedHelpers.digest(:SHA1).hexdigest(uri)
275
275
  end
276
276
 
277
277
  # Note: Do not override if you don't know what you are doing.
@@ -287,6 +287,19 @@ module Bundler
287
287
  def root
288
288
  Bundler.root
289
289
  end
290
+
291
+ # @private
292
+ # Returns true
293
+ def bundler_plugin_api_source?
294
+ true
295
+ end
296
+
297
+ # @private
298
+ # This API on source might not be stable, and for now we expect plugins
299
+ # to download all specs in `#specs`, so we implement the method for
300
+ # compatibility purposes and leave it undocumented (and don't support)
301
+ # overriding it)
302
+ def double_check_for(*); end
290
303
  end
291
304
  end
292
305
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ module Plugin
5
+ module Events
6
+ def self.define(const, event)
7
+ const = const.to_sym.freeze
8
+ if const_defined?(const) && const_get(const) != event
9
+ raise ArgumentError, "Attempting to reassign #{const} to a different value"
10
+ end
11
+ const_set(const, event) unless const_defined?(const)
12
+ @events ||= {}
13
+ @events[event] = const
14
+ end
15
+ private_class_method :define
16
+
17
+ def self.reset
18
+ @events.each_value do |const|
19
+ remove_const(const)
20
+ end
21
+ @events = nil
22
+ end
23
+ private_class_method :reset
24
+
25
+ # Check if an event has been defined
26
+ # @param event [String] An event to check
27
+ # @return [Boolean] A boolean indicating if the event has been defined
28
+ def self.defined_event?(event)
29
+ @events ||= {}
30
+ @events.key?(event)
31
+ end
32
+
33
+ # @!parse
34
+ # A hook called before each individual gem is installed
35
+ # Includes a Bundler::ParallelInstaller::SpecInstallation.
36
+ # No state, error, post_install_message will be present as nothing has installed yet
37
+ # GEM_BEFORE_INSTALL = "before-install"
38
+ define :GEM_BEFORE_INSTALL, "before-install"
39
+
40
+ # @!parse
41
+ # A hook called after each individual gem is installed
42
+ # Includes a Bundler::ParallelInstaller::SpecInstallation.
43
+ # - If state is failed, an error will be present.
44
+ # - If state is success, a post_install_message may be present.
45
+ # GEM_AFTER_INSTALL = "after-install"
46
+ define :GEM_AFTER_INSTALL, "after-install"
47
+
48
+ # @!parse
49
+ # A hook called before any gems install
50
+ # Includes an Array of Bundler::Dependency objects
51
+ # GEM_BEFORE_INSTALL_ALL = "before-install-all"
52
+ define :GEM_BEFORE_INSTALL_ALL, "before-install-all"
53
+
54
+ # @!parse
55
+ # A hook called after any gems install
56
+ # Includes an Array of Bundler::Dependency objects
57
+ # GEM_AFTER_INSTALL_ALL = "after-install-all"
58
+ define :GEM_AFTER_INSTALL_ALL, "after-install-all"
59
+ end
60
+ end
61
+ end
@@ -20,6 +20,8 @@ module Bundler
20
20
  end
21
21
  end
22
22
 
23
+ attr_reader :commands
24
+
23
25
  def initialize
24
26
  @plugin_paths = {}
25
27
  @commands = {}
@@ -27,7 +29,12 @@ module Bundler
27
29
  @hooks = {}
28
30
  @load_paths = {}
29
31
 
30
- load_index(global_index_file, true)
32
+ begin
33
+ load_index(global_index_file, true)
34
+ rescue GenericSystemCallError
35
+ # no need to fail when on a read-only FS, for example
36
+ nil
37
+ end
31
38
  load_index(local_index_file) if SharedHelpers.in_bundle?
32
39
  end
33
40
 
@@ -56,7 +63,7 @@ module Bundler
56
63
  @plugin_paths[name] = path
57
64
  @load_paths[name] = load_paths
58
65
  save_index
59
- rescue
66
+ rescue StandardError
60
67
  @commands = old_commands
61
68
  raise
62
69
  end
@@ -13,12 +13,13 @@ module Bundler
13
13
 
14
14
  def install(names, options)
15
15
  version = options[:version] || [">= 0"]
16
-
17
- if options[:git]
18
- install_git(names, version, options)
19
- else
20
- sources = options[:source] || Bundler.rubygems.sources
21
- install_rubygems(names, version, sources)
16
+ Bundler.settings.temporary(:lockfile_uses_separate_rubygems_sources => false, :disable_multisource => false) do
17
+ if options[:git]
18
+ install_git(names, version, options)
19
+ else
20
+ sources = options[:source] || Bundler.rubygems.sources
21
+ install_rubygems(names, version, sources)
22
+ end
22
23
  end
23
24
  end
24
25
 
@@ -5,13 +5,6 @@ module Bundler
5
5
  # approptiate options to be used with Source classes for plugin installation
6
6
  module Plugin
7
7
  class SourceList < Bundler::SourceList
8
- def initialize
9
- @path_sources = []
10
- @git_sources = []
11
- @rubygems_aggregate = Plugin::Installer::Rubygems.new
12
- @rubygems_sources = []
13
- end
14
-
15
8
  def add_git_source(options = {})
16
9
  add_source_to_list Plugin::Installer::Git.new(options), git_sources
17
10
  end
@@ -21,7 +14,13 @@ module Bundler
21
14
  end
22
15
 
23
16
  def all_sources
24
- path_sources + git_sources + rubygems_sources
17
+ path_sources + git_sources + rubygems_sources + [metadata_source]
18
+ end
19
+
20
+ private
21
+
22
+ def rubygems_aggregate_class
23
+ Plugin::Installer::Rubygems
25
24
  end
26
25
  end
27
26
  end
@@ -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,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Psych could be a gem, so try to ask for it
3
4
  begin
4
5
  gem "psych"
@@ -25,3 +26,12 @@ module Bundler
25
26
  YamlLibrarySyntaxError = ::ArgumentError
26
27
  end
27
28
  end
29
+
30
+ require "bundler/deprecate"
31
+ begin
32
+ Bundler::Deprecate.skip_during do
33
+ require "rubygems/safe_yaml"
34
+ end
35
+ rescue LoadError
36
+ # it's OK if the file isn't there
37
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "uri"
3
- require "rubygems/spec_fetcher"
4
4
 
5
5
  module Bundler
6
6
  # Represents a lazily loaded gem specification, where the full specification
@@ -12,6 +12,7 @@ module Bundler
12
12
  include Comparable
13
13
 
14
14
  attr_reader :name, :version, :platform
15
+ attr_writer :dependencies
15
16
  attr_accessor :source, :remote
16
17
 
17
18
  def initialize(name, version, platform, spec_fetcher)
@@ -19,6 +20,7 @@ module Bundler
19
20
  @version = Gem::Version.create version
20
21
  @platform = platform
21
22
  @spec_fetcher = spec_fetcher
23
+ @dependencies = nil
22
24
  end
23
25
 
24
26
  # Needed before installs, since the arch matters then and quick
@@ -50,6 +52,7 @@ module Bundler
50
52
  # once the remote gem is downloaded, the backend specification will
51
53
  # be swapped out.
52
54
  def __swap__(spec)
55
+ SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
53
56
  @_remote_specification = spec
54
57
  end
55
58
 
@@ -70,8 +73,29 @@ module Bundler
70
73
  "#<#{self.class} name=#{name} version=#{version} platform=#{platform}>"
71
74
  end
72
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]}"
91
+ end
92
+
73
93
  private
74
94
 
95
+ def to_ary
96
+ nil
97
+ end
98
+
75
99
  def _remote_specification
76
100
  @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
77
101
  @_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \
@@ -81,5 +105,10 @@ module Bundler
81
105
  def method_missing(method, *args, &blk)
82
106
  _remote_specification.send(method, *args, &blk)
83
107
  end
108
+
109
+ def respond_to?(method, include_all = false)
110
+ super || _remote_specification.respond_to?(method, include_all)
111
+ end
112
+ public :respond_to?
84
113
  end
85
114
  end
@@ -1,169 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler
3
4
  class Resolver
4
5
  require "bundler/vendored_molinillo"
5
-
6
- class Molinillo::VersionConflict
7
- def printable_dep(dep)
8
- if dep.is_a?(Bundler::Dependency)
9
- DepProxy.new(dep, dep.platforms.join(", ")).to_s.strip
10
- else
11
- dep.to_s
12
- end
13
- end
14
-
15
- def message
16
- conflicts.sort.reduce(String.new) do |o, (name, conflict)|
17
- o << %(Bundler could not find compatible versions for gem "#{name}":\n)
18
- if conflict.locked_requirement
19
- o << %( In snapshot (#{Bundler.default_lockfile.basename}):\n)
20
- o << %( #{printable_dep(conflict.locked_requirement)}\n)
21
- o << %(\n)
22
- end
23
- o << %( In Gemfile:\n)
24
- o << conflict.requirement_trees.sort_by {|t| t.reverse.map(&:name) }.map do |tree|
25
- t = String.new
26
- depth = 2
27
- tree.each do |req|
28
- t << " " * depth << req.to_s
29
- unless tree.last == req
30
- if spec = conflict.activated_by_name[req.name]
31
- t << %( was resolved to #{spec.version}, which)
32
- end
33
- t << %( depends on)
34
- end
35
- t << %(\n)
36
- depth += 1
37
- end
38
- t
39
- end.join("\n")
40
-
41
- if name == "bundler"
42
- o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
43
- other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
44
- end
45
-
46
- if name == "bundler" && other_bundler_required
47
- o << "\n"
48
- o << "This Gemfile requires a different version of Bundler.\n"
49
- o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
50
- end
51
- if conflict.locked_requirement
52
- o << "\n"
53
- o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
54
- o << %(the gems in your Gemfile, which may resolve the conflict.\n)
55
- elsif !conflict.existing
56
- o << "\n"
57
- if conflict.requirement_trees.first.size > 1
58
- o << "Could not find gem '#{conflict.requirement}', which is required by "
59
- o << "gem '#{conflict.requirement_trees.first[-2]}', in any of the sources."
60
- else
61
- o << "Could not find gem '#{conflict.requirement}' in any of the sources\n"
62
- end
63
- end
64
- o
65
- end
66
- end
67
- end
68
-
69
- ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze
70
-
71
- class SpecGroup < Array
72
- include GemHelpers
73
-
74
- attr_reader :activated, :required_by
75
-
76
- def initialize(a)
77
- super
78
- @required_by = []
79
- @activated = []
80
- @dependencies = nil
81
- @specs = {}
82
-
83
- ALL.each do |p|
84
- @specs[p] = reverse.find {|s| s.match_platform(p) }
85
- end
86
- end
87
-
88
- def initialize_copy(o)
89
- super
90
- @required_by = o.required_by.dup
91
- @activated = o.activated.dup
92
- end
93
-
94
- def to_specs
95
- specs = {}
96
-
97
- @activated.each do |p|
98
- next unless s = @specs[p]
99
- platform = generic(Gem::Platform.new(s.platform))
100
- next if specs[platform]
101
-
102
- lazy_spec = LazySpecification.new(name, version, platform, source)
103
- lazy_spec.dependencies.replace s.dependencies
104
- specs[platform] = lazy_spec
105
- end
106
- specs.values
107
- end
108
-
109
- def activate_platform!(platform)
110
- @activated << platform if !@activated.include?(platform) && for?(platform, nil)
111
- end
112
-
113
- def name
114
- @name ||= first.name
115
- end
116
-
117
- def version
118
- @version ||= first.version
119
- end
120
-
121
- def source
122
- @source ||= first.source
123
- end
124
-
125
- def for?(platform, ruby_version)
126
- spec = @specs[platform]
127
- return false unless spec
128
-
129
- return true if ruby_version.nil?
130
- # Only allow endpoint specifications since they won't hit the network to
131
- # fetch the full gemspec when calling required_ruby_version
132
- return true if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
133
- return true if spec.required_ruby_version.nil?
134
-
135
- spec.required_ruby_version.satisfied_by?(ruby_version.to_gem_version_with_patchlevel)
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 {|_, 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
- next unless 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
- dependencies
164
- end
165
- end
166
- end
6
+ require "bundler/resolver/spec_group"
167
7
 
168
8
  # Figures out the best possible configuration of gems that satisfies
169
9
  # the list of passed dependencies and any child dependencies without
@@ -175,32 +15,45 @@ module Bundler
175
15
  # ==== Returns
176
16
  # <GemBundle>,nil:: If the list of dependencies can be resolved, a
177
17
  # collection of gemspecs is returned. Otherwise, nil is returned.
178
- def self.resolve(requirements, index, source_requirements = {}, base = [], ruby_version = nil, gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [])
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
179
20
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
180
- resolver = new(index, source_requirements, base, ruby_version, gem_version_promoter, additional_base_requirements)
21
+ resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
181
22
  result = resolver.start(requirements)
182
23
  SpecSet.new(result)
183
24
  end
184
25
 
185
- def initialize(index, source_requirements, base, ruby_version, gem_version_promoter, additional_base_requirements)
26
+ def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
186
27
  @index = index
187
28
  @source_requirements = source_requirements
188
29
  @base = base
189
30
  @resolver = Molinillo::Resolver.new(self, self)
190
31
  @search_for = {}
191
32
  @base_dg = Molinillo::DependencyGraph.new
192
- @base.each {|ls| @base_dg.add_vertex(ls.name, Dependency.new(ls.name, ls.version), true) }
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
193
37
  additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
194
- @ruby_version = ruby_version
38
+ @platforms = platforms
195
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
58
  names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
206
59
  raise CyclicDependencyError, "Your bundle requires gems that depend" \
@@ -224,11 +77,11 @@ module Bundler
224
77
 
225
78
  def debug?
226
79
  return @debug_mode if defined?(@debug_mode)
227
- @debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"]
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
@@ -236,7 +89,7 @@ module Bundler
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
95
  include Molinillo::SpecificationProvider
@@ -251,9 +104,18 @@ module Bundler
251
104
  search = @search_for[dependency] ||= begin
252
105
  index = index_for(dependency)
253
106
  results = index.search(dependency, @base[dependency.name])
107
+
254
108
  if vertex = @base_dg.vertex_named(dependency.name)
255
109
  locked_requirement = vertex.payload.requirement
256
110
  end
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
+
257
119
  spec_groups = if results.any?
258
120
  nested = []
259
121
  results.each do |spec|
@@ -266,24 +128,39 @@ module Bundler
266
128
  end
267
129
  nested.reduce([]) do |groups, (version, specs)|
268
130
  next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
269
- groups << SpecGroup.new(specs)
131
+ spec_group = SpecGroup.new(specs)
132
+ spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
133
+ groups << spec_group
270
134
  end
271
135
  else
272
136
  []
273
137
  end
274
138
  # GVP handles major itself, but it's still a bit risky to trust it with it
275
139
  # until we get it settled with new behavior. For 2.x it can take over all cases.
276
- if @gem_version_promoter.major?
140
+ if !@use_gvp
277
141
  spec_groups
278
142
  else
279
143
  @gem_version_promoter.sort_versions(dependency, spec_groups)
280
144
  end
281
145
  end
282
- search.select {|sg| sg.for?(platform, @ruby_version) }.each {|sg| sg.activate_platform!(platform) }
146
+ search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
283
147
  end
284
148
 
285
149
  def index_for(dependency)
286
- @source_requirements[dependency.name] || @index
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
163
+ end
287
164
  end
288
165
 
289
166
  def name_for(dependency)
@@ -303,23 +180,58 @@ module Bundler
303
180
  end
304
181
 
305
182
  def requirement_satisfied_by?(requirement, activated, spec)
306
- requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
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
307
196
  end
308
197
 
309
198
  def sort_dependencies(dependencies, activated, conflicts)
310
199
  dependencies.sort_by do |dependency|
200
+ dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
311
201
  name = name_for(dependency)
202
+ vertex = activated.vertex_named(name)
312
203
  [
313
- activated.vertex_named(name).payload ? 0 : 1,
204
+ @base_dg.vertex_named(name) ? 0 : 1,
205
+ vertex.payload ? 0 : 1,
206
+ vertex.root? ? 0 : 1,
314
207
  amount_constrained(dependency),
315
208
  conflicts[name] ? 0 : 1,
316
- 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),
317
211
  ]
318
212
  end
319
213
  end
320
214
 
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
+
321
227
  private
322
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
323
235
  def amount_constrained(dependency)
324
236
  @amount_constrained ||= {}
325
237
  @amount_constrained[dependency.name] ||= begin
@@ -327,10 +239,12 @@ module Bundler
327
239
  dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
328
240
  else
329
241
  all = index_for(dependency).search(dependency.name).size
242
+
330
243
  if all <= 1
331
- all
244
+ all - 1_000_000
332
245
  else
333
- search = search_for(dependency).size
246
+ search = search_for(dependency)
247
+ search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
334
248
  search - all
335
249
  end
336
250
  end
@@ -339,29 +253,36 @@ module Bundler
339
253
 
340
254
  def verify_gemfile_dependencies_are_found!(requirements)
341
255
  requirements.each do |requirement|
342
- next if requirement.name == "bundler"
256
+ name = requirement.name
257
+ next if name == "bundler"
343
258
  next unless search_for(requirement).empty?
344
- if (base = @base[requirement.name]) && !base.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?
345
267
  version = base.first.version
346
268
  message = "You have requested:\n" \
347
- " #{requirement.name} #{requirement.requirement}\n\n" \
348
- "The bundle currently has #{requirement.name} locked at #{version}.\n" \
349
- "Try running `bundle update #{requirement.name}`\n\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" \
350
272
  "If you are updating multiple gems in your Gemfile at once,\n" \
351
273
  "try passing them all to `bundle update`"
352
- elsif requirement.source
353
- name = requirement.name
354
- specs = @source_requirements[name][name]
274
+ elsif source = @source_requirements[name]
275
+ specs = source.specs[name]
355
276
  versions_with_platforms = specs.map {|s| [s.version, s.platform] }
356
- message = String.new("Could not find gem '#{requirement}' in #{requirement.source}.\n")
277
+ message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
357
278
  message << if versions_with_platforms.any?
358
- "Source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
279
+ "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
359
280
  else
360
- "Source does not contain any versions of '#{requirement}'"
281
+ "The source does not contain any versions of '#{name}'"
361
282
  end
362
283
  else
363
284
  message = "Could not find gem '#{requirement}' in any of the gem sources " \
364
- "listed in your Gemfile or available on this machine."
285
+ "listed in your Gemfile#{cache_message}."
365
286
  end
366
287
  raise GemNotFound, message
367
288
  end
@@ -372,9 +293,81 @@ module Bundler
372
293
  version = vwp.first
373
294
  platform = vwp.last
374
295
  version_platform_str = String.new(version.to_s)
375
- version_platform_str << " #{platform}" unless platform.nil?
296
+ version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
297
+ version_platform_str
376
298
  end
377
299
  version_platform_strs.join(", ")
378
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
379
372
  end
380
373
  end