86 lines
2.1 KiB
Ruby
86 lines
2.1 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Packages
|
||
|
module Debian
|
||
|
class ExtractMetadataService
|
||
|
include Gitlab::Utils::StrongMemoize
|
||
|
|
||
|
ExtractionError = Class.new(StandardError)
|
||
|
|
||
|
def initialize(package_file)
|
||
|
@package_file = package_file
|
||
|
end
|
||
|
|
||
|
def execute
|
||
|
raise ExtractionError.new('invalid package file') unless valid_package_file?
|
||
|
|
||
|
extract_metadata
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
attr_reader :package_file
|
||
|
|
||
|
def valid_package_file?
|
||
|
package_file &&
|
||
|
package_file.package&.debian? &&
|
||
|
package_file.file.size > 0 # rubocop:disable Style/ZeroLengthPredicate
|
||
|
end
|
||
|
|
||
|
def file_type_basic
|
||
|
%i[dsc deb udeb buildinfo changes].each do |format|
|
||
|
return format if package_file.file_name.end_with?(".#{format}")
|
||
|
end
|
||
|
|
||
|
nil
|
||
|
end
|
||
|
|
||
|
def file_type_source
|
||
|
# https://manpages.debian.org/buster/dpkg-dev/dpkg-source.1.en.html
|
||
|
%i[gzip bzip2 lzma xz].each do |format|
|
||
|
return :source if package_file.file_name.end_with?(".tar.#{format}")
|
||
|
end
|
||
|
|
||
|
nil
|
||
|
end
|
||
|
|
||
|
def file_type
|
||
|
strong_memoize(:file_type) do
|
||
|
file_type_basic || file_type_source || :unknown
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def file_type_debian?
|
||
|
file_type == :deb || file_type == :udeb
|
||
|
end
|
||
|
|
||
|
def file_type_meta?
|
||
|
file_type == :dsc || file_type == :buildinfo || file_type == :changes
|
||
|
end
|
||
|
|
||
|
def extracted_fields
|
||
|
if file_type_debian?
|
||
|
package_file.file.use_file do |file_path|
|
||
|
::Packages::Debian::ExtractDebMetadataService.new(file_path).execute
|
||
|
end
|
||
|
elsif file_type_meta?
|
||
|
package_file.file.use_file do |file_path|
|
||
|
::Packages::Debian::ParseDebian822Service.new(File.read(file_path)).execute.each_value.first
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def extract_metadata
|
||
|
fields = extracted_fields
|
||
|
architecture = fields.delete(:Architecture) if file_type_debian?
|
||
|
|
||
|
{
|
||
|
file_type: file_type,
|
||
|
architecture: architecture,
|
||
|
fields: fields
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|