debian-mirror-gitlab/app/services/packages/debian/process_changes_service.rb
2023-04-23 21:23:45 +05:30

115 lines
3.5 KiB
Ruby

# frozen_string_literal: true
module Packages
module Debian
class ProcessChangesService
include ExclusiveLeaseGuard
include Gitlab::Utils::StrongMemoize
# used by ExclusiveLeaseGuard
DEFAULT_LEASE_TIMEOUT = 1.hour.to_i.freeze
def initialize(package_file, creator)
@package_file = package_file
@creator = creator
end
def execute
# return if changes file has already been processed
return if package_file.debian_file_metadatum&.changes?
validate!
try_obtain_lease do
package_file.transaction do
update_files_metadata
update_changes_metadata
end
::Packages::Debian::GenerateDistributionWorker.perform_async(:project, package.debian_distribution.id)
end
end
private
attr_reader :package_file, :creator
def validate!
raise ArgumentError, 'invalid package file' unless package_file.debian_file_metadatum
raise ArgumentError, 'invalid package file' unless package_file.debian_file_metadatum.unknown?
raise ArgumentError, 'invalid package file' unless metadata[:file_type] == :changes
raise ArgumentError, 'missing Source field' unless metadata.dig(:fields, 'Source').present?
raise ArgumentError, 'missing Version field' unless metadata.dig(:fields, 'Version').present?
raise ArgumentError, 'missing Distribution field' unless metadata.dig(:fields, 'Distribution').present?
end
def update_files_metadata
files.each do |filename, entry|
file_metadata = ::Packages::Debian::ExtractMetadataService.new(entry.package_file).execute
::Packages::UpdatePackageFileService.new(entry.package_file, package_id: package.id)
.execute
# Force reload from database, as package has changed
entry.package_file.reload_package
entry.package_file.debian_file_metadatum.update!(
file_type: file_metadata[:file_type],
component: files[filename].component,
architecture: file_metadata[:architecture],
fields: file_metadata[:fields]
)
end
end
def update_changes_metadata
::Packages::UpdatePackageFileService.new(package_file, package_id: package.id)
.execute
# Force reload from database, as package has changed
package_file.reload_package
package_file.debian_file_metadatum.update!(
file_type: metadata[:file_type],
fields: metadata[:fields]
)
end
def metadata
strong_memoize(:metadata) do
::Packages::Debian::ExtractChangesMetadataService.new(package_file).execute
end
end
def files
metadata[:files]
end
def project
package_file.package.project
end
def package
strong_memoize(:package) do
params = {
'name': metadata[:fields]['Source'],
'version': metadata[:fields]['Version'],
'distribution_name': metadata[:fields]['Distribution']
}
response = Packages::Debian::FindOrCreatePackageService.new(project, creator, params).execute
response.payload[:package]
end
end
# used by ExclusiveLeaseGuard
def lease_key
"packages:debian:process_changes_service:package_file:#{package_file.id}"
end
# used by ExclusiveLeaseGuard
def lease_timeout
DEFAULT_LEASE_TIMEOUT
end
end
end
end