2021-03-08 18:12:59 +05:30
|
|
|
# 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
|
2021-06-08 01:23:25 +05:30
|
|
|
raise ExtractionError, 'invalid package file' unless valid_package_file?
|
2021-03-08 18:12:59 +05:30
|
|
|
|
2023-05-27 22:25:52 +05:30
|
|
|
if file_type == :unsupported
|
|
|
|
raise ExtractionError, "unsupported file extension for file #{package_file.file_name}"
|
|
|
|
end
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
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
|
2023-05-27 22:25:52 +05:30
|
|
|
%i[dsc deb udeb buildinfo changes ddeb].each do |format|
|
2021-03-08 18:12:59 +05:30
|
|
|
return format if package_file.file_name.end_with?(".#{format}")
|
|
|
|
end
|
|
|
|
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
|
|
|
def file_type_source
|
2023-05-27 22:25:52 +05:30
|
|
|
# https://manpages.debian.org/buster/dpkg-dev/dpkg-source.1.en.html#Format:_3.0_(quilt)
|
|
|
|
%i[gz bz2 lzma xz].each do |format|
|
2021-03-08 18:12:59 +05:30
|
|
|
return :source if package_file.file_name.end_with?(".tar.#{format}")
|
|
|
|
end
|
|
|
|
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
|
|
|
def file_type
|
2023-05-27 22:25:52 +05:30
|
|
|
file_type_basic || file_type_source || :unsupported
|
2021-03-08 18:12:59 +05:30
|
|
|
end
|
2023-05-27 22:25:52 +05:30
|
|
|
strong_memoize_attr :file_type
|
2021-03-08 18:12:59 +05:30
|
|
|
|
|
|
|
def file_type_debian?
|
2023-05-27 22:25:52 +05:30
|
|
|
file_type == :deb || file_type == :udeb || file_type == :ddeb
|
2021-03-08 18:12:59 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def file_type_meta?
|
|
|
|
file_type == :dsc || file_type == :buildinfo || file_type == :changes
|
|
|
|
end
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
def fields
|
2023-05-27 22:25:52 +05:30
|
|
|
if file_type_debian?
|
|
|
|
package_file.file.use_open_file(unlink_early: false) do |file|
|
|
|
|
::Packages::Debian::ExtractDebMetadataService.new(file.file_path).execute
|
|
|
|
end
|
|
|
|
elsif file_type_meta?
|
|
|
|
package_file.file.use_open_file do |file|
|
|
|
|
::Packages::Debian::ParseDebian822Service.new(file.read).execute.each_value.first
|
2021-03-08 18:12:59 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2023-05-27 22:25:52 +05:30
|
|
|
strong_memoize_attr :fields
|
2021-03-08 18:12:59 +05:30
|
|
|
|
|
|
|
def extract_metadata
|
2021-04-29 21:17:54 +05:30
|
|
|
architecture = fields['Architecture'] if file_type_debian?
|
2021-03-08 18:12:59 +05:30
|
|
|
|
|
|
|
{
|
|
|
|
file_type: file_type,
|
|
|
|
architecture: architecture,
|
|
|
|
fields: fields
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|