bundler 2.2.13 → 2.2.18

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +85 -5
  3. data/bundler.gemspec +2 -3
  4. data/lib/bundler.rb +1 -0
  5. data/lib/bundler/build_metadata.rb +2 -2
  6. data/lib/bundler/cli.rb +16 -35
  7. data/lib/bundler/cli/common.rb +15 -2
  8. data/lib/bundler/cli/gem.rb +9 -1
  9. data/lib/bundler/cli/outdated.rb +8 -11
  10. data/lib/bundler/compact_index_client/updater.rb +10 -6
  11. data/lib/bundler/current_ruby.rb +1 -0
  12. data/lib/bundler/definition.rb +40 -87
  13. data/lib/bundler/dsl.rb +3 -6
  14. data/lib/bundler/feature_flag.rb +0 -2
  15. data/lib/bundler/fetcher.rb +2 -1
  16. data/lib/bundler/fetcher/downloader.rb +8 -4
  17. data/lib/bundler/friendly_errors.rb +1 -1
  18. data/lib/bundler/gem_helper.rb +16 -0
  19. data/lib/bundler/index.rb +1 -2
  20. data/lib/bundler/injector.rb +2 -2
  21. data/lib/bundler/inline.rb +1 -1
  22. data/lib/bundler/installer/parallel_installer.rb +36 -15
  23. data/lib/bundler/lazy_specification.rb +6 -1
  24. data/lib/bundler/lockfile_parser.rb +2 -16
  25. data/lib/bundler/man/bundle-add.1 +1 -1
  26. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  27. data/lib/bundler/man/bundle-cache.1 +1 -1
  28. data/lib/bundler/man/bundle-check.1 +1 -1
  29. data/lib/bundler/man/bundle-clean.1 +1 -1
  30. data/lib/bundler/man/bundle-config.1 +21 -10
  31. data/lib/bundler/man/bundle-config.1.ronn +21 -11
  32. data/lib/bundler/man/bundle-doctor.1 +1 -1
  33. data/lib/bundler/man/bundle-exec.1 +1 -1
  34. data/lib/bundler/man/bundle-gem.1 +1 -1
  35. data/lib/bundler/man/bundle-info.1 +1 -1
  36. data/lib/bundler/man/bundle-init.1 +1 -1
  37. data/lib/bundler/man/bundle-inject.1 +1 -1
  38. data/lib/bundler/man/bundle-install.1 +1 -1
  39. data/lib/bundler/man/bundle-list.1 +1 -1
  40. data/lib/bundler/man/bundle-lock.1 +1 -1
  41. data/lib/bundler/man/bundle-open.1 +1 -1
  42. data/lib/bundler/man/bundle-outdated.1 +1 -1
  43. data/lib/bundler/man/bundle-platform.1 +1 -1
  44. data/lib/bundler/man/bundle-pristine.1 +1 -1
  45. data/lib/bundler/man/bundle-remove.1 +1 -1
  46. data/lib/bundler/man/bundle-show.1 +1 -1
  47. data/lib/bundler/man/bundle-update.1 +1 -1
  48. data/lib/bundler/man/bundle-viz.1 +1 -1
  49. data/lib/bundler/man/bundle.1 +1 -1
  50. data/lib/bundler/man/gemfile.5 +1 -1
  51. data/lib/bundler/plugin.rb +2 -2
  52. data/lib/bundler/plugin/api/source.rb +21 -0
  53. data/lib/bundler/resolver.rb +13 -96
  54. data/lib/bundler/resolver/spec_group.rb +0 -24
  55. data/lib/bundler/retry.rb +1 -1
  56. data/lib/bundler/rubygems_ext.rb +2 -2
  57. data/lib/bundler/settings.rb +60 -11
  58. data/lib/bundler/source.rb +15 -0
  59. data/lib/bundler/source/metadata.rb +0 -4
  60. data/lib/bundler/source/path.rb +3 -1
  61. data/lib/bundler/source/path/installer.rb +1 -1
  62. data/lib/bundler/source/rubygems.rb +37 -10
  63. data/lib/bundler/source/rubygems_aggregate.rb +64 -0
  64. data/lib/bundler/source_list.rb +37 -8
  65. data/lib/bundler/source_map.rb +58 -0
  66. data/lib/bundler/spec_set.rb +18 -5
  67. data/lib/bundler/templates/Gemfile +1 -1
  68. data/lib/bundler/templates/gems.rb +1 -1
  69. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -4
  70. data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
  71. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
  72. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +1 -1
  73. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  74. data/lib/bundler/version.rb +1 -1
  75. metadata +9 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4227db15ba56c781814845c3e7c2811def8bba66c074098d04496cf3f7ce3ed
