113 lines
3.3 KiB
Ruby
113 lines
3.3 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Packages
|
||
|
module Debian
|
||
|
class ExtractChangesMetadataService
|
||
|
include Gitlab::Utils::StrongMemoize
|
||
|
|
||
|
ExtractionError = Class.new(StandardError)
|
||
|
|
||
|
def initialize(package_file)
|
||
|
@package_file = package_file
|
||
|
@entries = {}
|
||
|
end
|
||
|
|
||
|
def execute
|
||
|
{
|
||
|
file_type: file_type,
|
||
|
architecture: metadata[:architecture],
|
||
|
fields: fields,
|
||
|
files: files
|
||
|
}
|
||
|
rescue ActiveModel::ValidationError => e
|
||
|
raise ExtractionError.new(e.message)
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def metadata
|
||
|
strong_memoize(:metadata) do
|
||
|
::Packages::Debian::ExtractMetadataService.new(@package_file).execute
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def file_type
|
||
|
metadata[:file_type]
|
||
|
end
|
||
|
|
||
|
def fields
|
||
|
metadata[:fields]
|
||
|
end
|
||
|
|
||
|
def files
|
||
|
strong_memoize(:files) do
|
||
|
raise ExtractionError.new("is not a changes file") unless file_type == :changes
|
||
|
raise ExtractionError.new("Files field is missing") if fields[:Files].blank?
|
||
|
raise ExtractionError.new("Checksums-Sha1 field is missing") if fields[:'Checksums-Sha1'].blank?
|
||
|
raise ExtractionError.new("Checksums-Sha256 field is missing") if fields[:'Checksums-Sha256'].blank?
|
||
|
|
||
|
init_entries_from_files
|
||
|
entries_from_checksums_sha1
|
||
|
entries_from_checksums_sha256
|
||
|
entries_from_package_files
|
||
|
|
||
|
@entries
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def init_entries_from_files
|
||
|
each_lines_for(:Files) do |line|
|
||
|
md5sum, size, section, priority, filename = line.split
|
||
|
entry = FileEntry.new(
|
||
|
filename: filename,
|
||
|
size: size.to_i,
|
||
|
md5sum: md5sum,
|
||
|
section: section,
|
||
|
priority: priority)
|
||
|
|
||
|
@entries[filename] = entry
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def entries_from_checksums_sha1
|
||
|
each_lines_for(:'Checksums-Sha1') do |line|
|
||
|
sha1sum, size, filename = line.split
|
||
|
entry = @entries[filename]
|
||
|
raise ExtractionError.new("#{filename} is listed in Checksums-Sha1 but not in Files") unless entry
|
||
|
raise ExtractionError.new("Size for #{filename} in Files and Checksums-Sha1 differ") unless entry.size == size.to_i
|
||
|
|
||
|
entry.sha1sum = sha1sum
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def entries_from_checksums_sha256
|
||
|
each_lines_for(:'Checksums-Sha256') do |line|
|
||
|
sha256sum, size, filename = line.split
|
||
|
entry = @entries[filename]
|
||
|
raise ExtractionError.new("#{filename} is listed in Checksums-Sha256 but not in Files") unless entry
|
||
|
raise ExtractionError.new("Size for #{filename} in Files and Checksums-Sha256 differ") unless entry.size == size.to_i
|
||
|
|
||
|
entry.sha256sum = sha256sum
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def each_lines_for(field)
|
||
|
fields[field].split("\n").each do |line|
|
||
|
next if line.blank?
|
||
|
|
||
|
yield(line)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def entries_from_package_files
|
||
|
@entries.each do |filename, entry|
|
||
|
entry.package_file = ::Packages::PackageFileFinder.new(@package_file.package, filename).execute!
|
||
|
entry.validate!
|
||
|
rescue ActiveRecord::RecordNotFound
|
||
|
raise ExtractionError.new("#{filename} is listed in Files but was not uploaded")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|