bundler 2.6.2 → 2.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/README.md +2 -2
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli/console.rb +8 -6
  6. data/lib/bundler/cli/doctor.rb +9 -5
  7. data/lib/bundler/cli/info.rb +4 -4
  8. data/lib/bundler/cli/issue.rb +1 -1
  9. data/lib/bundler/cli/outdated.rb +6 -4
  10. data/lib/bundler/cli/show.rb +1 -1
  11. data/lib/bundler/current_ruby.rb +23 -33
  12. data/lib/bundler/definition.rb +62 -60
  13. data/lib/bundler/dependency.rb +92 -47
  14. data/lib/bundler/dsl.rb +83 -78
  15. data/lib/bundler/endpoint_specification.rb +10 -3
  16. data/lib/bundler/errors.rb +4 -0
  17. data/lib/bundler/feature_flag.rb +2 -6
  18. data/lib/bundler/gem_helpers.rb +4 -10
  19. data/lib/bundler/gem_version_promoter.rb +0 -2
  20. data/lib/bundler/installer.rb +16 -2
  21. data/lib/bundler/lazy_specification.rb +50 -45
  22. data/lib/bundler/man/bundle-add.1 +3 -3
  23. data/lib/bundler/man/bundle-binstubs.1 +3 -3
  24. data/lib/bundler/man/bundle-cache.1 +3 -3
  25. data/lib/bundler/man/bundle-check.1 +3 -3
  26. data/lib/bundler/man/bundle-clean.1 +3 -3
  27. data/lib/bundler/man/bundle-config.1 +3 -3
  28. data/lib/bundler/man/bundle-console.1 +3 -3
  29. data/lib/bundler/man/bundle-doctor.1 +3 -3
  30. data/lib/bundler/man/bundle-env.1 +3 -3
  31. data/lib/bundler/man/bundle-exec.1 +3 -3
  32. data/lib/bundler/man/bundle-fund.1 +3 -3
  33. data/lib/bundler/man/bundle-gem.1 +3 -3
  34. data/lib/bundler/man/bundle-help.1 +3 -3
  35. data/lib/bundler/man/bundle-info.1 +3 -3
  36. data/lib/bundler/man/bundle-init.1 +3 -3
  37. data/lib/bundler/man/bundle-inject.1 +3 -3
  38. data/lib/bundler/man/bundle-install.1 +3 -3
  39. data/lib/bundler/man/bundle-issue.1 +3 -3
  40. data/lib/bundler/man/bundle-licenses.1 +3 -3
  41. data/lib/bundler/man/bundle-list.1 +3 -3
  42. data/lib/bundler/man/bundle-lock.1 +3 -3
  43. data/lib/bundler/man/bundle-open.1 +3 -3
  44. data/lib/bundler/man/bundle-outdated.1 +3 -3
  45. data/lib/bundler/man/bundle-platform.1 +3 -3
  46. data/lib/bundler/man/bundle-plugin.1 +3 -3
  47. data/lib/bundler/man/bundle-pristine.1 +3 -3
  48. data/lib/bundler/man/bundle-remove.1 +3 -3
  49. data/lib/bundler/man/bundle-show.1 +3 -3
  50. data/lib/bundler/man/bundle-update.1 +3 -3
  51. data/lib/bundler/man/bundle-version.1 +3 -3
  52. data/lib/bundler/man/bundle-viz.1 +3 -3
  53. data/lib/bundler/man/bundle.1 +3 -3
  54. data/lib/bundler/man/gemfile.5 +3 -3
  55. data/lib/bundler/match_metadata.rb +13 -0
  56. data/lib/bundler/plugin/index.rb +4 -0
  57. data/lib/bundler/resolver/base.rb +2 -1
  58. data/lib/bundler/resolver/package.rb +8 -4
  59. data/lib/bundler/resolver/spec_group.rb +1 -25
  60. data/lib/bundler/resolver.rb +13 -3
  61. data/lib/bundler/ruby_dsl.rb +12 -3
  62. data/lib/bundler/rubygems_ext.rb +83 -82
  63. data/lib/bundler/rubygems_integration.rb +2 -15
  64. data/lib/bundler/runtime.rb +19 -24
  65. data/lib/bundler/source/git.rb +1 -0
  66. data/lib/bundler/source/rubygems.rb +19 -4
  67. data/lib/bundler/source.rb +2 -0
  68. data/lib/bundler/source_list.rb +4 -0
  69. data/lib/bundler/spec_set.rb +66 -29
  70. data/lib/bundler/templates/newgem/Gemfile.tt +1 -0
  71. data/lib/bundler/version.rb +1 -1
  72. data/lib/bundler.rb +10 -30
  73. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3728802be4074809ca22f929200d5a37e70e6fc4ce6a2c532724240965347b2
