blob: d8eb5b8f490f2d6a988444a5ea170f87c1060ca8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
# frozen_string_literal: true
module Security
class ReportSchemaVersionMatcher
def initialize(report_declared_version:, supported_versions:)
@report_version = Gem::Version.new(report_declared_version)
@supported_versions = supported_versions.sort.map { |version| Gem::Version.new(version) }
end
attr_reader :report_version, :supported_versions
def call
find_matching_versions
end
private
def find_matching_versions
dependency = Gem::Dependency.new('', approximate_version)
matches = supported_versions.map do |supported_version|
exact_version = ['', supported_version.to_s]
[supported_version.to_s, dependency.match?(*exact_version)]
end
matches.to_h.select { |_, matches_dependency| matches_dependency == true }.keys.max
end
def approximate_version
"~> #{generate_patch_version}"
end
def generate_patch_version
# We can't use #approximate_recommendation here because
# for "14.0.32" it would yield "~> 14.0" and according to
# https://www.rubydoc.info/github/rubygems/rubygems/Gem/Version#label-Preventing+Version+Catastrophe-3A
# "~> 3.0" covers [3.0...4.0)
# and version 14.1.0 would fall within that range
#
# Instead we replace the patch number with 0 and get "~> 14.0.0"
# Which will work as we want it to
(report_version.segments[0...2] << 0).join('.')
end
end
end
|