diff --git a/Library/Homebrew/cask/dsl/depends_on.rb b/Library/Homebrew/cask/dsl/depends_on.rb index 56a4107274..3c6ac402ae 100644 --- a/Library/Homebrew/cask/dsl/depends_on.rb +++ b/Library/Homebrew/cask/dsl/depends_on.rb @@ -37,25 +37,6 @@ module Cask end end - def self.coerce_os_release(arg) - @macos_symbols ||= MacOS::Version::SYMBOLS - @inverted_macos_symbols ||= @macos_symbols.invert - - begin - if arg.is_a?(Symbol) - Gem::Version.new(@macos_symbols.fetch(arg)) - elsif arg =~ /^\s*:?([a-z]\S+)\s*$/i - Gem::Version.new(@macos_symbols.fetch(Regexp.last_match[1].downcase.to_sym)) - elsif @inverted_macos_symbols.key?(arg) - Gem::Version.new(arg) - else - raise - end - rescue - raise "invalid 'depends_on macos' value: #{arg.inspect}" - end - end - def formula=(*args) @formula.concat(args) end @@ -65,19 +46,23 @@ module Cask end def macos=(*args) - @macos ||= [] - macos = if args.count == 1 && args.first =~ /^\s*(<|>|[=<>]=)\s*(\S+)\s*$/ - raise "'depends_on macos' comparison expressions cannot be combined" unless @macos.empty? + raise "Only a single 'depends_on macos:' is allowed." if defined?(@macos) - operator = Regexp.last_match[1].to_sym - release = self.class.coerce_os_release(Regexp.last_match[2]) - [[operator, release]] - else - raise "'depends_on macos' comparison expressions cannot be combined" if @macos.first.is_a?(Symbol) - - args.map(&self.class.method(:coerce_os_release)).sort + begin + @macos = if args.count > 1 + MacOSRequirement.new([args], comparator: "==") + elsif MacOS::Version::SYMBOLS.key?(args.first) + MacOSRequirement.new([args.first], comparator: "==") + elsif /^\s*(?<|>|[=<>]=)\s*:(?\S+)\s*$/ =~ args.first + MacOSRequirement.new([version.to_sym], comparator: comparator) + elsif /^\s*(?<|>|[=<>]=)\s*(?\S+)\s*$/ =~ args.first + MacOSRequirement.new([version], comparator: comparator) + else + MacOSRequirement.new([args.first], comparator: "==") + end + rescue + raise "invalid 'depends_on macos' value: #{args.first.inspect}" end - @macos.concat(macos) end def arch=(*args) diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index ec656ddbf4..c517163950 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -253,29 +253,9 @@ module Cask def macos_dependencies return unless @cask.depends_on.macos + return if @cask.depends_on.macos.satisfied? - if @cask.depends_on.macos.first.is_a?(Array) - operator, release = @cask.depends_on.macos.first - unless MacOS.version.send(operator, release) - raise CaskError, - "Cask #{@cask} depends on macOS release #{operator} #{release}, " \ - "but you are running release #{MacOS.version}." - end - elsif @cask.depends_on.macos.length > 1 - unless @cask.depends_on.macos.include?(Gem::Version.new(MacOS.version.to_s)) - raise CaskError, - "Cask #{@cask} depends on macOS release being one of " \ - "[#{@cask.depends_on.macos.map(&:to_s).join(", ")}], " \ - "but you are running release #{MacOS.version}." - end - else - unless MacOS.version == @cask.depends_on.macos.first - raise CaskError, - "Cask #{@cask} depends on macOS release " \ - "#{@cask.depends_on.macos.first}, " \ - "but you are running release #{MacOS.version}." - end - end + raise CaskError, @cask.depends_on.macos.message(type: :cask) end def arch_dependencies diff --git a/Library/Homebrew/compat.rb b/Library/Homebrew/compat.rb index 35bd487de4..e5d13c8d05 100644 --- a/Library/Homebrew/compat.rb +++ b/Library/Homebrew/compat.rb @@ -1,3 +1,4 @@ # frozen_string_literal: true require "compat/cask/dsl/version" +require "compat/requirements/macos_requirement" diff --git a/Library/Homebrew/compat/requirements/macos_requirement.rb b/Library/Homebrew/compat/requirements/macos_requirement.rb new file mode 100644 index 0000000000..9930b7baed --- /dev/null +++ b/Library/Homebrew/compat/requirements/macos_requirement.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class MacOSRequirement < Requirement + module Compat + def initialize(tags = [], comparator: ">=") + if tags.first.respond_to?(:map) + versions, *rest = tags + + versions = versions.map do |v| + next v if v.is_a?(Symbol) + + sym = MacOS::Version.new(v).to_sym + + odeprecated "depends_on macos: #{v.inspect}", "depends_on macos: #{sym.inspect}", + disable_on: Time.parse("2019-10-15") + + sym + end + + tags = [versions, *rest] + elsif !tags.empty? && !tags.first.is_a?(Symbol) + v, *rest = tags + sym = MacOS::Version.new(v).to_sym + + odeprecated "depends_on macos: #{v.inspect}", "depends_on macos: #{sym.inspect}", + disable_on: Time.parse("2019-10-15") + + tags = [sym, *rest] + end + + super(tags, comparator: comparator) + end + end + + prepend Compat +end diff --git a/Library/Homebrew/requirements/macos_requirement.rb b/Library/Homebrew/requirements/macos_requirement.rb index 35655ce9f8..8f7b2bcc22 100644 --- a/Library/Homebrew/requirements/macos_requirement.rb +++ b/Library/Homebrew/requirements/macos_requirement.rb @@ -6,7 +6,12 @@ class MacOSRequirement < Requirement fatal true def initialize(tags = [], comparator: ">=") - @version = MacOS::Version.from_symbol(tags.shift) unless tags.empty? + if comparator == "==" && tags.first.respond_to?(:map) + @version = tags.shift.map { |s| MacOS::Version.from_symbol(s) } + else + @version = MacOS::Version.from_symbol(tags.shift) unless tags.empty? + end + @comparator = comparator super(tags) end @@ -16,25 +21,35 @@ class MacOSRequirement < Requirement end satisfy(build_env: false) do - next MacOS.version.public_send(@comparator, @version) if version_specified? + next [*@version].any? { |v| MacOS.version.public_send(@comparator, v) } if version_specified? next true if OS.mac? next true if @version false end - def message + def message(type: :formula) return "macOS is required." unless version_specified? case @comparator when ">=" "macOS #{@version.pretty_name} or newer is required." when "<=" - <<~EOS - This formula either does not compile or function as expected on macOS - versions newer than #{@version.pretty_name} due to an upstream incompatibility. - EOS + case type + when :formula + <<~EOS + This formula either does not compile or function as expected on macOS + versions newer than #{@version.pretty_name} due to an upstream incompatibility. + EOS + when :cask + "This cask does not on macOS versions newer than #{@version.pretty_name}." + end else + if @version.respond_to?(:to_ary) + *versions, last = @version.map(:pretty_name) + return "macOS #{versions.join(", ")} or #{last} is required." + end + "macOS #{@version.pretty_name} is required." end end diff --git a/Library/Homebrew/test/cask/depends_on_spec.rb b/Library/Homebrew/test/cask/depends_on_spec.rb index f8d679e6eb..c630d3dfd4 100644 --- a/Library/Homebrew/test/cask/depends_on_spec.rb +++ b/Library/Homebrew/test/cask/depends_on_spec.rb @@ -45,8 +45,8 @@ describe "Satisfy Dependencies and Requirements", :cask do it { is_expected.not_to raise_error } end - context "given a string" do - let(:cask) { Cask::CaskLoader.load(cask_path("with-depends-on-macos-string")) } + context "given a string", :needs_compat do + let(:cask) { Cask::CaskLoader.load(cask_path("compat/with-depends-on-macos-string")) } it { is_expected.not_to raise_error } end diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index 3e1de25e8d..5b6b8b7808 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -337,8 +337,8 @@ describe Cask::DSL, :cask do end describe "depends_on macos" do - context "valid" do - let(:token) { "with-depends-on-macos-string" } + context "valid", :needs_compat do + let(:token) { "compat/with-depends-on-macos-string" } it "allows depends_on macos to be specified" do expect(cask.depends_on.macos).not_to be nil diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-string.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/compat/with-depends-on-macos-string.rb similarity index 100% rename from Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-string.rb rename to Library/Homebrew/test/support/fixtures/cask/Casks/compat/with-depends-on-macos-string.rb diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-array.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-array.rb index 761d71c8e7..8d7135c0d9 100644 --- a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-array.rb +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-array.rb @@ -6,7 +6,7 @@ cask 'with-depends-on-macos-array' do homepage 'https://brew.sh/with-depends-on-macos-array' # since all OS releases are included, this should always pass - depends_on macos: ['10.9', '10.10', MacOS.version.to_s] + depends_on macos: [:mavericks, :sierra, MacOS.version.to_sym] app 'Caffeine.app' end diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-comparison.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-comparison.rb index aa2cb6649a..c7dff81b39 100644 --- a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-comparison.rb +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-comparison.rb @@ -5,7 +5,7 @@ cask 'with-depends-on-macos-comparison' do url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip" homepage 'https://brew.sh/with-depends-on-macos-comparison' - depends_on macos: '>= 10.9' + depends_on macos: '>= :mavericks' app 'Caffeine.app' end diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb index 66c001fce6..c35b584007 100644 --- a/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-depends-on-macos-failure.rb @@ -6,7 +6,7 @@ cask 'with-depends-on-macos-failure' do homepage 'https://brew.sh/with-depends-on-macos-failure' # guarantee a mismatched release - depends_on macos: MacOS.version.to_s == '10.9' ? '10.10' : '10.9' + depends_on macos: MacOS.version == :mavericks ? :sierra : :mavericks app 'Caffeine.app' end