4
- data.tar.gz: 02ce39fa7358e3ec4923893aa1760f27963a1620b0e62e1b304305d72a1587de
3
+ metadata.gz: e6db19c6c72f2c38f056adfac393dcfebd51e4ae14eee0fc6a1b8122ba5f9f92
4
+ data.tar.gz: a83020c6d99aef70bee13b2ea4ef794dc0a5804aba44baff57a9a90777070361
5
5
  SHA512:
6
- metadata.gz: fe1caf39624053f3acd53633ac14621bc3b65fa2aa59eadca1e530fd44207bcd4a4f383fc6624ba6bb3b6663e1067ae278ed43c44a44da2434bb1c3aa6da890b
7
- data.tar.gz: 7d992c1527acea98a361fb315f201c73e01efed2034a3f6ba61004be4f722841aac5b61cb629a45c0d55d088b199a681e3288f359eb652a6c12cb2db697f1ac7
6
+ metadata.gz: 6ebc0d4dda2d618578455c0d322008014beb2c81671f271bed81d904ace7c6871fbf25b2aa584b5331244814987299fc6b0aebe69ed4d02c2411db41a819c47f
7
+ data.tar.gz: aacaaef051b9e0f1fd08b24892e3f1b995d7c88ed3e9b4b401c94f922e4632bef37b02f8fdaac4dcc2457dde8bb45bd558f5410a6e514f41a6a8ee42899ba7f1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,56 @@
1
+ # 2.6.4 (February 17, 2025)
2
+
3
+ ## Enhancements:
4
+
5
+ - Make Bundler never instantiate development dependencies [#8486](https://github.com/rubygems/rubygems/pull/8486)
6
+ - Fix some invalid options to `gem` DSL not getting reported as invalid [#8480](https://github.com/rubygems/rubygems/pull/8480)
7
+ - Add `irb` to a Gemfile for a newly created gem [#8467](https://github.com/rubygems/rubygems/pull/8467)
8
+ - Auto-heal empty installation directory [#8457](https://github.com/rubygems/rubygems/pull/8457)
9
+ - Fix `bundle console` unnecessarily trying to load IRB twice [#8443](https://github.com/rubygems/rubygems/pull/8443)
10
+ - Add ruby_34 and ruby_35 as valid platform: [#8430](https://github.com/rubygems/rubygems/pull/8430)
11
+ - Consider gems under `platform: :windows` filter in Gemfile when running on Windows with ARM architecture [#8428](https://github.com/rubygems/rubygems/pull/8428)
12
+
13
+ ## Bug fixes:
14
+
15
+ - Fix regression when running `bundle update <foo>` would sometimes downgrade a top level dependency [#8491](https://github.com/rubygems/rubygems/pull/8491)
16
+ - Fix dependency locking when Bundler finds incorrect lockfile dependencies [#8489](https://github.com/rubygems/rubygems/pull/8489)
17
+ - Raise error when lockfile is missing deps in frozen mode [#8483](https://github.com/rubygems/rubygems/pull/8483)
18
+ - Fix `bundle install --prefer-local` sometimes installing very old versions [#8484](https://github.com/rubygems/rubygems/pull/8484)
19
+ - Fix incorrect error message when running `bundle update` in frozen mode [#8481](https://github.com/rubygems/rubygems/pull/8481)
20
+ - Keep platform variants in `vendor/cache` even if incompatible with the current Ruby version [#8471](https://github.com/rubygems/rubygems/pull/8471)
21
+ - Fix `bundle console` printing bug report template incorrectly [#8436](https://github.com/rubygems/rubygems/pull/8436)
22
+ - Fix `--prefer-local` not respecting default gems [#8412](https://github.com/rubygems/rubygems/pull/8412)
23
+
24
+ ## Performance:
25
+
26
+ - Improve resolution performance [#8458](https://github.com/rubygems/rubygems/pull/8458)
27
+
28
+ ## Documentation:
29
+
30
+ - Fix more broken links [#8416](https://github.com/rubygems/rubygems/pull/8416)
31
+
32
+ # 2.6.3 (January 16, 2025)
33
+
34
+ ## Enhancements:
35
+
36
+ - Don't fallback to evaluating YAML gemspecs as Ruby code [#8404](https://github.com/rubygems/rubygems/pull/8404)
37
+ - Print message when blocking on file locks [#8299](https://github.com/rubygems/rubygems/pull/8299)
38
+ - Add support for mise version manager file [#8356](https://github.com/rubygems/rubygems/pull/8356)
39
+ - Add Ruby 3.5 to Gemfile DSL platform values [#8365](https://github.com/rubygems/rubygems/pull/8365)
40
+
41
+ ## Bug fixes:
42
+
43
+ - Revert RubyGems plugins getting loaded on `Bundler.require` [#8410](https://github.com/rubygems/rubygems/pull/8410)
44
+ - Fix platform specific gems sometimes being removed from the lockfile [#8401](https://github.com/rubygems/rubygems/pull/8401)
45
+ - Serialize gemspec when caching git source [#8403](https://github.com/rubygems/rubygems/pull/8403)
46
+ - Fix crash on read-only filesystems in Ruby 3.4 [#8372](https://github.com/rubygems/rubygems/pull/8372)
47
+ - Fix `bundle outdated <GEM>` failing if not all gems are installed [#8361](https://github.com/rubygems/rubygems/pull/8361)
48
+ - Fix `bundle install` crash on Windows [#8362](https://github.com/rubygems/rubygems/pull/8362)
49
+
50
+ ## Documentation:
51
+
52
+ - Fix broken links in the documents [#8389](https://github.com/rubygems/rubygems/pull/8389)
53
+
1
54
  # 2.6.2 (December 23, 2024)
2
55
 
3
56
  ## Bug fixes:
data/README.md CHANGED
@@ -29,7 +29,7 @@ See [bundler.io](https://bundler.io) for the full documentation.
29
29
 
30
30
  ### Troubleshooting
31
31
 
32
- For help with common problems, see [TROUBLESHOOTING](doc/TROUBLESHOOTING.md).
32
+ For help with common problems, see [TROUBLESHOOTING](../doc/bundler/TROUBLESHOOTING.md).
33
33
 
34
34
  Still stuck? Try [filing an issue](https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md).
35
35
 
@@ -41,7 +41,7 @@ To get in touch with the Bundler core team and other Bundler users, please join
41
41
 
42
42
  ### Contributing
43
43
 
44
- If you'd like to contribute to Bundler, that's awesome, and we <3 you. We've put together [the Bundler contributor guide](https://github.com/rubygems/rubygems/blob/master/bundler/doc/contributing/README.md) with all of the information you need to get started.
44
+ If you'd like to contribute to Bundler, that's awesome, and we <3 you. We've put together [the Bundler contributor guide](https://github.com/rubygems/rubygems/blob/master/doc/bundler/contributing/README.md) with all of the information you need to get started.
45
45
 
46
46
  If you'd like to request a substantial change to Bundler or its documentation, refer to the [Bundler RFC process](https://github.com/rubygems/rfcs) for more information.
47
47
 
@@ -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 = "2024-12-23".freeze
8
- @git_commit_sha = "90ebd47c740".freeze
7
+ @built_at = "2025-02-17".freeze
8
+ @git_commit_sha = "87f7bf0ac12".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
@@ -20,9 +20,14 @@ module Bundler
20
20
  require name
21
21
  get_constant(name)
22
22
  rescue LoadError
23
- Bundler.ui.error "Couldn't load console #{name}, falling back to irb"
24
- require "irb"
25
- get_constant("irb")
23
+ if name == "irb"
24
+ Bundler.ui.error "#{name} is not available"
25
+ exit 1
26
+ else
27
+ Bundler.ui.error "Couldn't load console #{name}, falling back to irb"
28
+ name = "irb"
29
+ retry
30
+ end
26
31
  end
27
32
 
28
33
  def get_constant(name)
@@ -32,9 +37,6 @@ module Bundler
32
37
  "irb" => :IRB,
33
38
  }[name]
34
39
  Object.const_get(const_name)
35
- rescue NameError
36
- Bundler.ui.error "Could not find constant #{const_name}"
37
- exit 1
38
40
  end
39
41
  end
40
42
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "rbconfig"
4
4
  require "shellwords"
5
- require "fiddle"
6
5
 
7
6
  module Bundler
8
7
  class CLI::Doctor
@@ -57,6 +56,14 @@ module Bundler
57
56
  Dir.glob("#{spec.full_gem_path}/**/*.bundle")
58
57
  end
59
58
 
59
+ def lookup_with_fiddle(path)
60
+ require "fiddle"
61
+ Fiddle.dlopen(path)
62
+ false
63
+ rescue Fiddle::DLError
64
+ true
65
+ end
66
+
60
67
  def check!
61
68
  require_relative "check"
62
69
  Bundler::CLI::Check.new({}).run
@@ -73,10 +80,7 @@ module Bundler
73
80
  definition.specs.each do |spec|
74
81
  bundles_for_gem(spec).each do |bundle|
75
82
  bad_paths = dylibs(bundle).select do |f|
76
- Fiddle.dlopen(f)
77
- false
78
- rescue Fiddle::DLError
79
- true
83
+ lookup_with_fiddle(f)
80
84
  end
81
85
  if bad_paths.any?
82
86
  broken_links[spec] ||= []
@@ -39,8 +39,8 @@ module Bundler
39
39
  path = File.expand_path("../../..", __dir__)
40
40
  else
41
41
  path = spec.full_gem_path
42
- if spec.deleted_gem?
43
- return Bundler.ui.warn "The gem #{name} has been deleted. It was installed at: #{path}"
42
+ if spec.installation_missing?
43
+ return Bundler.ui.warn "The gem #{name} is missing. It should be installed at #{path}, but was not found"
44
44
  end
45
45
  end
46
46
 
@@ -65,8 +65,8 @@ module Bundler
65
65
  gem_info << "\tDefault Gem: yes\n" if spec.respond_to?(:default_gem?) && spec.default_gem?
66
66
  gem_info << "\tReverse Dependencies: \n\t\t#{gem_dependencies.join("\n\t\t")}" if gem_dependencies.any?
67
67
 
68
- if name != "bundler" && spec.deleted_gem?
69
- return Bundler.ui.warn "The gem #{name} has been deleted. Gemspec information is still available though:\n#{gem_info}"
68
+ if name != "bundler" && spec.installation_missing?
69
+ return Bundler.ui.warn "The gem #{name} is missing. Gemspec information is still available though:\n#{gem_info}"
70
70
  end
71
71
 
72
72
  Bundler.ui.info gem_info
@@ -10,7 +10,7 @@ module Bundler
10
10
  be sure to check out these resources:
11
11
 
12
12
  1. Check out our troubleshooting guide for quick fixes to common issues:
13
- https://github.com/rubygems/rubygems/blob/master/bundler/doc/TROUBLESHOOTING.md
13
+ https://github.com/rubygems/rubygems/blob/master/doc/bundler/TROUBLESHOOTING.md
14
14
 
15
15
  2. Instructions for common Bundler uses can be found on the documentation
16
16
  site: https://bundler.io/
@@ -26,13 +26,15 @@ module Bundler
26
26
  def run
27
27
  check_for_deployment_mode!
28
28
 
29
- gems.each do |gem_name|
30
- Bundler::CLI::Common.select_spec(gem_name)
31
- end
32
-
33
29
  Bundler.definition.validate_runtime!
34
30
  current_specs = Bundler.ui.silence { Bundler.definition.resolve }
35
31
 
32
+ gems.each do |gem_name|
33
+ if current_specs[gem_name].empty?
34
+ raise GemNotFound, "Could not find gem '#{gem_name}'."
35
+ end
36
+ end
37
+
36
38
  current_dependencies = Bundler.ui.silence do
37
39
  Bundler.load.dependencies.map {|dep| [dep.name, dep] }.to_h
38
40
  end
@@ -24,7 +24,7 @@ module Bundler
24
24
  return unless spec
25
25
  path = spec.full_gem_path
26
26
  unless File.directory?(path)
27
- return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}"
27
+ return Bundler.ui.warn "The gem #{gem_name} is missing. It should be installed at #{path}, but was not found"
28
28
  end
29
29
  end
30
30
  return Bundler.ui.info(path)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "rubygems_ext"
4
+
3
5
  module Bundler
4
6
  # Returns current version of Ruby
5
7
  #
@@ -9,38 +11,25 @@ module Bundler
9
11
  end
10
12
 
11
13
  class CurrentRuby
12
- KNOWN_MINOR_VERSIONS = %w[
13
- 1.8
14
- 1.9
15
- 2.0
16
- 2.1
17
- 2.2
18
- 2.3
19
- 2.4
20
- 2.5
21
- 2.6
22
- 2.7
23
- 3.0
24
- 3.1
25
- 3.2
26
- 3.3
27
- ].freeze
28
-
29
- KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze
30
-
31
- KNOWN_PLATFORMS = %w[
32
- jruby
33
- maglev
34
- mingw
35
- mri
36
- mswin
37
- mswin64
38
- rbx
39
- ruby
40
- truffleruby
41
- windows
42
- x64_mingw
43
- ].freeze
14
+ ALL_RUBY_VERSIONS = (18..27).to_a.concat((30..35).to_a).freeze
15
+ KNOWN_MINOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.reverse.join(".") }.freeze
16
+ KNOWN_MAJOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.last.to_s }.uniq.freeze
17
+ PLATFORM_MAP = {
18
+ ruby: [Gem::Platform::RUBY, CurrentRuby::ALL_RUBY_VERSIONS],
19
+ mri: [Gem::Platform::RUBY, CurrentRuby::ALL_RUBY_VERSIONS],
20
+ rbx: [Gem::Platform::RUBY],
21
+ truffleruby: [Gem::Platform::RUBY],
22
+ jruby: [Gem::Platform::JAVA, [18, 19]],
23
+ windows: [Gem::Platform::WINDOWS, CurrentRuby::ALL_RUBY_VERSIONS],
24
+ # deprecated
25
+ mswin: [Gem::Platform::MSWIN, CurrentRuby::ALL_RUBY_VERSIONS],
26
+ mswin64: [Gem::Platform::MSWIN64, CurrentRuby::ALL_RUBY_VERSIONS - [18]],
27
+ mingw: [Gem::Platform::UNIVERSAL_MINGW, CurrentRuby::ALL_RUBY_VERSIONS],
28
+ x64_mingw: [Gem::Platform::UNIVERSAL_MINGW, CurrentRuby::ALL_RUBY_VERSIONS - [18, 19]],
29
+ }.each_with_object({}) do |(platform, spec), hash|
30
+ hash[platform] = spec[0]
31
+ spec[1]&.each {|version| hash[:"#{platform}_#{version}"] = spec[0] }
32
+ end.freeze
44
33
 
45
34
  def ruby?
46
35
  return true if Bundler::GemHelpers.generic_local_platform_is_ruby?
@@ -82,7 +71,8 @@ module Bundler
82
71
  RUBY_VERSION.start_with?("#{version}.")
83
72
  end
84
73
 
85
- KNOWN_PLATFORMS.each do |platform|
74
+ all_platforms = PLATFORM_MAP.keys << "maglev"
75
+ all_platforms.each do |platform|
86
76
  define_method(:"#{platform}_#{trimmed_version}?") do
87
77
  send(:"#{platform}?") && send(:"on_#{trimmed_version}?")
88
78
  end
@@ -58,17 +58,28 @@ module Bundler
58
58
  # @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
59
59
  # @param optional_groups [Array(String)] A list of optional groups
60
60
  def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = [])
61
- if [true, false].include?(unlock)
61
+ unlock ||= {}
62
+
63
+ if unlock == true
64
+ @unlocking_all = true
62
65
  @unlocking_bundler = false
63
66
  @unlocking = unlock
67
+ @sources_to_unlock = []
68
+ @unlocking_ruby = false
69
+ @explicit_unlocks = []
70
+ conservative = false
64
71
  else
72
+ @unlocking_all = false
65
73
  @unlocking_bundler = unlock.delete(:bundler)
66
74
  @unlocking = unlock.any? {|_k, v| !Array(v).empty? }
75
+ @sources_to_unlock = unlock.delete(:sources) || []
76
+ @unlocking_ruby = unlock.delete(:ruby)
77
+ @explicit_unlocks = unlock.delete(:gems) || []
78
+ conservative = unlock.delete(:conservative)
67
79
  end
68
80
 
69
81
  @dependencies = dependencies
70
82
  @sources = sources
71
- @unlock = unlock
72
83
  @optional_groups = optional_groups
73
84
  @prefer_local = false
74
85
  @specs = nil
@@ -93,29 +104,24 @@ module Bundler
93
104
  @platforms = @locked_platforms.dup
94
105
  @locked_bundler_version = @locked_gems.bundler_version
95
106
  @locked_ruby_version = @locked_gems.ruby_version
96
- @originally_locked_deps = @locked_gems.dependencies
107
+ @locked_deps = @locked_gems.dependencies
97
108
  @originally_locked_specs = SpecSet.new(@locked_gems.specs)
98
109
  @locked_checksums = @locked_gems.checksums
99
110
 
100
- if unlock != true
101
- @locked_deps = @originally_locked_deps
102
- @locked_specs = @originally_locked_specs
103
- @locked_sources = @locked_gems.sources
104
- else
105
- @unlock = {}
106
- @locked_deps = {}
111
+ if @unlocking_all
107
112
  @locked_specs = SpecSet.new([])
108
113
  @locked_sources = []
114
+ else
115
+ @locked_specs = @originally_locked_specs
116
+ @locked_sources = @locked_gems.sources
109
117
  end
110
118
  else
111
- @unlock = {}
112
- @locked_gems = nil
119
+ @locked_gems = nil
113
120
  @locked_platforms = []
114
121
  @most_specific_locked_platform = nil
115
122
  @platforms = []
116
123
  @locked_deps = {}
117
124
  @locked_specs = SpecSet.new([])
118
- @originally_locked_deps = {}
119
125
  @originally_locked_specs = @locked_specs
120
126
  @locked_sources = []
121
127
  @locked_checksums = Bundler.feature_flag.lockfile_checksums?
@@ -134,11 +140,10 @@ module Bundler
134
140
  @sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
135
141
  end
136
142
 
137
- @sources_to_unlock = @unlock.delete(:sources) || []
138
- @unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
143
+ @unlocking_ruby ||= if @ruby_version && locked_ruby_version_object
139
144
  @ruby_version.diff(locked_ruby_version_object)
140
145
  end
141
- @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
146
+ @unlocking ||= @unlocking_ruby ||= (!@locked_ruby_version ^ !@ruby_version)
142
147
 
143
148
  @current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
144
149
 
@@ -146,9 +151,7 @@ module Bundler
146
151
  @path_changes = converge_paths
147
152
  @source_changes = converge_sources
148
153
 
149
- @explicit_unlocks = @unlock.delete(:gems) || []
150
-
151
- if @unlock[:conservative]
154
+ if conservative
152
155
  @gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
153
156
  else
154
157
  eager_unlock = @explicit_unlocks.map {|name| Dependency.new(name, ">= 0") }
@@ -220,6 +223,8 @@ module Bundler
220
223
 
221
224
  def prefer_local!
222
225
  @prefer_local = true
226
+
227
+ sources.prefer_local!
223
228
  end
224
229
 
225
230
  # For given dependency list returns a SpecSet with Gemspec of all the required
@@ -374,7 +379,7 @@ module Bundler
374
379
 
375
380
  def locked_ruby_version
376
381
  return unless ruby_version
377
- if @unlock[:ruby] || !@locked_ruby_version
382
+ if @unlocking_ruby || !@locked_ruby_version
378
383
  Bundler::RubyVersion.system
379
384
  else
380
385
  @locked_ruby_version
@@ -435,23 +440,23 @@ module Bundler
435
440
  changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
436
441
  end
437
442
 
438
- reason = nothing_changed? ? "some dependencies were deleted from your gemfile" : change_reason
443
+ reason = resolve_needed? ? change_reason : "some dependencies were deleted from your gemfile"
439
444
  msg = String.new
440
445
  msg << "#{reason.capitalize.strip}, but the lockfile can't be updated because frozen mode is set"
441
446
  msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
442
447
  msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
443
448
  msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
444
- msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_gemfile_path} to version control.\n"
449
+ msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_gemfile_path} to version control.\n" unless unlocking?
445
450
 
446
451
  unless explicit_flag
447
452
  suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
448
453
  "bundle config set frozen false"
449
454
  end
450
- msg << "If this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} " \
455
+ msg << "\n\nIf this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} " \
451
456
  "freeze by running `#{suggested_command}`." if suggested_command
452
457
  end
453
458
 
454
- raise ProductionError, msg if added.any? || deleted.any? || changed.any? || !nothing_changed?
459
+ raise ProductionError, msg if added.any? || deleted.any? || changed.any? || resolve_needed?
455
460
  end
456
461
 
457
462
  def validate_runtime!
@@ -620,8 +625,8 @@ module Bundler
620
625
  @resolution_packages ||= begin
621
626
  last_resolve = converge_locked_specs
622
627
  remove_invalid_platforms!
623
- packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local)
624
- packages = additional_base_requirements_to_prevent_downgrades(packages, last_resolve)
628
+ packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @unlocking_all || @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: @new_platforms)
629
+ packages = additional_base_requirements_to_prevent_downgrades(packages)
625
630
  packages = additional_base_requirements_to_force_updates(packages)
626
631
  packages
627
632
  end
@@ -639,6 +644,8 @@ module Bundler
639
644
  specs = begin
640
645
  resolve.materialize(dependencies)
641
646
  rescue IncorrectLockfileDependencies => e
647
+ raise if Bundler.frozen_bundle?
648
+
642
649
  spec = e.spec
643
650
  raise "Infinite loop while fixing lockfile dependencies" if incorrect_spec == spec
644
651
 
@@ -742,7 +749,7 @@ module Bundler
742
749
 
743
750
  @platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
744
751
 
745
- SpecSet.new(result.for(dependencies, @platforms))
752
+ SpecSet.new(result.for(dependencies, @platforms | [Gem::Platform::RUBY]))
746
753
  end
747
754
 
748
755
  def precompute_source_requirements_for_indirect_dependencies?
@@ -761,6 +768,7 @@ module Bundler
761
768
  @most_specific_non_local_locked_ruby_platform = find_most_specific_locked_ruby_platform
762
769
  return if @most_specific_non_local_locked_ruby_platform
763
770
 
771
+ @new_platforms << local_platform
764
772
  @platforms << local_platform
765
773
  true
766
774
  end
@@ -782,7 +790,7 @@ module Bundler
782
790
  unlock_reason = if unlock_targets
783
791
  "#{unlock_targets.first}: (#{unlock_targets.last.join(", ")})"
784
792
  else
785
- @unlock[:ruby] ? "ruby" : ""
793
+ @unlocking_ruby ? "ruby" : ""
786
794
  end
787
795
 
788
796
  return "bundler is unlocking #{unlock_reason}"
@@ -852,8 +860,6 @@ module Bundler
852
860
  end
853
861
 
854
862
  def check_lockfile
855
- @missing_lockfile_dep = nil
856
-
857
863
  @locked_spec_with_invalid_deps = nil
858
864
  @locked_spec_with_missing_deps = nil
859
865
 
@@ -871,10 +877,6 @@ module Bundler
871
877
  @locked_specs.delete(missing)
872
878
 
873
879
  @locked_spec_with_missing_deps = missing.first.name
874
- elsif !@dependency_changes
875
- @missing_lockfile_dep = current_dependencies.find do |d|
876
- @locked_specs[d.name].empty? && d.name != "bundler"
877
- end&.name
878
880
  end
879
881
 
880
882
  if invalid.any?
@@ -935,32 +937,33 @@ module Bundler
935
937
  end
936
938
 
937
939
  def converge_dependencies
938
- changes = false
940
+ @missing_lockfile_dep = nil
941
+ @changed_dependencies = []
939
942
 
940
- @dependencies.each do |dep|
943
+ current_dependencies.each do |dep|
941
944
  if dep.source
942
945
  dep.source = sources.get(dep.source)
943
946
  end
944
947
 
945
- unless locked_dep = @originally_locked_deps[dep.name]
946
- changes = true
947
- next
948
+ name = dep.name
949
+
950
+ dep_changed = @locked_deps[name].nil?
951
+
952
+ unless name == "bundler"
953
+ locked_specs = @originally_locked_specs[name]
954
+
955
+ if locked_specs.any? && !dep.matches_spec?(locked_specs.first)
956
+ @gems_to_unlock << name
957
+ dep_changed = true
958
+ elsif locked_specs.empty? && dep_changed == false
959
+ @missing_lockfile_dep = name
960
+ end
948
961
  end
949
962
 
950
- # Gem::Dependency#== matches Gem::Dependency#type. As the lockfile
951
- # doesn't carry a notion of the dependency type, if you use
952
- # add_development_dependency in a gemspec that's loaded with the gemspec
953
- # directive, the lockfile dependencies and resolved dependencies end up
954
- # with a mismatch on #type. Work around that by setting the type on the
955
- # dep from the lockfile.
956
- locked_dep.instance_variable_set(:@type, dep.type)
957
-
958
- # We already know the name matches from the hash lookup
959
- # so we only need to check the requirement now
960
- changes ||= dep.requirement != locked_dep.requirement
963
+ @changed_dependencies << name if dep_changed
961
964
  end
962
965
 
963
- changes
966
+ @changed_dependencies.any?
964
967
  end
965
968
 
966
969
  # Remove elements from the locked specs that are expired. This will most
@@ -1022,11 +1025,6 @@ module Bundler
1022
1025
  end
1023
1026
  end
1024
1027
 
1025
- if dep.nil? && requested_dep = requested_dependencies.find {|d| name == d.name }
1026
- @gems_to_unlock << name
1027
- deps << requested_dep
1028
- end
1029
-
1030
1028
  converged << s
1031
1029
  end
1032
1030
 
@@ -1095,11 +1093,15 @@ module Bundler
1095
1093
  current == proposed
1096
1094
  end
1097
1095
 
1098
- def additional_base_requirements_to_prevent_downgrades(resolution_packages, last_resolve)
1096
+ def additional_base_requirements_to_prevent_downgrades(resolution_packages)
1099
1097
  return resolution_packages unless @locked_gems && !sources.expired_sources?(@locked_gems.sources)
1100
- converge_specs(@originally_locked_specs - last_resolve).each do |locked_spec|
1098
+ @originally_locked_specs.each do |locked_spec|
1101
1099
  next if locked_spec.source.is_a?(Source::Path)
1102
- resolution_packages.base_requirements[locked_spec.name] = Gem::Requirement.new(">= #{locked_spec.version}")
1100
+
1101
+ name = locked_spec.name
1102
+ next if @changed_dependencies.include?(name)
1103
+
1104
+ resolution_packages.base_requirements[name] = Gem::Requirement.new(">= #{locked_spec.version}")
1103
1105
  end
1104
1106
  resolution_packages
1105
1107
  end
@@ -1108,7 +1110,7 @@ module Bundler
1108
1110
  return resolution_packages if @explicit_unlocks.empty?
1109
1111
  full_update = dup_for_full_unlock.resolve
1110
1112
  @explicit_unlocks.each do |name|
1111
- version = full_update[name].first&.version
1113
+ version = full_update.version_for(name)
1112
1114
  resolution_packages.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
1113
1115
  end
1114
1116
  resolution_packages