Skip to content

Commit

Permalink
Merge pull request #4750 from rubygems/speed_up_bundler_setup
Browse files Browse the repository at this point in the history
Slightly speed up `bundler/setup`
  • Loading branch information
deivid-rodriguez committed Jul 12, 2021
2 parents 0702369 + eb54835 commit 8459ebd
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 35 deletions.
51 changes: 23 additions & 28 deletions bundler/lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,25 +190,15 @@ def resolve_remotely!
#
# @return [Bundler::SpecSet]
def specs
@specs ||= begin
begin
specs = resolve.materialize(requested_dependencies)
rescue GemNotFound => e # Handle yanked gem
gem_name, gem_version = extract_gem_info(e)
locked_gem = @locked_specs[gem_name].last
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
"removed in order to install."
end
unless specs["bundler"].any?
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
specs["bundler"] = bundler
end

specs
end
@specs ||= add_bundler_to(resolve.materialize(requested_dependencies))
rescue GemNotFound => e # Handle yanked gem
gem_name, gem_version = extract_gem_info(e)
locked_gem = @locked_specs[gem_name].last
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
"removed in order to install."
end

def new_specs
Expand Down Expand Up @@ -240,17 +230,11 @@ def missing_specs?
end

def requested_specs
@requested_specs ||= begin
groups = requested_groups
groups.map!(&:to_sym)
specs_for(groups)
end
specs_for(requested_groups)
end

def requested_dependencies
groups = requested_groups
groups.map!(&:to_sym)
dependencies_for(groups)
dependencies_for(requested_groups)
end

def current_dependencies
Expand All @@ -260,11 +244,13 @@ def current_dependencies
end

def specs_for(groups)
groups = requested_groups if groups.empty?
deps = dependencies_for(groups)
SpecSet.new(specs.for(expand_dependencies(deps)))
add_bundler_to(resolve.materialize(expand_dependencies(deps)))
end

def dependencies_for(groups)
groups.map!(&:to_sym)
current_dependencies.reject do |d|
(d.groups & groups).empty?
end
Expand Down Expand Up @@ -514,6 +500,15 @@ def unlocking?

private

def add_bundler_to(specs)
unless specs["bundler"].any?
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
specs["bundler"] = bundler
end

specs
end

def precompute_source_requirements_for_indirect_dependencies?
sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
end
Expand Down
2 changes: 1 addition & 1 deletion bundler/lib/bundler/installer/standalone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Bundler
class Standalone
def initialize(groups, definition)
@specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
@specs = definition.specs_for(groups)
end

def generate
Expand Down
4 changes: 1 addition & 3 deletions bundler/lib/bundler/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ def initialize(root, definition)
def setup(*groups)
@definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?

groups.map!(&:to_sym)

# Has to happen first
clean_load_path

specs = groups.any? ? @definition.specs_for(groups) : requested_specs
specs = @definition.specs_for(groups)

SharedHelpers.set_bundle_environment
Bundler.rubygems.replace_entrypoints(specs)
Expand Down
6 changes: 3 additions & 3 deletions bundler/lib/bundler/spec_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ def for(dependencies, check = false, match_current_platform = false, raise_on_mi

loop do
break unless dep = deps.shift
next if handled.include?(dep)
next if handled.any?{|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"

handled << dep

specs_for_dep = spec_for_dependency(dep, match_current_platform)
if specs_for_dep.any?
specs |= specs_for_dep
specs += specs_for_dep

specs_for_dep.first.dependencies.each do |d|
next if d.type == :development
Expand All @@ -42,7 +42,7 @@ def for(dependencies, check = false, match_current_platform = false, raise_on_mi
end

if spec = lookup["bundler"].first
specs |= [spec]
specs << spec
end

check ? true : specs
Expand Down
19 changes: 19 additions & 0 deletions bundler/spec/runtime/setup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,25 @@ def clean_load_path(lp)
expect(err).to be_empty
end

it "doesn't re-resolve when a pre-release bundler is used and a dependency includes a dependency on bundler" do
system_gems "bundler-9.99.9.beta1"

build_repo4 do
build_gem "depends_on_bundler", "1.0" do |s|
s.add_dependency "bundler", ">= 1.5.0"
end
end

install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "depends_on_bundler"
G

ruby "require '#{system_gem_path("gems/bundler-9.99.9.beta1/lib/bundler.rb")}'; Bundler.setup", :env => { "DEBUG" => "1" }
expect(out).to include("Found no changes, using resolution from the lockfile")
expect(err).to be_empty
end

it "remembers --without and does not include groups passed to Bundler.setup" do
bundle "config set --local without rails"
install_gemfile <<-G
Expand Down

0 comments on commit 8459ebd

Please sign in to comment.