123456789_123456789_123456789_123456789_123456789_

Class: Bundler::Checksum::Store

Relationships & Source Files
Inherits: Object
Defined in: lib/bundler/checksum.rb

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.newStore

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 170

def initialize
  @store = {}
  @store_mutex = Mutex.new
end

Instance Attribute Details

#store (readonly, protected)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 167

attr_reader :store

Instance Method Details

#checksums_to_lock(full_name)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 240

def checksums_to_lock(full_name)
  checksums = @store[full_name]
  return unless checksums&.any?

  checksums.values.map(&:to_lock).sort.join(",")
end

#empty?(spec) ⇒ Boolean

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 212

def empty?(spec)
  return false unless spec.source.is_a?(Bundler::Source::Rubygems)

  @store[spec.full_name].empty?
end

#fetch_checksum(full_name, algo) (private)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 280

def fetch_checksum(full_name, algo)
  @store[full_name]&.fetch(algo, nil)
end

#init_checksum(full_name) (private)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 276

def init_checksum(full_name)
  @store[full_name] ||= {}
end

#inspect

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 175

def inspect
  "#<#{self.class}:#{object_id} size=#{store.size}>"
end

#merge!(other)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 222

def merge!(other)
  other.store.each do |full_name, checksums|
    checksums.each do |_algo, checksum|
      register_checksum(full_name, checksum)
    end
  end
end

#merge_checksum(full_name, checksum, existing, display_name = full_name) (private)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 268

def merge_checksum(full_name, checksum, existing, display_name = full_name)
  existing.merge!(checksum) || raise(ChecksumMismatchError.new(display_name, existing, checksum))
end

#missing?(spec) ⇒ Boolean

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 208

def missing?(spec)
  @store[spec.full_name].nil?
end

#platform_full_name(spec) (private)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 249

def platform_full_name(spec)
  Gem::NameTuple.new(spec.name, spec.version, spec.platform).full_name
end

#register(spec, checksum)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 218

def register(spec, checksum)
  register_checksum(spec.full_name, checksum, spec.lock_name)
end

#register_checksum(full_name, checksum, display_name = full_name) (private)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 253

def register_checksum(full_name, checksum, display_name = full_name)
  @store_mutex.synchronize do
    if checksum
      existing = fetch_checksum(full_name, checksum.algo)
      if existing
        merge_checksum(full_name, checksum, existing, display_name)
      else
        store_checksum(full_name, checksum)
      end
    else
      init_checksum(full_name)
    end
  end
end

#replace(spec, checksum)

Replace when the new checksum is from the same source. The primary purpose is registering checksums from gems where there are duplicates of the same gem (according to full_name) in the index.

In particular, this is when 2 gems have two similar platforms, e.g. "darwin20" and "darwin-20", both of which resolve to darwin-20. In the ::Bundler::Index, the later gem replaces the former, so we do that here.

However, if the new checksum is from a different source, we register like normal. This ensures a mismatch error where there are multiple top level sources that contain the same gem with different checksums. The store is keyed by full name rather than lock name because a content-addressable build and the ordinary platform build of the same name, version, and platform share a lock name while being different files with different checksums.

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 194

def replace(spec, checksum)
  return unless checksum

  full_name = spec.full_name
  @store_mutex.synchronize do
    existing = fetch_checksum(full_name, checksum.algo)
    if !existing || existing.same_source?(checksum)
      store_checksum(full_name, checksum)
    else
      merge_checksum(full_name, checksum, existing, spec.lock_name)
    end
  end
end

#store_checksum(full_name, checksum) (private)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 272

def store_checksum(full_name, checksum)
  init_checksum(full_name)[checksum.algo] = checksum
end

#to_lock(spec)

[ GitHub ]

  
# File 'lib/bundler/checksum.rb', line 230

def to_lock(spec)
  lock_name = spec.lock_name
  checksums = checksums_to_lock(platform_full_name(spec))
  if checksums
    "#{lock_name} #{checksums}"
  else
    lock_name
  end
end