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,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler
3
4
  class Source
4
5
  class Path
@@ -6,6 +7,7 @@ module Bundler
6
7
  attr_reader :spec
7
8
 
8
9
  def initialize(spec, options = {})
10
+ @options = options
9
11
  @spec = spec
10
12
  @gem_dir = Bundler.rubygems.path(spec.full_gem_path)
11
13
  @wrappers = true
@@ -13,7 +15,7 @@ module Bundler
13
15
  @format_executable = options[:format_executable] || false
14
16
  @build_args = options[:build_args] || Bundler.rubygems.build_args
15
17
  @gem_bin_dir = "#{Bundler.rubygems.gem_dir}/bin"
16
- @disable_extentions = options[:disable_extensions]
18
+ @disable_extensions = options[:disable_extensions]
17
19
 
18
20
  if Bundler.requires_sudo?
19
21
  @tmp_dir = Bundler.tmp(spec.full_name).to_s
@@ -27,7 +29,7 @@ module Bundler
27
29
  SharedHelpers.chdir(@gem_dir) do
28
30
  run_hooks(:pre_install)
29
31
 
30
- unless @disable_extentions
32
+ unless @disable_extensions
31
33
  build_extensions
32
34
  run_hooks(:post_build)
33
35
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "uri"
3
4
  require "rubygems/user_interaction"
4
- require "rubygems/spec_fetcher"
5
5
 
6
6
  module Bundler
7
7
  class Source
@@ -32,6 +32,7 @@ module Bundler
32
32
  end
33
33
 
34
34
  def cached!
35
+ @specs = nil
35
36
  @allow_cached = true
36
37
  end
37
38
 
@@ -50,6 +51,7 @@ module Bundler
50
51
  end
51
52
 
52
53
  def can_lock?(spec)
54
+ return super if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
53
55
  spec.source.is_a?(Rubygems)
54
56
  end
55
57
 
@@ -70,8 +72,12 @@ module Bundler
70
72
  end
71
73
 
72
74
  def to_s
73
- remote_names = remotes.map(&:to_s).join(", ")
74
- "rubygems repository #{remote_names}"
75
+ if remotes.empty?
76
+ "locally installed gems"
77
+ else
78
+ remote_names = remotes.map(&:to_s).join(", ")
79
+ "rubygems repository #{remote_names} or installed locally"
80
+ end
75
81
  end
76
82
  alias_method :name, :to_s
77
83
 
@@ -100,8 +106,8 @@ module Bundler
100
106
  end
101
107
  end
102
108
 
103
- if installed?(spec) && (!force || spec.name.eql?("bundler"))
104
- Bundler.ui.info "Using #{version_message(spec)}"
109
+ if installed?(spec) && !force
110
+ print_using_message "Using #{version_message(spec)}"
105
111
  return nil # no post-install message
106
112
  end
107
113
 
@@ -132,6 +138,8 @@ module Bundler
132
138
  bin_path = Bundler.system_bindir
133
139
  end
134
140
 
141
+ Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
142
+
135
143
  installed_spec = nil
136
144
  Bundler.rubygems.preserve_paths do
137
145
  installed_spec = Bundler::RubyGemsGemInstaller.at(
@@ -140,7 +148,10 @@ module Bundler
140
148
  :bin_dir => bin_path.to_s,
141
149
  :ignore_dependencies => true,
142
150
  :wrappers => true,
143
- :env_shebang => true
151
+ :env_shebang => true,
152
+ :build_args => opts[:build_args],
153
+ :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum,
154
+ :bundler_extension_cache_path => extension_cache_path(spec)
144
155
  ).install
145
156
  end
146
157
  spec.full_gem_path = installed_spec.full_gem_path
@@ -211,13 +222,21 @@ module Bundler
211
222
  @remotes.unshift(uri) unless @remotes.include?(uri)
212
223
  end
213
224
 
214
- def replace_remotes(other_remotes)
225
+ def equivalent_remotes?(other_remotes)
226
+ other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
227
+ end
228
+
229
+ def replace_remotes(other_remotes, allow_equivalent = false)
215
230
  return false if other_remotes == @remotes
216
231
 
232
+ equivalent = allow_equivalent && equivalent_remotes?(other_remotes)
233
+
217
234
  @remotes = []
218
235
  other_remotes.reverse_each do |r|
219
236
  add_remote r.to_s
220
237
  end
238
+
239
+ !equivalent
221
240
  end
