Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-06-12 18:10:26 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-06-12 18:10:26 +0300
commitc0b17cee8be646588b14db49ad6d91b8cc818f97 (patch)
tree97287971303bccd649da1718c1a3a1ba8f345df6 /app/presenters/packages
parent8ef107c43390ea9c9932afb55d1318e4716fbf3b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/presenters/packages')
-rw-r--r--app/presenters/packages/nuget/packages_metadata_presenter.rb4
-rw-r--r--app/presenters/packages/nuget/presenter_helpers.rb1
-rw-r--r--app/presenters/packages/nuget/search_results_presenter.rb4
-rw-r--r--app/presenters/packages/nuget/version_helpers.rb88
4 files changed, 93 insertions, 4 deletions
diff --git a/app/presenters/packages/nuget/packages_metadata_presenter.rb b/app/presenters/packages/nuget/packages_metadata_presenter.rb
index 10a19060f8a..f87f447fb23 100644
--- a/app/presenters/packages/nuget/packages_metadata_presenter.rb
+++ b/app/presenters/packages/nuget/packages_metadata_presenter.rb
@@ -59,8 +59,8 @@ module Packages
end
def sorted_versions
- versions = @packages.map(&:version).compact
- VersionSorter.sort(versions)
+ versions = @packages.filter_map(&:version)
+ sort_versions(versions)
end
strong_memoize_attr :sorted_versions
end
diff --git a/app/presenters/packages/nuget/presenter_helpers.rb b/app/presenters/packages/nuget/presenter_helpers.rb
index ea8558c54f4..16c32a9d0d0 100644
--- a/app/presenters/packages/nuget/presenter_helpers.rb
+++ b/app/presenters/packages/nuget/presenter_helpers.rb
@@ -4,6 +4,7 @@ module Packages
module Nuget
module PresenterHelpers
include ::API::Helpers::RelatedResourcesHelpers
+ include Packages::Nuget::VersionHelpers
PACKAGE_DEPENDENCY_GROUP = 'PackageDependencyGroup'
PACKAGE_DEPENDENCY = 'PackageDependency'
diff --git a/app/presenters/packages/nuget/search_results_presenter.rb b/app/presenters/packages/nuget/search_results_presenter.rb
index 45c2c5170ae..020e8656a36 100644
--- a/app/presenters/packages/nuget/search_results_presenter.rb
+++ b/app/presenters/packages/nuget/search_results_presenter.rb
@@ -45,8 +45,8 @@ module Packages
end
def latest_version(packages)
- versions = packages.map(&:version).compact
- VersionSorter.sort(versions).last
+ versions = packages.filter_map(&:version)
+ sort_versions(versions).last
end
end
end
diff --git a/app/presenters/packages/nuget/version_helpers.rb b/app/presenters/packages/nuget/version_helpers.rb
new file mode 100644
index 00000000000..8c9c82791b3
--- /dev/null
+++ b/app/presenters/packages/nuget/version_helpers.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module Packages
+ module Nuget
+ module VersionHelpers
+ private
+
+ def sort_versions(versions)
+ versions.sort { |a, b| compare_versions(a, b) }
+ end
+
+ # NuGet version sorting algorithm as per https://semver.org/spec/v2.0.0.html#spec-item-11
+ def compare_versions(version_a, version_b)
+ return 0 if version_a == version_b
+ return 1 if version_b.nil?
+ return -1 if version_a.nil?
+
+ a_without_build_meta, a_build_meta = version_a.split('+', 2)
+ b_without_build_meta, b_build_meta = version_b.split('+', 2)
+
+ a_core, a_pre = a_without_build_meta.split(/-/, 2)
+ b_core, b_pre = b_without_build_meta.split(/-/, 2)
+
+ a_core_parts = a_core.split('.')
+ b_core_parts = b_core.split('.')
+
+ compare_core_parts(a_core_parts, b_core_parts) ||
+ compare_pre_release_parts(a_pre, b_pre) ||
+ pick_non_nil(a_pre, b_pre) ||
+ compare_build_meta_parts(a_build_meta, b_build_meta)
+ end
+
+ def compare_core_parts(a_core_parts, b_core_parts)
+ while a_core_parts.any? || b_core_parts.any?
+ a_part = a_core_parts.shift&.to_i || 0
+ b_part = b_core_parts.shift&.to_i || 0
+ return a_part <=> b_part if a_part != b_part
+ end
+ end
+
+ def compare_pre_release_parts(a_pre, b_pre)
+ return unless a_pre && b_pre
+
+ a_pre_parts = a_pre.split('.').map(&:downcase)
+ b_pre_parts = b_pre.split('.').map(&:downcase)
+
+ while a_pre_parts.any? || b_pre_parts.any?
+ a_pre_part = a_pre_parts.shift
+ b_pre_part = b_pre_parts.shift
+
+ # Empty parts are considered lower
+ return -1 if a_pre_part.nil?
+ return 1 if b_pre_part.nil?
+
+ a_num = a_pre_part.to_i
+ b_num = b_pre_part.to_i
+ next if a_num == b_num && a_pre_part.to_s == b_pre_part.to_s # Both are same numeric/alphanumeric parts
+
+ return select_numeric_before_alphanumeric(a_num, a_pre_part, b_num, b_pre_part) ||
+ compare_numeric_parts(a_pre_part, a_num, b_pre_part, b_num) ||
+ a_pre_part <=> b_pre_part
+ end
+ end
+
+ def compare_build_meta_parts(a_build_meta, b_build_meta)
+ (a_build_meta || '').casecmp(b_build_meta || '')
+ end
+
+ def select_numeric_before_alphanumeric(a_num, a_pre_part, b_num, b_pre_part)
+ return -1 if a_num != b_num && numeric?(a_pre_part) && !numeric?(b_pre_part)
+ return 1 if a_num != b_num && !numeric?(a_pre_part) && numeric?(b_pre_part)
+ end
+
+ def numeric?(pre_part)
+ !!Integer(pre_part, exception: false)
+ end
+
+ def compare_numeric_parts(a_pre_part, a_num, b_pre_part, b_num)
+ a_num <=> b_num if a_num != b_num && numeric?(a_pre_part) && numeric?(b_pre_part)
+ end
+
+ def pick_non_nil(var_a, var_b)
+ return -1 if var_a && !var_b
+ return 1 if !var_a && var_b
+ end
+ end
+ end
+end