gitlab-org--gitlab-foss/app/services/packages/nuget/update_package_from_metadat...

153 lines
4.3 KiB
Ruby

# frozen_string_literal: true
module Packages
module Nuget
class UpdatePackageFromMetadataService
include Gitlab::Utils::StrongMemoize
include ExclusiveLeaseGuard
# used by ExclusiveLeaseGuard
DEFAULT_LEASE_TIMEOUT = 1.hour.to_i.freeze
SYMBOL_PACKAGE_IDENTIFIER = 'SymbolsPackage'
InvalidMetadataError = Class.new(StandardError)
def initialize(package_file)
@package_file = package_file
end
def execute
raise InvalidMetadataError, 'package name and/or package version not found in metadata' unless valid_metadata?
try_obtain_lease do
@package_file.transaction do
process_package_update
end
end
rescue ActiveRecord::RecordInvalid => e
raise InvalidMetadataError, e.message
end
private
def process_package_update
package_to_destroy = nil
target_package = @package_file.package
if existing_package
package_to_destroy = @package_file.package
target_package = existing_package
else
if symbol_package?
raise InvalidMetadataError, 'symbol package is invalid, matching package does not exist'
end
update_linked_package
end
update_package(target_package)
::Packages::UpdatePackageFileService.new(@package_file, package_id: target_package.id, file_name: package_filename)
.execute
package_to_destroy&.destroy!
end
def update_package(package)
return if symbol_package?
::Packages::Nuget::SyncMetadatumService
.new(package, metadata.slice(:project_url, :license_url, :icon_url))
.execute
::Packages::UpdateTagsService
.new(package, package_tags)
.execute
rescue StandardError => e
raise InvalidMetadataError, e.message
end
def valid_metadata?
package_name.present? && package_version.present?
end
def link_to_existing_package
package_to_destroy = @package_file.package
# Updating package_id updates the path where the file is stored.
# We must pass the file again so that CarrierWave can handle the update
@package_file.update!(
package_id: existing_package.id,
file: @package_file.file
)
package_to_destroy.destroy!
existing_package
end
def update_linked_package
@package_file.package.update!(
name: package_name,
version: package_version,
status: :default
)
::Packages::Nuget::CreateDependencyService.new(@package_file.package, package_dependencies)
.execute
@package_file.package
end
def existing_package
strong_memoize(:existing_package) do
@package_file.project.packages
.nuget
.with_name(package_name)
.with_version(package_version)
.not_pending_destruction
.first
end
end
def package_name
metadata[:package_name]
end
def package_version
metadata[:package_version]
end
def package_dependencies
metadata.fetch(:package_dependencies, [])
end
def package_tags
metadata.fetch(:package_tags, [])
end
def package_types
metadata.fetch(:package_types, [])
end
def symbol_package?
package_types.include?(SYMBOL_PACKAGE_IDENTIFIER)
end
def metadata
strong_memoize(:metadata) do
::Packages::Nuget::MetadataExtractionService.new(@package_file.id).execute
end
end
def package_filename
"#{package_name.downcase}.#{package_version.downcase}.#{symbol_package? ? 'snupkg' : 'nupkg'}"
end
# used by ExclusiveLeaseGuard
def lease_key
package_id = existing_package ? existing_package.id : @package_file.package_id
"packages:nuget:update_package_from_metadata_service:package:#{package_id}"
end
# used by ExclusiveLeaseGuard
def lease_timeout
DEFAULT_LEASE_TIMEOUT
end
end
end
end