gitlab-ce/app/services/packages/nuget/check_duplicates_service.rb

79 lines
2.3 KiB
Ruby

# frozen_string_literal: true
module Packages
module Nuget
class CheckDuplicatesService < BaseService
include Gitlab::Utils::StrongMemoize
ExtractionError = Class.new(StandardError)
def execute
return ServiceResponse.success if package_settings_allow_duplicates? || !target_package_is_duplicate?
ServiceResponse.error(
message: 'A package with the same name and version already exists',
reason: :conflict
)
rescue ExtractionError => e
ServiceResponse.error(message: e.message, reason: :bad_request)
end
private
def package_settings_allow_duplicates?
package_settings.nuget_duplicates_allowed? || package_settings.class.duplicates_allowed?(existing_package)
end
def target_package_is_duplicate?
existing_package.name.casecmp(metadata[:package_name]) == 0 &&
(existing_package.version.casecmp(metadata[:package_version]) == 0 ||
existing_package.normalized_nuget_version&.casecmp(metadata[:package_version]) == 0)
end
def package_settings
project.namespace.package_settings
end
strong_memoize_attr :package_settings
def existing_package
::Packages::Nuget::PackageFinder
.new(
current_user,
project,
package_name: metadata[:package_name],
package_version: metadata[:package_version]
)
.execute
.first
end
strong_memoize_attr :existing_package
def metadata
if params[:remote_url].present?
::Packages::Nuget::ExtractMetadataContentService
.new(nuspec_file_content)
.execute
.payload
else # to cover the case when package file is on disk not in object storage
Zip::InputStream.open(params[:file]) do |zip|
::Packages::Nuget::MetadataExtractionService
.new(zip)
.execute
.payload
end
end
end
strong_memoize_attr :metadata
def nuspec_file_content
::Packages::Nuget::ExtractRemoteMetadataFileService
.new(params[:remote_url])
.execute
.payload
rescue ::Packages::Nuget::ExtractRemoteMetadataFileService::ExtractionError => e
raise ExtractionError, e.message
end
end
end
end