class Bundler::Checksum::Store
def empty?(spec)
def empty?(spec) return false unless spec.source.is_a?(Bundler::Source::Rubygems) @store[spec.lock_name].empty? end
def fetch_checksum(lock_name, algo)
def fetch_checksum(lock_name, algo) @store[lock_name]&.fetch(algo, nil) end
def init_checksum(lock_name)
def init_checksum(lock_name) @store[lock_name] ||= {} end
def initialize
def initialize @store = {} @store_mutex = Mutex.new end
def inspect
def inspect "#<#{self.class}:#{object_id} size=#{store.size}>" end
def merge!(other)
def merge!(other) other.store.each do |lock_name, checksums| checksums.each do |_algo, checksum| register_checksum(lock_name, checksum) end end end
def merge_checksum(lock_name, checksum, existing)
def merge_checksum(lock_name, checksum, existing) existing.merge!(checksum) || raise(ChecksumMismatchError.new(lock_name, existing, checksum)) end
def missing?(spec)
def missing?(spec) @store[spec.lock_name].nil? end
def register(spec, checksum)
def register(spec, checksum) register_checksum(spec.lock_name, checksum) end
def register_checksum(lock_name, checksum)
def register_checksum(lock_name, checksum) @store_mutex.synchronize do if checksum existing = fetch_checksum(lock_name, checksum.algo) if existing merge_checksum(lock_name, checksum, existing) else store_checksum(lock_name, checksum) end else init_checksum(lock_name) end end end
def replace(spec, checksum)
This ensures a mismatch error where there are multiple top level sources
However, if the new checksum is from a different source, we register like normal.
In the Index, the later gem replaces the former, so we do that here.
"darwin20" and "darwin-20", both of which resolve to darwin-20.
In particular, this is when 2 gems have two similar platforms, e.g.
duplicates of the same gem (according to full_name) in the index.
The primary purpose is registering checksums from gems where there are
Replace when the new checksum is from the same source.
def replace(spec, checksum) return unless checksum lock_name = spec.lock_name @store_mutex.synchronize do existing = fetch_checksum(lock_name, checksum.algo) if !existing || existing.same_source?(checksum) store_checksum(lock_name, checksum) else merge_checksum(lock_name, checksum, existing) end end end
def store_checksum(lock_name, checksum)
def store_checksum(lock_name, checksum) init_checksum(lock_name)[checksum.algo] = checksum end
def to_lock(spec)
def to_lock(spec) lock_name = spec.lock_name checksums = @store[lock_name] if checksums&.any? "#{lock_name} #{checksums.values.map(&:to_lock).sort.join(",")}" else lock_name end end