222
241
 
223
242
  def unmet_deps
@@ -235,6 +254,41 @@ module Bundler
235
254
  end
236
255
  end
237
256
 
257
+ def double_check_for(unmet_dependency_names)
258
+ return unless @allow_remote
259
+ return unless api_fetchers.any?
260
+
261
+ unmet_dependency_names = unmet_dependency_names.call
262
+ unless unmet_dependency_names.nil?
263
+ if api_fetchers.size <= 1
264
+ # can't do this when there are multiple fetchers because then we might not fetch from _all_
265
+ # of them
266
+ unmet_dependency_names -= remote_specs.spec_names # avoid re-fetching things we've already gotten
267
+ end
268
+ return if unmet_dependency_names.empty?
269
+ end
270
+
271
+ Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}"
272
+
273
+ fetch_names(api_fetchers, unmet_dependency_names, specs, false)
274
+ end
275
+
276
+ def dependency_names_to_double_check
277
+ names = []
278
+ remote_specs.each do |spec|
279
+ case spec
280
+ when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
281
+ names.concat(spec.runtime_dependencies)
282
+ when RemoteSpecification # from the full index
283
+ return nil
284
+ else
285
+ raise "unhandled spec type (#{spec.inspect})"
286
+ end
287
+ end
288
+ names.map!(&:name) if names
289
+ names
290
+ end
291
+
238
292
  protected
239
293
 
240
294
  def credless_remotes
@@ -275,7 +329,7 @@ module Bundler
275
329
  end
276
330
 
277
331
  def suppress_configured_credentials(remote)
278
- remote_nouser = remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
332
+ remote_nouser = remove_auth(remote)
279
333
  if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser]
280
334
  remote_nouser
281
335
  else
@@ -283,33 +337,25 @@ module Bundler
283
337
  end
284
338
  end
285
339
 
340
+ def remove_auth(remote)
341
+ if remote.user || remote.password
342
+ remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
343
+ else
344
+ remote.to_s
345
+ end
346
+ end
347
+
286
348
  def installed_specs
287
- @installed_specs ||= begin
288
- idx = Index.new
289
- have_bundler = false
349
+ @installed_specs ||= Index.build do |idx|
290
350
  Bundler.rubygems.all_specs.reverse_each do |spec|
291
- next if spec.name == "bundler" && spec.version.to_s != VERSION
292
- have_bundler = true if spec.name == "bundler"
351
+ next if spec.name == "bundler"
293
352
  spec.source = self
294
- idx << spec
295
- end
296
-
297
- # Always have bundler locally
298
- unless have_bundler
299
- # We're running bundler directly from the source
300
- # so, let's create a fake gemspec for it (it's a path)
301
- # gemspec
302
- bundler = Gem::Specification.new do |s|
303
- s.name = "bundler"
304
- s.version = VERSION
305
- s.platform = Gem::Platform::RUBY
306
- s.source = self
307
- s.authors = ["bundler team"]
308
- s.loaded_from = File.expand_path("..", __FILE__)
353
+ if Bundler.rubygems.spec_missing_extensions?(spec, false)
354
+ Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
355
+ next
309
356
  end
310
- idx << bundler
357
+ idx << spec
311
358
  end
312
- idx
313
359
  end
314
360
  end
315
361
 
@@ -321,11 +367,15 @@ module Bundler
321
367
  next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
322
368
  s ||= Bundler.rubygems.spec_from_gem(gemfile)
323
369
  s.source = self
370
+ if Bundler.rubygems.spec_missing_extensions?(s, false)
371
+ Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
372
+ next
373
+ end
324
374
  idx << s
325
375
  end
326
- end
327
376
 
328
- idx
377
+ idx
378
+ end
329
379
  end
330
380
 
331
381
  def api_fetchers
@@ -337,69 +387,35 @@ module Bundler
337
387
  index_fetchers = fetchers - api_fetchers
338
388
 
339
389
  # gather lists from non-api sites
340
- index_fetchers.each do |f|
341
- Bundler.ui.info "Fetching source index from #{f.uri}"
342
- idx.use f.specs_with_retry(nil, self)
343
- end
390
+ fetch_names(index_fetchers, nil, idx, false)
344
391
 
345
392
  # because ensuring we have all the gems we need involves downloading
346
393
  # the gemspecs of those gems, if the non-api sites contain more than
