From 69293f52550032cbda8d92188407b8700f4c3bb1 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 26 Nov 2025 20:03:13 +0100 Subject: [PATCH] [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 b7829f2a0d..d3c948c7ce 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -120,10 +120,18 @@ module Bundler 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 @@ module Bundler 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 bfd9f5c914..945bdbd551 100644 --- a/lib/bundler/vendor/thor/lib/thor.rb +++ b/lib/bundler/vendor/thor/lib/thor.rb @@ -625,7 +625,7 @@ class Bundler::Thor # 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 611c1985e2..33a23a75de 100644 --- a/spec/bundler/bundler/cli_spec.rb +++ b/spec/bundler/bundler/cli_spec.rb @@ -87,27 +87,16 @@ RSpec.describe "bundle executable" do 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 1039737b99..a2c745b070 100644 --- a/spec/bundler/other/cli_dispatch_spec.rb +++ b/spec/bundler/other/cli_dispatch_spec.rb @@ -15,6 +15,6 @@ RSpec.describe "bundle command names" do 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