Skip to content

Commit

Permalink
[rubygems/rubygems] Add auto_install support to require "bundler/setup"
Browse files Browse the repository at this point in the history
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"`.

rubygems/rubygems@bb3c922341
  • Loading branch information
technicalpickles authored and matzbot committed Apr 25, 2024
1 parent b6489e9 commit 6f4f360
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 21 deletions.
20 changes: 20 additions & 0 deletions lib/bundler.rb
Expand Up @@ -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__)
Expand Down Expand Up @@ -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).
Expand Down
23 changes: 2 additions & 21 deletions lib/bundler/cli.rb
Expand Up @@ -5,6 +5,7 @@
module Bundler
class CLI < Thor
require_relative "cli/common"
require_relative "cli/install"

package_name "Bundler"

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down
3 changes: 3 additions & 0 deletions lib/bundler/setup.rb
Expand Up @@ -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 }
Expand Down
15 changes: 15 additions & 0 deletions spec/bundler/runtime/setup_spec.rb
Expand Up @@ -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

0 comments on commit 6f4f360

Please sign in to comment.