[rubygems/rubygems] Raise an error in frozen mode if CHECKSUMS entries are missing
https://github.com/rubygems/rubygems/commit/054a0cd76c
This commit is contained in:
parent
60d00da083
commit
55930987e1
Notes:
git
2025-03-24 04:25:24 +00:00
@ -201,9 +201,11 @@ module Bundler
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def register(spec, checksum)
|
def missing?(spec)
|
||||||
return unless checksum
|
@store[spec.lock_name].nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def register(spec, checksum)
|
||||||
register_checksum(spec.lock_name, checksum)
|
register_checksum(spec.lock_name, checksum)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -218,7 +220,7 @@ module Bundler
|
|||||||
def to_lock(spec)
|
def to_lock(spec)
|
||||||
lock_name = spec.lock_name
|
lock_name = spec.lock_name
|
||||||
checksums = @store[lock_name]
|
checksums = @store[lock_name]
|
||||||
if checksums
|
if checksums&.any?
|
||||||
"#{lock_name} #{checksums.values.map(&:to_lock).sort.join(",")}"
|
"#{lock_name} #{checksums.values.map(&:to_lock).sort.join(",")}"
|
||||||
else
|
else
|
||||||
lock_name
|
lock_name
|
||||||
@ -229,11 +231,15 @@ module Bundler
|
|||||||
|
|
||||||
def register_checksum(lock_name, checksum)
|
def register_checksum(lock_name, checksum)
|
||||||
@store_mutex.synchronize do
|
@store_mutex.synchronize do
|
||||||
existing = fetch_checksum(lock_name, checksum.algo)
|
if checksum
|
||||||
if existing
|
existing = fetch_checksum(lock_name, checksum.algo)
|
||||||
merge_checksum(lock_name, checksum, existing)
|
if existing
|
||||||
|
merge_checksum(lock_name, checksum, existing)
|
||||||
|
else
|
||||||
|
store_checksum(lock_name, checksum)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
store_checksum(lock_name, checksum)
|
init_checksum(lock_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -243,7 +249,11 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def store_checksum(lock_name, checksum)
|
def store_checksum(lock_name, checksum)
|
||||||
(@store[lock_name] ||= {})[checksum.algo] = checksum
|
init_checksum(lock_name)[checksum.algo] = checksum
|
||||||
|
end
|
||||||
|
|
||||||
|
def init_checksum(lock_name)
|
||||||
|
@store[lock_name] ||= {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_checksum(lock_name, algo)
|
def fetch_checksum(lock_name, algo)
|
||||||
|
@ -147,8 +147,8 @@ module Bundler
|
|||||||
|
|
||||||
@current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
|
@current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
|
||||||
|
|
||||||
@path_changes = converge_paths
|
|
||||||
@source_changes = converge_sources
|
@source_changes = converge_sources
|
||||||
|
@path_changes = converge_paths
|
||||||
|
|
||||||
if conservative
|
if conservative
|
||||||
@gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
|
@gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
|
||||||
@ -563,6 +563,7 @@ module Bundler
|
|||||||
@local_changes ||
|
@local_changes ||
|
||||||
@missing_lockfile_dep ||
|
@missing_lockfile_dep ||
|
||||||
@unlocking_bundler ||
|
@unlocking_bundler ||
|
||||||
|
@locked_spec_with_missing_checksums ||
|
||||||
@locked_spec_with_missing_deps ||
|
@locked_spec_with_missing_deps ||
|
||||||
@locked_spec_with_invalid_deps
|
@locked_spec_with_invalid_deps
|
||||||
end
|
end
|
||||||
@ -815,6 +816,7 @@ module Bundler
|
|||||||
[@local_changes, "the gemspecs for git local gems changed"],
|
[@local_changes, "the gemspecs for git local gems changed"],
|
||||||
[@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
|
[@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
|
||||||
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
|
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
|
||||||
|
[@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
|
||||||
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
|
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
|
||||||
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
|
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
|
||||||
].select(&:first).map(&:last).join(", ")
|
].select(&:first).map(&:last).join(", ")
|
||||||
@ -873,21 +875,27 @@ module Bundler
|
|||||||
def check_lockfile
|
def check_lockfile
|
||||||
@locked_spec_with_invalid_deps = nil
|
@locked_spec_with_invalid_deps = nil
|
||||||
@locked_spec_with_missing_deps = nil
|
@locked_spec_with_missing_deps = nil
|
||||||
|
@locked_spec_with_missing_checksums = nil
|
||||||
|
|
||||||
missing = []
|
missing_deps = []
|
||||||
|
missing_checksums = []
|
||||||
invalid = []
|
invalid = []
|
||||||
|
|
||||||
@locked_specs.each do |s|
|
@locked_specs.each do |s|
|
||||||
|
missing_checksums << s if @locked_checksums && s.source.checksum_store.missing?(s)
|
||||||
|
|
||||||
validation = @locked_specs.validate_deps(s)
|
validation = @locked_specs.validate_deps(s)
|
||||||
|
|
||||||
missing << s if validation == :missing
|
missing_deps << s if validation == :missing
|
||||||
invalid << s if validation == :invalid
|
invalid << s if validation == :invalid
|
||||||
end
|
end
|
||||||
|
|
||||||
if missing.any?
|
@locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
|
||||||
@locked_specs.delete(missing)
|
|
||||||
|
|
||||||
@locked_spec_with_missing_deps = missing.first.name
|
if missing_deps.any?
|
||||||
|
@locked_specs.delete(missing_deps)
|
||||||
|
|
||||||
|
@locked_spec_with_missing_deps = missing_deps.first.name
|
||||||
end
|
end
|
||||||
|
|
||||||
if invalid.any?
|
if invalid.any?
|
||||||
|
@ -239,7 +239,6 @@ module Bundler
|
|||||||
spaces = $1
|
spaces = $1
|
||||||
return unless spaces.size == 2
|
return unless spaces.size == 2
|
||||||
checksums = $6
|
checksums = $6
|
||||||
return unless checksums
|
|
||||||
name = $2
|
name = $2
|
||||||
version = $3
|
version = $3
|
||||||
platform = $4
|
platform = $4
|
||||||
@ -249,10 +248,14 @@ module Bundler
|
|||||||
full_name = Gem::NameTuple.new(name, version, platform).full_name
|
full_name = Gem::NameTuple.new(name, version, platform).full_name
|
||||||
return unless spec = @specs[full_name]
|
return unless spec = @specs[full_name]
|
||||||
|
|
||||||
checksums.split(",") do |lock_checksum|
|
if checksums
|
||||||
column = line.index(lock_checksum) + 1
|
checksums.split(",") do |lock_checksum|
|
||||||
checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
|
column = line.index(lock_checksum) + 1
|
||||||
spec.source.checksum_store.register(spec, checksum)
|
checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
|
||||||
|
spec.source.checksum_store.register(spec, checksum)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
spec.source.checksum_store.register(spec, nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ module Bundler
|
|||||||
class Source
|
class Source
|
||||||
class Gemspec < Path
|
class Gemspec < Path
|
||||||
attr_reader :gemspec
|
attr_reader :gemspec
|
||||||
|
attr_writer :checksum_store
|
||||||
|
|
||||||
def initialize(options)
|
def initialize(options)
|
||||||
super
|
super
|
||||||
|
@ -183,9 +183,7 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
path = @path_sources.map do |source|
|
path = @path_sources.map do |source|
|
||||||
next source if source.is_a?(Source::Gemspec)
|
replace_path_source(replacement_sources, source)
|
||||||
|
|
||||||
replace_source(replacement_sources, source)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
[rubygems, path, git, plugin]
|
[rubygems, path, git, plugin]
|
||||||
@ -201,6 +199,8 @@ module Bundler
|
|||||||
replacement_source.remotes = gemfile_source.remotes
|
replacement_source.remotes = gemfile_source.remotes
|
||||||
|
|
||||||
yield replacement_source if block_given?
|
yield replacement_source if block_given?
|
||||||
|
|
||||||
|
replacement_source
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -208,11 +208,22 @@ module Bundler
|
|||||||
replacement_source = replacement_sources.find {|s| s == gemfile_source }
|
replacement_source = replacement_sources.find {|s| s == gemfile_source }
|
||||||
return gemfile_source unless replacement_source
|
return gemfile_source unless replacement_source
|
||||||
|
|
||||||
yield replacement_source if block_given?
|
replacement_source = yield(replacement_source) if block_given?
|
||||||
|
|
||||||
replacement_source
|
replacement_source
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def replace_path_source(replacement_sources, gemfile_source)
|
||||||
|
replace_source(replacement_sources, gemfile_source) do |replacement_source|
|
||||||
|
if gemfile_source.is_a?(Source::Gemspec)
|
||||||
|
gemfile_source.checksum_store = replacement_source.checksum_store
|
||||||
|
gemfile_source
|
||||||
|
else
|
||||||
|
replacement_source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def different_sources?(lock_sources, replacement_sources)
|
def different_sources?(lock_sources, replacement_sources)
|
||||||
!equivalent_sources?(lock_sources, replacement_sources)
|
!equivalent_sources?(lock_sources, replacement_sources)
|
||||||
end
|
end
|
||||||
|
@ -1221,7 +1221,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
|
|||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
myrack!
|
myrack!
|
||||||
#{checksums_section}
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
#{Bundler::VERSION}
|
#{Bundler::VERSION}
|
||||||
L
|
L
|
||||||
|
@ -1613,6 +1613,39 @@ RSpec.describe "the lockfile format" do
|
|||||||
expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
|
expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "raises a clear error when frozen mode is set and lockfile is missing entries in CHECKSUMS section, and does not install any gems" do
|
||||||
|
lockfile <<-L
|
||||||
|
GEM
|
||||||
|
remote: https://gem.repo2/
|
||||||
|
specs:
|
||||||
|
myrack_middleware (1.0)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
#{lockfile_platforms}
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
myrack_middleware
|
||||||
|
|
||||||
|
CHECKSUMS
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
#{Bundler::VERSION}
|
||||||
|
L
|
||||||
|
|
||||||
|
install_gemfile <<-G, env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
|
||||||
|
source "https://gem.repo2"
|
||||||
|
gem "myrack_middleware"
|
||||||
|
G
|
||||||
|
|
||||||
|
expect(err).to eq <<~L.strip
|
||||||
|
Your lockfile is missing a checksums entry for \"myrack_middleware\", but can't be updated because frozen mode is set
|
||||||
|
|
||||||
|
Run `bundle install` elsewhere and add the updated Gemfile.lock to version control.
|
||||||
|
L
|
||||||
|
|
||||||
|
expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
|
||||||
|
end
|
||||||
|
|
||||||
it "automatically fixes the lockfile when it's missing deps, they conflict with other locked deps, but conflicts are fixable" do
|
it "automatically fixes the lockfile when it's missing deps, they conflict with other locked deps, but conflicts are fixable" do
|
||||||
build_repo4 do
|
build_repo4 do
|
||||||
build_gem "other_dep", "0.9"
|
build_gem "other_dep", "0.9"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user