PHP 8.2.31
Preview: checksum.rb Size: 7.12 KB
/proc/thread-self/root/opt/alt/ruby34/share/gems/gems/bundler-2.6.9/lib/bundler/checksum.rb

# frozen_string_literal: true

module Bundler
  class Checksum
    ALGO_SEPARATOR = "="
    DEFAULT_ALGORITHM = "sha256"
    private_constant :DEFAULT_ALGORITHM
    DEFAULT_BLOCK_SIZE = 16_384
    private_constant :DEFAULT_BLOCK_SIZE

    class << self
      def from_gem_package(gem_package, algo = DEFAULT_ALGORITHM)
        return if Bundler.settings[:disable_checksum_validation]
        return unless source = gem_package.instance_variable_get(:@gem)
        return unless source.respond_to?(:with_read_io)

        source.with_read_io do |io|
          from_gem(io, source.path)
        ensure
          io.rewind
        end
      end

      def from_gem(io, pathname, algo = DEFAULT_ALGORITHM)
        digest = Bundler::SharedHelpers.digest(algo.upcase).new
        buf = String.new(capacity: DEFAULT_BLOCK_SIZE)
        digest << io.readpartial(DEFAULT_BLOCK_SIZE, buf) until io.eof?
        Checksum.new(algo, digest.hexdigest!, Source.new(:gem, pathname))
      end

      def from_api(digest, source_uri, algo = DEFAULT_ALGORITHM)
        return if Bundler.settings[:disable_checksum_validation]

        Checksum.new(algo, to_hexdigest(digest, algo), Source.new(:api, source_uri))
      end

      def from_lock(lock_checksum, lockfile_location)
        algo, digest = lock_checksum.strip.split(ALGO_SEPARATOR, 2)
        Checksum.new(algo, to_hexdigest(digest, algo), Source.new(:lock, lockfile_location))
      end

      def to_hexdigest(digest, algo = DEFAULT_ALGORITHM)
        return digest unless algo == DEFAULT_ALGORITHM
        return digest if digest.match?(/\A[0-9a-f]{64}\z/i)

        if digest.match?(%r{\A[-0-9a-z_+/]{43}={0,2}\z}i)
          digest = digest.tr("-_", "+/") # fix urlsafe base64
          digest.unpack1("m0").unpack1("H*")
        else
          raise ArgumentError, "#{digest.inspect} is not a valid SHA256 hex or base64 digest"
        end
      end
    end

    attr_reader :algo, :digest, :sources

    def initialize(algo, digest, source)
      @algo = algo
      @digest = digest
      @sources = [source]
    end

    def ==(other)
      match?(other) && other.sources == sources
    end

    alias_method :eql?, :==

    def same_source?(other)
      sources.include?(other.sources.first)
    end

    def match?(other)
      other.is_a?(self.class) && other.digest == digest && other.algo == algo
    end

    def hash
      digest.hash
    end

    def to_s
      "#{to_lock} (from #{sources.first}#{", ..." if sources.size > 1})"
    end

    def to_lock
      "#{algo}#{ALGO_SEPARATOR}#{digest}"
    end

    def merge!(other)
      return nil unless match?(other)

      @sources.concat(other.sources).uniq!
      self
    end

    def formatted_sources
      sources.join("\n    and ").concat("\n")
    end

    def removable?
      sources.all?(&:removable?)
    end

    def removal_instructions
      msg = +""
      i = 1
      sources.each do |source|
        msg << "  #{i}. #{source.removal}\n"
        i += 1
      end
      msg << "  #{i}. run `bundle install`\n"
    end

    def inspect
      abbr = "#{algo}#{ALGO_SEPARATOR}#{digest[0, 8]}"
      from = "from #{sources.join(" and ")}"
      "#<#{self.class}:#{object_id} #{abbr} #{from}>"
    end

    class Source
      attr_reader :type, :location

      def initialize(type, location)
        @type = type
        @location = location
      end

      def removable?
        [:lock, :gem].include?(type)
      end

      def ==(other)
        other.is_a?(self.class) && other.type == type && other.location == location
      end

      # phrased so that the usual string format is grammatically correct
      #   rake (10.3.2) sha256=abc123 from #{to_s}
      def to_s
        case type
        when :lock
          "the lockfile CHECKSUMS at #{location}"
        when :gem
          "the gem at #{location}"
        when :api
          "the API at #{location}"
        else
          "#{location} (#{type})"
        end
      end

      # A full sentence describing how to remove the checksum
      def removal
        case type
        when :lock
          "remove the matching checksum in #{location}"
        when :gem
          "remove the gem at #{location}"
        when :api
          "checksums from #{location} cannot be locally modified, you may need to update your sources"
        else
          "remove #{location} (#{type})"
        end
      end
    end

    class Store
      attr_reader :store
      protected :store

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

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

      # 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 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.
      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 missing?(spec)
        @store[spec.lock_name].nil?
      end

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

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

      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

      private

      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 merge_checksum(lock_name, checksum, existing)
        existing.merge!(checksum) || raise(ChecksumMismatchError.new(lock_name, existing, checksum))
      end

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

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

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

Directory Contents

Dirs: 12 × Files: 77

Name Size Perms Modified Actions
cli DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
fetcher DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
installer DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
man DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
plugin DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
resolver DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
settings DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
source DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
templates DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
ui DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
vendor DIR
- drwxr-xr-x 2026-04-20 12:16:04
Edit Download
1.22 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
877 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
7.12 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.72 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
40.16 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.28 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
311 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.51 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
40.02 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.14 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.19 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
876 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.16 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
22.78 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.49 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.92 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
1.42 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
8.64 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
1.81 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
11.64 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
544 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.74 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
6.88 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.71 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
138 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
5.06 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.95 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.85 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
10.00 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.45 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
9.42 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
7.45 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.42 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
9.01 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
769 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
583 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
863 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
1.37 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
5.77 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
11.98 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
554 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.92 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
18.48 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
1.59 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
14.23 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.67 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
12.42 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.40 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.68 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
10.41 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
597 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
6.45 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
15.11 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
1.36 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
12.42 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
1.84 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.04 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
7.34 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.17 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
9.58 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.43 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
255 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
1.29 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
715 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
101 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
735 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
197 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
99 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
387 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
180 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
209 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
93 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
496 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
259 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
465 B lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.85 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.42 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download

If ZipArchive is unavailable, a .tar will be created (no compression).