diff --git a/Library/Homebrew/dev-cmd/unbottled.rb b/Library/Homebrew/dev-cmd/unbottled.rb index 118e68cd0f..8cbe3ad802 100644 --- a/Library/Homebrew/dev-cmd/unbottled.rb +++ b/Library/Homebrew/dev-cmd/unbottled.rb @@ -202,7 +202,7 @@ module Homebrew when MacOSRequirement next true unless r.version_specified? - macos_version.public_send(r.comparator, r.version) + macos_version.compare(r.comparator, r.version) when XcodeRequirement next true unless r.version diff --git a/Library/Homebrew/extend/os/mac/readall.rb b/Library/Homebrew/extend/os/mac/readall.rb index adb0ad26ab..4f180a0550 100644 --- a/Library/Homebrew/extend/os/mac/readall.rb +++ b/Library/Homebrew/extend/os/mac/readall.rb @@ -19,7 +19,7 @@ module Readall # Fine to have missing URLs for unsupported macOS macos_req = cask.depends_on.macos next if macos_req&.version && Array(macos_req.version).none? do |macos_version| - current_macos_version.public_send(macos_req.comparator, macos_version) + current_macos_version.compare(macos_req.comparator, macos_version) end raise "Missing URL" if cask.url.nil? diff --git a/Library/Homebrew/requirements/macos_requirement.rb b/Library/Homebrew/requirements/macos_requirement.rb index addba7473d..6309f5d47a 100644 --- a/Library/Homebrew/requirements/macos_requirement.rb +++ b/Library/Homebrew/requirements/macos_requirement.rb @@ -56,7 +56,7 @@ class MacOSRequirement < Requirement satisfy(build_env: false) do T.bind(self, MacOSRequirement) - next Array(@version).any? { |v| MacOS.version.public_send(@comparator, v) } if OS.mac? && version_specified? + next Array(@version).any? { |v| MacOS.version.compare(@comparator, v) } if OS.mac? && version_specified? next true if OS.mac? next true if @version diff --git a/Library/Homebrew/test/version_spec.rb b/Library/Homebrew/test/version_spec.rb index 62e3126885..647fb5dcca 100644 --- a/Library/Homebrew/test/version_spec.rb +++ b/Library/Homebrew/test/version_spec.rb @@ -93,6 +93,26 @@ describe Version do expect(described_class.create("1.2.3")).to be < described_class.create("1.2.3-p34") end + specify "compare" do + expect(described_class.create("0.1").compare("==", described_class.create("0.1.0"))).to be true + expect(described_class.create("0.1").compare("<", described_class.create("0.2"))).to be true + expect(described_class.create("1.2.3").compare(">", described_class.create("1.2.2"))).to be true + expect(described_class.create("1.2.4").compare("<", described_class.create("1.2.4.1"))).to be true + expect(described_class.create("0.1").compare("!=", described_class.create("0.1.0"))).to be false + expect(described_class.create("0.1").compare(">=", described_class.create("0.2"))).to be false + expect(described_class.create("1.2.3").compare("<=", described_class.create("1.2.2"))).to be false + expect(described_class.create("1.2.4").compare(">=", described_class.create("1.2.4.1"))).to be false + + expect(described_class.create("1.2.3").compare(">", described_class.create("1.2.3alpha4"))).to be true + expect(described_class.create("1.2.3").compare(">", described_class.create("1.2.3beta2"))).to be true + expect(described_class.create("1.2.3").compare(">", described_class.create("1.2.3rc3"))).to be true + expect(described_class.create("1.2.3").compare("<", described_class.create("1.2.3-p34"))).to be true + expect(described_class.create("1.2.3").compare("<=", described_class.create("1.2.3alpha4"))).to be false + expect(described_class.create("1.2.3").compare("<=", described_class.create("1.2.3beta2"))).to be false + expect(described_class.create("1.2.3").compare("<=", described_class.create("1.2.3rc3"))).to be false + expect(described_class.create("1.2.3").compare(">=", described_class.create("1.2.3-p34"))).to be false + end + specify "HEAD" do expect(described_class.create("HEAD")).to be > described_class.create("1.2.3") expect(described_class.create("HEAD-abcdef")).to be > described_class.create("1.2.3") diff --git a/Library/Homebrew/version.rb b/Library/Homebrew/version.rb index 625de73440..7b76ed791f 100644 --- a/Library/Homebrew/version.rb +++ b/Library/Homebrew/version.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "pkg_version" +require "version/head" require "version/null" require "version/parser" @@ -532,6 +533,19 @@ class Version false end + sig { params(comparator: String, other: Version).returns(T::Boolean) } + def compare(comparator, other) + case comparator + when ">=" then self >= other + when ">" then self > other + when "<" then self < other + when "<=" then self <= other + when "==" then self == other + when "!=" then self != other + else raise ArgumentError, "Unknown comparator: #{comparator}" + end + end + sig { params(other: T.untyped).returns(T.nilable(Integer)) } def <=>(other) # Needed to retain API compatibility with older string comparisons @@ -663,34 +677,3 @@ class Version version.scan(SCAN_PATTERN).map { |token| Token.create(T.cast(token, String)) } end end - -# A formula's HEAD version. -# @see https://docs.brew.sh/Formula-Cookbook#unstable-versions-head Unstable versions (head) -# -# @api private -class HeadVersion < Version - extend T::Sig - - sig { returns(T.nilable(String)) } - attr_reader :commit - - def initialize(*) - super - @commit = @version[/^HEAD-(.+)$/, 1] - end - - sig { params(commit: T.nilable(String)).void } - def update_commit(commit) - @commit = commit - @version = if commit - "HEAD-#{commit}" - else - "HEAD" - end - end - - sig { returns(T::Boolean) } - def head? - true - end -end diff --git a/Library/Homebrew/version/head.rb b/Library/Homebrew/version/head.rb new file mode 100644 index 0000000000..2607c91517 --- /dev/null +++ b/Library/Homebrew/version/head.rb @@ -0,0 +1,35 @@ +# typed: true +# frozen_string_literal: true + +class Version + # A formula's HEAD version. + # @see https://docs.brew.sh/Formula-Cookbook#unstable-versions-head Unstable versions (head) + # + # @api private + class HeadVersion < Version + extend T::Sig + + sig { returns(T.nilable(String)) } + attr_reader :commit + + def initialize(*) + super + @commit = @version[/^HEAD-(.+)$/, 1] + end + + sig { params(commit: T.nilable(String)).void } + def update_commit(commit) + @commit = commit + @version = if commit + "HEAD-#{commit}" + else + "HEAD" + end + end + + sig { returns(T::Boolean) } + def head? + true + end + end +end