From b2ca64b207813b1d85cfc92d80df5d1344b5ad48 Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Sun, 19 Jan 2025 16:36:37 +0100 Subject: [PATCH 1/7] feat: allow linux blocks in casks --- Library/Homebrew/cask/dsl.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index 434159b57a..823415cc85 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -106,7 +106,7 @@ module Cask ]).freeze extend Attrable - include OnSystem::MacOSOnly + include OnSystem::MacOSAndLinux attr_reader :cask, :token, :deprecation_date, :deprecation_reason, :deprecation_replacement, :disable_date, :disable_reason, :disable_replacement, :on_system_block_min_os From 6de67b6c45ec482a500f1a89e4c23cacea6ef5ad Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Sun, 19 Jan 2025 16:01:52 +0000 Subject: [PATCH 2/7] fix: set correct inheritance for moved artifact --- Library/Homebrew/extend/os/linux/cask/artifact/moved.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/extend/os/linux/cask/artifact/moved.rb b/Library/Homebrew/extend/os/linux/cask/artifact/moved.rb index 3f6c420b47..03928272d6 100644 --- a/Library/Homebrew/extend/os/linux/cask/artifact/moved.rb +++ b/Library/Homebrew/extend/os/linux/cask/artifact/moved.rb @@ -20,4 +20,4 @@ module OS end end -Cask::Artifact::Moved.prepend(OS::Linux::Cask::Config) +Cask::Artifact::Moved.prepend(OS::Linux::Cask::Artifact::Moved) From 975fe8a83fd57a8d8e790ec6fb10c2f13f705d02 Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Sun, 19 Jan 2025 16:15:19 +0000 Subject: [PATCH 3/7] feat: allow cask binaries on linux --- Library/Homebrew/cask/artifact/symlinked.rb | 14 ++++----- Library/Homebrew/cask/dsl.rb | 28 ++++++++++++++--- Library/Homebrew/extend/on_system.rbi | 3 ++ .../extend/os/cask/artifact/symlinked.rb | 5 ++++ .../os/linux/cask/artifact/symlinked.rb | 26 ++++++++++++++++ .../extend/os/linux/cask/installer.rb | 3 ++ .../extend/os/mac/cask/artifact/symlinked.rb | 30 +++++++++++++++++++ 7 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 Library/Homebrew/extend/os/cask/artifact/symlinked.rb create mode 100644 Library/Homebrew/extend/os/linux/cask/artifact/symlinked.rb create mode 100644 Library/Homebrew/extend/os/mac/cask/artifact/symlinked.rb diff --git a/Library/Homebrew/cask/artifact/symlinked.rb b/Library/Homebrew/cask/artifact/symlinked.rb index 170ecc5367..3ed0f956b6 100644 --- a/Library/Homebrew/cask/artifact/symlinked.rb +++ b/Library/Homebrew/cask/artifact/symlinked.rb @@ -62,7 +62,7 @@ module Cask end ohai "Linking #{self.class.english_name} '#{source.basename}' to '#{target}'" - create_filesystem_link(command:) + create_filesystem_link(command) end def unlink(command: nil, **) @@ -72,14 +72,10 @@ module Cask Utils.gain_permissions_remove(target, command:) end - def create_filesystem_link(command: nil) - Utils.gain_permissions_mkpath(target.dirname, command:) - - command.run! "/bin/ln", args: ["-h", "-f", "-s", "--", source, target], - sudo: !target.dirname.writable? - - add_altname_metadata(source, target.basename, command:) - end + sig { params(command: T.class_of(SystemCommand)).void } + def create_filesystem_link(command); end end end end + +require "extend/os/cask/artifact/symlinked" diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index 823415cc85..6ca8db2860 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -311,17 +311,18 @@ module Cask # # ```ruby # sha256 arm: "7bdb497080ffafdfd8cc94d8c62b004af1be9599e865e5555e456e2681e150ca", - # intel: "b3c1c2442480a0219b9e05cf91d03385858c20f04b764ec08a3fa83d1b27e7b2" + # intel: "b3c1c2442480a0219b9e05cf91d03385858c20f04b764ec08a3fa83d1b27e7b2" + # linux: "1a2aee7f1ddc999993d4d7d42a150c5e602bc17281678050b8ed79a0500cc90f" # ``` # # @api public - def sha256(arg = nil, arm: nil, intel: nil) + def sha256(arg = nil, arm: nil, intel: nil, linux: nil) should_return = arg.nil? && arm.nil? && intel.nil? set_unique_stanza(:sha256, should_return) do - @on_system_blocks_exist = true if arm.present? || intel.present? + @on_system_blocks_exist = true if arm.present? || intel.present? || linux.present? - val = arg || on_arch_conditional(arm:, intel:) + val = arg || on_system_conditional(macos: on_arch_conditional(arm:, intel:), linux:) case val when :no_check val @@ -352,6 +353,25 @@ module Cask end end + # Sets the cask's os strings. + # + # ### Example + # + # ```ruby + # os macos: "darwin", linux: "tux" + # ``` + # + # @api public + def os(macos: nil, linux: nil) + should_return = macos.nil? && linux.nil? + + set_unique_stanza(:os, should_return) do + @on_system_blocks_exist = true + + on_system_conditional(macos:, linux:) + end + end + # Declare dependencies and requirements for a cask. # # NOTE: Multiple dependencies can be specified. diff --git a/Library/Homebrew/extend/on_system.rbi b/Library/Homebrew/extend/on_system.rbi index c80492017b..dd0b178347 100644 --- a/Library/Homebrew/extend/on_system.rbi +++ b/Library/Homebrew/extend/on_system.rbi @@ -20,4 +20,7 @@ module OnSystem::MacOSAndLinux .returns(T.type_parameter(:U)) } def on_macos(&block); end + + sig { params(arm: T.nilable(String), intel: T.nilable(String)).returns(T.nilable(String)) } + def on_arch_conditional(arm: nil, intel: nil); end end diff --git a/Library/Homebrew/extend/os/cask/artifact/symlinked.rb b/Library/Homebrew/extend/os/cask/artifact/symlinked.rb new file mode 100644 index 0000000000..e9df4618bd --- /dev/null +++ b/Library/Homebrew/extend/os/cask/artifact/symlinked.rb @@ -0,0 +1,5 @@ +# typed: strict +# frozen_string_literal: true + +require "extend/os/mac/cask/artifact/symlinked" if OS.mac? +require "extend/os/linux/cask/artifact/symlinked" if OS.linux? diff --git a/Library/Homebrew/extend/os/linux/cask/artifact/symlinked.rb b/Library/Homebrew/extend/os/linux/cask/artifact/symlinked.rb new file mode 100644 index 0000000000..3d8d78f597 --- /dev/null +++ b/Library/Homebrew/extend/os/linux/cask/artifact/symlinked.rb @@ -0,0 +1,26 @@ +# typed: strict +# frozen_string_literal: true + +module OS + module Linux + module Cask + module Artifact + module Symlinked + extend T::Helpers + + requires_ancestor { ::Cask::Artifact::Symlinked } + + sig { params(command: T.class_of(SystemCommand)).void } + def create_filesystem_link(command) + ::Cask::Utils.gain_permissions_mkpath(target.dirname, command:) + + command.run! "/bin/ln", args: ["--no-dereference", "--force", "--symbolic", source, target], + sudo: !target.dirname.writable? + end + end + end + end + end +end + +Cask::Artifact::Symlinked.prepend(OS::Linux::Cask::Artifact::Symlinked) diff --git a/Library/Homebrew/extend/os/linux/cask/installer.rb b/Library/Homebrew/extend/os/linux/cask/installer.rb index 76ac45eb7f..5add7aae64 100644 --- a/Library/Homebrew/extend/os/linux/cask/installer.rb +++ b/Library/Homebrew/extend/os/linux/cask/installer.rb @@ -15,6 +15,9 @@ module OS def check_stanza_os_requirements return if artifacts.all?(::Cask::Artifact::Font) + install_artifacts = artifacts.reject { |artifact| artifact.instance_of?(::Cask::Artifact::Zap) } + return if install_artifacts.all?(::Cask::Artifact::Binary) + raise ::Cask::CaskError, "macOS is required for this software." end end diff --git a/Library/Homebrew/extend/os/mac/cask/artifact/symlinked.rb b/Library/Homebrew/extend/os/mac/cask/artifact/symlinked.rb new file mode 100644 index 0000000000..90dbe68c64 --- /dev/null +++ b/Library/Homebrew/extend/os/mac/cask/artifact/symlinked.rb @@ -0,0 +1,30 @@ +# typed: strict +# frozen_string_literal: true + +require "cask/macos" + +module OS + module Mac + module Cask + module Artifact + module Symlinked + extend T::Helpers + + requires_ancestor { ::Cask::Artifact::Symlinked } + + sig { params(command: T.class_of(SystemCommand)).void } + def create_filesystem_link(command) + ::Cask::Utils.gain_permissions_mkpath(target.dirname, command:) + + command.run! "/bin/ln", args: ["-h", "-f", "-s", "--", source, target], + sudo: !target.dirname.writable? + + add_altname_metadata(source, target.basename, command:) + end + end + end + end + end +end + +Cask::Artifact::Symlinked.prepend(OS::Mac::Cask::Artifact::Symlinked) From 27a2d94c48356fbc681d91562a4c62733c16a9f5 Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Tue, 28 Jan 2025 17:30:53 +0000 Subject: [PATCH 4/7] feat: allow zap on linux --- .../cask/artifact/abstract_uninstall.rb | 6 ++++- .../os/cask/artifact/abstract_uninstall.rb | 5 ++++ .../linux/cask/artifact/abstract_uninstall.rb | 23 +++++++++++++++++ .../mac/cask/artifact/abstract_uninstall.rb | 25 +++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 Library/Homebrew/extend/os/cask/artifact/abstract_uninstall.rb create mode 100644 Library/Homebrew/extend/os/linux/cask/artifact/abstract_uninstall.rb create mode 100644 Library/Homebrew/extend/os/mac/cask/artifact/abstract_uninstall.rb diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index 2242b7961a..0c9edb929d 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -411,7 +411,7 @@ module Cask next end - if MacOS.undeletable?(resolved_path) + if undeletable?(resolved_path) opoo "Skipping #{Formatter.identifier(action)} for undeletable path '#{path}'." next end @@ -538,6 +538,10 @@ module Cask recursive_rmdir(*resolved_paths, **kwargs) end end + + def undeletable?(target); end end end end + +require "extend/os/cask/artifact/abstract_uninstall" diff --git a/Library/Homebrew/extend/os/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/extend/os/cask/artifact/abstract_uninstall.rb new file mode 100644 index 0000000000..9298c18f91 --- /dev/null +++ b/Library/Homebrew/extend/os/cask/artifact/abstract_uninstall.rb @@ -0,0 +1,5 @@ +# typed: strict +# frozen_string_literal: true + +require "extend/os/mac/cask/artifact/abstract_uninstall" if OS.mac? +require "extend/os/linux/cask/artifact/abstract_uninstall" if OS.linux? diff --git a/Library/Homebrew/extend/os/linux/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/extend/os/linux/cask/artifact/abstract_uninstall.rb new file mode 100644 index 0000000000..761fc2bc03 --- /dev/null +++ b/Library/Homebrew/extend/os/linux/cask/artifact/abstract_uninstall.rb @@ -0,0 +1,23 @@ +# typed: strict +# frozen_string_literal: true + +module OS + module Linux + module Cask + module Artifact + module AbstractUninstall + extend T::Helpers + + requires_ancestor { ::Cask::Artifact::AbstractUninstall } + + sig { params(target: Pathname).returns(T::Boolean) } + def undeletable?(target) + !target.parent.writable? + end + end + end + end + end +end + +Cask::Artifact::AbstractUninstall.prepend(OS::Linux::Cask::Artifact::AbstractUninstall) diff --git a/Library/Homebrew/extend/os/mac/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/extend/os/mac/cask/artifact/abstract_uninstall.rb new file mode 100644 index 0000000000..2871527d17 --- /dev/null +++ b/Library/Homebrew/extend/os/mac/cask/artifact/abstract_uninstall.rb @@ -0,0 +1,25 @@ +# typed: strict +# frozen_string_literal: true + +require "cask/macos" + +module OS + module Mac + module Cask + module Artifact + module AbstractUninstall + extend T::Helpers + + requires_ancestor { ::Cask::Artifact::AbstractUninstall } + + sig { params(target: Pathname).returns(T::Boolean) } + def undeletable?(target) + MacOS.undeletable?(target) + end + end + end + end + end +end + +Cask::Artifact::AbstractUninstall.prepend(OS::Mac::Cask::Artifact::AbstractUninstall) From a28fde1a8c99c7a2e753868c1a8c2921f023a9bf Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Tue, 28 Jan 2025 17:44:48 +0000 Subject: [PATCH 5/7] fix sha256 on linux --- Library/Homebrew/cask/dsl.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index 6ca8db2860..b602ee5cd8 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -317,7 +317,7 @@ module Cask # # @api public def sha256(arg = nil, arm: nil, intel: nil, linux: nil) - should_return = arg.nil? && arm.nil? && intel.nil? + should_return = arg.nil? && arm.nil? && intel.nil? && linux.nil? set_unique_stanza(:sha256, should_return) do @on_system_blocks_exist = true if arm.present? || intel.present? || linux.present? From f874603a21ea5ea5c77790db27a9e2bd72a66679 Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Wed, 5 Feb 2025 10:26:50 -0500 Subject: [PATCH 6/7] Add implicit macOS dependency to casks without explicit `depends_on` stanza --- Library/Homebrew/cask/cask.rb | 1 + Library/Homebrew/cask/dsl.rb | 7 +++++++ .../Homebrew/test/support/fixtures/cask/everything.json | 7 ++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index 7eba153bdf..0bbe88cc10 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -114,6 +114,7 @@ module Cask return unless @block @dsl.instance_eval(&@block) + @dsl.add_implicit_macos_dependency @dsl.language_eval end diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index b602ee5cd8..d6c5d4ab12 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -390,6 +390,13 @@ module Cask @depends_on end + # @api private + def add_implicit_macos_dependency + return if @depends_on.present? && @depends_on.macos.present? + + depends_on macos: ">= :#{MacOSVersion::SYMBOLS.key MacOSVersion::SYMBOLS.values.min}" + end + # Declare conflicts that keep a cask from installing or working correctly. # # @api public diff --git a/Library/Homebrew/test/support/fixtures/cask/everything.json b/Library/Homebrew/test/support/fixtures/cask/everything.json index 9bc4c6af19..b247e82a05 100644 --- a/Library/Homebrew/test/support/fixtures/cask/everything.json +++ b/Library/Homebrew/test/support/fixtures/cask/everything.json @@ -76,7 +76,12 @@ "depends_on": { "cask": [ "something" - ] + ], + "macos": { + ">=": [ + "10.11" + ] + } }, "conflicts_with": { "formula": [ From 22ed703c2b7fd9eacab60532164420174b77b131 Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Sun, 9 Feb 2025 12:18:48 +0100 Subject: [PATCH 7/7] fix: use bottle naming for sha256 Signed-off-by: Sean Molenaar --- Library/Homebrew/cask/dsl.rb | 37 +++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index d6c5d4ab12..b01b707083 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -310,19 +310,36 @@ module Cask # For architecture-dependent downloads: # # ```ruby - # sha256 arm: "7bdb497080ffafdfd8cc94d8c62b004af1be9599e865e5555e456e2681e150ca", - # intel: "b3c1c2442480a0219b9e05cf91d03385858c20f04b764ec08a3fa83d1b27e7b2" - # linux: "1a2aee7f1ddc999993d4d7d42a150c5e602bc17281678050b8ed79a0500cc90f" + # sha256 arm: "7bdb497080ffafdfd8cc94d8c62b004af1be9599e865e5555e456e2681e150ca", + # x86_64: "b3c1c2442480a0219b9e05cf91d03385858c20f04b764ec08a3fa83d1b27e7b2" + # x86_64_linux: "1a2aee7f1ddc999993d4d7d42a150c5e602bc17281678050b8ed79a0500cc90f" + # arm64_linux: "bd766af7e692afceb727a6f88e24e6e68d9882aeb3e8348412f6c03d96537c75" # ``` # # @api public - def sha256(arg = nil, arm: nil, intel: nil, linux: nil) - should_return = arg.nil? && arm.nil? && intel.nil? && linux.nil? + sig { + params( + arg: T.nilable(T.any(String, Symbol)), + arm: T.nilable(String), + intel: T.nilable(String), + x86_64: T.nilable(String), + x86_64_linux: T.nilable(String), + arm64_linux: T.nilable(String), + ).returns(T.nilable(T.any(Symbol, Checksum))) + } + def sha256(arg = nil, arm: nil, intel: nil, x86_64: nil, x86_64_linux: nil, arm64_linux: nil) + should_return = arg.nil? && arm.nil? && (intel.nil? || x86_64.nil?) && x86_64_linux.nil? && arm64_linux.nil? + x86_64 ||= intel if intel.present? && x86_64.nil? set_unique_stanza(:sha256, should_return) do - @on_system_blocks_exist = true if arm.present? || intel.present? || linux.present? + if arm.present? || x86_64.present? || x86_64_linux.present? || arm64_linux.present? + @on_system_blocks_exist = true + end - val = arg || on_system_conditional(macos: on_arch_conditional(arm:, intel:), linux:) + val = arg || on_system_conditional( + macos: on_arch_conditional(arm:, intel: x86_64), + linux: on_arch_conditional(arm: arm64_linux, intel: x86_64_linux), + ) case val when :no_check val @@ -362,6 +379,12 @@ module Cask # ``` # # @api public + sig { + params( + macos: T.nilable(String), + linux: T.nilable(String), + ).returns(T.nilable(String)) + } def os(macos: nil, linux: nil) should_return = macos.nil? && linux.nil?