deprecate!/disable!: allow to specify replacement type

Signed-off-by: botantony <antonsm21@gmail.com>
This commit is contained in:
botantony 2025-03-24 16:23:57 +01:00 committed by Anton Melnikov
parent e32b0bd796
commit e594e7e0bb
5 changed files with 189 additions and 66 deletions

View File

@ -91,11 +91,13 @@ module Cask
:deprecation_date,
:deprecation_reason,
:deprecation_replacement,
:deprecation_replacement_type,
:disable!,
:disabled?,
:disable_date,
:disable_reason,
:disable_replacement,
:disable_replacement_type,
:discontinued?, # TODO: remove once discontinued? is removed (4.5.0)
:livecheck,
:livecheck_defined?,
@ -110,8 +112,9 @@ module Cask
include OnSystem::MacOSAndLinux
attr_reader :cask, :token, :deprecation_date, :deprecation_reason, :deprecation_replacement, :disable_date,
:disable_reason, :disable_replacement, :on_system_block_min_os
attr_reader :cask, :token, :deprecation_date, :deprecation_reason, :deprecation_replacement,
:deprecation_replacement_type, :disable_date, :disable_reason,
:disable_replacement, :disable_replacement_type, :on_system_block_min_os
def initialize(cask)
@cask = cask
@ -526,12 +529,16 @@ module Cask
# NOTE: A warning will be shown when trying to install this cask.
#
# @api public
def deprecate!(date:, because:, replacement: nil)
def deprecate!(date:, because:, replacement: nil, replacement_type: :cask)
raise ArgumentError, "Invalid replacement type: #{replacement_type}" if [:formula,
:cask].exclude?(replacement_type)
@deprecation_date = Date.parse(date)
return if @deprecation_date > Date.today
@deprecation_reason = because
@deprecation_replacement = replacement
@deprecation_replacement_type = replacement_type
@deprecated = true
end
@ -540,18 +547,23 @@ module Cask
# NOTE: An error will be thrown when trying to install this cask.
#
# @api public
def disable!(date:, because:, replacement: nil)
def disable!(date:, because:, replacement: nil, replacement_type: :cask)
raise ArgumentError, "Invalid replacement type: #{replacement_type}" if [:formula,
:cask].exclude?(replacement_type)
@disable_date = Date.parse(date)
if @disable_date > Date.today
@deprecation_reason = because
@deprecation_replacement = replacement
@deprecation_replacement_type = replacement_type
@deprecated = true
return
end
@disable_reason = because
@disable_replacement = replacement
@disable_replacement_type = replacement_type
@disabled = true
end

View File

@ -83,11 +83,17 @@ module DeprecateDisable
formula_or_cask.disable_replacement
end
replacement_type = if formula_or_cask.deprecated?
formula_or_cask.deprecation_replacement_type
elsif formula_or_cask.disabled?
formula_or_cask.disable_replacement_type
end
if replacement.present?
message << "\n"
message << <<~EOS
Replacement:
brew install #{replacement}
brew install --#{replacement_type} #{replacement}
EOS
end

View File

