diff --git a/Library/Homebrew/extend/on_system.rb b/Library/Homebrew/extend/on_system.rb index f881dbd3b1..35fedde1d1 100644 --- a/Library/Homebrew/extend/on_system.rb +++ b/Library/Homebrew/extend/on_system.rb @@ -1,6 +1,7 @@ # typed: strict # frozen_string_literal: true +require "requirements/macos_requirement" require "simulate_system" module OnSystem @@ -27,6 +28,7 @@ module OnSystem prop :intel, T::Boolean, default: false prop :linux, T::Boolean, default: false prop :macos, T::Boolean, default: false + prop :macos_requirements, T::Set[MacOSRequirement], default: Set[] alias arm? arm alias intel? intel @@ -36,7 +38,7 @@ module OnSystem # Whether the object has only default values. sig { returns(T::Boolean) } def empty? - !@arm && !@intel && !@linux && !@macos + !@arm && !@intel && !@linux && !@macos && @macos_requirements.empty? end # Whether the object has any non-default values. @@ -44,6 +46,20 @@ module OnSystem def present? = !empty? end + # Converts an `or_condition` value to a suitable `MacOSRequirements` + # `comparator` string, defaulting to `==` if the provided argument is `nil`. + sig { params(symbol: T.nilable(Symbol)).returns(String) } + def self.comparator_from_or_condition(symbol) + case symbol + when :or_newer + ">=" + when :or_older + "<=" + else + "==" + end + end + sig { params(arch: Symbol).returns(T::Boolean) } def self.arch_condition_met?(arch) raise ArgumentError, "Invalid arch condition: #{arch.inspect}" if ARCH_OPTIONS.exclude?(arch) @@ -142,6 +158,9 @@ module OnSystem else [macos.to_sym, nil] end + + comparator = OnSystem.comparator_from_or_condition(or_condition) + @uses_on_system.macos_requirements << MacOSRequirement.new([os_version], comparator:) return if !OnSystem.os_condition_met?(os_version, or_condition) && !OnSystem.os_condition_met?(:linux) @called_in_on_system_block = true @@ -172,6 +191,9 @@ module OnSystem @uses_on_system.macos = true os_condition = OnSystem.condition_from_method_name T.must(__method__) + comparator = OnSystem.comparator_from_or_condition(or_condition) + @uses_on_system.macos_requirements << MacOSRequirement.new([os_condition], comparator:) + return unless OnSystem.os_condition_met? os_condition, or_condition @on_system_block_min_os = T.let( diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index 0895cbdfb2..82c384c4d4 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -855,6 +855,12 @@ RSpec.describe Cask::DSL, :cask do it "sets @uses_on_system.macos to true" do expect(cask.uses_on_system.macos?).to be true end + + it "sets @uses_on_system.macos_requirements using macos argument" do + expect(cask.uses_on_system.macos_requirements).to eq(Set[ + MacOSRequirement.new([:sequoia], comparator: ">="), + ]) + end end context "when cask uses on_system_conditional" do @@ -890,6 +896,14 @@ RSpec.describe Cask::DSL, :cask do it "sets @uses_on_system.macos to true" do expect(cask.uses_on_system.macos?).to be true end + + it "sets @uses_on_system.macos_requirements using on_* macos version conditions" do + expect(cask.uses_on_system.macos_requirements).to eq(Set[ + MacOSRequirement.new([:big_sur], comparator: "<="), + MacOSRequirement.new([:monterey], comparator: "=="), + MacOSRequirement.new([:ventura], comparator: ">="), + ]) + end end end end diff --git a/Library/Homebrew/test/extend/on_system_spec.rb b/Library/Homebrew/test/extend/on_system_spec.rb index 84fc72c006..1789999a52 100644 --- a/Library/Homebrew/test/extend/on_system_spec.rb +++ b/Library/Homebrew/test/extend/on_system_spec.rb @@ -52,6 +52,24 @@ RSpec.describe OnSystem do end end + describe "::comparator_from_or_condition" do + it 'returns ">=" for `:or_newer` symbol' do + expect(described_class.comparator_from_or_condition(:or_newer)).to eq(">=") + end + + it 'returns "<=" for `:or_older` symbol' do + expect(described_class.comparator_from_or_condition(:or_older)).to eq("<=") + end + + it 'returns "==" for an unsupported symbol' do + expect(described_class.comparator_from_or_condition(:nonexistent)).to eq("==") + end + + it 'returns "==" for `nil`' do + expect(described_class.comparator_from_or_condition(nil)).to eq("==") + end + end + describe "::arch_condition_met?" do it "returns true if current arch equals provided arch" do Homebrew::SimulateSystem.with(arch: :arm) do diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index f9d2aa28ab..05cae65fc7 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -2073,6 +2073,12 @@ RSpec.describe Formula do it "sets @uses_on_system.macos to true" do expect(f_on_system.uses_on_system.macos?).to be true end + + it "sets @uses_on_system.macos_requirements using macos argument" do + expect(f_on_system.uses_on_system.macos_requirements).to eq(Set[ + MacOSRequirement.new([:sequoia], comparator: ">="), + ]) + end end context "when formula uses on_system_conditional" do @@ -2131,6 +2137,14 @@ RSpec.describe Formula do it "sets @uses_on_system.macos to true" do expect(f_on_macos_versions.uses_on_system.macos?).to be true end + + it "sets @uses_on_system.macos_requirements using on_* macos version conditions" do + expect(f_on_macos_versions.uses_on_system.macos_requirements).to eq(Set[ + MacOSRequirement.new([:big_sur], comparator: "<="), + MacOSRequirement.new([:monterey], comparator: "=="), + MacOSRequirement.new([:ventura], comparator: ">="), + ]) + end end end