Sha256: cec1d6d860ec29290567f2194267119ed35e0f0f1b73751a0474e345e775c3b2

Contents?: true

Size: 1.68 KB

Versions: 5

Compression:

Stored size: 1.68 KB

Contents

# frozen_string_literal: true

module Spandx
  module Rubygems
    class OfflineIndex
      attr_reader :db

      def initialize(package_manager)
        @db = ::Spandx::Core::Database.new(url: "https://github.com/mokhan/spandx-#{package_manager}.git")
      end

      def licenses_for(name:, version:)
        found = search(name: name, version: version)
        found ? found[2].split('-|-') : []
      end

      private

      def digest_for(components)
        Digest::SHA1.hexdigest(Array(components).join('/'))
      end

      def key_for(name)
        digest_for(name)[0...2]
      end

      def search(name:, version:)
        db.open(datafile_for(name)) do |io|
          search_for("#{name}-#{version}", io, lines_in(io))
        end
      end

      def datafile_for(name)
        "lib/spandx/rubygems/index/#{key_for(name)}/data"
      end

      def lines_in(io)
        lines = []
        io.seek(0)
        until io.eof?
          lines << io.pos
          io.gets
        end
        lines
      end

      def search_for(term, io, lines)
        return if lines.empty?

        mid = lines.size == 1 ? 0 : lines.size / 2
        io.seek(lines[mid])
        comparison = matches?(term, parse_row(io)) { |row| return row }
        search_for(term, io, partition(comparison, mid, lines))
      end

      def matches?(term, row)
        (term <=> "#{row[0]}-#{row[1]}").tap do |comparison|
          yield row if comparison.zero?
        end
      end

      def partition(comparison, mid, lines)
        min, max = comparison.positive? ? [mid + 1, lines.length] : [0, mid]
        lines.slice(min, max)
      end

      def parse_row(io)
        CSV.parse(io.readline)[0]
      end
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
spandx-0.10.0 lib/spandx/rubygems/offline_index.rb
spandx-0.9.0 lib/spandx/rubygems/offline_index.rb
spandx-0.8.0 lib/spandx/rubygems/offline_index.rb
spandx-0.7.0 lib/spandx/rubygems/offline_index.rb
spandx-0.6.0 lib/spandx/rubygems/offline_index.rb