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
19 changes: 16 additions & 3 deletions bundler/lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1125,11 +1125,24 @@ def preload_git_source_worker
end

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

# Git sources needed for the requested groups (excludes sources only used by --without groups)
def needed_git_sources
needed_deps = dependencies_for(requested_groups)
sources.git_sources.select do |source|
needed_deps.any? {|d| d.source == source }
end
end

# Git sources that should be excluded (only used by --without groups)
def excluded_git_sources
sources.git_sources - needed_git_sources
end

def find_source_requirements
if Gem.ruby_version >= Gem::Version.new("3.3")
# Ruby 3.2 has a bug that incorrectly triggers a circular dependency warning. This version will continue to
Expand All @@ -1141,10 +1154,10 @@ def find_source_requirements
# specs will be available later when the resolver knows where to
# look for that gemspec (or its dependencies)
source_requirements = if precompute_source_requirements_for_indirect_dependencies?
all_requirements = source_map.all_requirements
all_requirements = source_map.all_requirements(excluded_git_sources)
{ default: default_source }.merge(all_requirements)
else
{ default: Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
{ default: Source::RubygemsAggregate.new(sources, source_map, excluded_git_sources) }.merge(source_map.direct_requirements)
end
source_requirements.merge!(source_map.locked_requirements) if nothing_changed?
metadata_dependencies.each do |dep|
Expand Down
5 changes: 4 additions & 1 deletion bundler/lib/bundler/source/rubygems_aggregate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ class Source
class RubygemsAggregate
attr_reader :source_map, :sources

def initialize(sources, source_map)
def initialize(sources, source_map, excluded_sources = [])
@sources = sources
@source_map = source_map
@excluded_sources = excluded_sources

@index = build_index
end
Expand All @@ -31,6 +32,8 @@ def build_index
dependency_names = source_map.pinned_spec_names

sources.all_sources.each do |source|
next if @excluded_sources.include?(source)

source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
idx.add_source source.specs
dependency_names.concat(source.unmet_deps).uniq!
Expand Down
8 changes: 6 additions & 2 deletions bundler/lib/bundler/source_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ def pinned_spec_names(skip = nil)
direct_requirements.reject {|_, source| source == skip }.keys
end

def all_requirements
def all_requirements(excluded_sources = [])
requirements = direct_requirements.dup

unmet_deps = sources.non_default_explicit_sources.map do |source|
explicit_sources = sources.non_default_explicit_sources.reject do |source|
excluded_sources.include?(source)
end

unmet_deps = explicit_sources.map do |source|
(source.spec_names - pinned_spec_names).each do |indirect_dependency_name|
previous_source = requirements[indirect_dependency_name]
if previous_source.nil?
Expand Down
28 changes: 28 additions & 0 deletions bundler/spec/install/git_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,32 @@
end
end
end

describe "with excluded groups" do
it "works if you exclude a group with a git gem", ruby: ">= 3.3" do
build_git "production_gem", "1.0"
build_git "development_gem", "1.0"

gemfile <<-G
source "https://gem.repo1"

gem "production_gem", :git => "#{lib_path("production_gem-1.0")}"

group :development do
gem "development_gem", :git => "#{lib_path("development_gem-1.0")}"
end
G

# First install all groups to create lockfile
bundle :install

# Set without and reinstall
bundle "config set --local without development"
bundle :install

# Verify only production gem is available
expect(the_bundle).to include_gems("production_gem 1.0")
expect(the_bundle).not_to include_gems("development_gem 1.0")
end
end
end