From 413d15a3440abf570fc4bff24fe4b5ee8b7880a5 Mon Sep 17 00:00:00 2001 From: Edouard CHIN Date: Fri, 28 Nov 2025 02:08:21 +0100 Subject: [PATCH 1/7] [ruby/rubygems] Add `MAKEFLAGS=-j` by default before compiling: - Depending on the native extension, it can greatly reduce compilation time when executing recipes simultaneously. For example on Prism: ``` # Before time gem install prism Building native extensions. This could take a while... Successfully installed prism-1.6.0 1 gem installed gem install prism 3.61s user 0.80s system 95% cpu 4.595 total ``` ``` # After time MAKEFLAGS="-j" gem install prism Building native extensions. This could take a while... Successfully installed prism-1.6.0 1 gem installed MAKEFLAGS="-j" gem install prism 4.47s user 1.27s system 246% cpu 2.330 total ``` I don't think adding `-j` as a default is harmful, but I'm admitedly not very knowledgable when it comes to compiler. https://github.com/ruby/rubygems/commit/61340081c6 Co-authored-by: Aaron Patterson --- lib/rubygems/ext/ext_conf_builder.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb index ec2fa59412df64..021273ef12e3f0 100644 --- a/lib/rubygems/ext/ext_conf_builder.rb +++ b/lib/rubygems/ext/ext_conf_builder.rb @@ -40,6 +40,7 @@ def self.build(extension, dest_path, results, args = [], lib_dir = nil, extensio end ENV["DESTDIR"] = nil + ENV["MAKEFLAGS"] ||= "-j#{Etc.nprocessors + 1}" make dest_path, results, extension_dir, tmp_dest_relative, target_rbconfig: target_rbconfig From 7bd80e7e3e3dbb724616c038e6e0944128d6f905 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 29 Nov 2025 07:06:24 +0900 Subject: [PATCH 2/7] nmake didn't support -j flag --- lib/rubygems/ext/ext_conf_builder.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb index 021273ef12e3f0..745cf08b6c8b45 100644 --- a/lib/rubygems/ext/ext_conf_builder.rb +++ b/lib/rubygems/ext/ext_conf_builder.rb @@ -40,7 +40,9 @@ def self.build(extension, dest_path, results, args = [], lib_dir = nil, extensio end ENV["DESTDIR"] = nil - ENV["MAKEFLAGS"] ||= "-j#{Etc.nprocessors + 1}" + unless RbConfig::CONFIG["MAKE"] =~ /nmake/ + ENV["MAKEFLAGS"] ||= "-j#{Etc.nprocessors + 1}" + end make dest_path, results, extension_dir, tmp_dest_relative, target_rbconfig: target_rbconfig From bb2e4d58cce135d3609dba1ee17ed614522a88bf Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 28 Nov 2025 16:57:15 +0900 Subject: [PATCH 3/7] [ruby/rubygems] Fixed checksums generation issue when no source is specified https://github.com/ruby/rubygems/commit/bb4d791cb4 --- lib/bundler/definition.rb | 2 ++ spec/bundler/commands/lock_spec.rb | 50 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 437390f3ec448b..2fa7d0d277943b 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -539,6 +539,8 @@ def unlocking? end def add_checksums + require "rubygems/package" + @locked_checksums = true setup_domain!(add_checksums: true) diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index ab1926734c1e78..c8af9c8dd404fb 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -2035,6 +2035,56 @@ L end + it "adds checksums when source is not specified" do + system_gems(%w[myrack-1.0.0], path: default_bundle_path) + + gemfile <<-G + gem "myrack" + G + + lockfile <<~L + GEM + specs: + myrack (1.0.0) + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + myrack + + BUNDLED WITH + #{Bundler::VERSION} + L + + simulate_platform "x86_64-linux" do + bundle "lock --add-checksums" + end + + # myrack is coming from gem_repo1 + # but it's simulated to install in the system gems path + checksums = checksums_section do |c| + c.checksum gem_repo1, "myrack", "1.0.0" + end + + expect(lockfile).to eq <<~L + GEM + specs: + myrack (1.0.0) + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + myrack + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + end + it "adds checksums to an existing lockfile, when gems are already installed" do build_repo4 do build_gem "nokogiri", "1.14.2" From f18bedaf96d950a69ae18df9a7eeea6754224c20 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 29 Nov 2025 07:18:43 +0900 Subject: [PATCH 4/7] [ruby/rubygems] Use String#include? with suggested by Performance/StringInclude cop https://github.com/ruby/rubygems/commit/fdd3419144 --- lib/rubygems/ext/ext_conf_builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb index 745cf08b6c8b45..bc70ed67fb8604 100644 --- a/lib/rubygems/ext/ext_conf_builder.rb +++ b/lib/rubygems/ext/ext_conf_builder.rb @@ -40,7 +40,7 @@ def self.build(extension, dest_path, results, args = [], lib_dir = nil, extensio end ENV["DESTDIR"] = nil - unless RbConfig::CONFIG["MAKE"] =~ /nmake/ + unless RbConfig::CONFIG["MAKE"]&.include?("nmake") ENV["MAKEFLAGS"] ||= "-j#{Etc.nprocessors + 1}" end From 7dae2a1f488afc4133dfbd6ea243aaeb71107f71 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 26 Nov 2025 18:58:42 +0100 Subject: [PATCH 5/7] [ruby/rubygems] Restore `install` as default command Fix: https://github.com/ruby/rubygems/issues/9124 This behavior is a deeply entrenched convention and changing it will annoy lots of developers with unclear gains. https://github.com/ruby/rubygems/commit/628e0ede46 --- lib/bundler/cli.rb | 12 +----------- spec/bundler/bundler/cli_spec.rb | 3 +-- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 55f656e3f3afd0..b7829f2a0db248 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -123,17 +123,7 @@ def cli_help def self.default_command(meth = nil) return super if meth - default_cli_command = Bundler.settings[:default_cli_command] - return default_cli_command if default_cli_command - - Bundler.ui.warn(<<~MSG) - In the next version of Bundler, running `bundle` without argument will no longer run `bundle install`. - Instead, the `help` command will be displayed. - - If you'd like to keep the previous behaviour please run `bundle config set default_cli_command install --global`. - MSG - - "install" + Bundler.settings[:default_cli_command] || "install" end class_option "no-color", type: :boolean, desc: "Disable colorization in output" diff --git a/spec/bundler/bundler/cli_spec.rb b/spec/bundler/bundler/cli_spec.rb index ee3c0d0fd50ff5..611c1985e277b3 100644 --- a/spec/bundler/bundler/cli_spec.rb +++ b/spec/bundler/bundler/cli_spec.rb @@ -87,9 +87,8 @@ def out_with_macos_man_workaround end context "with no arguments" do - it "installs and log a warning by default" do + it "installs by default" do bundle "", raise_on_error: false - expect(err).to include("running `bundle` without argument will no longer run `bundle install`.") expect(err).to include("Could not locate Gemfile") end From 69293f52550032cbda8d92188407b8700f4c3bb1 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 26 Nov 2025 20:03:13 +0100 Subject: [PATCH 6/7] [ruby/rubygems] Print help summary when the default command fail As mentioned in https://github.com/ruby/rubygems/issues/9124, the intent for changing the default command was to be more welcoming. I think we can acheive that by attempting to install, but to print that same help message if there is no Gemfile. That should address both concerns. https://github.com/ruby/rubygems/commit/f3f505c02a --- lib/bundler/cli.rb | 23 ++++++++++++++++++++++- lib/bundler/vendor/thor/lib/thor.rb | 2 +- spec/bundler/bundler/cli_spec.rb | 13 +------------ spec/bundler/other/cli_dispatch_spec.rb | 2 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index b7829f2a0db248..d3c948c7ce22ce 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -120,10 +120,18 @@ def cli_help self.class.send(:class_options_help, shell) end + desc "install_or_cli_help", "Tries to run bundle install but prints a summary of bundler commands if there is no Gemfile", hide: true + def install_or_cli_help + invoke_other_command("install") + rescue GemfileNotFound => error + Bundler.ui.error error.message, wrap: true + invoke_other_command("cli_help") + end + def self.default_command(meth = nil) return super if meth - Bundler.settings[:default_cli_command] || "install" + Bundler.settings[:default_cli_command] || "install_or_cli_help" end class_option "no-color", type: :boolean, desc: "Disable colorization in output" @@ -713,6 +721,19 @@ def current_command config[:current_command] end + def invoke_other_command(name) + _, _, config = @_initializer + original_command = config[:current_command] + command = self.class.all_commands[name] + config[:current_command] = command + send(name) + ensure + config[:current_command] = original_command + end + + def current_command=(command) + end + def print_command return unless Bundler.ui.debug? cmd = current_command diff --git a/lib/bundler/vendor/thor/lib/thor.rb b/lib/bundler/vendor/thor/lib/thor.rb index bfd9f5c91412ab..945bdbd5515fe5 100644 --- a/lib/bundler/vendor/thor/lib/thor.rb +++ b/lib/bundler/vendor/thor/lib/thor.rb @@ -625,7 +625,7 @@ def normalize_command_name(meth) #:nodoc: # alias name. def find_command_possibilities(meth) len = meth.to_s.length - possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort + possibilities = all_commands.reject { |_k, c| c.hidden? }.merge(map).keys.select { |n| meth == n[0, len] }.sort unique_possibilities = possibilities.map { |k| map[k] || k }.uniq if possibilities.include?(meth) diff --git a/spec/bundler/bundler/cli_spec.rb b/spec/bundler/bundler/cli_spec.rb index 611c1985e277b3..33a23a75def180 100644 --- a/spec/bundler/bundler/cli_spec.rb +++ b/spec/bundler/bundler/cli_spec.rb @@ -87,27 +87,16 @@ def out_with_macos_man_workaround end context "with no arguments" do - it "installs by default" do + it "tries to installs by default but print help on missing Gemfile" do bundle "", raise_on_error: false expect(err).to include("Could not locate Gemfile") - end - it "prints a concise help message when default_cli_command set to cli_help" do - bundle "config set default_cli_command cli_help" - bundle "" - expect(err).to be_empty expect(out).to include("Bundler version #{Bundler::VERSION}"). and include("\n\nBundler commands:\n\n"). and include("\n\n Primary commands:\n"). and include("\n\n Utilities:\n"). and include("\n\nOptions:\n") end - - it "runs bundle install when default_cli_command set to install" do - bundle "config set default_cli_command install" - bundle "", raise_on_error: false - expect(err).to include("Could not locate Gemfile") - end end context "when ENV['BUNDLE_GEMFILE'] is set to an empty string" do diff --git a/spec/bundler/other/cli_dispatch_spec.rb b/spec/bundler/other/cli_dispatch_spec.rb index 1039737b993983..a2c745b0703d24 100644 --- a/spec/bundler/other/cli_dispatch_spec.rb +++ b/spec/bundler/other/cli_dispatch_spec.rb @@ -15,6 +15,6 @@ it "print a friendly error when ambiguous" do bundle "in", raise_on_error: false - expect(err).to eq("Ambiguous command in matches [info, init, inject, install]") + expect(err).to eq("Ambiguous command in matches [info, init, install]") end end From a9d2a46d64ead4dae8491c2f93b9e86416006fd4 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 28 Nov 2025 19:23:50 +0900 Subject: [PATCH 7/7] [ruby/rubygems] Add informational message when default_cli_command is unset. https://github.com/ruby/rubygems/commit/9e44b5ebc4 --- lib/bundler/cli.rb | 10 ++++++++++ spec/bundler/bundler/cli_spec.rb | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index d3c948c7ce22ce..f5977863ddcc26 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -131,6 +131,16 @@ def install_or_cli_help def self.default_command(meth = nil) return super if meth + unless Bundler.settings[:default_cli_command] + Bundler.ui.info <<-MSG + In the feature version of Bundler, running `bundle` without argument will no longer run `bundle install`. + Instead, the `cli_help` command will be displayed. Please use `bundle install` explicitly for scripts like CI/CD. + If you wish to use feature behavior now with `bundle config set default_cli_command cli_help --global` + or you can continue to use the old behavior with `bundle config set default_cli_command install_or_cli_help --global`. + This message will be removed after a default_cli_command value is set. + MSG + end + Bundler.settings[:default_cli_command] || "install_or_cli_help" end diff --git a/spec/bundler/bundler/cli_spec.rb b/spec/bundler/bundler/cli_spec.rb index 33a23a75def180..ac6b77ad7483bf 100644 --- a/spec/bundler/bundler/cli_spec.rb +++ b/spec/bundler/bundler/cli_spec.rb @@ -90,6 +90,7 @@ def out_with_macos_man_workaround it "tries to installs by default but print help on missing Gemfile" do bundle "", raise_on_error: false expect(err).to include("Could not locate Gemfile") + expect(out).to include("In the feature version of Bundler") expect(out).to include("Bundler version #{Bundler::VERSION}"). and include("\n\nBundler commands:\n\n"). @@ -97,6 +98,13 @@ def out_with_macos_man_workaround and include("\n\n Utilities:\n"). and include("\n\nOptions:\n") end + + it "runs bundle install when default_cli_command set to install" do + bundle "config set default_cli_command install_or_cli_help" + bundle "", raise_on_error: false + expect(out).to_not include("In the feature version of Bundler") + expect(err).to include("Could not locate Gemfile") + end end context "when ENV['BUNDLE_GEMFILE'] is set to an empty string" do