Skip to content

Commit 85b07ae

Browse files
committed
feat: add appimage support for linux
1 parent b5225c1 commit 85b07ae

File tree

10 files changed

+119
-16
lines changed

10 files changed

+119
-16
lines changed

Library/Homebrew/cask/artifact.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# frozen_string_literal: true
33

44
require "cask/artifact/app"
5+
require "cask/artifact/appimage"
56
require "cask/artifact/artifact" # generic 'artifact' stanza
67
require "cask/artifact/audio_unit_plugin"
78
require "cask/artifact/binary"
@@ -53,5 +54,9 @@ module Artifact
5354
::Cask::Artifact::VstPlugin,
5455
::Cask::Artifact::Vst3Plugin,
5556
].freeze
57+
58+
LINUX_ONLY_ARTIFACTS = [
59+
::Cask::Artifact::AppImage,
60+
].freeze
5661
end
5762
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# typed: strict
2+
# frozen_string_literal: true
3+
4+
require "cask/artifact/symlinked"
5+
6+
module Cask
7+
module Artifact
8+
class AppImage < Symlinked
9+
sig { params(target: T.any(String, Pathname)).returns(Pathname) }
10+
def resolve_target(target)
11+
config.appimagedir/target
12+
end
13+
end
14+
end
15+
end

Library/Homebrew/cask/cask.rb

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,65 @@ def font?
164164
end
165165

166166
sig { returns(T::Boolean) }
167-
def supports_macos? = true
167+
def supports_macos?
168+
return true if font?
169+
170+
if @dsl.on_system_blocks_exist?
171+
any_loaded = false
172+
begin
173+
[:arm, :intel].each do |arch|
174+
bottle_tag = ::Utils::Bottles::Tag.new(system: :macos, arch: arch)
175+
Homebrew::SimulateSystem.with_tag(bottle_tag) do
176+
refresh
177+
178+
any_loaded = true
179+
return false if artifacts.any? do |artifact|
180+
::Cask::Artifact::LINUX_ONLY_ARTIFACTS.include?(artifact.class)
181+
end
182+
end
183+
end
184+
rescue CaskInvalidError
185+
# Invalid cask for macOS
186+
ensure
187+
refresh
188+
end
189+
190+
return false if !any_loaded
191+
end
192+
193+
true
194+
end
168195

169196
sig { returns(T::Boolean) }
170197
def supports_linux?
171198
return true if font?
172199

173-
return false if artifacts.any? do |artifact|
174-
::Cask::Artifact::MACOS_ONLY_ARTIFACTS.include?(artifact.class)
200+
if @dsl.on_system_blocks_exist?
201+
any_loaded = false
202+
begin
203+
[:arm, :intel].each do |arch|
204+
bottle_tag = ::Utils::Bottles::Tag.new(system: :linux, arch: arch)
205+
begin
206+
Homebrew::SimulateSystem.with_tag(bottle_tag) do
207+
refresh
208+
209+
any_loaded = true
210+
return false if artifacts.any? do |artifact|
211+
::Cask::Artifact::MACOS_ONLY_ARTIFACTS.include?(artifact.class)
212+
end
213+
rescue CaskInvalidError => e
214+
# Invalid cask for Linux
215+
end
216+
end
217+
end
218+
ensure
219+
refresh
220+
end
221+
222+
return false if !any_loaded
175223
end
176224

177-
@dsl.os.present?
225+
true
178226
end
179227

180228
# The caskfile is needed during installation when there are