347
- # about 100 gems, we treat all sites as non-api for speed.
394
+ # about 500 gems, we treat all sites as non-api for speed.
348
395
  allow_api = idx.size < API_REQUEST_LIMIT && dependency_names.size < API_REQUEST_LIMIT
349
396
  Bundler.ui.debug "Need to query more than #{API_REQUEST_LIMIT} gems." \
350
397
  " Downloading full index instead..." unless allow_api
351
398
 
352
- if allow_api
353
- api_fetchers.each do |f|
354
- Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
355
- idx.use f.specs_with_retry(dependency_names, self)
356
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
357
- end
358
-
359
- # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
360
- # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
361
- # but will not have found any versions of Bar from source B, which is a problem if the requested version
362
- # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
363
- # each spec we found, we add all possible versions from all sources to the index.
364
- loop do
365
- idxcount = idx.size
366
- api_fetchers.each do |f|
367
- Bundler.ui.info "Fetching version metadata from #{f.uri}", Bundler.ui.debug?
368
- idx.use f.specs_with_retry(idx.dependency_names, self), true
369
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
370
- end
371
- break if idxcount == idx.size
372
- end
373
-
374
- if api_fetchers.any?
375
- # it's possible that gems from one source depend on gems from some
376
- # other source, so now we download gemspecs and iterate over those
377
- # dependencies, looking for gems we don't have info on yet.
378
- unmet = idx.unmet_dependency_names
379
-
380
- # if there are any cross-site gems we missed, get them now
381
- api_fetchers.each do |f|
382
- Bundler.ui.info "Fetching dependency metadata from #{f.uri}", Bundler.ui.debug?
383
- idx.use f.specs_with_retry(unmet, self)
384
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
385
- end if unmet.any?
386
- else
387
- allow_api = false
388
- end
389
- end
399
+ fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
400
+ end
401
+ end
390
402
 
391
- unless allow_api
392
- api_fetchers.each do |f|
393
- Bundler.ui.info "Fetching source index from #{f.uri}"
394
- idx.use f.specs_with_retry(nil, self)
395
- end
403
+ def fetch_names(fetchers, dependency_names, index, override_dupes)
404
+ fetchers.each do |f|
405
+ if dependency_names
406
+ Bundler.ui.info "Fetching gem metadata from #{f.uri}", Bundler.ui.debug?
407
+ index.use f.specs_with_retry(dependency_names, self), override_dupes
408
+ Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
409
+ else
410
+ Bundler.ui.info "Fetching source index from #{f.uri}"
411
+ index.use f.specs_with_retry(nil, self), override_dupes
396
412
  end
397
413
  end
398
414
  end
399
415
 
400
416
  def fetch_gem(spec)
401
417
  return false unless spec.remote
402
- uri = spec.remote.uri
418
+
403
419
  spec.fetch_platform
404
420
 
405
421
  download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
@@ -408,7 +424,7 @@ module Bundler
408
424
  SharedHelpers.filesystem_access("#{download_path}/cache") do |p|
409
425
  FileUtils.mkdir_p(p)
410
426
  end
411
- Bundler.rubygems.download_gem(spec, uri, download_path)
427
+ download_gem(spec, download_path)
412
428
 
413
429
  if requires_sudo?
414
430
  SharedHelpers.filesystem_access("#{rubygems_dir}/cache") do |p|
@@ -445,6 +461,79 @@ module Bundler
445
461
  def cache_path
446
462
  Bundler.app_cache
447
463
  end
