diff options
Diffstat (limited to 'lib/security/report_schema_version_matcher.rb')
-rw-r--r-- | lib/security/report_schema_version_matcher.rb | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/security/report_schema_version_matcher.rb b/lib/security/report_schema_version_matcher.rb new file mode 100644 index 00000000000..d8eb5b8f490 --- /dev/null +++ b/lib/security/report_schema_version_matcher.rb @@ -0,0 +1,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 |