From bb3c922341eb7a873a021cbd287a5aec9f2fa1be Mon Sep 17 00:00:00 2001 From: Josh Nichols Date: Tue, 28 Mar 2023 15:45:41 -0400 Subject: [PATCH] Add auto_install support to require "bundler/setup" We have some places that already use `bundle config auto_install true`, ie: https://github.com/technicalpickles/rubygems/blob/7a144f3374f6a400cc9832f072dc1fc0bca8c724/bundler/lib/bundler/cli.rb#L11 This applies the same logic (copy and pasted) to happen when you `require "bundler/setup"`. --- bundler/lib/bundler.rb | 20 ++++++++++++++++++++ bundler/lib/bundler/cli.rb | 23 ++--------------------- bundler/lib/bundler/setup.rb | 3 +++ bundler/spec/runtime/setup_spec.rb | 15 +++++++++++++++ 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/bundler/lib/bundler.rb b/bundler/lib/bundler.rb index 50b7a0c83781..5033109db64a 100644 --- a/bundler/lib/bundler.rb +++ b/bundler/lib/bundler.rb @@ -40,6 +40,7 @@ module Bundler SUDO_MUTEX = Thread::Mutex.new autoload :Checksum, File.expand_path("bundler/checksum", __dir__) + autoload :CLI, File.expand_path("bundler/cli", __dir__) autoload :CIDetector, File.expand_path("bundler/ci_detector", __dir__) autoload :Definition, File.expand_path("bundler/definition", __dir__) autoload :Dependency, File.expand_path("bundler/dependency", __dir__) @@ -165,6 +166,25 @@ def setup(*groups) end end + # Automatically install dependencies if Bundler.settings[:auto_install] exists. + # This is set through config cmd `bundle config set --global auto_install 1`. + # + # Note that this method `nil`s out the global Definition object, so it + # should be called first, before you instantiate anything like an + # `Installer` that'll keep a reference to the old one instead. + def auto_install + return unless settings[:auto_install] + + begin + definition.specs + rescue GemNotFound, GitError + ui.info "Automatically installing missing gems." + reset! + CLI::Install.new({}).run + reset! + end + end + # Setups Bundler environment (see Bundler.setup) if it is not already set, # and loads all gems from groups specified. Unlike ::setup, can be called # multiple times with different groups (if they were allowed by setup). diff --git a/bundler/lib/bundler/cli.rb b/bundler/lib/bundler/cli.rb index 98d8cfe307e0..40f19c7fed1d 100644 --- a/bundler/lib/bundler/cli.rb +++ b/bundler/lib/bundler/cli.rb @@ -5,6 +5,7 @@ module Bundler class CLI < Thor require_relative "cli/common" + require_relative "cli/install" package_name "Bundler" @@ -69,7 +70,7 @@ def initialize(*args) Bundler.settings.set_command_option_if_given :retry, options[:retry] current_cmd = args.last[:current_command].name - auto_install if AUTO_INSTALL_CMDS.include?(current_cmd) + Bundler.auto_install if AUTO_INSTALL_CMDS.include?(current_cmd) rescue UnknownArgumentError => e raise InvalidOption, e.message ensure @@ -737,26 +738,6 @@ def self.deprecated_ext_value?(arguments) private - # Automatically invoke `bundle install` and resume if - # Bundler.settings[:auto_install] exists. This is set through config cmd - # `bundle config set --global auto_install 1`. - # - # Note that this method `nil`s out the global Definition object, so it - # should be called first, before you instantiate anything like an - # `Installer` that'll keep a reference to the old one instead. - def auto_install - return unless Bundler.settings[:auto_install] - - begin - Bundler.definition.specs - rescue GemNotFound, GitError - Bundler.ui.info "Automatically installing missing gems." - Bundler.reset! - invoke :install, [] - Bundler.reset! - end - end - def current_command _, _, config = @_initializer config[:current_command] diff --git a/bundler/lib/bundler/setup.rb b/bundler/lib/bundler/setup.rb index 7131d150558f..6010d6674282 100644 --- a/bundler/lib/bundler/setup.rb +++ b/bundler/lib/bundler/setup.rb @@ -5,6 +5,9 @@ if Bundler::SharedHelpers.in_bundle? require_relative "../bundler" + # try to auto_install first before we get to the `Bundler.ui.silence`, so user knows what is happening + Bundler.auto_install + if STDOUT.tty? || ENV["BUNDLER_FORCE_TTY"] begin Bundler.ui.silence { Bundler.setup } diff --git a/bundler/spec/runtime/setup_spec.rb b/bundler/spec/runtime/setup_spec.rb index ccfe5d55b683..0344d24223fd 100644 --- a/bundler/spec/runtime/setup_spec.rb +++ b/bundler/spec/runtime/setup_spec.rb @@ -1599,4 +1599,19 @@ def require(path) sys_exec "#{Gem.ruby} #{script}", raise_on_error: false expect(out).to include("requiring foo used the monkeypatch") end + + it "performs an automatic bundle install" do + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem "rack", :group => :test + G + + bundle "config set auto_install 1" + + ruby <<-RUBY + require 'bundler/setup' + RUBY + expect(err).to be_empty + expect(out).to include("Installing rack 1.0.0") + end end