bundler 2.2.17 → 2.2.22

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -0
  3. data/bundler.gemspec +2 -3
  4. data/lib/bundler.rb +2 -1
  5. data/lib/bundler/build_metadata.rb +2 -2
  6. data/lib/bundler/cli.rb +13 -33
  7. data/lib/bundler/cli/check.rb +4 -2
  8. data/lib/bundler/cli/doctor.rb +11 -1
  9. data/lib/bundler/cli/install.rb +7 -8
  10. data/lib/bundler/cli/lock.rb +5 -1
  11. data/lib/bundler/cli/outdated.rb +9 -10
  12. data/lib/bundler/cli/update.rb +8 -3
  13. data/lib/bundler/current_ruby.rb +4 -4
  14. data/lib/bundler/definition.rb +38 -127
  15. data/lib/bundler/dsl.rb +3 -11
  16. data/lib/bundler/feature_flag.rb +0 -3
  17. data/lib/bundler/fetcher/compact_index.rb +1 -1
  18. data/lib/bundler/fetcher/downloader.rb +1 -2
  19. data/lib/bundler/fetcher/index.rb +0 -1
  20. data/lib/bundler/friendly_errors.rb +2 -4
  21. data/lib/bundler/index.rb +1 -2
  22. data/lib/bundler/installer.rb +5 -12
  23. data/lib/bundler/lockfile_parser.rb +2 -20
  24. data/lib/bundler/man/bundle-add.1 +1 -1
  25. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  26. data/lib/bundler/man/bundle-cache.1 +1 -1
  27. data/lib/bundler/man/bundle-check.1 +1 -1
  28. data/lib/bundler/man/bundle-clean.1 +1 -1
  29. data/lib/bundler/man/bundle-config.1 +1 -10
  30. data/lib/bundler/man/bundle-config.1.ronn +0 -11
  31. data/lib/bundler/man/bundle-doctor.1 +1 -1
  32. data/lib/bundler/man/bundle-exec.1 +1 -1
  33. data/lib/bundler/man/bundle-gem.1 +1 -1
  34. data/lib/bundler/man/bundle-info.1 +1 -1
  35. data/lib/bundler/man/bundle-init.1 +1 -1
  36. data/lib/bundler/man/bundle-inject.1 +1 -1
  37. data/lib/bundler/man/bundle-install.1 +1 -1
  38. data/lib/bundler/man/bundle-list.1 +1 -1
  39. data/lib/bundler/man/bundle-lock.1 +1 -1
  40. data/lib/bundler/man/bundle-open.1 +1 -1
  41. data/lib/bundler/man/bundle-outdated.1 +1 -1
  42. data/lib/bundler/man/bundle-platform.1 +1 -1
  43. data/lib/bundler/man/bundle-pristine.1 +1 -1
  44. data/lib/bundler/man/bundle-remove.1 +1 -1
  45. data/lib/bundler/man/bundle-show.1 +1 -1
  46. data/lib/bundler/man/bundle-update.1 +4 -4
  47. data/lib/bundler/man/bundle-update.1.ronn +3 -3
  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/api/source.rb +14 -0
  52. data/lib/bundler/plugin/installer.rb +1 -1
  53. data/lib/bundler/resolver.rb +15 -96
  54. data/lib/bundler/resolver/spec_group.rb +0 -24
  55. data/lib/bundler/rubygems_ext.rb +2 -2
  56. data/lib/bundler/rubygems_integration.rb +4 -3
  57. data/lib/bundler/settings.rb +21 -4
  58. data/lib/bundler/source.rb +11 -0
  59. data/lib/bundler/source/rubygems.rb +22 -22
  60. data/lib/bundler/source/rubygems_aggregate.rb +64 -0
  61. data/lib/bundler/source_list.rb +69 -27
  62. data/lib/bundler/source_map.rb +58 -0
  63. data/lib/bundler/spec_set.rb +2 -6
  64. data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -2
  65. data/lib/bundler/version.rb +1 -1
  66. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c654f563fcfd784d65d2441b1cf8b5384f9e90ff8d7107de070e33dba2ee729