464
+
465
+ private
466
+
467
+ # Checks if the requested spec exists in the global cache. If it does,
468
+ # we copy it to the download path, and if it does not, we download it.
469
+ #
470
+ # @param [Specification] spec
471
+ # the spec we want to download or retrieve from the cache.
472
+ #
473
+ # @param [String] download_path
474
+ # the local directory the .gem will end up in.
475
+ #
476
+ def download_gem(spec, download_path)
477
+ local_path = File.join(download_path, "cache/#{spec.full_name}.gem")
478
+
479
+ if (cache_path = download_cache_path(spec)) && cache_path.file?
480
+ SharedHelpers.filesystem_access(local_path) do
481
+ FileUtils.cp(cache_path, local_path)
482
+ end
483
+ else
484
+ uri = spec.remote.uri
485
+ Bundler.ui.confirm("Fetching #{version_message(spec)}")
486
+ rubygems_local_path = Bundler.rubygems.download_gem(spec, uri, download_path)
487
+ if rubygems_local_path != local_path
488
+ FileUtils.mv(rubygems_local_path, local_path)
489
+ end
490
+ cache_globally(spec, local_path)
491
+ end
492
+ end
493
+
494
+ # Checks if the requested spec exists in the global cache. If it does
495
+ # not, we create the relevant global cache subdirectory if it does not
496
+ # exist and copy the spec from the local cache to the global cache.
497
+ #
498
+ # @param [Specification] spec
499
+ # the spec we want to copy to the global cache.
500
+ #
501
+ # @param [String] local_cache_path
502
+ # the local directory from which we want to copy the .gem.
503
+ #
504
+ def cache_globally(spec, local_cache_path)
505
+ return unless cache_path = download_cache_path(spec)
506
+ return if cache_path.exist?
507
+
508
+ SharedHelpers.filesystem_access(cache_path.dirname, &:mkpath)
509
+ SharedHelpers.filesystem_access(cache_path) do
510
+ FileUtils.cp(local_cache_path, cache_path)
511
+ end
512
+ end
513
+
514
+ # Returns the global cache path of the calling Rubygems::Source object.
515
+ #
516
+ # Note that the Source determines the path's subdirectory. We use this
517
+ # subdirectory in the global cache path so that gems with the same name
518
+ # -- and possibly different versions -- from different sources are saved
519
+ # to their respective subdirectories and do not override one another.
520
+ #
521
+ # @param [Gem::Specification] specification
522
+ #
523
+ # @return [Pathname] The global cache path.
524
+ #
525
+ def download_cache_path(spec)
526
+ return unless Bundler.feature_flag.global_gem_cache?
527
+ return unless remote = spec.remote
528
+ return unless cache_slug = remote.cache_slug
529
+
530
+ Bundler.user_cache.join("gems", cache_slug, spec.file_name)
531
+ end
532
+
533
+ def extension_cache_slug(spec)
534
+ return unless remote = spec.remote
535
+ remote.cache_slug
536
+ end
448
537
  end
449
538
  end
450
539
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler
3
4
  class Source
4
5
  class Rubygems
@@ -20,16 +21,25 @@ module Bundler
20
21
  #
21
22
  def cache_slug
22
23
  @cache_slug ||= begin
24
+ return nil unless SharedHelpers.md5_available?
25
+
23
26
  cache_uri = original_uri || uri
24
27
 
25
- uri_parts = [cache_uri.host, cache_uri.user, cache_uri.port, cache_uri.path]
26
- uri_digest = Digest::MD5.hexdigest(uri_parts.compact.join("."))
28
+ # URI::File of Ruby 2.6 returns empty string when given "file://".
29
+ host = defined?(URI::File) && cache_uri.is_a?(URI::File) ? nil : cache_uri.host
30
+
31
+ uri_parts = [host, cache_uri.user, cache_uri.port, cache_uri.path]
32
+ uri_digest = SharedHelpers.digest(:MD5).hexdigest(uri_parts.compact.join("."))
27
33
 
28
34
  uri_parts[-1] = uri_digest
29
35
  uri_parts.compact.join(".")
30
36
  end
31
37
  end
32
38
 
39
+ def to_s
40
+ "rubygems remote at #{anonymized_uri}"
41
+ end
42
+
33
43
  private
34
44
 
35
45
  def apply_auth(uri, auth)
@@ -1,16 +1,21 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Bundler
3
4
  class SourceList
4
5
  attr_reader :path_sources,
5
6
  :git_sources,
6
- :plugin_sources
7
+ :plugin_sources,
8
+ :global_rubygems_source,
9
+ :metadata_source
7
10
 
8
11
  def initialize
9
- @path_sources = []
10
- @git_sources = []
11
- @plugin_sources = []
12
- @rubygems_aggregate = Source::Rubygems.new
13
- @rubygems_sources = []
12
+ @path_sources = []
13
+ @git_sources = []
14
+ @plugin_sources = []
15
+ @global_rubygems_source = nil
16
+ @rubygems_aggregate = rubygems_aggregate_class.new
17
+ @rubygems_sources = []
18
+ @metadata_source = Source::Metadata.new
14
19
  end
15
20
 
16
21
  def add_path_source(options = {})
@@ -35,13 +40,28 @@ module Bundler
35
40
  add_source_to_list Plugin.source(source).new(options), @plugin_sources
36
41
  end
37
42
 
