OnSystem: Add UsesOnSystem class

This adds a `UsesOnSystem` class to `OnSystem`, containing boolean
instance variables to indicate which types of on_system methods are
used in a formula or cask. This is intended as a replacement for
`@on_system_blocks_exist`, which doesn't allow us to determine what
kinds of on_system calls were used. This provides more granularity
but we can still use `@uses_on_system.present?` to determine whether
any on_system calls were used (and this doubles as a `nil` check in
`Formula`, as the `self.class` instance variable has to use a nilable
type).

The `UsesOnSystem` instance variables cover the current
`ARCH_OPTIONS` and `BASE_OS_OPTIONS`. At the moment, we mostly need
to tell whether there are macOS/Linux or Intel/ARM on_system calls,
so I've omitted instance variables for specific macOS version until
we have a need for them.

As a practical example, if you wanted to determine whether a cask
uses Linux on_system calls, you can call
`cask.uses_on_system.linux?`. The `linux` boolean will be `true` if
the cask has an `on_linux` block, an `on_system` block (which requires
Linux), or uses `os linux: ...`. This is something that would be
challenging to determine from outside of `OnSystem` but it's
relatively easy to collect the information in `OnSystem` methods and
make it available like this.
This commit is contained in:
Sam Ford 2025-04-07 12:38:50 -04:00
parent bafa2ec126
commit 3df8f70511
No known key found for this signature in database
GPG Key ID: 7AF5CBEE1DD6F76D
24 changed files with 720 additions and 36 deletions

View File

@ -718,7 +718,7 @@ module Cask
cask_min_os = [on_system_block_min_os, cask.depends_on.macos&.minimum_version].compact.max
odebug "Declared minimum OS version: #{cask_min_os&.to_sym}"
return if cask_min_os&.to_sym == min_os.to_sym
return if cask.on_system_blocks_exist? &&
return if cask.uses_on_system.present? &&
OnSystem.arch_condition_met?(:arm) &&
cask_min_os.present? &&
cask_min_os < MacOSVersion.new("11")

View File

@ -414,7 +414,7 @@ module Cask
hash = to_h
variations = {}
if @dsl.on_system_blocks_exist?
if @dsl.uses_on_system.present?
begin
OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag|
next if bottle_tag.linux? && @dsl.os.nil?

View File

