diff --git a/Library/Homebrew/cask/artifact.rb b/Library/Homebrew/cask/artifact.rb index 3659365825733..41f62450d5c1b 100644 --- a/Library/Homebrew/cask/artifact.rb +++ b/Library/Homebrew/cask/artifact.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "cask/artifact/app" +require "cask/artifact/appimage" require "cask/artifact/artifact" # generic 'artifact' stanza require "cask/artifact/audio_unit_plugin" require "cask/artifact/binary" @@ -54,6 +55,8 @@ module Artifact ::Cask::Artifact::Vst3Plugin, ].freeze - LINUX_ONLY_ARTIFACTS = T.let([].freeze, T::Array[T.untyped]) + LINUX_ONLY_ARTIFACTS = [ + ::Cask::Artifact::AppImage, + ].freeze end end diff --git a/Library/Homebrew/cask/artifact/appimage.rb b/Library/Homebrew/cask/artifact/appimage.rb new file mode 100644 index 0000000000000..875789ac9598f --- /dev/null +++ b/Library/Homebrew/cask/artifact/appimage.rb @@ -0,0 +1,15 @@ +# typed: strict +# frozen_string_literal: true + +require "cask/artifact/symlinked" + +module Cask + module Artifact + class AppImage < Symlinked + sig { params(target: T.any(String, Pathname)).returns(Pathname) } + def resolve_target(target) + Pathname.new("#{config.appimagedir}/#{target}") + end + end + end +end diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index 69e201228c95a..5f91a0489dc42 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -181,11 +181,11 @@ def supports_linux? # Cache the os value before contains_os_specific_artifacts? refreshes the cask # (the refresh clears @dsl.os in generic/non-OS-specific contexts) - os_value = @dsl.os + on_system_blocks_exist = @dsl.on_system_blocks_exist? return false if contains_os_specific_artifacts? - os_value.present? + on_system_blocks_exist end sig { returns(T::Boolean) } diff --git a/Library/Homebrew/cask/config.rb b/Library/Homebrew/cask/config.rb index fbf5a426d12ee..9b462d794cd63 100644 --- a/Library/Homebrew/cask/config.rb +++ b/Library/Homebrew/cask/config.rb @@ -16,6 +16,7 @@ class Config DEFAULT_DIRS = T.let( { appdir: "/Applications", + appimagedir: "~/Applications", keyboard_layoutdir: "/Library/Keyboard Layouts", colorpickerdir: "~/Library/ColorPickers", prefpanedir: "~/Library/PreferencePanes", @@ -49,6 +50,7 @@ def self.from_args(args) args = T.unsafe(args) new(explicit: { appdir: args.appdir, + appimagedir: args.appimagedir, keyboard_layoutdir: args.keyboard_layoutdir, colorpickerdir: args.colorpickerdir, prefpanedir: args.prefpanedir, diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index 69cc9b6b8bfed..110ba059a1b68 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -38,6 +38,7 @@ class DSL ORDINARY_ARTIFACT_CLASSES = [ Artifact::Installer, Artifact::App, + Artifact::AppImage, Artifact::Artifact, Artifact::AudioUnitPlugin, Artifact::Binary, diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index 8e0fbfb78c5bc..728fd01bdf8fe 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -66,6 +66,10 @@ def self.global_cask_options description: "Target location for Applications " \ "(default: `#{Cask::Config::DEFAULT_DIRS[:appdir]}`).", }], + [:flag, "--appimagedir=", { + description: "Target location for AppImages " \ + "(default: `#{Cask::Config::DEFAULT_DIRS[:appimagedir]}`).", + }], [:flag, "--keyboard-layoutdir=", { description: "Target location for Keyboard Layouts " \ "(default: `#{Cask::Config::DEFAULT_DIRS[:keyboard_layoutdir]}`).", diff --git a/Library/Homebrew/extend/os/cask/installer.rb b/Library/Homebrew/extend/os/cask/installer.rb index a7a6e0c277d9e..f435378b2ae74 100644 --- a/Library/Homebrew/extend/os/cask/installer.rb +++ b/Library/Homebrew/extend/os/cask/installer.rb @@ -2,3 +2,4 @@ # frozen_string_literal: true require "extend/os/linux/cask/installer" if OS.linux? +require "extend/os/mac/cask/installer" if OS.mac? diff --git a/Library/Homebrew/extend/os/mac/cask/installer.rb b/Library/Homebrew/extend/os/mac/cask/installer.rb new file mode 100644 index 0000000000000..60b86ea52a19c --- /dev/null +++ b/Library/Homebrew/extend/os/mac/cask/installer.rb @@ -0,0 +1,30 @@ +# typed: strict +# frozen_string_literal: true + +module OS + module Mac + module Cask + module Installer + extend T::Helpers + + requires_ancestor { ::Cask::Installer } + + sig { void } + def check_stanza_os_requirements + return if artifacts.all? { |artifact| supported_artifact?(artifact) } + + raise ::Cask::CaskError, "Linux is required for this software." + end + + private + + sig { params(artifact: ::Cask::Artifact::AbstractArtifact).returns(T::Boolean) } + def supported_artifact?(artifact) + ::Cask::Artifact::LINUX_ONLY_ARTIFACTS.exclude?(artifact.class) + end + end + end + end +end + +Cask::Installer.prepend(OS::Mac::Cask::Installer) diff --git a/Library/Homebrew/sorbet/rbi/dsl/cask/cask.rbi b/Library/Homebrew/sorbet/rbi/dsl/cask/cask.rbi index 6ce5a078a9435..b815c99ffa797 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/cask/cask.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/cask/cask.rbi @@ -9,6 +9,9 @@ class Cask::Cask sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) } def app(*args, &block); end + sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) } + def app_image(*args, &block); end + sig { params(args: T.untyped, block: T.untyped).returns(T.untyped) } def appdir(*args, &block); end diff --git a/Library/Homebrew/sorbet/rbi/dsl/cask/config.rbi b/Library/Homebrew/sorbet/rbi/dsl/cask/config.rbi index 5e2f38940e4a1..86f9a88dae98a 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/cask/config.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/cask/config.rbi @@ -10,6 +10,9 @@ module Cask sig { returns(String) } def appdir; end + sig { returns(String) } + def appimagedir; end + sig { returns(String) } def audio_unit_plugindir; end diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/install_cmd.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/install_cmd.rbi index 8215d6dc05914..0aa236c222b29 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/install_cmd.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/install_cmd.rbi @@ -20,6 +20,9 @@ class Homebrew::Cmd::InstallCmd::Args < Homebrew::CLI::Args sig { returns(T.nilable(String)) } def appdir; end + sig { returns(T.nilable(String)) } + def appimagedir; end + sig { returns(T::Boolean) } def as_dependency?; end diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/reinstall.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/reinstall.rbi index beee25bbbe15c..b68d09254df08 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/reinstall.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/reinstall.rbi @@ -17,6 +17,9 @@ class Homebrew::Cmd::Reinstall::Args < Homebrew::CLI::Args sig { returns(T.nilable(String)) } def appdir; end + sig { returns(T.nilable(String)) } + def appimagedir; end + sig { returns(T::Boolean) } def ask?; end diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/upgrade_cmd.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/upgrade_cmd.rbi index 3eb336f954f33..7b3fa1a661041 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/upgrade_cmd.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/upgrade_cmd.rbi @@ -14,6 +14,9 @@ class Homebrew::Cmd::UpgradeCmd::Args < Homebrew::CLI::Args sig { returns(T.nilable(String)) } def appdir; end + sig { returns(T.nilable(String)) } + def appimagedir; end + sig { returns(T::Boolean) } def ask?; end