43
+ def global_rubygems_source=(uri)
44
+ if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
45
+ @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
46
+ end
47
+ add_rubygems_remote(uri)
48
+ end
49
+
38
50
  def add_rubygems_remote(uri)
51
+ if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
52
+ return if Bundler.feature_flag.disable_multisource?
53
+ raise InvalidOption, "`lockfile_uses_separate_rubygems_sources` cannot be set without `disable_multisource` being set"
54
+ end
39
55
  @rubygems_aggregate.add_remote(uri)
40
56
  @rubygems_aggregate
41
57
  end
42
58
 
59
+ def default_source
60
+ global_rubygems_source || @rubygems_aggregate
61
+ end
62
+
43
63
  def rubygems_sources
44
- @rubygems_sources + [@rubygems_aggregate]
64
+ @rubygems_sources + [default_source]
45
65
  end
46
66
 
47
67
  def rubygems_remotes
@@ -49,18 +69,25 @@ module Bundler
49
69
  end
50
70
 
51
71
  def all_sources
52
- path_sources + git_sources + plugin_sources + rubygems_sources
72
+ path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
53
73
  end
54
74
 
55
75
  def get(source)
56
- source_list_for(source).find {|s| source == s }
76
+ source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) }
57
77
  end
58
78
 
59
79
  def lock_sources
60
- lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
61
- lock_sources << combine_rubygems_sources
80
+ if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
81
+ [[default_source], @rubygems_sources, git_sources, path_sources, plugin_sources].map do |sources|
82
+ sources.sort_by(&:to_s)
83
+ end.flatten(1)
84
+ else
85
+ lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
86
+ lock_sources << combine_rubygems_sources
87
+ end
62
88
  end
63
89
 
90
+ # Returns true if there are changes
64
91
  def replace_sources!(replacement_sources)
65
92
  return true if replacement_sources.empty?
66
93
 
@@ -70,13 +97,14 @@ module Bundler
70
97
  end
71
98
  end
72
99
 
73
- replacement_rubygems =
100
+ replacement_rubygems = !Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? &&
74
101
  replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
75
102
  @rubygems_aggregate = replacement_rubygems if replacement_rubygems
76
103
 
77
- # Return true if there were changes
78
- lock_sources.to_set != replacement_sources.to_set ||
79
- rubygems_remotes.to_set != replacement_rubygems.remotes.to_set
104
+ return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
105
+ return true if replacement_rubygems && rubygems_remotes.to_set != replacement_rubygems.remotes.to_set
106
+
107
+ false
80
108
  end
81
109
 
82
110
  def cached!
@@ -93,6 +121,10 @@ module Bundler
93
121
 
94
122
  private
95
123
 
124
+ def rubygems_aggregate_class
125
+ Source::Rubygems
126
+ end
127
+
96
128
  def add_source_to_list(source, list)
97
129
  list.unshift(source).uniq!
98
130
  source
@@ -122,5 +154,33 @@ module Bundler
122
154
  "protocol to keep your data secure."
123
155
  end
124
156
  end
157
+
158
+ def equal_sources?(lock_sources, replacement_sources)
159
+ lock_sources.to_set == replacement_sources.to_set
160
+ end
161
+
162
+ def equal_source?(source, other_source)
163
+ source == other_source
164
+ end
165
+
166
+ def equivalent_source?(source, other_source)
167
+ return false unless Bundler.settings[:allow_deployment_source_credential_changes] && source.is_a?(Source::Rubygems)
168
+
169
+ equivalent_rubygems_sources?([source], [other_source])
170
+ end
171
+
172
+ def equivalent_sources?(lock_sources, replacement_sources)
173
+ return false unless Bundler.settings[:allow_deployment_source_credential_changes]
174
+
175
+ lock_rubygems_sources, lock_other_sources = lock_sources.partition {|s| s.is_a?(Source::Rubygems) }
176
+ replacement_rubygems_sources, replacement_other_sources = replacement_sources.partition {|s| s.is_a?(Source::Rubygems) }
177
+
178
+ equivalent_rubygems_sources?(lock_rubygems_sources, replacement_rubygems_sources) && equal_sources?(lock_other_sources, replacement_other_sources)
179
+ end
180
+
181
+ def equivalent_rubygems_sources?(lock_sources, replacement_sources)
182
+ actual_remotes = replacement_sources.map(&:remotes).flatten.uniq
183
+ lock_sources.all? {|s| s.equivalent_remotes?(actual_remotes) }
184
+ end
125
185
  end
126
186
  end