@ -106,9 +106,9 @@ module Cask
:no_autobump!,
:autobump?,
:no_autobump_message,
:on_system_blocks_exist?,
:on_system_block_min_os,
:depends_on_set_in_block?,
:on_system_block_min_os,
:uses_on_system,
*ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key),
*ACTIVATABLE_ARTIFACT_CLASSES.map(&:dsl_key),
*ARTIFACT_BLOCK_CLASSES.flat_map { |klass| [klass.dsl_key, klass.uninstall_dsl_key] },
@ -121,6 +121,11 @@ module Cask
:disable_date, :disable_reason, :disable_replacement_cask,
:disable_replacement_formula, :on_system_block_min_os
# A `UsesOnSystem` object that contains boolean instance variables
# indicating whether the cask uses specific on_system methods.
sig { returns(OnSystem::UsesOnSystem) }
attr_reader :uses_on_system
sig { params(cask: Cask).void }
def initialize(cask)
# NOTE: Variables set by `set_unique_stanza` must be initialized to `nil`.
@ -153,13 +158,13 @@ module Cask
@name = T.let([], T::Array[String])
@autobump = T.let(true, T::Boolean)
@no_autobump_defined = T.let(false, T::Boolean)
@on_system_blocks_exist = T.let(false, T::Boolean)
@os = T.let(nil, T.nilable(String))
@on_system_block_min_os = T.let(nil, T.nilable(MacOSVersion))
@sha256 = T.let(nil, T.nilable(T.any(Checksum, Symbol)))
@staged_path = T.let(nil, T.nilable(Pathname))
@token = T.let(cask.token, String)
@url = T.let(nil, T.nilable(URL))
@uses_on_system = T.let(OnSystem::UsesOnSystem.new, OnSystem::UsesOnSystem)
@version = T.let(nil, T.nilable(DSL::Version))
end
@ -175,9 +180,6 @@ module Cask
sig { returns(T::Boolean) }
def livecheck_defined? = @livecheck_defined
sig { returns(T::Boolean) }
def on_system_blocks_exist? = @on_system_blocks_exist
# Specifies the cask's name.
#
# NOTE: Multiple names can be specified.
@ -392,8 +394,15 @@ module Cask
x86_64 ||= intel if intel.present? && x86_64.nil?
set_unique_stanza(:sha256, should_return) do
if arm.present? || x86_64.present? || x86_64_linux.present? || arm64_linux.present?
@on_system_blocks_exist = true
@uses_on_system.arm = true if arm.present?
@uses_on_system.intel = true if x86_64.present?
if x86_64_linux.present?
@uses_on_system.intel = true
@uses_on_system.linux = true
end
if arm64_linux.present?
@uses_on_system.arm = true
@uses_on_system.linux = true
end
val = arg || on_system_conditional(
@ -424,7 +433,8 @@ module Cask
should_return = arm.nil? && intel.nil?
set_unique_stanza(:arch, should_return) do
@on_system_blocks_exist = true
@uses_on_system.arm = true if arm
@uses_on_system.intel = true if intel
on_arch_conditional(arm:, intel:)
end
@ -449,7 +459,8 @@ module Cask
should_return = macos.nil? && linux.nil?
set_unique_stanza(:os, should_return) do
@on_system_blocks_exist = true
@uses_on_system.macos = true if macos
@uses_on_system.linux = true if linux
on_system_conditional(macos:, linux:)
end

View File

@ -199,7 +199,7 @@ module Homebrew
# to on_system blocks referencing macOS versions.
os_values = []
arch_values = depends_on_archs.presence || []
if cask.on_system_blocks_exist?
if cask.uses_on_system.present?
OnSystem::BASE_OS_OPTIONS.each do |os|
os_values << if os == :macos
(current_os_is_macos ? current_os : newest_macos)
@ -235,7 +235,7 @@ module Homebrew
old_cask = begin
Cask::CaskLoader.load(cask.sourcefile_path)
rescue Cask::CaskInvalidError, Cask::CaskUnreadableError
raise unless cask.on_system_blocks_exist?
raise unless cask.uses_on_system.present?
end
next if old_cask.nil?
@ -262,7 +262,7 @@ module Homebrew
replacement_pairs << [/"#{old_hash}"/, ":no_check"] if old_hash != :no_check
elsif old_hash == :no_check && new_hash != :no_check
replacement_pairs << [":no_check", "\"#{new_hash}\""] if new_hash.is_a?(String)
elsif new_hash && !cask.on_system_blocks_exist? && cask.languages.empty?
elsif new_hash && cask.uses_on_system.blank? && cask.languages.empty?
replacement_pairs << [old_hash.to_s, new_hash.to_s]
elsif old_hash != :no_check
opoo "Multiple checksum replacements required; ignoring specified `--sha256` argument." if new_hash

View File

@ -305,7 +305,7 @@ module Homebrew
).returns(VersionBumpInfo)
}
def retrieve_versions_by_arch(formula_or_cask:, repositories:, name:)
is_cask_with_blocks = formula_or_cask.is_a?(Cask::Cask) && formula_or_cask.on_system_blocks_exist?
is_cask_with_blocks = formula_or_cask.is_a?(Cask::Cask) && formula_or_cask.uses_on_system.present?
type, version_name = if formula_or_cask.is_a?(Formula)
[:formula, "formula version:"]
else

View File

