diff --git a/Library/Homebrew/ast_constants.rb b/Library/Homebrew/ast_constants.rb index c7a8fa88d7..1de605374d 100644 --- a/Library/Homebrew/ast_constants.rb +++ b/Library/Homebrew/ast_constants.rb @@ -32,9 +32,6 @@ FORMULA_COMPONENT_PRECEDENCE_LIST = [ [{ name: :on_linux, type: :block_call }], [{ name: :on_arm, type: :block_call }], [{ name: :on_intel, type: :block_call }], - *MacOSVersions::SYMBOLS.keys.map do |os_name| - [{ name: :"on_#{os_name}", type: :block_call }] - end, [{ name: :conflicts_with, type: :method_call }], [{ name: :skip_clean, type: :method_call }], [{ name: :cxxstdlib_check, type: :method_call }], diff --git a/Library/Homebrew/extend/on_system.rb b/Library/Homebrew/extend/on_system.rb index 35b81b062d..5ec59cbdfa 100644 --- a/Library/Homebrew/extend/on_system.rb +++ b/Library/Homebrew/extend/on_system.rb @@ -89,6 +89,25 @@ module OnSystem result end end + + base.define_method(:on_system) do |linux, macos:, &block| + @on_system_blocks_exist = true + + raise ArgumentError, "The first argument to `on_system` must be `:linux`" if linux != :linux + + os_version, or_condition = if macos.to_s.include?("_or_") + macos.to_s.split(/_(?=or_)/).map(&:to_sym) + else + [macos.to_sym, nil] + end + return if !OnSystem.os_condition_met?(os_version, or_condition) && !OnSystem.os_condition_met?(:linux) + + @called_in_on_system_block = true + result = block.call + @called_in_on_system_block = false + + result + end end sig { params(base: Class).void } diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index f9e3f93116..e47a197361 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -1538,10 +1538,10 @@ describe Formula do describe "#on_macos", :needs_macos do let(:f) do Class.new(Testball) do - @test = 0 attr_reader :test def install + @test = 0 on_macos do @test = 1 end @@ -1561,10 +1561,10 @@ describe Formula do describe "#on_linux", :needs_linux do let(:f) do Class.new(Testball) do - @test = 0 attr_reader :test def install + @test = 0 on_macos do @test = 1 end @@ -1581,6 +1581,65 @@ describe Formula do end end + describe "#on_system" do + after do + Homebrew::SimulateSystem.clear + end + + let(:f) do + Class.new(Testball) do + attr_reader :foo + attr_reader :bar + + def install + @foo = 0 + @bar = 0 + on_system :linux, macos: :monterey do + @foo = 1 + end + on_system :linux, macos: :big_sur_or_older do + @bar = 1 + end + end + end.new + end + + it "doesn't call code on Ventura", :needs_macos do + Homebrew::SimulateSystem.os = :ventura + f.brew { f.install } + expect(f.foo).to eq(0) + expect(f.bar).to eq(0) + end + + it "calls code on Linux", :needs_linux do + Homebrew::SimulateSystem.os = :linux + f.brew { f.install } + expect(f.foo).to eq(1) + expect(f.bar).to eq(1) + end + + it "calls code within `on_system :linux, macos: :monterey` on Monterey", :needs_macos do + Homebrew::SimulateSystem.os = :monterey + f.brew { f.install } + expect(f.foo).to eq(1) + expect(f.bar).to eq(0) + end + + it "calls code within `on_system :linux, macos: :big_sur_or_older` on Big Sur", :needs_macos do + Homebrew::SimulateSystem.os = :big_sur + f.brew { f.install } + expect(f.foo).to eq(0) + expect(f.bar).to eq(1) + end + + it "calls code within `on_system :linux, macos: :big_sur_or_older` on Catalina", :needs_macos do + Homebrew::SimulateSystem.os = :catalina + f.brew { f.install } + expect(f.foo).to eq(0) + expect(f.bar).to eq(1) + end + end + describe "on_{os_version} blocks", :needs_macos do before do Homebrew::SimulateSystem.os = :monterey @@ -1592,10 +1651,10 @@ describe Formula do let(:f) do Class.new(Testball) do - @test = 0 attr_reader :test def install + @test = 0 on_monterey :or_newer do @test = 1 end @@ -1647,10 +1706,10 @@ describe Formula do let(:f) do Class.new(Testball) do - @test = 0 attr_reader :test def install + @test = 0 on_arm do @test = 1 end @@ -1674,10 +1733,10 @@ describe Formula do let(:f) do Class.new(Testball) do - @test = 0 attr_reader :test def install + @test = 0 on_arm do @test = 1 end