1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
# 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, e.message
end
private
def metadata
::Packages::Debian::ExtractMetadataService.new(@package_file).execute
end
strong_memoize_attr :metadata
def file_type
metadata[:file_type]
end
def fields
metadata[:fields]
end
def files
raise ExtractionError, "is not a changes file" unless file_type == :changes
raise ExtractionError, "Files field is missing" if fields['Files'].blank?
raise ExtractionError, "Checksums-Sha1 field is missing" if fields['Checksums-Sha1'].blank?
raise ExtractionError, "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
strong_memoize_attr :files
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, "#{filename} is listed in Checksums-Sha1 but not in Files" unless entry
raise ExtractionError, "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, "#{filename} is listed in Checksums-Sha256 but not in Files" unless entry
raise ExtractionError, "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(incoming, filename).execute!
entry.validate!
rescue ActiveRecord::RecordNotFound
raise ExtractionError, "#{filename} is listed in Files but was not uploaded"
end
end
def incoming
::Packages::Debian::Package.for_projects(@package_file.package.project).incoming_package!
end
strong_memoize_attr(:incoming)
end
end
end
|