From a0b501effe4db00fe83772519bd7a33849da5395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 25 Jul 2025 11:44:33 +0200 Subject: [PATCH 1/7] [rubygems/rubygems] Remove out of date TODO After digging into git history a bit, I figure this was about unifying `bundle cache` and `bundle package`, which already happened a while ago. So remove this TODO since it's now misleading. https://github.com/rubygems/rubygems/commit/5a0b06b84d --- lib/bundler/cli/cache.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/bundler/cli/cache.rb b/lib/bundler/cli/cache.rb index 2e63a16ec3178b..92d7a1c519c219 100644 --- a/lib/bundler/cli/cache.rb +++ b/lib/bundler/cli/cache.rb @@ -16,7 +16,6 @@ def run setup_cache_all install - # TODO: move cache contents here now that all bundles are locked custom_path = Bundler.settings[:path] if options[:path] Bundler.settings.temporary(cache_all_platforms: options["all-platforms"]) do From 15e9dc19fba666d38bf48d05704b84e5810a170d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 25 Jul 2025 12:08:59 +0200 Subject: [PATCH 2/7] [rubygems/rubygems] Remove JRuby workaround Original issue was fixed in JRuby 9.3.0.0, which seems old enough for us to remove the workaround. https://github.com/rubygems/rubygems/commit/d285148d39 --- lib/bundler/source/path.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index ac76ae1fa0e44c..7511def2306192 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -124,11 +124,7 @@ def expanded_path end def expand(somepath) - if Bundler.current_ruby.jruby? # TODO: Unify when https://github.com/rubygems/bundler/issues/7598 fixed upstream and all supported jrubies include the fix - somepath.expand_path(root_path).expand_path - else - somepath.expand_path(root_path) - end + somepath.expand_path(root_path) rescue ArgumentError => e Bundler.ui.debug(e) raise PathError, "There was an error while trying to use the path " \ From e42f1aaa5aa77b51f6c590a23be59cd61776ae2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 25 Jul 2025 15:24:46 +0200 Subject: [PATCH 3/7] [rubygems/rubygems] Fix truffleruby failing to install sorbet-static when there's no lockfile The generic Ruby platform was getting unconditionally added in truffleruby, preventing resolution in situations where there's no generic ruby version (sorbet-static). Instead, the generic platform should be considered per dependency, not globally. https://github.com/rubygems/rubygems/commit/a96afc5351 --- lib/bundler/definition.rb | 1 - lib/bundler/resolver/package.rb | 1 + spec/bundler/commands/lock_spec.rb | 1 - .../install/gemfile/specific_platform_spec.rb | 18 +++++++++++++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 32006af109ee09..9fc733203c4fc6 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -740,7 +740,6 @@ def reresolve_without(incomplete_specs) def start_resolution local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && !@platforms.include?(Bundler.local_platform) @platforms << Bundler.local_platform if local_platform_needed_for_resolvability - add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby" result = SpecSet.new(resolver.start) diff --git a/lib/bundler/resolver/package.rb b/lib/bundler/resolver/package.rb index ff75e7b6bc2c94..3906be3f57718e 100644 --- a/lib/bundler/resolver/package.rb +++ b/lib/bundler/resolver/package.rb @@ -21,6 +21,7 @@ def initialize(name, platforms, locked_specs:, unlock:, prerelease: false, prefe @locked_version = locked_specs.version_for(name) @unlock = unlock @dependency = dependency || Dependency.new(name, @locked_version) + @platforms |= [Gem::Platform::RUBY] if @dependency.default_force_ruby_platform @top_level = !dependency.nil? @prerelease = @dependency.prerelease? || @locked_version&.prerelease? || prerelease ? :consider_first : :ignore @prefer_local = prefer_local diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index c47cc9727191ea..19c1a5ca8bf0ab 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -2237,7 +2237,6 @@ nokogiri (1.14.2-x86_64-linux) PLATFORMS - ruby x86_64-linux DEPENDENCIES diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 228ae7b0d06cc1..71065c36f33507 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -392,7 +392,23 @@ end end - it "installs sorbet-static, which does not provide a pure ruby variant, just fine", :truffleruby do + it "installs sorbet-static, which does not provide a pure ruby variant, in absence of a lockfile, just fine", :truffleruby do + skip "does not apply to Windows" if Gem.win_platform? + + build_repo2 do + build_gem("sorbet-static", "0.5.6403") {|s| s.platform = Bundler.local_platform } + end + + gemfile <<~G + source "https://gem.repo2" + + gem "sorbet-static", "0.5.6403" + G + + bundle "install --verbose" + end + + it "installs sorbet-static, which does not provide a pure ruby variant, in presence of a lockfile, just fine", :truffleruby do skip "does not apply to Windows" if Gem.win_platform? build_repo2 do From 2ec5e70fdb99693c0c4a100780cfe2d86e690b53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 06:51:23 +0000 Subject: [PATCH 4/7] [rubygems/rubygems] Bump thor in /bundler/spec/realworld/fixtures/tapioca Bumps [thor](https://github.com/rails/thor) from 1.3.2 to 1.4.0. - [Release notes](https://github.com/rails/thor/releases) - [Commits](https://github.com/rails/thor/compare/v1.3.2...v1.4.0) --- updated-dependencies: - dependency-name: thor dependency-version: 1.4.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] https://github.com/rubygems/rubygems/commit/0a4e5a377d --- spec/bundler/realworld/fixtures/tapioca/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock index c9ded0fd787030..39f6862b06ab0e 100644 --- a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock +++ b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock @@ -31,7 +31,7 @@ GEM spoom (>= 1.2.0) thor (>= 1.2.0) yard-sorbet - thor (1.3.2) + thor (1.4.0) yard (0.9.37) yard-sorbet (0.9.0) sorbet-runtime From 124cd77470177cb3c92f780dafd93df4b9c24f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 25 Jul 2025 12:00:05 +0200 Subject: [PATCH 5/7] [rubygems/rubygems] Keep fixture Gemfiles in sync when bumping version https://github.com/rubygems/rubygems/commit/781443cb0f --- spec/bundler/realworld/fixtures/tapioca/Gemfile.lock | 2 +- spec/bundler/realworld/fixtures/warbler/Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock index 39f6862b06ab0e..ccb51b6fd31eb3 100644 --- a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock +++ b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock @@ -46,4 +46,4 @@ DEPENDENCIES tapioca BUNDLED WITH - 2.7.0.dev + 2.8.0.dev diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock index f6d50aad359018..15f9a224e55bbb 100644 --- a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock +++ b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock @@ -36,4 +36,4 @@ DEPENDENCIES warbler! BUNDLED WITH - 2.7.0.dev + 2.8.0.dev From 862b30287ad5d03e8941c3c499ceb5f48d67d157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 25 Jul 2025 11:51:41 +0200 Subject: [PATCH 6/7] [rubygems/rubygems] Bump vendored thor to 1.4.0 https://github.com/rubygems/rubygems/commit/8078a747b3 --- .../lib/thor/actions/file_manipulation.rb | 48 ++++++++++++++++--- .../vendor/thor/lib/thor/parser/options.rb | 2 +- lib/bundler/vendor/thor/lib/thor/runner.rb | 2 +- .../vendor/thor/lib/thor/shell/basic.rb | 10 ++-- lib/bundler/vendor/thor/lib/thor/version.rb | 2 +- tool/bundler/vendor_gems.rb | 2 +- tool/bundler/vendor_gems.rb.lock | 6 +-- 7 files changed, 52 insertions(+), 20 deletions(-) diff --git a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb index bccfbb6b85e887..d8c9863054296b 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb @@ -242,6 +242,35 @@ def inject_into_module(path, module_name, *args, &block) insert_into_file(path, *(args << config), &block) end + # Run a regular expression replacement on a file, raising an error if the + # contents of the file are not changed. + # + # ==== Parameters + # path:: path of the file to be changed + # flag:: the regexp or string to be replaced + # replacement:: the replacement, can be also given as a block + # config:: give :verbose => false to not log the status, and + # :force => true, to force the replacement regardless of runner behavior. + # + # ==== Example + # + # gsub_file! 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1' + # + # gsub_file! 'README', /rake/, :green do |match| + # match << " no more. Use thor!" + # end + # + def gsub_file!(path, flag, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + + return unless behavior == :invoke || config.fetch(:force, false) + + path = File.expand_path(path, destination_root) + say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) + + actually_gsub_file(path, flag, args, true, &block) unless options[:pretend] + end + # Run a regular expression replacement on a file. # # ==== Parameters @@ -267,11 +296,7 @@ def gsub_file(path, flag, *args, &block) path = File.expand_path(path, destination_root) say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) - unless options[:pretend] - content = File.binread(path) - content.gsub!(flag, *args, &block) - File.open(path, "wb") { |file| file.write(content) } - end + actually_gsub_file(path, flag, args, false, &block) unless options[:pretend] end # Uncomment all lines matching a given regex. Preserves indentation before @@ -348,7 +373,7 @@ def capture(*args) end def with_output_buffer(buf = "".dup) #:nodoc: - raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen? + raise ArgumentError, "Buffer cannot be a frozen object" if buf.frozen? old_buffer = output_buffer self.output_buffer = buf yield @@ -357,6 +382,17 @@ def with_output_buffer(buf = "".dup) #:nodoc: self.output_buffer = old_buffer end + def actually_gsub_file(path, flag, args, error_on_no_change, &block) + content = File.binread(path) + success = content.gsub!(flag, *args, &block) + + if success.nil? && error_on_no_change + raise Bundler::Thor::Error, "The content of #{path} did not change" + end + + File.open(path, "wb") { |file| file.write(content) } + end + # Bundler::Thor::Actions#capture depends on what kind of buffer is used in ERB. # Thus CapturableERB fixes ERB to use String buffer. class CapturableERB < ERB diff --git a/lib/bundler/vendor/thor/lib/thor/parser/options.rb b/lib/bundler/vendor/thor/lib/thor/parser/options.rb index 734f5fe7e34af0..fe22d989e54095 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/options.rb @@ -144,7 +144,7 @@ def parse(args) # rubocop:disable Metrics/MethodLength def check_exclusive! opts = @assigns.keys # When option A and B are exclusive, if A and B are given at the same time, - # the diffrence of argument array size will decrease. + # the difference of argument array size will decrease. found = @exclusives.find{ |ex| (ex - opts).size < ex.size - 1 } if found names = names_to_switch_names(found & opts).map{|n| "'#{n}'"} diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb index c7cc873131f3e8..95f8b16e31893a 100644 --- a/lib/bundler/vendor/thor/lib/thor/runner.rb +++ b/lib/bundler/vendor/thor/lib/thor/runner.rb @@ -1,7 +1,6 @@ require_relative "../thor" require_relative "group" -require "yaml" require "digest/sha2" require "pathname" @@ -195,6 +194,7 @@ def thor_root def thor_yaml @thor_yaml ||= begin yaml_file = File.join(thor_root, "thor.yml") + require "yaml" yaml = YAML.load_file(yaml_file) if File.exist?(yaml_file) yaml || {} end diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb index b3e85733cba788..da02b9422758e5 100644 --- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +++ b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb @@ -314,7 +314,7 @@ def show_diff(destination, content) #:nodoc: diff_cmd = ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u" require "tempfile" - Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp| + Tempfile.open(File.basename(destination), File.dirname(destination), binmode: true) do |temp| temp.write content temp.rewind system %(#{diff_cmd} "#{destination}" "#{temp.path}") @@ -372,16 +372,12 @@ def merge(destination, content) #:nodoc: Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp| temp.write content temp.rewind - system %(#{merge_tool} "#{temp.path}" "#{destination}") + system(merge_tool, temp.path, destination) end end def merge_tool #:nodoc: - @merge_tool ||= ENV["THOR_MERGE"] || git_merge_tool - end - - def git_merge_tool #:nodoc: - `git config merge.tool`.rstrip rescue "" + @merge_tool ||= ENV["THOR_MERGE"] || "git difftool --no-index" end end end diff --git a/lib/bundler/vendor/thor/lib/thor/version.rb b/lib/bundler/vendor/thor/lib/thor/version.rb index cd7b4f060eac5b..5474a2f71badc8 100644 --- a/lib/bundler/vendor/thor/lib/thor/version.rb +++ b/lib/bundler/vendor/thor/lib/thor/version.rb @@ -1,3 +1,3 @@ class Bundler::Thor - VERSION = "1.3.2" + VERSION = "1.4.0" end diff --git a/tool/bundler/vendor_gems.rb b/tool/bundler/vendor_gems.rb index 71a7fbf4b0f7cc..b3e06d3f096047 100644 --- a/tool/bundler/vendor_gems.rb +++ b/tool/bundler/vendor_gems.rb @@ -12,6 +12,6 @@ gem "resolv", "0.6.2" gem "securerandom", "0.4.1" gem "timeout", "0.4.3" -gem "thor", "1.3.2" +gem "thor", "1.4.0" gem "tsort", "0.2.0" gem "uri", "1.0.3" diff --git a/tool/bundler/vendor_gems.rb.lock b/tool/bundler/vendor_gems.rb.lock index 82dbe8963c46bf..825107514a6f1a 100644 --- a/tool/bundler/vendor_gems.rb.lock +++ b/tool/bundler/vendor_gems.rb.lock @@ -37,7 +37,7 @@ GEM optparse (0.6.0) resolv (0.6.2) securerandom (0.4.1) - thor (1.3.2) + thor (1.4.0) timeout (0.4.3) tsort (0.2.0) uri (1.0.3) @@ -60,7 +60,7 @@ DEPENDENCIES pub_grub! resolv (= 0.6.2) securerandom (= 0.4.1) - thor (= 1.3.2) + thor (= 1.4.0) timeout (= 0.4.3) tsort (= 0.2.0) uri (= 1.0.3) @@ -76,7 +76,7 @@ CHECKSUMS pub_grub (0.5.0) resolv (0.6.2) sha256=61efe545cedddeb1b14f77e51f85c85ca66af5098fdbf567fadf32c34590fb14 securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 - thor (1.3.2) sha256=eef0293b9e24158ccad7ab383ae83534b7ad4ed99c09f96f1a6b036550abbeda + thor (1.4.0) sha256=8763e822ccb0f1d7bee88cde131b19a65606657b847cc7b7b4b82e772bcd8a3d timeout (0.4.3) sha256=9509f079b2b55fe4236d79633bd75e34c1c1e7e3fb4b56cb5fda61f80a0fe30e tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f uri (1.0.3) sha256=e9f2244608eea2f7bc357d954c65c910ce0399ca5e18a7a29207ac22d8767011 From e2fbd01714d5f98a7707a47bad6b4759aa132032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 25 Jul 2025 12:14:09 +0200 Subject: [PATCH 7/7] [rubygems/rubygems] Remove unnecessary endless loop detection Fixes a TODO now that no reports have been reported in a while. https://github.com/rubygems/rubygems/commit/f10dc84e7b --- lib/bundler/definition.rb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 9fc733203c4fc6..6c7a3e9c38a613 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -645,20 +645,12 @@ def filter_specs(specs, deps, skips: []) end def materialize(dependencies) - # Tracks potential endless loops trying to re-resolve. - # TODO: Remove as dead code if not reports are received in a while - incorrect_spec = nil - specs = begin resolve.materialize(dependencies) rescue IncorrectLockfileDependencies => e raise if Bundler.frozen_bundle? - spec = e.spec - raise "Infinite loop while fixing lockfile dependencies" if incorrect_spec == spec - - incorrect_spec = spec - reresolve_without([spec]) + reresolve_without([e.spec]) retry end