4
- data.tar.gz: '0295d490ed0dcf0989468a1a25b3b233c618006882757cbbf5a99e179b009568'
3
+ metadata.gz: f6d906edb7a9048324bea1cb57d8f5c6a3624f12f6333231cdba75b3b90c780f
4
+ data.tar.gz: 0e622ba68d42202c59c1a4ada4e6e01fd004fac72ccb4b84b5085b0c59e60aba
5
5
  SHA512:
6
- metadata.gz: fa78e4e46d7b7fe666950c26fd47df524d7af57612c4e584e088a7a10aa140db5eb243b0688f993dc3586a7b5c4cb2357488a237715b618891747b328d94d01a
7
- data.tar.gz: f1baab0b6a8b0c9ccf1c9bdafb7e6068252ba8fac05f96f50540320f47d4da8fa42ecae264e7b082fc1c50d4c0ff7cb456a928b2ffb07d0ca79e84d6272d1b54
6
+ metadata.gz: b76743e7abb16ca1feb285932b5761b872ecc1a03fb826fe32b624f714989a5f25050ba9ff43d59b2492657069d2216e4aa4ca4ba7b9302e1e13452494b2ec48
7
+ data.tar.gz: ffde8ec8ad9167dbe2f48d03a2fe7ee8c142e8e31101e8b2900e1c519681a995c670607ffd09dbeaca587e0072448b545e93686c7e81b6fbeb7c571f72393944
data/CHANGELOG.md CHANGED
@@ -1,3 +1,83 @@
1
+ # 2.2.18 (May 25, 2021)
2
+
3
+ ## Security fixes:
4
+
5
+ - Fix dependency confusion issues with implicit dependencies [#4609](https://github.com/rubygems/rubygems/pull/4609)
6
+
7
+ ## Enhancements:
8
+
9
+ - Use simpler notation for generated `required_ruby_version` [#4598](https://github.com/rubygems/rubygems/pull/4598)
10
+ - Undeprecate bundle show [#4586](https://github.com/rubygems/rubygems/pull/4586)
11
+ - Make sure link to new issue uses the proper template [#4592](https://github.com/rubygems/rubygems/pull/4592)
12
+
13
+ ## Bug fixes:
14
+
15
+ - Fix platform specific gems being removed from the lockfile [#4580](https://github.com/rubygems/rubygems/pull/4580)
16
+
17
+ # 2.2.17 (May 5, 2021)
18
+
19
+ ## Enhancements:
20
+
21
+ - Improve authentication required error message to include an alternative using `ENV` [#4565](https://github.com/rubygems/rubygems/pull/4565)
22
+ - Discard partial range responses without etag [#4563](https://github.com/rubygems/rubygems/pull/4563)
23
+ - Fix configuring ENV for a gem server with a name including dashes [#4571](https://github.com/rubygems/rubygems/pull/4571)
24
+ - Redact credentials from `bundle env` and `bundle config` [#4566](https://github.com/rubygems/rubygems/pull/4566)
25
+ - Redact all sources in verbose mode [#4564](https://github.com/rubygems/rubygems/pull/4564)
26
+ - Improve `bundle pristine` error if `BUNDLE_GEMFILE` does not exist [#4536](https://github.com/rubygems/rubygems/pull/4536)
27
+ - [CurrentRuby] Add 3.0 as a known minor [#4535](https://github.com/rubygems/rubygems/pull/4535)
28
+ - Prefer File.read instead of IO.read [#4530](https://github.com/rubygems/rubygems/pull/4530)
29
+ - Add space after open curly bracket in Gemfile and gems.rb template [#4518](https://github.com/rubygems/rubygems/pull/4518)
30
+
31
+ ## Bug fixes:
32
+
33
+ - Make sure specs are fetched from the right source when materializing [#4562](https://github.com/rubygems/rubygems/pull/4562)
34
+ - Fix `bundle cache` with an up-to-date lockfile and specs not already installed [#4554](https://github.com/rubygems/rubygems/pull/4554)
35
+ - Ignore `deployment` setting in inline mode [#4523](https://github.com/rubygems/rubygems/pull/4523)
36
+
37
+ ## Performance:
38
+
39
+ - Don't materialize resolutions when not necessary [#4556](https://github.com/rubygems/rubygems/pull/4556)
40
+
41
+ # 2.2.16 (April 8, 2021)
42
+
43
+ ## Enhancements:
44
+
45
+ - Add `--github-username` option and config to `bundle gem` [#3687](https://github.com/rubygems/rubygems/pull/3687)
46
+ - Bump vendored `tmpdir` library copy [#4506](https://github.com/rubygems/rubygems/pull/4506)
47
+ - Add `rake build:checksum` task to build checksums for a gem package [#4156](https://github.com/rubygems/rubygems/pull/4156)
48
+ - Enable bundler-cache for GitHub Actions template [#4498](https://github.com/rubygems/rubygems/pull/4498)
49
+ - Improve `bundle info` error when gem is on a "disabled" group [#4492](https://github.com/rubygems/rubygems/pull/4492)
50
+ - Small tweak to yank message [#4494](https://github.com/rubygems/rubygems/pull/4494)
51
+ - Don't show duplicate entries in `bundle outdated` output [#4474](https://github.com/rubygems/rubygems/pull/4474)
52
+ - Never downgrade top level gems when running `bundle update` [#4473](https://github.com/rubygems/rubygems/pull/4473)
53
+
54
+ ## Bug fixes:
55
+
56
+ - Fix incorrect logic for filtering metadata matching candidates [#4497](https://github.com/rubygems/rubygems/pull/4497)
57
+
58
+ # 2.2.15 (March 19, 2021)
59
+
60
+ ## Enhancements:
61
+
62
+ - Add a hint about bundler installing executables for path gems [#4461](https://github.com/rubygems/rubygems/pull/4461)
63
+ - Warn lockfiles with incorrect resolutions [#4459](https://github.com/rubygems/rubygems/pull/4459)
64
+ - Don't generate duplicate redundant sources in the lockfile [#4456](https://github.com/rubygems/rubygems/pull/4456)
65
+
66
+ ## Bug fixes:
67
+
68
+ - Respect running ruby when resolving platforms [#4449](https://github.com/rubygems/rubygems/pull/4449)
69
+
70
+ # 2.2.14 (March 8, 2021)
71
+
72
+ ## Security fixes:
73
+
74
+ - Lock GEM sources separately and fix locally installed specs confusing bundler [#4381](https://github.com/rubygems/rubygems/pull/4381)
75
+
76
+ ## Bug fixes:
77
+
78
+ - Make `rake` available to other gems' installers right after it's installed [#4428](https://github.com/rubygems/rubygems/pull/4428)
79
+ - Fix encoding issue on compact index updater [#4362](https://github.com/rubygems/rubygems/pull/4362)
80
+
1
81
  # 2.2.13 (March 3, 2021)
2
82
 
3
83
  ## Enhancements:
@@ -432,7 +512,7 @@
432
512
  - Ignore `frozen` setting in inline mode ([#7125](https://github.com/rubygems/bundler/pull/7125))
433
513
  - Fix incorrect "bundler attempted to update GEM but version stayed the same" message when updating git sourced gems ([#6325](https://github.com/rubygems/bundler/pull/6325))
434
514
  - Don't check for existence of a writable home directory if `BUNDLE_USER_HOME` is set ([#6885](https://github.com/rubygems/bundler/pull/6885))
435
- - Fix error message when server would respond to a bad username/password requiest with a 401 ([#6928](https://github.com/rubygems/bundler/pull/6928))
515
+ - Fix error message when server would respond to a bad username/password request with a 401 ([#6928](https://github.com/rubygems/bundler/pull/6928))
436
516
  - Fix `bundle outdated` pluralization when multiple groups are requested ([#7063](https://github.com/rubygems/bundler/pull/7063))
437
517
  - Fix `bundle install` not updating conservatively when gemspec is changed ([#7143](https://github.com/rubygems/bundler/pull/7143))
438
518
  - Fix `bundle exec` not respecting custom process titles inside scripts ([#7140](https://github.com/rubygems/bundler/pull/7140))
@@ -2077,7 +2157,7 @@ Changes
2077
2157
  - fix Bundler.which for directories ([#2697](https://github.com/rubygems/bundler/issues/2697), @rhysd)
2078
2158
  - properly require `Capistrano::Version` ([#2690](https://github.com/rubygems/bundler/issues/2690), @steveklabnik)
2079
2159
  - search for git.exe and git
2080
- - fix the bug that downloads every spec when API fetcher encouters an error
2160
+ - fix the bug that downloads every spec when API fetcher encounters an error
2081
2161
  - only retry network requests
2082
2162
 
2083
2163
  # 1.4.0.rc.1 (September 29, 2013)
@@ -2701,7 +2781,7 @@ Changes
2701
2781
 
2702
2782
  - Implement `to_ary` to avoid calls to method_missing (@tenderlove, [#1274](https://github.com/rubygems/bundler/issues/1274))
2703
2783
  - bundle clean removes old .gem files (@cldwalker, [#1293](https://github.com/rubygems/bundler/issues/1293))
2704
- - Correcly identify missing child dependency in error message
2784
+ - Correctly identify missing child dependency in error message
2705
2785
  - Run pre-install, post-build, and post-install gem hooks for git gems (@warhammerkid, [#1120](https://github.com/rubygems/bundler/issues/1120))
2706
2786
  - create Gemfile.lock for empty Gemfile ([#1218](https://github.com/rubygems/bundler/issues/1218))
2707
2787
 
@@ -2852,7 +2932,7 @@ Changes
2852
2932
 
2853
2933
  - Performance fix for MRI 1.9 (@efficientcloud, [#1288](https://github.com/rubygems/bundler/issues/1288))
2854
2934
  - Shortcuts (like `bundle i`) for all commands (@amatsuda)
2855
- - Correcly identify missing child dependency in error message
2935
+ - Correctly identify missing child dependency in error message
2856
2936
 
2857
2937
  ## Bug fixes:
2858
2938
 
@@ -3088,7 +3168,7 @@ Changes
3088
3168
 
3089
3169
  - Various bugfixes to the built-in rake helpers
3090
3170
  - Fix a bug where shortrefs weren't unique enough and were
3091
- therfore colliding
3171
+ therefore colliding
3092
3172
  - Fix a small bug involving checking whether a local git
3093
3173
  clone is up to date
3094
3174
  - Correctly handle explicit '=' dependencies with gems
data/bundler.gemspec CHANGED
@@ -34,13 +34,12 @@ Gem::Specification.new do |s|
34
34
  s.required_ruby_version = ">= 2.3.0"
35
35
  s.required_rubygems_version = ">= 2.5.2"
36
36
 
37
- s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
37
+ s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
38
38
 
39
- # Include the CHANGELOG.md, LICENSE.md, README.md manually
40
- s.files += %w[CHANGELOG.md LICENSE.md README.md]
41
39
  # include the gemspec itself because warbler breaks w/o it
42
40
  s.files += %w[bundler.gemspec]
43
41
 
42
+ s.extra_rdoc_files = %w[CHANGELOG.md LICENSE.md README.md]
44
43
  s.bindir = "exe"
45
44
  s.executables = %w[bundle bundler]
46
45
  s.require_paths = ["lib"]
data/lib/bundler.rb CHANGED
@@ -69,6 +69,7 @@ module Bundler
69
69
  autoload :SharedHelpers, File.expand_path("bundler/shared_helpers", __dir__)
70
70
  autoload :Source, File.expand_path("bundler/source", __dir__)
71
71
  autoload :SourceList, File.expand_path("bundler/source_list", __dir__)
72
+ autoload :SourceMap, File.expand_path("bundler/source_map", __dir__)
72
73
  autoload :SpecSet, File.expand_path("bundler/spec_set", __dir__)
73
74
  autoload :StubSpecification, File.expand_path("bundler/stub_specification", __dir__)
74
75
  autoload :UI, File.expand_path("bundler/ui", __dir__)
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = "2021-03-03".freeze
8
- @git_commit_sha = "9b15ab18c4".freeze
7
+ @built_at = "2021-05-25".freeze
8
+ @git_commit_sha = "6a9e89bacd".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
data/lib/bundler/cli.rb CHANGED
@@ -308,39 +308,19 @@ module Bundler
308
308
  end
309
309
  end
310
310
 
311
- unless Bundler.feature_flag.bundler_3_mode?
312
- desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
313
- long_desc <<-D
314
- Show lists the names and versions of all gems that are required by your Gemfile.
315
- Calling show with [GEM] will list the exact location of that gem on your machine.
316
- D
317
- method_option "paths", :type => :boolean,
318
- :banner => "List the paths of all gems that are required by your Gemfile."
319
- method_option "outdated", :type => :boolean,
320
- :banner => "Show verbose output including whether gems are outdated."
321
- def show(gem_name = nil)
322
- if ARGV[0] == "show"
323
- rest = ARGV[1..-1]
324
-
325
- if flag = rest.find{|arg| ["--verbose", "--outdated"].include?(arg) }
326
- Bundler::SharedHelpers.major_deprecation(2, "the `#{flag}` flag to `bundle show` was undocumented and will be removed without replacement")
327
- else
328
- new_command = rest.find {|arg| !arg.start_with?("--") } ? "info" : "list"
329
-
330
- new_arguments = rest.map do |arg|
331
- next arg if arg != "--paths"
332
- next "--path" if new_command == "info"
333
- end
334
-
335
- old_argv = ARGV.join(" ")
336
- new_argv = [new_command, *new_arguments.compact].join(" ")
337
-
338
- Bundler::SharedHelpers.major_deprecation(2, "use `bundle #{new_argv}` instead of `bundle #{old_argv}`")
339
- end
340
- end
341
- require_relative "cli/show"
342
- Show.new(options, gem_name).run
343
- end
311
+ desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
312
+ long_desc <<-D
313
+ Show lists the names and versions of all gems that are required by your Gemfile.
314
+ Calling show with [GEM] will list the exact location of that gem on your machine.
315
+ D
316
+ method_option "paths", :type => :boolean,
317
+ :banner => "List the paths of all gems that are required by your Gemfile."
318
+ method_option "outdated", :type => :boolean,
319
+ :banner => "Show verbose output including whether gems are outdated."
320
+ def show(gem_name = nil)
321
+ SharedHelpers.major_deprecation(2, "the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement") if ARGV.include?("--outdated")
322
+ require_relative "cli/show"
323
+ Show.new(options, gem_name).run
344
324
  end
345
325
 
346
326
  desc "list", "List all gems in the bundle"
@@ -504,8 +484,8 @@ module Bundler
504
484
  By default, setting a configuration value sets it for all projects
505
485
  on the machine.
506
486
 
507
- If a global setting is superceded by local configuration, this command
508
- will show the current value, as well as any superceded values and
487
+ If a global setting is superseded by local configuration, this command
488
+ will show the current value, as well as any superseded values and
509
489
  where they were specified.
510
490
  D
511
491
  require_relative "cli/config"
@@ -591,6 +571,7 @@ module Bundler
591
571
  :desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
592
572
  method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
593
573
  :desc => "Generate CI configuration, either GitHub Actions, Travis CI, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|travis|gitlab|circle)`"
574
+ method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
594
575
 
595
576
  def gem(name)
596
577
  end
@@ -36,10 +36,15 @@ module Bundler
36
36
  def self.without_groups_message(command)
37
37
  command_in_past_tense = command == :install ? "installed" : "updated"
38
38
  groups = Bundler.settings[:without]
39
+ "Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}."
40
+ end
41
+
42
+ def self.verbalize_groups(groups)
43
+ groups.map!{|g| "'#{g}'" }
39
44
  group_list = [groups[0...-1].join(", "), groups[-1..-1]].
40
45
  reject {|s| s.to_s.empty? }.join(" and ")
41
46
  group_str = groups.size == 1 ? "group" : "groups"
42
- "Gems in the #{group_str} #{group_list} were not #{command_in_past_tense}."
47
+ "#{group_str} #{group_list}"
43
48
  end
44
49
 
45
50
  def self.select_spec(name, regex_match = nil)
@@ -53,7 +58,13 @@ module Bundler
53
58
 
54
59
  case specs.count
55
60
  when 0
56
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
61
+ dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name }
62
+
63
+ if dep_in_other_group
64
+ raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored."
65
+ else
66
+ raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
67
+ end
57
68
  when 1
58
69
  specs.first
59
70
  else
@@ -83,6 +94,8 @@ module Bundler
83
94
  end
84
95
 
85
96
  def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems)
97
+ return unless locked_gems
98
+
86
99
  locked_names = locked_gems.specs.map(&:name).uniq
87
100
  names.-(locked_names).each do |g|
88
101
  raise GemNotFound, gem_not_found_message(g, locked_names)
@@ -42,9 +42,17 @@ module Bundler
42
42
  use_git = Bundler.git_present? && options[:git]
43
43
 
44
44
  git_author_name = use_git ? `git config user.name`.chomp : ""
45
- github_username = use_git ? `git config github.user`.chomp : ""
45
+ git_username = use_git ? `git config github.user`.chomp : ""
46
46
  git_user_email = use_git ? `git config user.email`.chomp : ""
47
47
 
48
+ github_username = if options[:github_username].nil?
49
+ git_username
50
+ elsif options[:github_username] == false
51
+ ""
52
+ else
53
+ options[:github_username]
54
+ end
55
+
48
56
  config = {
49
57
  :name => name,
50
58
  :underscored_name => underscored_name,
@@ -72,7 +72,7 @@ module Bundler
72
72
  gemfile_specs + dependency_specs
73
73
  end
74
74
 
75
- specs.sort_by(&:name).each do |current_spec|
75
+ specs.sort_by(&:name).uniq(&:name).each do |current_spec|
76
76
  next unless gems.empty? || gems.include?(current_spec.name)
77
77
 
78
78
  active_spec = retrieve_active_spec(definition, current_spec)
@@ -146,17 +146,14 @@ module Bundler
146
146
  end
147
147
 
148
148
  def retrieve_active_spec(definition, current_spec)
149
- if strict
150
- active_spec = definition.find_resolved_spec(current_spec)
151
- else
152
- active_specs = definition.find_indexed_specs(current_spec)
153
- if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
154
- active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
155
- end
156
- active_spec = active_specs.last
157
- end
149
+ active_spec = definition.resolve.find_by_name_and_platform(current_spec.name, current_spec.platform)
150
+ return active_spec if strict
158
151
 
159
- active_spec
152
+ active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
153
+ if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
154
+ active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
155
+ end
156
+ active_specs.last
160
157
  end
161
158
 
162
159
  def print_gems(gems_list)
@@ -50,16 +50,20 @@ module Bundler
50
50
 
51
51
  content = response.body
52
52
 
53
- SharedHelpers.filesystem_access(local_temp_path) do
53
+ etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
54
+ correct_response = SharedHelpers.filesystem_access(local_temp_path) do
54
55
  if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
55
56
  local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
57
+
58
+ etag_for(local_temp_path) == etag
56
59
  else
57
- local_temp_path.open("w") {|f| f << content }
60
+ local_temp_path.open("wb") {|f| f << content }
61
+
62
+ etag.length.zero? || etag_for(local_temp_path) == etag
58
63
  end
59
64
  end
60
65
 
61
- etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
62
- if etag.length.zero? || etag_for(local_temp_path) == etag
66
+ if correct_response
63
67
  SharedHelpers.filesystem_access(local_path) do
64
68
  FileUtils.mv(local_temp_path, local_path)
65
69
  end
@@ -92,11 +96,11 @@ module Bundler
92
96
 
93
97
  def checksum_for_file(path)
94
98
  return nil unless path.file?
95
- # This must use IO.read instead of Digest.file().hexdigest
99
+ # This must use File.read instead of Digest.file().hexdigest
96
100
  # because we need to preserve \n line endings on windows when calculating
97
101
  # the checksum
98
102
  SharedHelpers.filesystem_access(path, :read) do
99
- SharedHelpers.digest(:MD5).hexdigest(IO.read(path))
103
+ SharedHelpers.digest(:MD5).hexdigest(File.read(path))
100
104
  end
101
105
  end
102
106
  end
@@ -20,6 +20,7 @@ module Bundler
20
20
  2.5
21
21
  2.6
22
22
  2.7
23
+ 3.0
23
24
  ].freeze
24
25
 
25
26
  KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze
@@ -106,6 +106,17 @@ module Bundler
106
106
  @locked_platforms = []
107
107
  end
108
108
 
109
+ @locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
110
+ @disable_multisource = @locked_gem_sources.all?(&:disable_multisource?)
111
+
112
+ unless @disable_multisource
113
+ msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch."
114
+
115
+ Bundler::SharedHelpers.major_deprecation 2, msg
116
+
117
+ @sources.merged_gem_lockfile_sections!
118
+ end
119
+
109
120
  @unlock[:gems] ||= []
110
121
  @unlock[:sources] ||= []
111
122
  @unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
@@ -145,17 +156,19 @@ module Bundler
145
156
  end
146
157
  end
147
158
 
159
+ def disable_multisource?
160
+ @disable_multisource
161
+ end
162
+
148
163
  def resolve_with_cache!
149
- raise "Specs already loaded" if @specs
150
164
  sources.cached!
151
- specs
165
+ resolve
152
166
  end
153
167
 
154
168
  def resolve_remotely!
155
- return if @specs
156
169
  @remote = true
157
170
  sources.remote!
158
- specs
171
+ resolve
159
172
  end
160
173
 
161
174
  # For given dependency list returns a SpecSet with Gemspec of all the required
@@ -172,10 +185,10 @@ module Bundler
172
185
  gem_name, gem_version = extract_gem_info(e)
173
186
  locked_gem = @locked_specs[gem_name].last
174
187
  raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
175
- raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
176
- "be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
177
- "that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
178
- "to a version other than #{locked_gem} that hasn't been removed in order to install."
188
+ raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
189
+ "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
190
+ "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
191
+ "removed in order to install."
179
192
  end
180
193
  unless specs["bundler"].any?
181
194
  bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
@@ -206,7 +219,6 @@ module Bundler
206
219
  Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
207
220
  true
208
221
  rescue BundlerError => e
209
- @index = nil
210
222
  @resolve = nil
211
223
  @specs = nil
212
224
  @gem_version_promoter = nil
@@ -269,50 +281,6 @@ module Bundler
269
281
  end
270
282
  end
271
283
 
272
- def index
273
- @index ||= Index.build do |idx|
274
- dependency_names = @dependencies.map(&:name)
275
-
276
- sources.all_sources.each do |source|
277
- source.dependency_names = dependency_names - pinned_spec_names(source)
278
- idx.add_source source.specs
279
- dependency_names.concat(source.unmet_deps).uniq!
280
- end
281
-
282
- double_check_for_index(idx, dependency_names)
283
- end
284
- end
285
-
286
- # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
287
- # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
288
- # but will not have found any versions of Bar from source B, which is a problem if the requested version
289
- # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
290
- # each spec we found, we add all possible versions from all sources to the index.
291
- def double_check_for_index(idx, dependency_names)
292
- pinned_names = pinned_spec_names
293
- loop do
294
- idxcount = idx.size
295
-
296
- names = :names # do this so we only have to traverse to get dependency_names from the index once
297
- unmet_dependency_names = lambda do
298
- return names unless names == :names
299
- new_names = sources.all_sources.map(&:dependency_names_to_double_check)
300
- return names = nil if new_names.compact!
301
- names = new_names.flatten(1).concat(dependency_names)
302
- names.uniq!
303
- names -= pinned_names
304
- names
305
- end
306
-
307
- sources.all_sources.each do |source|
308
- source.double_check_for(unmet_dependency_names)
309
- end
310
-
311
- break if idxcount == idx.size
312
- end
313
- end
314
- private :double_check_for_index
315
-
316
284
  def has_rubygems_remotes?
317
285
  sources.rubygems_sources.any? {|s| s.remotes.any? }
318
286
  end
@@ -519,17 +487,12 @@ module Bundler
519
487
  end
520
488
  end
521
489
 
522
- def find_resolved_spec(current_spec)
523
- specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
524
- end
525
-
526
- def find_indexed_specs(current_spec)
527
- index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
528
- end
529
-
530
490
  attr_reader :sources
531
491
  private :sources
532
492
 
493
+ attr_reader :locked_gem_sources
494
+ private :locked_gem_sources
495
+
533
496
  def nothing_changed?
534
497
  !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
535
498
  end
@@ -540,6 +503,10 @@ module Bundler
540
503
 
541
504
  private
542
505
 
506
+ def precompute_source_requirements_for_indirect_dependencies?
507
+ sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && sources.no_aggregate_global_source?
508
+ end
509
+
543
510
  def current_ruby_platform_locked?
544
511
  return false unless generic_local_platform == Gem::Platform::RUBY
545
512
 
@@ -654,10 +621,8 @@ module Bundler
654
621
  end
655
622
 
656
623
  def converge_rubygems_sources
657
- return false if Bundler.feature_flag.disable_multisource?
624
+ return false if disable_multisource?
658
625
 
659
- # Get the RubyGems sources from the Gemfile.lock
660
- locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
661
626
  return false if locked_gem_sources.empty?
662
627
 
663
628
  # Get the RubyGems remotes from the Gemfile
@@ -667,9 +632,9 @@ module Bundler
667
632
  changes = false
668
633
 
669
634
  # If there is a RubyGems source in both
670
- locked_gem_sources.each do |locked_gem|
635
+ locked_gem_sources.each do |locked_gem_source|
671
636
  # Merge the remotes from the Gemfile into the Gemfile.lock
672
- changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
637
+ changes |= locked_gem_source.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
673
638
  end
674
639
 
675
640
  changes
@@ -888,26 +853,22 @@ module Bundler
888
853
  end
889
854
 
890
855
  def source_requirements
891
- # Load all specs from remote sources
892
- index
893
-
894
856
  # Record the specs available in each gem's source, so that those
895
857
  # specs will be available later when the resolver knows where to
896
858
  # look for that gemspec (or its dependencies)
897
- source_requirements = { :default => sources.default_source }.merge(dependency_source_requirements)
859
+ source_requirements = if precompute_source_requirements_for_indirect_dependencies?
860
+ { :default => sources.default_source }.merge(source_map.all_requirements)
861
+ else
862
+ { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
863
+ end
898
864
  metadata_dependencies.each do |dep|
899
865
  source_requirements[dep.name] = sources.metadata_source
900
866
  end
901
- source_requirements[:global] = index unless Bundler.feature_flag.disable_multisource?
902
- source_requirements[:default_bundler] = source_requirements["bundler"] || source_requirements[:default]
867
+ source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
903
868
  source_requirements["bundler"] = sources.metadata_source # needs to come last to override
904
869
  source_requirements
905
870
  end
906
871
 
907
- def pinned_spec_names(skip = nil)
908
- dependency_source_requirements.reject {|_, source| source == skip }.keys
909
- end
910
-
911
872
  def requested_groups
912
873
  groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
913
874
  end
@@ -943,7 +904,7 @@ module Bundler
943
904
  end
944
905
 
945
906
  def additional_base_requirements_for_resolve
946
- return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions?
907
+ return [] unless @locked_gems
947
908
  dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
948
909
  @locked_gems.specs.reduce({}) do |requirements, locked_spec|
949
910
  name = locked_spec.name
@@ -963,16 +924,8 @@ module Bundler
963
924
  Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
964
925
  end
965
926
 
966
- def dependency_source_requirements
967
- @dependency_source_requirements ||= begin
968
- source_requirements = {}
969
- default = sources.default_source
970
- dependencies.each do |dep|
971
- dep_source = dep.source || default
972
- source_requirements[dep.name] = dep_source
973
- end
974
- source_requirements
975
- end
927
+ def source_map
928
+ @source_map ||= SourceMap.new(sources, dependencies)
976
929
  end
977
930
  end
978
931
  end