formula: add new pour_bottle DSL with reason.

This allows there to be a user-visible description of why a bottle is
not being installed.
This commit is contained in:
Mike McQuaid 2016-01-09 11:06:17 +00:00
parent 74858b28c5
commit 26ec9f9ea0
3 changed files with 67 additions and 2 deletions

View File

@ -799,10 +799,16 @@ class Formula
# Can be overridden to selectively disable bottles from formulae. # Can be overridden to selectively disable bottles from formulae.
# Defaults to true so overridden version does not have to check if bottles # Defaults to true so overridden version does not have to check if bottles
# are supported. # are supported.
# Replaced by {.pour_bottle}'s `satisfy` method if it is specified.
def pour_bottle? def pour_bottle?
true true
end end
# @private
def pour_bottle_check_unsatisfied_reason
self.class.pour_bottle_check_unsatisfied_reason
end
# Can be overridden to run commands on both source and bottle installation. # Can be overridden to run commands on both source and bottle installation.
def post_install; end def post_install; end
@ -1614,6 +1620,11 @@ class Formula
# @private # @private
attr_reader :plist_manual attr_reader :plist_manual
# If `pour_bottle?` returns `false` the user-visible reason to display for
# why they cannot use the bottle.
# @private
attr_accessor :pour_bottle_check_unsatisfied_reason
# @!attribute [w] revision # @!attribute [w] revision
# Used for creating new Homebrew versions of software without new upstream # Used for creating new Homebrew versions of software without new upstream
# versions. For example, if we bump the major version of a library this # versions. For example, if we bump the major version of a library this
@ -2023,11 +2034,27 @@ class Formula
# #
# The test will fail if it returns false, or if an exception is raised. # The test will fail if it returns false, or if an exception is raised.
# Failed assertions and failed `system` commands will raise exceptions. # Failed assertions and failed `system` commands will raise exceptions.
def test(&block) def test(&block)
define_method(:test, &block) define_method(:test, &block)
end end
# Defines whether the {Formula}'s bottle can be used on the given Homebrew
# installation.
#
# For example, if the bottle requires the Xcode CLT to be installed a
# {Formula} would declare:
# <pre>pour_bottle? do
# reason "The bottle needs the Xcode CLT to be installed."
# satisfy { MacOS::CLT.installed? }
# end</pre>
#
# If `satisfy` returns `false` then a bottle will not be used and instead
# the {Formula} will be built from source and `reason` will be printed.
def pour_bottle?(&block)
@pour_bottle_check = PourBottleCheck.new(self)
@pour_bottle_check.instance_eval(&block)
end
# @private # @private
def link_overwrite(*paths) def link_overwrite(*paths)
paths.flatten! paths.flatten!

View File

@ -351,7 +351,7 @@ class PourBottleCheck
end end
def reason(reason) def reason(reason)
@formula.pour_bottle_check_unsatisfied_reason(reason) @formula.pour_bottle_check_unsatisfied_reason = reason
end end
def satisfy(&block) def satisfy(&block)

View File

@ -367,4 +367,42 @@ class FormulaTests < Homebrew::TestCase
[f1, f2, f3].each(&:clear_cache) [f1, f2, f3].each(&:clear_cache)
f3.rack.rmtree f3.rack.rmtree
end end
def test_pour_bottle
f_false = formula("foo") do
url "foo-1.0"
def pour_bottle?
false
end
end
refute f_false.pour_bottle?
f_true = formula("foo") do
url "foo-1.0"
def pour_bottle?
true
end
end
assert f_true.pour_bottle?
end
def test_pour_bottle_dsl
f_false = formula("foo") do
url "foo-1.0"
pour_bottle? do
reason "false reason"
satisfy { var == etc }
end
end
refute f_false.pour_bottle?
f_true = formula("foo") do
url "foo-1.0"
pour_bottle? do
reason "true reason"
satisfy { var == var }
end
end
assert f_true.pour_bottle?
end
end end