Library/Homebrew/cask/config.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class Config
1616
DEFAULT_DIRS = T.let(
1717
{
1818
appdir: "/Applications",
19+
appimagedir: "~/Applications",
1920
keyboard_layoutdir: "/Library/Keyboard Layouts",
2021
colorpickerdir: "~/Library/ColorPickers",
2122
prefpanedir: "~/Library/PreferencePanes",
@@ -49,6 +50,7 @@ def self.from_args(args)
4950
args = T.unsafe(args)
5051
new(explicit: {
5152
appdir: args.appdir,
53+
appimagedir: args.appimagedir,
5254
keyboard_layoutdir: args.keyboard_layoutdir,
5355
colorpickerdir: args.colorpickerdir,
5456
prefpanedir: args.prefpanedir,

Library/Homebrew/cask/dsl.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class DSL
3838
ORDINARY_ARTIFACT_CLASSES = [
3939
Artifact::Installer,
4040
Artifact::App,
41+
Artifact::AppImage,
4142
Artifact::Artifact,
4243
Artifact::AudioUnitPlugin,
4344
Artifact::Binary,

Library/Homebrew/cli/parser.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ def self.global_cask_options
6666
description: "Target location for Applications " \
6767
"(default: `#{Cask::Config::DEFAULT_DIRS[:appdir]}`).",
6868
}],
69+
[:flag, "--appimagedir=", {
70+
description: "Target location for AppImages " \
71+
"(default: `#{Cask::Config::DEFAULT_DIRS[:appimagedir]}`).",
72+
}],
6973
[:flag, "--keyboard-layoutdir=", {
7074
description: "Target location for Keyboard Layouts " \
7175
"(default: `#{Cask::Config::DEFAULT_DIRS[:keyboard_layoutdir]}`).",

Library/Homebrew/dev-cmd/generate-cask-ci-matrix.rb

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ def run
6767
pr_url = args.named if args.url?
6868
syntax_only = args.syntax_only?
6969

70-
repository = ENV.fetch("GITHUB_REPOSITORY", nil)
70+
# repository = ENV.fetch("GITHUB_REPOSITORY", nil)
71+
repository = "Homebrew/homebrew-cask" # For testing
7172
raise UsageError, "The `$GITHUB_REPOSITORY` environment variable must be set." if repository.blank?
7273

7374
tap = T.let(Tap.fetch(repository), Tap)
@@ -127,16 +128,20 @@ def run
127128

128129
sig { params(cask: Cask::Cask).returns(T::Hash[T::Hash[Symbol, T.any(Symbol, String)], Float]) }
129130
def filter_runners(cask)
130-
filtered_macos_runners = RUNNERS.select do |runner, _|
131-
runner[:symbol] != :linux &&
132-
cask.depends_on.macos.present? &&
133-
cask.depends_on.macos.allows?(MacOSVersion.from_symbol(T.must(runner[:symbol]).to_sym))
134-
end
131+
if cask.supports_macos?
132+
filtered_macos_runners = RUNNERS.select do |runner, _|
133+
runner[:symbol] != :linux &&
134+
cask.depends_on.macos.present? &&
135+
cask.depends_on.macos.allows?(MacOSVersion.from_symbol(T.must(runner[:symbol]).to_sym))
136+
end
135137

136-
filtered_runners = if filtered_macos_runners.any?
137-
filtered_macos_runners
138+
filtered_runners = if filtered_macos_runners.any?
139+
filtered_macos_runners
140+
else
141+
RUNNERS.dup
142+
end
138143
else
139-
RUNNERS.dup
144+
filtered_runners = {}
140145
end
141146

142147
filtered_runners = filtered_runners.merge(LINUX_RUNNERS) if cask.supports_linux?
@@ -151,6 +156,7 @@ def filter_runners(cask)
151156

152157
sig { params(cask: Cask::Cask).returns(T::Array[Symbol]) }
153158
def architectures(cask:)
159+
154160
return RUNNERS.keys.map { |r| r.fetch(:arch).to_sym }.uniq.sort if cask.depends_on.arch.blank?
155161

156162
cask.depends_on.arch.map { |arch| arch[:type] }.uniq.sort

Library/Homebrew/extend/os/cask/installer.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
# frozen_string_literal: true
33

44
require "extend/os/linux/cask/installer" if OS.linux?
5+
require "extend/os/mac/cask/installer" if OS.mac?

Library/Homebrew/extend/os/linux/cask/installer.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ module Installer
1111

1212
sig { void }
1313
def check_stanza_os_requirements
14-
return unless artifacts.any? do |artifact|
15-
::Cask::Artifact::MACOS_ONLY_ARTIFACTS.include?(artifact.class)
16-
end
14+
return unless @cask.supports_linux?
1715

1816
raise ::Cask::CaskError, "macOS is required for this software."
1917
end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# typed: strict
2+
# frozen_string_literal: true
3+
4+
module OS
5+
module Mac
6+
module Cask
7+
module Installer
8+
extend T::Helpers
9+
10+
requires_ancestor { ::Cask::Installer }
11+
12+
sig { void }
13+
def check_stanza_os_requirements
14+
return unless @cask.supports_macos?
15+
16+
raise ::Cask::CaskError, "Linux is required for this software."
17+
end
18+
end
19+
end
20+
end
21+
end
22+
23+
Cask::Installer.prepend(OS::Mac::Cask::Installer)

0 commit comments

Comments
 (0)