4
- data.tar.gz: 4554510c934d22551680c26ff77f0b1a1073f7d35c0b21030d103fd40ade6baf
3
+ metadata.gz: dd506f45451a29ba6416b7b97ee93f67f40e71b8ef9c9db79484ff6f840d6189
4
+ data.tar.gz: bb18e91f6cfbd8c62febba280ebcb91de345e9fdc5599a7a44245ff47364a141
5
5
  SHA512:
6
- metadata.gz: c4c62c6eb0c7fc78acc3317de4dbaed2d26de9859bffd8930a08e7368829a4acb9f1bea24ad290a57124983bab8ac372da21573b742f50f4d36fa6a054406189
7
- data.tar.gz: 1862e00690b660a6d872324c6e2819c29a48ee9e9d7d97bd0cf35a92f0ea7d008fd4f7921c3f917564a3fc3279ead82bf24a360f80ad63205b37e50975b232c9
6
+ metadata.gz: 1d9dc3b77ecff1849b900a3164578eb40371afeb49f2f1c557485b9647f71292fbf43dd61501416afdfdd9cd50d6da581606aec5c349550a1ea97153e3f94b98
7
+ data.tar.gz: ae00d5fa66bd664d65915cf15df9431512dc6a77b35f4b60f7faf649962fbd06d56f0b7b7a0659b7ef9ff2c23860c862d8b5b888d43714c714a6af6fbd5b524a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,73 @@
1
+ # 2.2.22 (July 6, 2021)
2
+
3
+ ## Enhancements:
4
+
5
+ - Never downgrade indirect dependencies when running `bundle update` [#4713](https://github.com/rubygems/rubygems/pull/4713)
6
+ - Fix `getaddrinfo` errors not treated as fatal on non darwin platforms [#4703](https://github.com/rubygems/rubygems/pull/4703)
7
+
8
+ ## Bug fixes:
9
+
10
+ - Fix `bundle update <gem>` sometimes hanging and `bundle lock --update` not being able to update an insecure lockfile to the new format if it requires downgrades [#4652](https://github.com/rubygems/rubygems/pull/4652)
11
+ - Fix edge case combination of DSL methods and duplicated sources causing gems to not be found [#4711](https://github.com/rubygems/rubygems/pull/4711)
12
+ - Fix `bundle doctor` crashing when finding a broken symlink [#4707](https://github.com/rubygems/rubygems/pull/4707)
13
+ - Fix incorrect re-resolve edge case [#4700](https://github.com/rubygems/rubygems/pull/4700)
14
+ - Fix some gems being unintentionally locked under multiple lockfile sections [#4701](https://github.com/rubygems/rubygems/pull/4701)
15
+ - Fix `--conservative` flag unexpectedly updating indirect dependencies [#4692](https://github.com/rubygems/rubygems/pull/4692)
16
+
17
+ # 2.2.21 (June 23, 2021)
18
+
19
+ ## Security fixes:
20
+
21
+ - Auto-update insecure lockfile to split GEM source sections whenever possible [#4647](https://github.com/rubygems/rubygems/pull/4647)
22
+
23
+ ## Enhancements:
24
+
25
+ - Use a more limited number of threads when fetching in parallel from the Compact Index API [#4670](https://github.com/rubygems/rubygems/pull/4670)
26
+ - Update TODO link in bundle gem template to https [#4671](https://github.com/rubygems/rubygems/pull/4671)
27
+
28
+ ## Bug fixes:
29
+
30
+ - Fix `bundle install --local` hitting the network when `cache_all_platforms` configured [#4677](https://github.com/rubygems/rubygems/pull/4677)
31
+
32
+ # 2.2.20 (June 11, 2021)
33
+
34
+ ## Enhancements:
35
+
36
+ - Don't print bug report template on server side errors [#4663](https://github.com/rubygems/rubygems/pull/4663)
37
+ - Don't load `resolv` unnecessarily [#4640](https://github.com/rubygems/rubygems/pull/4640)
38
+
39
+ ## Bug fixes:
40
+
41
+ - Fix `bundle outdated` edge case [#4648](https://github.com/rubygems/rubygems/pull/4648)
42
+ - Fix `bundle check` with scoped rubygems sources [#4639](https://github.com/rubygems/rubygems/pull/4639)
43
+
44
+ ## Performance:
45
+
46
+ - Don't use `extra_rdoc_files` with md files in gemspec to make installing bundler with docs faster [#4628](https://github.com/rubygems/rubygems/pull/4628)
47
+
48
+ # 2.2.19 (May 31, 2021)
49
+
50
+ ## Bug fixes:
51
+
52
+ - Restore support for configuration keys with dashes [#4582](https://github.com/rubygems/rubygems/pull/4582)
53
+ - Fix some cached gems being unintentionally ignored when using rubygems 3.2.18 [#4623](https://github.com/rubygems/rubygems/pull/4623)
54
+
55
+ # 2.2.18 (May 25, 2021)
56
+
57
+ ## Security fixes:
58
+
59
+ - Fix dependency confusion issues with implicit dependencies [#4609](https://github.com/rubygems/rubygems/pull/4609)
60
+
61
+ ## Enhancements:
62
+
63
+ - Use simpler notation for generated `required_ruby_version` [#4598](https://github.com/rubygems/rubygems/pull/4598)
64
+ - Undeprecate bundle show [#4586](https://github.com/rubygems/rubygems/pull/4586)
65
+ - Make sure link to new issue uses the proper template [#4592](https://github.com/rubygems/rubygems/pull/4592)
66
+
67
+ ## Bug fixes:
68
+
69
+ - Fix platform specific gems being removed from the lockfile [#4580](https://github.com/rubygems/rubygems/pull/4580)
70
+
1
71
  # 2.2.17 (May 5, 2021)
2
72
 
3
73
  ## Enhancements:
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.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__)
@@ -197,7 +198,7 @@ module Bundler
197
198
 
198
199
  def frozen_bundle?
199
200
  frozen = settings[:deployment]
200
- frozen ||= settings[:frozen] unless feature_flag.deployment_means_frozen?
201
+ frozen ||= settings[:frozen]
201
202
  frozen
202
203
  end
203
204
 
@@ -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-05-05".freeze
8
- @git_commit_sha = "69cbd6e10e".freeze
7
+ @built_at = "2021-07-06".freeze
8
+ @git_commit_sha = "0bdd3e8e71".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"
@@ -11,9 +11,11 @@ module Bundler
11
11
  def run
12
12
  Bundler.settings.set_command_option_if_given :path, options[:path]
13
13
 
14
+ definition = Bundler.definition
15
+ definition.validate_runtime!
16
+
14
17
  begin
15
- definition = Bundler.definition
16
- definition.validate_runtime!
18
+ definition.resolve_only_locally!
17
19
  not_installed = definition.missing_specs
18
20
  rescue GemNotFound, VersionConflict
19
21
  Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies."
@@ -100,8 +100,11 @@ module Bundler
100
100
  files_not_readable_or_writable = []
101
101
  files_not_rw_and_owned_by_different_user = []
102
102
  files_not_owned_by_current_user_but_still_rw = []
103
+ broken_symlinks = []
103
104
  Find.find(Bundler.bundle_path.to_s).each do |f|
104
- if !File.writable?(f) || !File.readable?(f)
105
+ if !File.exist?(f)
106
+ broken_symlinks << f
107
+ elsif !File.writable?(f) || !File.readable?(f)
105
108
  if File.stat(f).uid != Process.uid
106
109
  files_not_rw_and_owned_by_different_user << f
107
110
  else
@@ -113,6 +116,13 @@ module Bundler
113
116
  end
114
117
 
115
118
  ok = true
119
+
120
+ if broken_symlinks.any?
121
+ Bundler.ui.warn "Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{broken_symlinks.join("\n - ")}"
122
+
123
+ ok = false
124
+ end
125
+
116
126
  if files_not_owned_by_current_user_but_still_rw.any?
117
127
  Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \
118
128
  "user, but are still readable/writable. These files are:\n - #{files_not_owned_by_current_user_but_still_rw.join("\n - ")}"
@@ -33,12 +33,8 @@ module Bundler
33
33
 
34
34
  options[:local] = true if Bundler.app_cache.exist?
35
35
 
36
- if Bundler.feature_flag.deployment_means_frozen?
37
- Bundler.settings.set_command_option :deployment, true
38
- else
39
- Bundler.settings.set_command_option :deployment, true if options[:deployment]
40
- Bundler.settings.set_command_option :frozen, true if options[:frozen]
41
- end
36
+ Bundler.settings.set_command_option :deployment, true if options[:deployment]
37
+ Bundler.settings.set_command_option :frozen, true if options[:frozen]
42
38
  end
43
39
 
44
40
  # When install is called with --no-deployment, disable deployment mode
@@ -62,7 +58,10 @@ module Bundler
62
58
  definition.validate_runtime!
63
59
 
64
60
  installer = Installer.install(Bundler.root, definition, options)
65
- Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
61
+
62
+ Bundler.settings.temporary(:cache_all_platforms => options[:local] ? false : Bundler.settings[:cache_all_platforms]) do
63
+ Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
64
+ end
66
65
 
67
66
  Bundler.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}."
68
67
  Bundler::CLI::Common.output_without_groups_message(:install)
@@ -105,7 +104,7 @@ module Bundler
105
104
  private
106
105
 
107
106
  def warn_if_root
108
- return if Bundler.settings[:silence_root_warning] || Bundler::WINDOWS || !Process.uid.zero?
107
+ return if Bundler.settings[:silence_root_warning] || Gem.win_platform? || !Process.uid.zero?
109
108
  Bundler.ui.warn "Don't run Bundler as root. Bundler can ask for sudo " \
110
109
  "if it is needed, and installing your bundle as root will break this " \
111
110
  "application for all non-root users on this machine.", :wrap => true
@@ -21,9 +21,13 @@ module Bundler
21
21
  Bundler::Fetcher.disable_endpoint = options["full-index"]
22
22
 
23
23
  update = options[:update]
24
+ conservative = options[:conservative]
25
+
24
26
  if update.is_a?(Array) # unlocking specific gems
25
27
  Bundler::CLI::Common.ensure_all_gems_in_lockfile!(update)
26
- update = { :gems => update, :lock_shared_dependencies => options[:conservative] }
28
+ update = { :gems => update, :conservative => conservative }
29
+ elsif update
30
+ update = { :conservative => conservative } if conservative
27
31
  end
28
32
  definition = Bundler.definition(update)
29
33
 
@@ -146,17 +146,16 @@ 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 unless active_spec
158
151
 
159
- active_spec
152
+ return active_spec if strict
153
+
154
+ active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
155
+ if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
156
+ active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
157
+ end
158
+ active_specs.last
160
159
  end
161
160
 
162
161
  def print_gems(gems_list)
@@ -27,9 +27,14 @@ module Bundler
27
27
  raise InvalidOption, "Cannot specify --all along with specific options."
28
28
  end
29
29
 
30
+ conservative = options[:conservative]
31
+
30
32
  if full_update
31
- # We're doing a full update
32
- Bundler.definition(true)
33
+ if conservative
34
+ Bundler.definition(:conservative => conservative)
35
+ else
36
+ Bundler.definition(true)
37
+ end
33
38
  else
34
39
  unless Bundler.default_lockfile.exist?
35
40
  raise GemfileLockNotFound, "This Bundle hasn't been installed yet. " \
@@ -43,7 +48,7 @@ module Bundler
43
48
  end
44
49
 
45
50
  Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby],
46
- :lock_shared_dependencies => options[:conservative],
51
+ :conservative => conservative,
47
52
  :bundler => options[:bundler])
48
53
  end
49
54
 
@@ -65,19 +65,19 @@ module Bundler
65
65
  end
66
66
 
67
67
  def mswin?
68
- Bundler::WINDOWS
68
+ Gem.win_platform?
69
69
  end
70
70
 
71
71
  def mswin64?
72
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
72
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
73
73
  end
74
74
 
75
75
  def mingw?
76
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
76
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
77
77
  end
78
78
 
79
79
  def x64_mingw?
80
- Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
80
+ Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
81
81
  end
82
82
 
83
83
  (KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
@@ -56,10 +56,8 @@ module Bundler
56
56
  @unlocking_bundler = false
57
57
  @unlocking = unlock
58
58
  else
59
- unlock = unlock.dup
60
59
  @unlocking_bundler = unlock.delete(:bundler)
61
- unlock.delete_if {|_k, v| Array(v).empty? }
62
- @unlocking = !unlock.empty?
60
+ @unlocking = unlock.any? {|_k, v| !Array(v).empty? }
63
61
  end
64
62
 
65
63
  @dependencies = dependencies
@@ -106,18 +104,19 @@ module Bundler
106
104
  @locked_platforms = []
107
105
  end
108
106
 
109
- @locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
110
- @disable_multisource = @locked_gem_sources.all?(&:disable_multisource?)
107
+ locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
108
+ @multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?
111
109
 
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."
110
+ if @multisource_allowed
111
+ unless sources.aggregate_global_source?
112
+ msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
114
113
 
115
- Bundler::SharedHelpers.major_deprecation 2, msg
114
+ Bundler::SharedHelpers.major_deprecation 2, msg
115
+ end
116
116
 
117
- @sources.merged_gem_lockfile_sections!
117
+ @sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
118
118
  end
119
119
 
120
- @unlock[:gems] ||= []
121
120
  @unlock[:sources] ||= []
122
121
  @unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
123
122
  @ruby_version.diff(locked_ruby_version_object)
@@ -130,8 +129,10 @@ module Bundler
130
129
  @path_changes = converge_paths
131
130
  @source_changes = converge_sources
132
131
 
133
- unless @unlock[:lock_shared_dependencies]
134
- eager_unlock = expand_dependencies(@unlock[:gems], true)
132
+ if @unlock[:conservative]
133
+ @unlock[:gems] ||= @dependencies.map(&:name)
134
+ else
135
+ eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
135
136
  @unlock[:gems] = @locked_specs.for(eager_unlock, [], false, false, false).map(&:name)
136
137
  end
137
138
 
@@ -156,8 +157,14 @@ module Bundler
156
157
  end
157
158
  end
158
159
 
159
- def disable_multisource?
160
- @disable_multisource
160
+ def multisource_allowed?
161
+ @multisource_allowed
162
+ end
163
+
164
+ def resolve_only_locally!
165
+ @remote = false
166
+ sources.local_only!
167
+ resolve
161
168
  end
162
169
 
163
170
  def resolve_with_cache!
@@ -219,7 +226,6 @@ module Bundler
219
226
  Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
220
227
  true
221
228
  rescue BundlerError => e
222
- @index = nil
223
229
  @resolve = nil
224
230
  @specs = nil
225
231
  @gem_version_promoter = nil
@@ -250,7 +256,7 @@ module Bundler
250
256
 
251
257
  def specs_for(groups)
252
258
  deps = dependencies_for(groups)
253
- specs.for(expand_dependencies(deps))
259
+ SpecSet.new(specs.for(expand_dependencies(deps)))
254
260
  end
255
261
 
256
262
  def dependencies_for(groups)
@@ -282,50 +288,6 @@ module Bundler
282
288
  end
283
289
  end
284
290
 
285
- def index
286
- @index ||= Index.build do |idx|
287
- dependency_names = @dependencies.map(&:name)
288
-
289
- sources.all_sources.each do |source|
290
- source.dependency_names = dependency_names - pinned_spec_names(source)
291
- idx.add_source source.specs
292
- dependency_names.concat(source.unmet_deps).uniq!
293
- end
294
-
295
- double_check_for_index(idx, dependency_names)
296
- end
297
- end
298
-
299
- # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
300
- # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
301
- # but will not have found any versions of Bar from source B, which is a problem if the requested version
302
- # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
303
- # each spec we found, we add all possible versions from all sources to the index.
304
- def double_check_for_index(idx, dependency_names)
305
- pinned_names = pinned_spec_names
306
- loop do
307
- idxcount = idx.size
308
-
309
- names = :names # do this so we only have to traverse to get dependency_names from the index once
310
- unmet_dependency_names = lambda do
311
- return names unless names == :names
312
- new_names = sources.all_sources.map(&:dependency_names_to_double_check)
313
- return names = nil if new_names.compact!
314
- names = new_names.flatten(1).concat(dependency_names)
315
- names.uniq!
316
- names -= pinned_names
317
- names
318
- end
319
-
320
- sources.all_sources.each do |source|
321
- source.double_check_for(unmet_dependency_names)
322
- end
323
-
324
- break if idxcount == idx.size
325
- end
326
- end
327
- private :double_check_for_index
328
-
329
291
  def has_rubygems_remotes?
330
292
  sources.rubygems_sources.any? {|s| s.remotes.any? }
331
293
  end
@@ -532,20 +494,9 @@ module Bundler
532
494
  end
533
495
  end
534
496
 
535
- def find_resolved_spec(current_spec)
536
- specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
537
- end
538
-
539
- def find_indexed_specs(current_spec)
540
- index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
541
- end
542
-
543
497
  attr_reader :sources
544
498
  private :sources
545
499
 
546
- attr_reader :locked_gem_sources
547
- private :locked_gem_sources
548
-
549
500
  def nothing_changed?
550
501
  !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
551
502
  end
@@ -556,6 +507,10 @@ module Bundler
556
507
 
557
508
  private
558
509
 
510
+ def precompute_source_requirements_for_indirect_dependencies?
511
+ sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
512
+ end
513
+
559
514
  def current_ruby_platform_locked?
560
515
  return false unless generic_local_platform == Gem::Platform::RUBY
561
516
 
@@ -669,35 +624,11 @@ module Bundler
669
624
  end
670
625
  end
671
626
 
672
- def converge_rubygems_sources
673
- return false if disable_multisource?
674
-
675
- return false if locked_gem_sources.empty?
676
-
677
- # Get the RubyGems remotes from the Gemfile
678
- actual_remotes = sources.rubygems_remotes
679
- return false if actual_remotes.empty?
680
-
681
- changes = false
682
-
683
- # If there is a RubyGems source in both
684
- locked_gem_sources.each do |locked_gem|
685
- # Merge the remotes from the Gemfile into the Gemfile.lock
686
- changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
687
- end
688
-
689
- changes
690
- end
691
-
692
627
  def converge_sources
693
- changes = false
694
-
695
- changes |= converge_rubygems_sources
696
-
697
628
  # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
698
629
  # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
699
630
  # source in the Gemfile.lock, use the one from the Gemfile.
700
- changes |= sources.replace_sources!(@locked_sources)
631
+ changes = sources.replace_sources!(@locked_sources)
701
632
 
702
633
  sources.all_sources.each do |source|
703
634
  # If the source is unlockable and the current command allows an unlock of
@@ -782,8 +713,6 @@ module Bundler
782
713
  end
783
714
  end
784
715
 
785
- unlock_source_unlocks_spec = Bundler.feature_flag.unlock_source_unlocks_spec?
786
-
787
716
  converged = []
788
717
  @locked_specs.each do |s|
789
718
  # Replace the locked dependency's source with the equivalent source from the Gemfile
@@ -795,11 +724,6 @@ module Bundler
795
724
  next if s.source.nil?
796
725
  next if @unlock[:sources].include?(s.source.name)
797
726
 
798
- # XXX This is a backwards-compatibility fix to preserve the ability to
799
- # unlock a single gem by passing its name via `--source`. See issue #3759
800
- # TODO: delete in Bundler 2
801
- next if unlock_source_unlocks_spec && @unlock[:sources].include?(s.name)
802
-
803
727
  # If the spec is from a path source and it doesn't exist anymore
804
728
  # then we unlock it.
805
729
 
@@ -831,7 +755,7 @@ module Bundler
831
755
 
832
756
  resolve = SpecSet.new(converged)
833
757
  @locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), @unlock[:gems], true, true)
834
- resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems], false, false, false)
758
+ resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), [], false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
835
759
  diff = nil
836
760
 
837
761
  # Now, we unlock any sources that do not have anymore gems pinned to it
@@ -902,26 +826,22 @@ module Bundler
902
826
  end
903
827
 
904
828
  def source_requirements
905
- # Load all specs from remote sources
906
- index
907
-
908
829
  # Record the specs available in each gem's source, so that those
909
830
  # specs will be available later when the resolver knows where to
910
831
  # look for that gemspec (or its dependencies)
911
- source_requirements = { :default => sources.default_source }.merge(dependency_source_requirements)
832
+ source_requirements = if precompute_source_requirements_for_indirect_dependencies?
833
+ { :default => sources.default_source }.merge(source_map.all_requirements)
834
+ else
835
+ { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
836
+ end
912
837
  metadata_dependencies.each do |dep|
913
838
  source_requirements[dep.name] = sources.metadata_source
914
839
  end
915
- source_requirements[:global] = index unless Bundler.feature_flag.disable_multisource?
916
- source_requirements[:default_bundler] = source_requirements["bundler"] || source_requirements[:default]
840
+ source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
917
841
  source_requirements["bundler"] = sources.metadata_source # needs to come last to override
918
842
  source_requirements
919
843
  end
920
844
 
921
- def pinned_spec_names(skip = nil)
922
- dependency_source_requirements.reject {|_, source| source == skip }.keys
923
- end
924
-
925
845
  def requested_groups
926
846
  groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
927
847
  end
@@ -957,14 +877,13 @@ module Bundler
957
877
  end
958
878
 
959
879
  def additional_base_requirements_for_resolve
960
- return [] unless @locked_gems
880
+ return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
961
881
  dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
962
882
  @locked_gems.specs.reduce({}) do |requirements, locked_spec|
963
883
  name = locked_spec.name
964
884
  dependency = dependencies_by_name[name]
965
- next requirements unless dependency
966
885
  next requirements if @locked_gems.dependencies[name] != dependency
967
- next requirements if dependency.source.is_a?(Source::Path)
886
+ next requirements if dependency && dependency.source.is_a?(Source::Path)
968
887
  dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
969
888
  requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
970
889
  requirements
@@ -977,16 +896,8 @@ module Bundler
977
896
  Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
978
897
  end
979
898
 
980
- def dependency_source_requirements
981
- @dependency_source_requirements ||= begin
982
- source_requirements = {}
983
- default = sources.default_source
984
- dependencies.each do |dep|
985
- dep_source = dep.source || default
986
- source_requirements[dep.name] = dep_source
987
- end
988
- source_requirements
989
- end
899
+ def source_map
900
+ @source_map ||= SourceMap.new(sources, dependencies)
990
901
  end
991
902
  end
992
903
  end