mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Enforce finalized sorbet methods
This commit is contained in:
parent
f0c746a0b9
commit
33d9267d7d
@ -77,6 +77,9 @@ class Formula
|
|||||||
extend Cachable
|
extend Cachable
|
||||||
extend Attrable
|
extend Attrable
|
||||||
extend APIHashable
|
extend APIHashable
|
||||||
|
extend T::Helpers
|
||||||
|
|
||||||
|
abstract!
|
||||||
|
|
||||||
SUPPORTED_NETWORK_ACCESS_PHASES = [:build, :test, :postinstall].freeze
|
SUPPORTED_NETWORK_ACCESS_PHASES = [:build, :test, :postinstall].freeze
|
||||||
private_constant :SUPPORTED_NETWORK_ACCESS_PHASES
|
private_constant :SUPPORTED_NETWORK_ACCESS_PHASES
|
||||||
@ -1596,7 +1599,11 @@ class Formula
|
|||||||
|
|
||||||
# Yields |self,staging| with current working directory set to the uncompressed tarball
|
# Yields |self,staging| with current working directory set to the uncompressed tarball
|
||||||
# where staging is a {Mktemp} staging context.
|
# where staging is a {Mktemp} staging context.
|
||||||
def brew(fetch: true, keep_tmp: false, debug_symbols: false, interactive: false)
|
sig(:final) {
|
||||||
|
params(fetch: T::Boolean, keep_tmp: T::Boolean, debug_symbols: T::Boolean, interactive: T::Boolean,
|
||||||
|
_blk: T.proc.params(arg0: Formula, arg1: Mktemp).void).void
|
||||||
|
}
|
||||||
|
def brew(fetch: true, keep_tmp: false, debug_symbols: false, interactive: false, &_blk)
|
||||||
@prefix_returns_versioned_prefix = true
|
@prefix_returns_versioned_prefix = true
|
||||||
active_spec.fetch if fetch
|
active_spec.fetch if fetch
|
||||||
stage(interactive:, debug_symbols:) do |staging|
|
stage(interactive:, debug_symbols:) do |staging|
|
||||||
@ -3344,12 +3351,7 @@ class Formula
|
|||||||
def method_added(method)
|
def method_added(method)
|
||||||
super
|
super
|
||||||
|
|
||||||
case method
|
define_method(:test_defined?) { true } if method == :test
|
||||||
when :brew
|
|
||||||
raise "You cannot override Formula#brew in class #{name}"
|
|
||||||
when :test
|
|
||||||
define_method(:test_defined?) { true }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def freeze
|
def freeze
|
||||||
|
@ -13,14 +13,15 @@ require "build_environment"
|
|||||||
class Requirement
|
class Requirement
|
||||||
include Dependable
|
include Dependable
|
||||||
extend Cachable
|
extend Cachable
|
||||||
|
extend T::Helpers
|
||||||
|
|
||||||
|
# This base class enforces no constraints on its own.
|
||||||
|
# Individual subclasses use the `satisfy` DSL to define those constraints.
|
||||||
|
abstract!
|
||||||
|
|
||||||
attr_reader :name, :cask, :download
|
attr_reader :name, :cask, :download
|
||||||
|
|
||||||
def initialize(tags = [])
|
def initialize(tags = [])
|
||||||
# Only allow instances of subclasses. This base class enforces no constraints on its own.
|
|
||||||
# Individual subclasses use the `satisfy` DSL to define those constraints.
|
|
||||||
raise "Do not call `Requirement.new' directly without a subclass." unless self.class < Requirement
|
|
||||||
|
|
||||||
@cask = self.class.cask
|
@cask = self.class.cask
|
||||||
@download = self.class.download
|
@download = self.class.download
|
||||||
tags.each do |tag|
|
tags.each do |tag|
|
||||||
|
@ -8,7 +8,9 @@ require "extend/module"
|
|||||||
# In the future we should consider not doing this monkey patch,
|
# In the future we should consider not doing this monkey patch,
|
||||||
# if assured that there is no performance hit from removing this.
|
# if assured that there is no performance hit from removing this.
|
||||||
# There are mechanisms to achieve a middle ground (`default_checked_level`).
|
# There are mechanisms to achieve a middle ground (`default_checked_level`).
|
||||||
unless ENV["HOMEBREW_SORBET_RUNTIME"]
|
if ENV["HOMEBREW_SORBET_RUNTIME"]
|
||||||
|
T::Configuration.enable_final_checks_on_hooks
|
||||||
|
else
|
||||||
# Redefine `T.let`, etc. to make the `checked` parameter default to `false` rather than `true`.
|
# Redefine `T.let`, etc. to make the `checked` parameter default to `false` rather than `true`.
|
||||||
# @private
|
# @private
|
||||||
module TNoChecks
|
module TNoChecks
|
||||||
|
@ -60,6 +60,11 @@ RSpec.describe Formula do
|
|||||||
expect { klass.new }.to raise_error(ArgumentError)
|
expect { klass.new }.to raise_error(ArgumentError)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
specify "formula instantiation without a subclass" do
|
||||||
|
expect { described_class.new(name, path, spec) }
|
||||||
|
.to raise_error(RuntimeError, "Do not call `Formula.new' directly without a subclass.")
|
||||||
|
end
|
||||||
|
|
||||||
context "when in a Tap" do
|
context "when in a Tap" do
|
||||||
let(:tap) { Tap.fetch("foo", "bar") }
|
let(:tap) { Tap.fetch("foo", "bar") }
|
||||||
let(:path) { (tap.path/"Formula/#{name}.rb") }
|
let(:path) { (tap.path/"Formula/#{name}.rb") }
|
||||||
|
@ -24,7 +24,7 @@ RSpec.describe Formula do
|
|||||||
formula do
|
formula do
|
||||||
def brew; end
|
def brew; end
|
||||||
end
|
end
|
||||||
end.to raise_error(RuntimeError, /You cannot override Formula#brew/)
|
end.to raise_error(RuntimeError, /\AThe method `brew` on #{described_class} was declared as final/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "validates the `name`" do
|
it "validates the `name`" do
|
||||||
|
@ -10,6 +10,13 @@ RSpec.describe Requirement do
|
|||||||
|
|
||||||
let(:klass) { Class.new(described_class) }
|
let(:klass) { Class.new(described_class) }
|
||||||
|
|
||||||
|
describe "base class" do
|
||||||
|
it "raises an error when instantiated" do
|
||||||
|
expect { described_class.new }
|
||||||
|
.to raise_error(RuntimeError, "Requirement is declared as abstract; it cannot be instantiated")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#tags" do
|
describe "#tags" do
|
||||||
subject(:req) { klass.new(tags) }
|
subject(:req) { klass.new(tags) }
|
||||||
|
|
||||||
@ -52,6 +59,17 @@ RSpec.describe Requirement do
|
|||||||
describe "#fatal is omitted" do
|
describe "#fatal is omitted" do
|
||||||
it { is_expected.not_to be_fatal }
|
it { is_expected.not_to be_fatal }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "in subclasses" do
|
||||||
|
it "raises an error when instantiated" do
|
||||||
|
expect do
|
||||||
|
Class.new(described_class) do
|
||||||
|
def fatal? = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
.to raise_error(RuntimeError, /\AThe method `fatal\?` on #{described_class.name} was declared as final/)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#satisfied?" do
|
describe "#satisfied?" do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user