Skip to content

Commit 89ed2bc

Browse files
yahondaclaude
andcommitted
Skip git source exclusion when lockfile cannot backfill
The git source exclusion in `find_source_requirements` introduced by #9234 relies on `locked_requirements` to backfill the gap for sources used only by --without groups. Without a Gemfile.lock — e.g. an initial `BUNDLE_ONLY=ci bundle install` where a default-group gem from a git source is shifted into the "excluded" set — that fallback is absent, and the source's indirect dependencies fall through to the default rubygems source, causing resolution to fail. Gate the exclusion on `nothing_changed?` so it only applies when the lockfile is guaranteed to cover the excluded sources. Fix #9536 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 92b0305 commit 89ed2bc

2 files changed

Lines changed: 55 additions & 3 deletions

File tree

bundler/lib/bundler/definition.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,16 +1210,20 @@ def excluded_git_sources
12101210
def find_source_requirements
12111211
preload_git_sources
12121212

1213+
# Only safe to exclude when locked_requirements (merged below) backfills the gap.
1214+
nothing_changed = nothing_changed?
1215+
excluded = nothing_changed ? excluded_git_sources : []
1216+
12131217
# Record the specs available in each gem's source, so that those
12141218
# specs will be available later when the resolver knows where to
12151219
# look for that gemspec (or its dependencies)
12161220
source_requirements = if precompute_source_requirements_for_indirect_dependencies?
1217-
all_requirements = source_map.all_requirements(excluded_git_sources)
1221+
all_requirements = source_map.all_requirements(excluded)
12181222
{ default: default_source }.merge(all_requirements)
12191223
else
1220-
{ default: Source::RubygemsAggregate.new(sources, source_map, excluded_git_sources) }.merge(source_map.direct_requirements)
1224+
{ default: Source::RubygemsAggregate.new(sources, source_map, excluded) }.merge(source_map.direct_requirements)
12211225
end
1222-
source_requirements.merge!(source_map.locked_requirements) if nothing_changed?
1226+
source_requirements.merge!(source_map.locked_requirements) if nothing_changed
12231227
metadata_dependencies.each do |dep|
12241228
source_requirements[dep.name] = sources.metadata_source
12251229
end

spec/install/git_spec.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,5 +317,53 @@
317317
expect(the_bundle).to include_gems("production_gem 1.0")
318318
expect(the_bundle).not_to include_gems("development_gem 1.0")
319319
end
320+
321+
it "resolves indirect dependencies from a git source not in the requested groups" do
322+
build_lib "activesupport", "1.0", path: lib_path("rails/activesupport")
323+
build_git "activerecord", "1.0", path: lib_path("rails") do |s|
324+
s.add_dependency "activesupport", "= 1.0"
325+
end
326+
327+
gemfile <<-G
328+
source "https://gem.repo1"
329+
330+
gem "activerecord", :git => "#{lib_path("rails")}"
331+
332+
group :ci do
333+
gem "myrack"
334+
end
335+
G
336+
337+
bundle_config "only ci"
338+
bundle :install
339+
340+
expect(the_bundle).to include_gems("myrack 1.0.0")
341+
expect(the_bundle).not_to include_gems("activerecord 1.0")
342+
end
343+
344+
it "resolves indirect dependencies from a git source not in the requested groups (without compact_index dependency API)" do
345+
build_lib "activesupport", "1.0", path: lib_path("rails/activesupport")
346+
build_git "activerecord", "1.0", path: lib_path("rails") do |s|
347+
s.add_dependency "activesupport", "= 1.0"
348+
end
349+
350+
gemfile <<-G
351+
source "https://gem.repo1"
352+
353+
gem "activerecord", :git => "#{lib_path("rails")}"
354+
355+
group :ci do
356+
gem "myrack"
357+
end
358+
G
359+
360+
# Force the RubygemsAggregate code path in find_source_requirements by
361+
# making the dependency API unavailable.
362+
bundle_config "only ci"
363+
bundle :install, artifice: "endpoint_api_forbidden"
364+
365+
expect(the_bundle).to include_gems("myrack 1.0.0")
366+
expect(the_bundle).not_to include_gems("activerecord 1.0")
367+
end
320368
end
321369
end

0 commit comments

Comments
 (0)