lib/spandx/java/index.rb in spandx-0.11.0 vs lib/spandx/java/index.rb in spandx-0.12.0

- old
+ new

@@ -1,13 +1,95 @@ # frozen_string_literal: true +require 'tempfile' + module Spandx module Java class Index - def initialize(directory:) + include Enumerable + + attr_reader :name, :source + + def initialize(directory:, source: 'https://repo.maven.apache.org/maven2') @directory = directory + @source = source + @name = 'maven' end - def update!(catalogue:, output:); end + def update!(catalogue:, output:) + each do |metadata| + name = "#{metadata.group_id}:#{metadata.artifact_id}:#{metadata.version}" + output.puts [name, metadata.licenses_from(catalogue)].inspect + end + end + + def each + each_index_url do |url| + each_record_from("#{source}/.index/#{url}") do |record| + group_id, artifact_id, version = record['u'].split('|') + yield Metadata.new(artifact_id: artifact_id, group_id: group_id, version: version) + end + end + end + + private + + def each_record(io, record = {}) + until io.eof? + field_count = io.read(4).unpack1('N').to_i # read 4 bytes for field count + field_count.times do |_n| + io.read(1) # flags + key = read_key(io) + value = read_value(io) + record[key] = value + end + yield record + end + end + + def read_key(io) + length = io.read(2).unpack1('n').to_i # unsigned 16 bit int + io.read(length) + end + + def read_value(io) + length = io.read(4).unpack1('N').to_i + io.read(length) + end + + def each_record_from(url) + stream_from(url) do |io| + # read version + io.read(1) + # read timestamp + io.read(8) + # read records + each_record(io) do |x| + yield x + end + end + end + + def each_index_url + html = Nokogiri::HTML(http.get("#{source}/.index/").body) + html.css('a[href*="nexus-maven-repository-index"]').each do |anchor| + url = anchor['href'] + yield url if url.match(/\d+\.gz$/) + end + end + + def stream_from(url, path: Tempfile.new.path) + return unless system("curl --progress-bar \"#{url}\" > #{path}", exception: true) + + Zlib::GzipReader.open(path) do |gz| + yield gz + end + ensure + File.unlink(path) if File.exist?(path) + end + + def http + Spandx.http + end end end end