@ -22,6 +22,28 @@ module OnSystem
T::Array[Utils::Bottles::Tag],
)
class UsesOnSystem < T::Struct
prop :arm, T::Boolean, default: false
prop :intel, T::Boolean, default: false
prop :linux, T::Boolean, default: false
prop :macos, T::Boolean, default: false
alias arm? arm
alias intel? intel
alias linux? linux
alias macos? macos
# Whether the object has only default values.
sig { returns(T::Boolean) }
def empty?
!@arm && !@intel && !@linux && !@macos
end
# Whether the object has any non-default values.
sig { returns(T::Boolean) }
def present? = !empty?
end
sig { params(arch: Symbol).returns(T::Boolean) }
def self.arch_condition_met?(arch)
raise ArgumentError, "Invalid arch condition: #{arch.inspect}" if ARCH_OPTIONS.exclude?(arch)
@ -65,7 +87,8 @@ module OnSystem
def self.setup_arch_methods(base)
ARCH_OPTIONS.each do |arch|
base.define_method(:"on_#{arch}") do |&block|
@on_system_blocks_exist = T.let(true, T.nilable(T::Boolean))
@uses_on_system ||= T.let(OnSystem::UsesOnSystem.new, T.nilable(OnSystem::UsesOnSystem))
@uses_on_system.send(:"#{arch}=", true)
return unless OnSystem.arch_condition_met? OnSystem.condition_from_method_name(T.must(__method__))
@ -78,7 +101,9 @@ module OnSystem
end
base.define_method(:on_arch_conditional) do |arm: nil, intel: nil|
@on_system_blocks_exist = true
@uses_on_system ||= T.let(OnSystem::UsesOnSystem.new, T.nilable(OnSystem::UsesOnSystem))
@uses_on_system.arm = true if arm
@uses_on_system.intel = true if intel
if OnSystem.arch_condition_met? :arm
arm
@ -92,7 +117,8 @@ module OnSystem
def self.setup_base_os_methods(base)
BASE_OS_OPTIONS.each do |base_os|
base.define_method(:"on_#{base_os}") do |&block|
@on_system_blocks_exist = true
@uses_on_system ||= T.let(OnSystem::UsesOnSystem.new, T.nilable(OnSystem::UsesOnSystem))
@uses_on_system.send(:"#{base_os}=", true)
return unless OnSystem.os_condition_met? OnSystem.condition_from_method_name(T.must(__method__))
@ -105,7 +131,9 @@ module OnSystem
end
base.define_method(:on_system) do |linux, macos:, &block|
@on_system_blocks_exist = true
@uses_on_system ||= T.let(OnSystem::UsesOnSystem.new, T.nilable(OnSystem::UsesOnSystem))
@uses_on_system.linux = true
@uses_on_system.macos = true
raise ArgumentError, "The first argument to `on_system` must be `:linux`" if linux != :linux
@ -124,7 +152,9 @@ module OnSystem
end
base.define_method(:on_system_conditional) do |macos: nil, linux: nil|
@on_system_blocks_exist = true
@uses_on_system ||= T.let(OnSystem::UsesOnSystem.new, T.nilable(OnSystem::UsesOnSystem))
@uses_on_system.macos = true if macos
@uses_on_system.linux = true if linux
if OnSystem.os_condition_met?(:macos) && macos.present?
macos
@ -138,7 +168,8 @@ module OnSystem
def self.setup_macos_methods(base)
MacOSVersion::SYMBOLS.each_key do |os_name|
base.define_method(:"on_#{os_name}") do |or_condition = nil, &block|
@on_system_blocks_exist = true
@uses_on_system ||= T.let(OnSystem::UsesOnSystem.new, T.nilable(OnSystem::UsesOnSystem))
@uses_on_system.macos = true
os_condition = OnSystem.condition_from_method_name T.must(__method__)
return unless OnSystem.os_condition_met? os_condition, or_condition

View File

