Use MacOSRequirement for casks.

This commit is contained in:
Markus Reiter 2019-08-15 10:14:10 +02:00
parent 78aee4fed3
commit 16d2f8264c
11 changed files with 83 additions and 66 deletions

View File

@ -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*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/ =~ args.first
MacOSRequirement.new([version.to_sym], comparator: comparator)
elsif /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\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)

View File

@ -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

View File

@ -1,3 +1,4 @@
# frozen_string_literal: true
require "compat/cask/dsl/version"
require "compat/requirements/macos_requirement"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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