@ -1484,6 +1484,17 @@ class Formula
# @see .deprecate!
delegate deprecation_replacement: :"self.class"
# Type of the replacement for this deprecated {Formula}.
# Returns `nil` if the formula is not deprecated.
# @!method deprecation_replacement_type
# @return [Symbol]
# @see .deprecate!
# delegate deprecation_replacement_type: :@deprecation_replacement_type
sig { returns(T.nilable(Symbol)) }
def deprecation_replacement_type
@deprecation_replacement_type ||= T.let(nil, T.nilable(Symbol))
end
# Whether this {Formula} is disabled (i.e. cannot be installed).
# Defaults to false.
# @!method disabled?
@ -1512,6 +1523,17 @@ class Formula
# @see .disable!
delegate disable_replacement: :"self.class"
# Type of the replacement for this disabled {Formula}.
# Returns `nil` if no replacement is specified or the formula is not deprecated.
# @!method disable_replacement_type
# @return [Symbol]
# @see .disable!
# delegate disable_replacement_type: :@disable_replacement_type
sig { returns(T.nilable(Symbol)) }
def disable_replacement_type
@disable_replacement_type ||= T.let(nil, T.nilable(Symbol))
end
sig { returns(T::Boolean) }
def skip_cxxstdlib_check? = false
@ -2533,10 +2555,12 @@ class Formula
"deprecation_date" => deprecation_date,
"deprecation_reason" => deprecation_reason,
"deprecation_replacement" => deprecation_replacement,
"deprecation_replacement_type" => @deprecation_replacement_type,
"disabled" => disabled?,
"disable_date" => disable_date,
"disable_reason" => disable_reason,
"disable_replacement" => disable_replacement,
"disable_replacement_type" => @disable_replacement_type,
"post_install_defined" => post_install_defined?,
"service" => (service.to_hash if service?),
"tap_git_head" => tap_git_head,
@ -4320,17 +4344,29 @@ class Formula
# ```ruby
# deprecate! date: "2020-08-27", because: "has been replaced by foo", replacement: "foo"
# ```
# ```ruby
# deprecate! date: "2020-08-27", because: "has been replaced by foo", replacement: "foo",
# replacement_type: :cask
# ```
#
# @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae
# @see DeprecateDisable::FORMULA_DEPRECATE_DISABLE_REASONS
# @api public
sig { params(date: String, because: T.any(NilClass, String, Symbol), replacement: T.nilable(String)).void }
def deprecate!(date:, because:, replacement: nil)
sig {
params(date: String, because: T.any(NilClass, String, Symbol), replacement: T.nilable(String),
replacement_type: Symbol).void
}
def deprecate!(date:, because:, replacement: nil, replacement_type: :formula)
if [:formula, :cask].exclude?(replacement_type)
raise ArgumentError, "Invalid replacement type: #{replacement_type}"
end
@deprecation_date = T.let(Date.parse(date), T.nilable(Date))
return if T.must(@deprecation_date) > Date.today
@deprecation_reason = T.let(because, T.any(NilClass, String, Symbol))
@deprecation_replacement = T.let(replacement, T.nilable(String))
@deprecation_replacement_type = T.let(replacement_type, T.nilable(Symbol))
T.must(@deprecated = T.let(true, T.nilable(T::Boolean)))
end
@ -4363,6 +4399,13 @@ class Formula
sig { returns(T.nilable(String)) }
attr_reader :deprecation_replacement
# Type of the replacement for a deprecated {Formula}.
#
# @return [nil] if no replacement was provided or the formula is not deprecated.
# @see .deprecate!
sig { returns(T.nilable(Symbol)) }
attr_reader :deprecation_replacement_type
# Disables a {Formula} (on the given date) so it cannot be
# installed. If the date has not yet passed the formula
# will be deprecated instead of disabled.
@ -4380,23 +4423,35 @@ class Formula
# ```ruby
# disable! date: "2020-08-27", because: "has been replaced by foo", replacement: "foo"
# ```
# ```ruby
# disable! date: "2020-08-27", because: "has been replaced by foo", replacement: "foo", replacement_type: :cask
# ```
#
# @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae
# @see DeprecateDisable::FORMULA_DEPRECATE_DISABLE_REASONS
# @api public
sig { params(date: String, because: T.any(NilClass, String, Symbol), replacement: T.nilable(String)).void }
def disable!(date:, because:, replacement: nil)
sig {
params(date: String, because: T.any(NilClass, String, Symbol), replacement: T.nilable(String),
replacement_type: Symbol).void
}
def disable!(date:, because:, replacement: nil, replacement_type: :formula)
if [:formula, :cask].exclude?(replacement_type)
raise ArgumentError, "Invalid replacement type: #{replacement_type}"
end
@disable_date = T.let(Date.parse(date), T.nilable(Date))
if T.must(@disable_date) > Date.today
@deprecation_reason = T.let(because, T.any(NilClass, String, Symbol))
@deprecation_replacement = T.let(replacement, T.nilable(String))
@deprecation_replacement_type = T.let(replacement_type, T.nilable(Symbol))
@deprecated = T.let(true, T.nilable(T::Boolean))
return
end
@disable_reason = T.let(because, T.nilable(T.any(String, Symbol)))
@disable_replacement = T.let(replacement, T.nilable(String))
@disable_replacement_type = T.let(replacement_type, T.nilable(Symbol))
@disabled = T.let(true, T.nilable(T::Boolean))
end
@ -4430,6 +4485,13 @@ class Formula
sig { returns(T.nilable(String)) }
attr_reader :disable_replacement
# Type of the replacement for a disabled {Formula}.
# Returns `nil` if the formula is not disabled.
#
# @see .disable!
sig { returns(T.nilable(Symbol)) }
attr_reader :disable_replacement_type
# Permit overwriting certain files while linking.
#
# ### Examples

View File

