Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions bundler/lib/bundler/definition.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative "lockfile_parser"
require_relative "worker"

module Bundler
class Definition
Expand Down Expand Up @@ -1100,7 +1101,23 @@ def source_requirements
@source_requirements ||= find_source_requirements
end

def preload_git_source_worker
@preload_git_source_worker ||= Bundler::Worker.new(5, "Git source preloading", ->(source, _) { source.specs })
end

def preload_git_sources
sources.git_sources.each {|source| preload_git_source_worker.enq(source) }
ensure
preload_git_source_worker.stop
end

def find_source_requirements
if Gem.ruby_version >= "3.3"
# Ruby 3.2 has a bug that incorrectly triggers a circular dependency warning. This version will continue to
# fetch git repositories one by one.
preload_git_sources
end

# Record the specs available in each gem's source, so that those
# specs will be available later when the resolver knows where to
# look for that gemspec (or its dependencies)
Expand Down
16 changes: 10 additions & 6 deletions bundler/lib/bundler/ui/shell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def initialize(options = {})
@level = ENV["DEBUG"] ? "debug" : "info"
@warning_history = []
@output_stream = :stdout
@thread_safe_logger_key = "logger_level_#{object_id}"
end

def add_color(string, *color)
Expand Down Expand Up @@ -97,11 +98,13 @@ def level=(level)
end

def level(name = nil)
return @level unless name
current_level = Thread.current.thread_variable_get(@thread_safe_logger_key) || @level
return current_level unless name

unless index = LEVELS.index(name)
raise "#{name.inspect} is not a valid level"
end
index <= LEVELS.index(@level)
index <= LEVELS.index(current_level)
end

def output_stream=(symbol)
Expand Down Expand Up @@ -167,12 +170,13 @@ def word_wrap(text, line_width = Thor::Terminal.terminal_width)
end * "\n"
end

def with_level(level)
original = @level
@level = level
def with_level(desired_level)
old_level = level
Thread.current.thread_variable_set(@thread_safe_logger_key, desired_level)

yield
ensure
@level = original
Thread.current.thread_variable_set(@thread_safe_logger_key, old_level)
end

def with_output_stream(symbol)
Expand Down
28 changes: 28 additions & 0 deletions bundler/spec/bundler/ui/shell_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,32 @@
end
end
end

describe "threads" do
it "is thread safe when using with_level" do
stop_thr1 = false
stop_thr2 = false

expect(subject.level).to eq("debug")

thr1 = Thread.new do
subject.silence do
sleep(0.1) until stop_thr1
end

stop_thr2 = true
end

thr2 = Thread.new do
subject.silence do
stop_thr1 = true
sleep(0.1) until stop_thr2
end
end

[thr1, thr2].each(&:join)

expect(subject.level).to eq("debug")
end
end
end
9 changes: 5 additions & 4 deletions bundler/spec/commands/ssl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@
end
end

@previous_level = Bundler.ui.level
Bundler.ui.instance_variable_get(:@warning_history).clear
@previous_client = Gem::Request::ConnectionPools.client
@previous_ui = Bundler.ui
Bundler.ui = Bundler::UI::Shell.new
Bundler.ui.level = "info"

@previous_client = Gem::Request::ConnectionPools.client
Artifice.activate_with(@dummy_endpoint)
Gem::Request::ConnectionPools.client = Gem::Net::HTTP
end

after(:each) do
Bundler.ui.level = @previous_level
Bundler.ui = @previous_ui
Artifice.deactivate
Gem::Request::ConnectionPools.client = @previous_client
end
Expand Down