Skip to content
Open
Changes from 1 commit
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
8 changes: 7 additions & 1 deletion bundler/lib/bundler/lockfile_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def add_section(name, value)
end

def bundler_checksum
return [] if Bundler.gem_version.to_s.end_with?(".dev")
return [] unless released_bundler?

bundler_spec = definition.sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
return [] unless File.exist?(bundler_spec.cache_file)
Expand All @@ -115,5 +115,11 @@ def bundler_checksum

[definition.sources.metadata_source.checksum_store.to_lock(bundler_spec)]
end

def released_bundler?
return false if Bundler.gem_version.prerelease?
# Released gem specs live under .../specifications/; source checkouts don't.
Gem.loaded_specs["bundler"]&.loaded_from.to_s.include?("/specifications/")
end
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

released_bundler? relies on loaded_from.to_s.include?("/specifications/"), which is not portable to Windows paths ("\specifications\") and is also a brittle substring check. Consider determining whether the bundler spec is installed by comparing File.dirname(loaded_from) against Gem::Specification.dirs and Gem.default_specifications_dir (or otherwise normalizing separators and doing an anchored path check).

Suggested change
# Released gem specs live under .../specifications/; source checkouts don't.
Gem.loaded_specs["bundler"]&.loaded_from.to_s.include?("/specifications/")
end
bundler_spec = Gem.loaded_specs["bundler"]
return false unless bundler_spec&.loaded_from
released_bundler_spec_dirs.include?(File.expand_path(File.dirname(bundler_spec.loaded_from)))
end
def released_bundler_spec_dirs
@released_bundler_spec_dirs ||= begin
dirs = Gem::Specification.dirs.map {|dir| File.expand_path(dir) }
dirs << File.expand_path(Gem.default_specifications_dir) if Gem.respond_to?(:default_specifications_dir)
dirs.uniq
end
end

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change alters when Bundler writes its own checksum (now based on version prerelease status and where Bundler is loaded from). There are existing specs around lockfile checksums; please add coverage for the new behavior (e.g., a released version running from a source checkout should not record the bundler self-checksum, while an installed released bundler still should).

Suggested change
# Released gem specs live under .../specifications/; source checkouts don't.
Gem.loaded_specs["bundler"]&.loaded_from.to_s.include?("/specifications/")
end
# Released gem specs live under a "specifications" directory; source checkouts don't.
path_components(Gem.loaded_specs["bundler"]&.loaded_from).include?("specifications")
end
def path_components(path)
separators = [File::SEPARATOR, File::ALT_SEPARATOR].compact.uniq
path.to_s.split(Regexp.union(separators))
end

Copilot uses AI. Check for mistakes.
end
end
Loading