@ -270,7 +270,7 @@ class Formula
@follow_installed_alias = T.let(true, T::Boolean)
@prefix_returns_versioned_prefix = T.let(false, T.nilable(T::Boolean))
@oldname_locks = T.let([], T::Array[FormulaLock])
@on_system_blocks_exist = T.let(false, T::Boolean)
@uses_on_system = T.let(OnSystem::UsesOnSystem.new, OnSystem::UsesOnSystem)
end
sig { params(spec_sym: Symbol).void }
@ -2591,7 +2591,7 @@ class Formula
variations = {}
if path.exist? && on_system_blocks_exist?
if path.exist? && uses_on_system.present?
formula_contents = path.read
OnSystem::VALID_OS_ARCH_TAGS.each do |bottle_tag|
Homebrew::SimulateSystem.with_tag(bottle_tag) do
@ -2789,9 +2789,11 @@ class Formula
end
end
sig { returns(T.nilable(T::Boolean)) }
def on_system_blocks_exist?
self.class.on_system_blocks_exist? || @on_system_blocks_exist
# A `UsesOnSystem` object that contains boolean instance variables indicating
# whether the formula uses specific on_system methods.
sig { returns(OnSystem::UsesOnSystem) }
def uses_on_system
self.class.uses_on_system || @uses_on_system
end
sig {
@ -3331,7 +3333,7 @@ class Formula
@skip_clean_paths = T.let(Set.new, T.nilable(T::Set[T.any(String, Symbol)]))
@link_overwrite_paths = T.let(Set.new, T.nilable(T::Set[String]))
@loaded_from_api = T.let(false, T.nilable(T::Boolean))
@on_system_blocks_exist = T.let(false, T.nilable(T::Boolean))
@uses_on_system = T.let(OnSystem::UsesOnSystem.new, T.nilable(OnSystem::UsesOnSystem))
@network_access_allowed = T.let(SUPPORTED_NETWORK_ACCESS_PHASES.to_h do |phase|
[phase, DEFAULT_NETWORK_ACCESS_ALLOWED]
end, T.nilable(T::Hash[Symbol, T::Boolean]))
@ -3345,6 +3347,7 @@ class Formula
@conflicts.freeze
@skip_clean_paths.freeze
@link_overwrite_paths.freeze
@uses_on_system.freeze
super
end
@ -3355,10 +3358,10 @@ class Formula
sig { returns(T::Boolean) }
def loaded_from_api? = !!@loaded_from_api
# Whether this formula contains OS/arch-specific blocks
# (e.g. `on_macos`, `on_arm`, `on_monterey :or_older`, `on_system :linux, macos: :big_sur_or_newer`).
sig { returns(T::Boolean) }
def on_system_blocks_exist? = !!@on_system_blocks_exist
# A `UsesOnSystem` object that contains boolean instance variables
# indicating whether the formula uses specific on_system methods.
sig { returns(T.nilable(OnSystem::UsesOnSystem)) }
attr_reader :uses_on_system
# The reason for why this software is not linked (by default) to {::HOMEBREW_PREFIX}.
sig { returns(T.nilable(KegOnlyReason)) }

View File

@ -66,7 +66,7 @@ module Readall
readall_formula = readall_formula_class.new(formula_name, file, :stable, tap:)
readall_formula.to_hash
# TODO: Remove check for MACOS_MODULE_REGEX once the `MacOS` module is undefined on Linux
cache[:valid_formulae][file] = if readall_formula.on_system_blocks_exist? ||
cache[:valid_formulae][file] = if readall_formula.uses_on_system.present? ||
formula_contents.match?(MACOS_MODULE_REGEX)
[bottle_tag, *cache[:valid_formulae][file]]
else

View File

@ -153,9 +153,6 @@ class Cask::Cask
sig { params(args: T.untyped, block: T.untyped).returns(T.nilable(MacOSVersion)) }
def on_system_block_min_os(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T::Boolean) }
def on_system_blocks_exist?(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def os(*args, &block); end
@ -204,6 +201,9 @@ class Cask::Cask
sig { params(args: T.untyped, block: T.untyped).returns(T.nilable(::Cask::URL)) }
def url(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def uses_on_system(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) }
def version(*args, &block); end

View File

@ -141,6 +141,10 @@ RSpec.describe Cask::DSL, :cask do
it "stores only the arm checksum" do
expect(cask.sha256).to eq("imasha2arm")
end
it "sets @uses_on_system.arm to true" do
expect(cask.uses_on_system.arm?).to be true
end
end
context "when running on intel" do
@ -151,6 +155,86 @@ RSpec.describe Cask::DSL, :cask do
it "stores only the intel checksum" do
expect(cask.sha256).to eq("imasha2intel")
end
it "sets @uses_on_system.intel to true" do
expect(cask.uses_on_system.intel?).to be true
end
end
end
context "with an arm64_linux checksum" do
let(:cask_arm_linux) do
Homebrew::SimulateSystem.with os: :linux, arch: :arm do
Cask::Cask.new("arm64_linux-checksum-cask") do
sha256 arm64_linux: "imasha2armlinux"
end
end
end
before do
allow(Hardware::CPU).to receive(:type).and_return(:arm)
end
it "stores only the intel checksum" do
expect(cask_arm_linux.sha256).to eq("imasha2armlinux")
end
it "sets @uses_on_system.arm to true" do
expect(cask_arm_linux.uses_on_system.arm?).to be true
end
it "sets @uses_on_system.linux to true" do
expect(cask_arm_linux.uses_on_system.linux?).to be true
end
end
context "with an x86_64_linux checksum" do
let(:cask_intel_linux) do
Homebrew::SimulateSystem.with os: :linux, arch: :intel do
Cask::Cask.new("x86_64_linux-checksum-cask") do
sha256 x86_64_linux: "imasha2intellinux"
end
end
end
before do
allow(Hardware::CPU).to receive(:type).and_return(:intel)
end
it "stores only the intel checksum" do
expect(cask_intel_linux.sha256).to eq("imasha2intellinux")
end
it "sets @uses_on_system.intel to true" do
expect(cask_intel_linux.uses_on_system.intel?).to be true
end
it "sets @uses_on_system.linux to true" do
expect(cask_intel_linux.uses_on_system.linux?).to be true
end
end
context "with a :no_check checksum" do
let(:cask_no_check) do
Cask::Cask.new("no_check-checksum-cask") do
sha256 :no_check
end
end
it "stores the :no_check symbol" do
expect(cask_no_check.sha256).to eq(:no_check)
end
end
context "with an invalid checksum value" do
let(:cask_invalid_checksum) do
Cask::Cask.new("invalid-checksum-cask") do
sha256 :invalid_symbol
end
end
it "refuses to load" do
expect { cask_invalid_checksum }.to raise_error(Cask::CaskInvalidError)
end
end
end
@ -369,6 +453,10 @@ RSpec.describe Cask::DSL, :cask do
it "returns the value" do
expect(cask.url.to_s).to eq "file://#{TEST_FIXTURE_DIR}/cask/caffeine-arm.zip"
end
it "sets uses_on_system.arm to true" do
expect(cask.uses_on_system.arm?).to be true
end
end
context "when running on intel" do
@ -381,6 +469,104 @@ RSpec.describe Cask::DSL, :cask do
end
end
end
context "when no arm value is specified" do
let(:token) { "arch-intel-only" }
context "when running on intel" do
before do
allow(Hardware::CPU).to receive(:type).and_return(:intel)
end
it "returns the value" do
expect(cask.url.to_s).to eq "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel.zip"
end
it "sets uses_on_system.intel to true" do
expect(cask.uses_on_system.intel?).to be true
end
end
context "when running on arm" do
before do
allow(Hardware::CPU).to receive(:type).and_return(:arm)
end
it "defaults to `nil` for the other when no arrays are passed" do
expect(cask.url.to_s).to eq "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
end
end
end
end
describe "os stanza" do
context "when os is called more than once" do
let(:cask_multiple_os_calls) { Cask::CaskLoader.load(cask_path("invalid/invalid-two-os")) }
it "prevents defining multiple oss" do
expect { cask_multiple_os_calls }.to raise_error(Cask::CaskInvalidError, /'os' stanza may only appear once/)
end
end
context "when only a macos value is specified" do
context "when running on macos" do
let(:cask_os_macos_only) do
Homebrew::SimulateSystem.with(os: :sequoia) do
Cask::CaskLoader.load(cask_path("os-macos-only"))
end
end
it "returns the value" do
expect(cask_os_macos_only.url.to_s).to eq "file://#{TEST_FIXTURE_DIR}/cask/caffeine-darwin.zip"
end
it "sets uses_on_system.macos to true" do
expect(cask_os_macos_only.uses_on_system.macos?).to be true
end
end
context "when running on linux" do
let(:cask_os_macos_only) do
Homebrew::SimulateSystem.with(os: :linux) do
Cask::CaskLoader.load(cask_path("os-macos-only"))
end
end
it "defaults to `nil`" do
expect(cask_os_macos_only.url.to_s).to eq "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
end
end
end
context "when only a linux value is specified" do
context "when running on linux" do
let(:cask_os_linux_only) do
Homebrew::SimulateSystem.with(os: :linux) do
Cask::CaskLoader.load(cask_path("os-linux-only"))
end
end
it "returns the value" do
expect(cask_os_linux_only.url.to_s).to eq "file://#{TEST_FIXTURE_DIR}/cask/caffeine-linux.zip"
end
it "sets uses_on_system.linux to true" do
expect(cask_os_linux_only.uses_on_system.linux?).to be true
end
end
context "when running on macos" do
let(:cask_os_linux_only) do
Homebrew::SimulateSystem.with(os: :sequoia) do
Cask::CaskLoader.load(cask_path("os-linux-only"))
end
end
it "defaults to `nil`" do
expect(cask_os_linux_only.url.to_s).to eq "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
end
end
end
end
describe "depends_on stanza" do
@ -598,4 +784,112 @@ RSpec.describe Cask::DSL, :cask do
]
end
end
describe "#uses_on_system" do
context "when cask uses on_arm" do
let(:token) { "with-on-arch-blocks" }
it "sets @uses_on_system.arm to true" do
expect(cask.uses_on_system.arm?).to be true
end
end
context "when cask uses on_intel" do
let(:token) { "with-on-arch-blocks" }
it "sets @uses_on_system.intel to true" do
expect(cask.uses_on_system.intel?).to be true
end
end
context "when cask uses on_arch_conditional" do
context "when arm argument is provided" do
let(:token) { "with-on-arch-conditional" }
it "sets @uses_on_system.arm to true" do
expect(cask.uses_on_system.arm?).to be true
end
end
context "when intel argument is provided" do
let(:token) { "with-on-arch-conditional" }
it "sets @uses_on_system.intel to true" do
expect(cask.uses_on_system.intel?).to be true
end
end
context "when no arguments are provided" do
let(:token) { "with-on-arch-conditional-no-args" }
it "doesn't set @uses_on_system.arm or .intel to true" do
expect(cask.uses_on_system.arm?).to be false
expect(cask.uses_on_system.intel?).to be false
end
end
end
context "when cask uses on_linux" do
let(:token) { "with-on-os-blocks" }
it "sets @uses_on_system.linux to true" do
expect(cask.uses_on_system.linux?).to be true
end
end
context "when cask uses on_macos" do
let(:token) { "with-on-os-blocks" }
it "sets @uses_on_system.macos to true" do
expect(cask.uses_on_system.macos?).to be true
end
end
context "when cask uses on_system" do
let(:token) { "with-on-system-blocks" }
it "sets @uses_on_system.linux to true" do
expect(cask.uses_on_system.linux?).to be true
end
it "sets @uses_on_system.macos to true" do
expect(cask.uses_on_system.macos?).to be true
end
end
context "when cask uses on_system_conditional" do
context "when linux argument is provided" do
let(:token) { "with-on-system-conditional" }
it "sets @uses_on_system.linux to true" do
expect(cask.uses_on_system.linux?).to be true
end
end
context "when macos argument is provided" do
let(:token) { "with-on-system-conditional" }
it "sets @uses_on_system.macos to true" do
expect(cask.uses_on_system.macos?).to be true
end
end
context "when no arguments are provided" do
let(:token) { "with-on-system-conditional-no-args" }
it "doesn't set @uses_on_system.linux or .macos to true" do
expect(cask.uses_on_system.linux?).to be false
expect(cask.uses_on_system.macos?).to be false
end
end
end
context "when cask uses on_* macos version methods" do
let(:token) { "with-on-macos-version-blocks" }
it "sets @uses_on_system.macos to true" do
expect(cask.uses_on_system.macos?).to be true
end
end
end
end

