diff --git a/docker/lib/dependabot/docker/requirement.rb b/docker/lib/dependabot/docker/requirement.rb index 99fcbf5a1f2..0ad1abfd014 100644 --- a/docker/lib/dependabot/docker/requirement.rb +++ b/docker/lib/dependabot/docker/requirement.rb @@ -13,6 +13,10 @@ def self.requirements_array(requirement_string) [new(requirement_string)] end + def satisfied_by?(version) + super(version.release_part) + end + # Patches Gem::Requirement to make it accept requirement strings like # "~> 4.2.5, >= 4.2.5.1" without first needing to split them. def initialize(*requirements) diff --git a/docker/lib/dependabot/docker/version.rb b/docker/lib/dependabot/docker/version.rb index 42d2b835eef..98bc8b6ac38 100644 --- a/docker/lib/dependabot/docker/version.rb +++ b/docker/lib/dependabot/docker/version.rb @@ -4,9 +4,28 @@ module Dependabot module Docker + # In the special case of Java, the version string may also contain + # optional "update number" and "identifier" components. + # See https://www.oracle.com/java/technologies/javase/versioning-naming.html + # for a description of Java versions. + # class Version < Gem::Version def initialize(version) - super(version.tr("_", ".")) + release_part, update_part = version.split("_", 2) + + @release_part = Gem::Version.new(release_part) + + @update_part = Gem::Version.new(update_part&.start_with?(/[0-9]/) ? update_part : 0) + end + + attr_reader :release_part + + def <=>(other) + sort_criteria <=> other.sort_criteria + end + + def sort_criteria + [@release_part, @update_part] end end end diff --git a/docker/spec/dependabot/docker/update_checker_spec.rb b/docker/spec/dependabot/docker/update_checker_spec.rb index 0f298016935..b6558f1e4f6 100644 --- a/docker/spec/dependabot/docker/update_checker_spec.rb +++ b/docker/spec/dependabot/docker/update_checker_spec.rb @@ -413,7 +413,7 @@ it { is_expected.to eq("jdk-11.0.2.9-alpine-slim") } end - context "when the dependencies have a underscore" do + context "when the dependencies have an underscore" do let(:dependency_name) { "eclipse-temurin" } let(:tags_fixture_name) { "eclipse-temurin.json" } let(:repo_url) do @@ -448,6 +448,11 @@ let(:version) { "17.0.1_12-jre-alpine" } it { is_expected.to eq("17.0.2_8-jre-alpine") } end + + context "followed by numbers and with less components than other version but higher underscore part" do + let(:version) { "11.0.16_8-jdk" } + it { is_expected.to eq("11.0.16.1_1-jdk") } + end end context "when the dependency has a namespace" do diff --git a/docker/spec/dependabot/docker/version_spec.rb b/docker/spec/dependabot/docker/version_spec.rb new file mode 100644 index 00000000000..db938840991 --- /dev/null +++ b/docker/spec/dependabot/docker/version_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "spec_helper" +require "dependabot/docker/version" + +RSpec.describe Dependabot::Docker::Version do + describe ".new" do + it "sorts properly" do + expect(described_class.new("2.4.2")).to be >= described_class.new("2.1.0") + expect(described_class.new("2.4.2")).to be < described_class.new("2.4.3") + end + + it "sorts properly when it uses underscores" do + expect(described_class.new("11.0.16_8-jdk")).to be < described_class.new("11.0.16.1-jdk") + expect(described_class.new("17.0.2_8-jdk")).to be > described_class.new("17.0.1_12-jdk") + end + end +end diff --git a/docker/spec/fixtures/docker/registry_tags/eclipse-temurin.json b/docker/spec/fixtures/docker/registry_tags/eclipse-temurin.json index 07d197ec525..376e68b7968 100644 --- a/docker/spec/fixtures/docker/registry_tags/eclipse-temurin.json +++ b/docker/spec/fixtures/docker/registry_tags/eclipse-temurin.json @@ -6,6 +6,8 @@ "17.0.1_12-jre-alpine", "17-jre-alpine", "11.0.14_9-jre-alpine", - "11-jre-alpine" + "11-jre-alpine", + "11.0.16_8-jdk", + "11.0.16.1_1-jdk" ] }