@ -69,6 +69,9 @@ class Cask::Cask
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def deprecation_replacement(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def deprecation_replacement_type(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def desc(*args, &block); end
@ -87,6 +90,9 @@ class Cask::Cask
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def disable_replacement(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def disable_replacement_type(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T::Boolean) }
def disabled?(*args, &block); end

View File

@ -7,27 +7,33 @@ RSpec.describe DeprecateDisable do
let(:disable_date) { deprecate_date >> DeprecateDisable::REMOVE_DISABLED_TIME_WINDOW }
let(:deprecated_formula) do
instance_double(Formula, deprecated?: true, disabled?: false, deprecation_reason: :does_not_build,
deprecation_replacement: nil, deprecation_date: nil, disable_date: nil)
deprecation_replacement: nil, deprecation_replacement_type: nil,
deprecation_date: nil, disable_date: nil)
end
let(:deprecated_formula_with_date) do
instance_double(Formula, deprecated?: true, disabled?: false, deprecation_reason: :does_not_build,
deprecation_replacement: nil, deprecation_date: deprecate_date, disable_date: nil)
deprecation_replacement: nil, deprecation_replacement_type: nil,
deprecation_date: deprecate_date, disable_date: nil)
end
let(:disabled_formula) do
instance_double(Formula, deprecated?: false, disabled?: true, disable_reason: "is broken",
disable_replacement: nil, deprecation_date: nil, disable_date: nil)
disable_replacement: nil, disable_replacement_type: nil,
deprecation_date: nil, disable_date: nil)
end
let(:disabled_formula_with_date) do
instance_double(Formula, deprecated?: false, disabled?: true, disable_reason: :does_not_build,
disable_replacement: nil, deprecation_date: nil, disable_date: disable_date)
disable_replacement: nil, disable_replacement_type: nil,
deprecation_date: nil, disable_date: disable_date)
end
let(:deprecated_cask) do
instance_double(Cask::Cask, deprecated?: true, disabled?: false, deprecation_reason: :discontinued,
deprecation_replacement: nil, deprecation_date: nil, disable_date: nil)
deprecation_replacement: nil, deprecation_replacement_type: nil,
deprecation_date: nil, disable_date: nil)
end
let(:disabled_cask) do
instance_double(Cask::Cask, deprecated?: false, disabled?: true, disable_reason: nil,
disable_replacement: nil, deprecation_date: nil, disable_date: nil)
disable_replacement: nil, disable_replacement_type: nil,
deprecation_date: nil, disable_date: nil)
end
let(:deprecated_formula_with_replacement) do
instance_double(Formula, deprecated?: true, disabled?: false, deprecation_reason: :does_not_build,
@ -125,23 +131,54 @@ RSpec.describe DeprecateDisable do
end
it "returns a replacement message for a deprecated formula" do
# allow(deprecated_formula_with_replacement).to receive(:deprecation_replacement_type).and_return(:formula)
expect(deprecated_formula_with_replacement).to receive(:deprecation_replacement_type).and_return(:formula)
expect(described_class.message(deprecated_formula_with_replacement))
.to eq "deprecated because it does not build!\nReplacement:\n brew install foo\n"
.to eq "deprecated because it does not build!\nReplacement:\n brew install --formula foo\n"
end
it "returns a replacement cask message for a deprecated formula" do
allow(deprecated_formula_with_replacement).to receive(:deprecation_replacement_type).and_return(:cask)
expect(described_class.message(deprecated_formula_with_replacement))
.to eq "deprecated because it does not build!\nReplacement:\n brew install --cask foo\n"
end
it "returns a replacement message for a disabled formula" do
# allow(disabled_formula_with_replacement).to receive(:disable_replacement_type).and_return(:formula)
expect(disabled_formula_with_replacement).to receive(:disable_replacement_type).and_return(:formula)
expect(described_class.message(disabled_formula_with_replacement))
.to eq "disabled because it is broken!\nReplacement:\n brew install bar\n"
.to eq "disabled because it is broken!\nReplacement:\n brew install --formula bar\n"
end
it "returns a replacement cask message for a disabled formula" do
allow(disabled_formula_with_replacement).to receive(:disable_replacement_type).and_return(:cask)
expect(described_class.message(disabled_formula_with_replacement))
.to eq "disabled because it is broken!\nReplacement:\n brew install --cask bar\n"
end
it "returns a replacement message for a deprecated cask" do
# allow(deprecated_cask_with_replacement).to receive(:deprecation_replacement_type).and_return(:cask)
expect(deprecated_cask_with_replacement).to receive(:deprecation_replacement_type).and_return(:cask)
expect(described_class.message(deprecated_cask_with_replacement))
.to eq "deprecated because it is discontinued upstream!\nReplacement:\n brew install baz\n"
.to eq "deprecated because it is discontinued upstream!\nReplacement:\n brew install --cask baz\n"
end
it "returns a replacement formula message for a deprecated cask" do
allow(deprecated_cask_with_replacement).to receive(:deprecation_replacement_type).and_return(:formula)
expect(described_class.message(deprecated_cask_with_replacement))
.to eq "deprecated because it is discontinued upstream!\nReplacement:\n brew install --formula baz\n"
end
it "returns a replacement message for a disabled cask" do
expect(disabled_cask_with_replacement).to receive(:disable_replacement_type).and_return(:cask)
expect(described_class.message(disabled_cask_with_replacement))
.to eq "disabled!\nReplacement:\n brew install qux\n"
.to eq "disabled!\nReplacement:\n brew install --cask qux\n"
end
it "returns a replacement formula message for a disabled cask" do
allow(disabled_cask_with_replacement).to receive(:disable_replacement_type).and_return(:formula)
expect(described_class.message(disabled_cask_with_replacement))
.to eq "disabled!\nReplacement:\n brew install --formula qux\n"
end
end