View File

@ -27,6 +27,31 @@ RSpec.describe OnSystem do
end
end
describe "UsesOnSystem" do
uses_on_system_empty = described_class::UsesOnSystem.new
uses_on_system_present = described_class::UsesOnSystem.new(arm: true)
describe "#empty?" do
it "returns true if all properties are default values" do
expect(uses_on_system_empty.empty?).to be true
end
it "returns false if any properties have a non-default value" do
expect(uses_on_system_present.empty?).to be false
end
end
describe "#present?" do
it "returns true if object is not empty" do
expect(uses_on_system_present.present?).to be true
end
it "returns false if object is empty" do
expect(uses_on_system_empty.present?).to be false
end
end
end
describe "::arch_condition_met?" do
it "returns true if current arch equals provided arch" do
Homebrew::SimulateSystem.with(arch: :arm) do

View File

@ -1951,6 +1951,189 @@ RSpec.describe Formula do
end
end
describe "#uses_on_system" do
# These formula definitions use a different way of creating the formula,
# as the `Class.new` approach doesn't seem to work as expected for
# `uses_on_system`.
context "when formula uses on_arm" do
let(:f_on_arm) do
formula("on-arm") do
on_arm do
url "https://brew.sh/foo-1.0-arm.tar.gz"
end
url "https://brew.sh/foo-1.0.tar.gz"
end
end
it "sets @uses_on_system.arm to true" do
expect(f_on_arm.uses_on_system.arm?).to be true
end
end
context "when formula uses on_intel" do
let(:f_on_intel) do
formula("on-intel") do
on_intel do
url "https://brew.sh/foo-1.0-arm.tar.gz"
end
url "https://brew.sh/foo-1.0.tar.gz"
end
end
it "sets @uses_on_system.intel to true" do
expect(f_on_intel.uses_on_system.intel?).to be true
end
end
context "when formula uses on_arch_conditional" do
let(:f_on_arch_conditional) do
formula("on-arch-conditional") do
folder = on_arch_conditional arm: "arm/", intel: "intel/"
url "https://brew.sh/#{folder}foo-1.0.tar.gz"
end
end
let(:f_on_arch_conditional_no_args) do
formula("on-arch-conditional-no-args") do
folder = on_arch_conditional
url "https://brew.sh/#{folder}foo-1.0.tar.gz"
end
end
context "when arm argument is provided" do
it "sets @uses_on_system.arm to true" do
expect(f_on_arch_conditional.uses_on_system.arm?).to be true
end
end
context "when intel argument is provided" do
it "sets @uses_on_system.intel to true" do
expect(f_on_arch_conditional.uses_on_system.intel?).to be true
end
end
context "when no arguments are provided" do
it "doesn't set @uses_on_system.arm or .intel to true" do
expect(f_on_arch_conditional_no_args.uses_on_system.arm?).to be false
expect(f_on_arch_conditional_no_args.uses_on_system.intel?).to be false
end
end
end
context "when formula uses on_linux" do
let(:f_on_linux) do
formula("on-linux") do
on_linux do
url "https://brew.sh/foo-1.0-linux.tar.gz"
end
url "https://brew.sh/foo-1.0.tar.gz"
end
end
it "sets @uses_on_system.linux to true" do
expect(f_on_linux.uses_on_system.linux?).to be true
end
end
context "when formula uses on_macos" do
let(:f_on_macos) do
formula("on-macos") do
on_macos do
url "https://brew.sh/foo-1.0-macos.tar.gz"
end
url "https://brew.sh/foo-1.0.tar.gz"
end
end
it "sets @uses_on_system.macos to true" do
expect(f_on_macos.uses_on_system.macos?).to be true
end
end
context "when formula uses on_system" do
let(:f_on_system) do
formula("on-system") do
on_system :linux, macos: :sequoia_or_newer do
url "https://brew.sh/foo-1.0-new.tar.gz"
end
url "https://brew.sh/foo-1.0.tar.gz"
end
end
it "sets @uses_on_system.linux to true" do
expect(f_on_system.uses_on_system.linux?).to be true
end
it "sets @uses_on_system.macos to true" do
expect(f_on_system.uses_on_system.macos?).to be true
end
end
context "when formula uses on_system_conditional" do
let(:f_on_system_conditional) do
formula("on-system-conditional") do
folder = on_system_conditional linux: "linux/", macos: "macos/"
url "https://brew.sh/#{folder}foo-1.0.tar.gz"
end
end
let(:f_on_system_conditional_no_args) do
formula("on-system-conditional-no-args") do
folder = on_system_conditional
url "https://brew.sh/#{folder}foo-1.0.tar.gz"
end
end
context "when linux argument is provided" do
it "sets @uses_on_system.linux to true" do
expect(f_on_system_conditional.uses_on_system.linux?).to be true
end
end
context "when macos argument is provided" do
it "sets @uses_on_system.macos to true" do
expect(f_on_system_conditional.uses_on_system.macos?).to be true
end
end
context "when no arguments are provided" do
it "doesn't set @uses_on_system.linux or .macos to true" do
expect(f_on_system_conditional_no_args.uses_on_system.linux?).to be false
expect(f_on_system_conditional_no_args.uses_on_system.macos?).to be false
end
end
end
context "when formula uses on_* macos version methods" do
let(:f_on_macos_versions) do
formula("on-macos-versions") do
url "https://brew.sh/foo-1.0.tar.gz"
on_big_sur :or_older do
depends_on "abc"
end
on_monterey do
depends_on "def"
end
on_ventura :or_newer do
depends_on "ghi"
end
end
end
it "sets @uses_on_system.macos to true" do
expect(f_on_macos_versions.uses_on_system.macos?).to be true
end
end
end
describe "#network_access_allowed?" do
it "throws an error when passed an invalid symbol" do
f = Testball.new

View File

@ -0,0 +1,11 @@
cask "arch-intel-only" do
arch intel: "-intel"
version "1.2.3"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
url "file://#{TEST_FIXTURE_DIR}/cask/caffeine#{arch}.zip"
homepage "https://brew.sh/"
app "Caffeine.app"
end

View File

@ -0,0 +1,12 @@
cask "invalid-two-os" do
os linux: "linux", macos: "darwin"
os linux: "linux2", macos: "darwin2"
version "1.2.3"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
homepage "https://brew.sh/"
app "Caffeine.app"
end

View File

@ -0,0 +1,11 @@
cask "os-linux-only" do
os linux: "-linux"
version "1.2.3"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
url "file://#{TEST_FIXTURE_DIR}/cask/caffeine#{os}.zip"
homepage "https://brew.sh/"
app "Caffeine.app"
end

View File

@ -0,0 +1,11 @@
cask "os-macos-only" do
os macos: "-darwin"
version "1.2.3"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
url "file://#{TEST_FIXTURE_DIR}/cask/caffeine#{os}.zip"
homepage "https://brew.sh/"
app "Caffeine.app"
end

View File

@ -0,0 +1,15 @@
cask "with-on-arch-blocks" do
on_arm do
version "1.2.4"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
end
on_intel do
version "1.2.3"
sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
end
url "https://brew.sh/TestCask-#{version}.dmg"
homepage "https://brew.sh/"
app "TestCask.app"
end

View File

@ -0,0 +1,8 @@
cask "with-on-arch-conditional-no-args" do
folder = on_arch_conditional
url "https://brew.sh/#{folder}TestCask-#{version}.dmg"
homepage "https://brew.sh/"
app "TestCask.app"
end

View File

@ -0,0 +1,8 @@
cask "with-on-arch-conditional" do
folder = on_arch_conditional arm: "arm-dir/", intel: "intel-dir/"
url "https://brew.sh/#{folder}TestCask-#{version}.dmg"
homepage "https://brew.sh/"
app "TestCask.app"
end

View File

@ -0,0 +1,19 @@
cask "with-on-macos-version-blocks" do
on_big_sur :or_older do
version "1.2.3"
sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
end
on_monterey do
version "1.2.4"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
end
on_ventura :or_newer do
version "1.2.5"
sha256 "306c6ca7407560340797866e077e053627ad409277d1b9da58106fce4cf717cb"
end
url "https://brew.sh/TestCask-#{version}.dmg"
homepage "https://brew.sh/"
app "TestCask.app"
end

View File

@ -0,0 +1,15 @@
cask "with-on-os-blocks" do
on_linux do
version "1.2.3"
sha256 "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
end
on_macos do
version "1.2.4"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
end
url "https://brew.sh/TestCask-#{version}.zip"
homepage "https://brew.sh/"
binary "testcask"
end

View File

@ -0,0 +1,11 @@
cask "with-on-system-blocks" do
on_system :linux, macos: :sequoia_or_newer do
version "1.2.4"
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
end
url "https://brew.sh/TestCask-#{version}.dmg"
homepage "https://brew.sh/"
app "TestCask.app"
end

View File

@ -0,0 +1,8 @@
cask "with-on-system-conditional-no-args" do
folder = on_system_conditional
url "https://brew.sh/#{folder}TestCask-#{version}.dmg"
homepage "https://brew.sh/"
app "TestCask.app"
end

View File

@ -0,0 +1,8 @@
cask "with-on-system-conditional" do
folder = on_system_conditional linux: "linux-dir/", macos: "macos-dir/"
url "https://brew.sh/#{folder}TestCask-#{version}.dmg"
homepage "https://brew.sh/"
app "TestCask.app"
end