Skip to content

Commit e90b53b

Browse files
authored
Merge pull request Homebrew#16621 from reitermarkus/cask-loader-improvements
More `CaskLoader` improvements.
2 parents a58941a + 5cf4f2f commit e90b53b

File tree

7 files changed

+145
-52
lines changed

7 files changed

+145
-52
lines changed

Library/Homebrew/api/cask.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def download_and_cache_data!
6060
end
6161
private :download_and_cache_data!
6262

63-
sig { returns(Hash) }
63+
sig { returns(T::Hash[String, Hash]) }
6464
def all_casks
6565
unless cache.key?("casks")
6666
json_updated = download_and_cache_data!

Library/Homebrew/cask/cask_loader.rb

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,14 @@ class FromPathLoader < AbstractContentLoader
9090
.returns(T.nilable(T.attached_class))
9191
}
9292
def self.try_new(ref, warn: false)
93-
ref = Pathname(ref) if ref.is_a?(String)
94-
return unless ref.is_a?(Pathname)
95-
96-
path = ref
93+
path = case ref
94+
when String
95+
Pathname(ref)
96+
when Pathname
97+
ref
98+
else
99+
return
100+
end
97101

98102
return if %w[.rb .json].exclude?(path.extname)
99103
return unless path.expand_path.exist?
@@ -110,9 +114,8 @@ def initialize(path, token: T.unsafe(nil))
110114
path = Pathname(path).expand_path
111115

112116
@token = path.basename(path.extname).to_s
113-
114117
@path = path
115-
@tap = Homebrew::API.tap_from_source_download(path)
118+
@tap = Tap.from_path(path) || Homebrew::API.tap_from_source_download(path)
116119
end
117120

118121
def load(config:)
@@ -191,27 +194,8 @@ def load(config:)
191194
end
192195
end
193196

194-
# Loads a cask from a tap path.
195-
class FromTapPathLoader < FromPathLoader
196-
sig {
197-
params(ref: T.any(String, Pathname, Cask, URI::Generic), warn: T::Boolean)
198-
.returns(T.nilable(T.attached_class))
199-
}
200-
def self.try_new(ref, warn: false)
201-
return unless (loader = super)
202-
203-
loader unless Tap.from_path(ref).nil?
204-
end
205-
206-
sig { params(path: T.any(Pathname, String)).void }
207-
def initialize(path)
208-
super(path)
209-
@tap = Tap.from_path(path)
210-
end
211-
end
212-
213197
# Loads a cask from a specific tap.
214-
class FromTapLoader < FromTapPathLoader
198+
class FromTapLoader < FromPathLoader
215199
sig {
216200
params(ref: T.any(String, Pathname, Cask, URI::Generic), warn: T::Boolean)
217201
.returns(T.nilable(T.attached_class))
@@ -225,9 +209,9 @@ def self.try_new(ref, warn: false)
225209
new("#{tap}/#{token}")
226210
end
227211

228-
sig { params(tapped_name: String).void }
229-
def initialize(tapped_name)
230-
user, repo, token = tapped_name.split("/", 3)
212+
sig { params(tapped_token: String).void }
213+
def initialize(tapped_token)
214+
user, repo, token = tapped_token.split("/", 3)
231215
tap = Tap.fetch(user, repo)
232216
cask = CaskLoader.find_cask_in_tap(token, tap)
233217
super cask
@@ -249,7 +233,7 @@ class FromDefaultTapLoader < FromTapLoader
249233
def self.try_new(ref, warn: false)
250234
ref = ref.to_s
251235

252-
return unless (match = ref.match(HOMEBREW_MAIN_TAP_CASK_REGEX))
236+
return unless (match = ref.match(HOMEBREW_DEFAULT_TAP_CASK_REGEX))
253237

254238
token = match[:token]
255239

@@ -261,7 +245,7 @@ def self.try_new(ref, warn: false)
261245
end
262246

263247
# Loads a cask from the default tap path.
264-
class FromDefaultTapPathLoader < FromTapPathLoader
248+
class FromDefaultTapPathLoader < FromPathLoader
265249
sig {
266250
params(ref: T.any(String, Pathname, Cask, URI::Generic), warn: T::Boolean)
267251
.returns(T.nilable(T.attached_class))
@@ -297,7 +281,11 @@ def load(config:)
297281
class FromAPILoader
298282
include ILoader
299283

300-
attr_reader :token, :path
284+
sig { returns(String) }
285+
attr_reader :token
286+
287+
sig { returns(Pathname) }
288+
attr_reader :path
301289

302290
sig { returns(T.nilable(Hash)) }
303291
attr_reader :from_json
@@ -309,12 +297,8 @@ class FromAPILoader
309297
def self.try_new(ref, warn: false)
310298
return if Homebrew::EnvConfig.no_install_from_api?
311299
return unless ref.is_a?(String)
312-
313-
return unless (match = ref.match(HOMEBREW_MAIN_TAP_CASK_REGEX))
314-
315-
token = match[:token]
316-
317-
return unless Homebrew::API::Cask.all_casks.key?(token)
300+
return unless (token = ref[HOMEBREW_DEFAULT_TAP_CASK_REGEX, :token])
301+
return if !Homebrew::API::Cask.all_casks.key?(token) && !Homebrew::API::Cask.all_renames.key?(token)
318302

319303
ref = "#{CoreCaskTap.instance}/#{token}"
320304

@@ -330,7 +314,7 @@ def initialize(token, from_json: T.unsafe(nil))
330314
end
331315

332316
def load(config:)
333-
json_cask = from_json || Homebrew::API::Cask.all_casks[token]
317+
json_cask = from_json || Homebrew::API::Cask.all_casks.fetch(token)
334318

335319
cask_options = {
336320
loaded_from_api: true,
@@ -480,13 +464,13 @@ def from_h_gsubs(value, appdir)
480464

481465
# Loader which tries loading casks from tap paths, failing
482466
# if the same token exists in multiple taps.
483-
class FromAmbiguousTapPathLoader < FromTapPathLoader
467+
class FromAmbiguousTapPathLoader < FromPathLoader
484468
def self.try_new(ref, warn: false)
485-
case (possible_tap_casks = CaskLoader.tap_paths(ref, warn: warn)).count
469+
case (possible_tap_casks = CaskLoader.tap_paths(ref)).count
486470
when 1
487471
new(possible_tap_casks.first)
488472
when 2..Float::INFINITY
489-
loaders = possible_tap_casks.map(&FromTapPathLoader.method(:new))
473+
loaders = possible_tap_casks.map(&FromPathLoader.method(:new))
490474
raise TapCaskAmbiguityError.new(ref, loaders)
491475
end
492476
end
@@ -568,7 +552,6 @@ def self.for(ref, need_path: false, warn: true)
568552
FromURILoader,
569553
FromAPILoader,
570554
FromTapLoader,
571-
FromTapPathLoader,
572555
FromPathLoader,
573556
FromDefaultTapPathLoader,
574557
FromAmbiguousTapPathLoader,
@@ -587,7 +570,7 @@ def self.default_path(token)
587570
find_cask_in_tap(token.to_s.downcase, CoreCaskTap.instance)
588571
end
589572

590-
def self.tap_paths(token, warn: true)
573+
def self.tap_paths(token)
591574
token = token.to_s.downcase
592575

593576
Tap.map { |tap| find_cask_in_tap(token, tap) }.select(&:exist?)

Library/Homebrew/cask/caskroom.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def self.casks(config: nil)
5656
CaskLoader.load(token, config: config)
5757
rescue TapCaskAmbiguityError
5858
tap_path = CaskLoader.tap_paths(token).first
59-
CaskLoader::FromTapPathLoader.new(tap_path).load(config: config)
59+
CaskLoader::FromPathLoader.new(tap_path).load(config: config)
6060
rescue
6161
# Don't blow up because of a single unavailable cask.
6262
nil

Library/Homebrew/cli/named_args.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,11 @@ def to_paths(only: parent&.only_formula_or_cask, recurse_tap: false)
256256
paths = []
257257

258258
if formula_path.exist? ||
259-
(!CoreTap.instance.installed? && Homebrew::API::Formula.all_formulae.key?(path.basename))
259+
(!CoreTap.instance.installed? && Homebrew::API::Formula.all_formulae.key?(path.basename.to_s))
260260
paths << formula_path
261261
end
262262
if cask_path.exist? ||
263-
(!CoreCaskTap.instance.installed? && Homebrew::API::Cask.all_casks.key?(path.basename))
263+
(!CoreCaskTap.instance.installed? && Homebrew::API::Cask.all_casks.key?(path.basename.to_s))
264264
paths << cask_path
265265
end
266266

Library/Homebrew/sorbet/rbi/upstream.rbi

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,111 @@
22

33
# This file contains temporary definitions for fixes that have
44
# been submitted upstream to https://github.com/sorbet/sorbet.
5+
6+
# https://github.com/sorbet/sorbet/pull/7678
7+
class String
8+
sig do
9+
params(
10+
arg0: Integer,
11+
arg1: Integer,
12+
)
13+
.returns(T.nilable(String))
14+
end
15+
sig do
16+
params(
17+
arg0: T.any(T::Range[Integer], Regexp),
18+
)
19+
.returns(T.nilable(String))
20+
end
21+
sig do
22+
params(
23+
arg0: Regexp,
24+
arg1: Integer,
25+
)
26+
.returns(T.nilable(String))
27+
end
28+
sig do
29+
params(
30+
arg0: Regexp,
31+
arg1: T.any(String, Symbol),
32+
)
33+
.returns(T.nilable(String))
34+
end
35+
sig do
36+
params(
37+
arg0: String,
38+
)
39+
.returns(T.nilable(String))
40+
end
41+
def [](arg0, arg1=T.unsafe(nil)); end
42+
43+
sig do
44+
params(
45+
arg0: Integer,
46+
arg1: Integer,
47+
)
48+
.returns(T.nilable(String))
49+
end
50+
sig do
51+
params(
52+
arg0: T.any(T::Range[Integer], Regexp),
53+
)
54+
.returns(T.nilable(String))
55+
end
56+
sig do
57+
params(
58+
arg0: Regexp,
59+
arg1: Integer,
60+
)
61+
.returns(T.nilable(String))
62+
end
63+
sig do
64+
params(
65+
arg0: Regexp,
66+
arg1: T.any(String, Symbol),
67+
)
68+
.returns(T.nilable(String))
69+
end
70+
sig do
71+
params(
72+
arg0: String,
73+
)
74+
.returns(T.nilable(String))
75+
end
76+
def slice!(arg0, arg1=T.unsafe(nil)); end
77+
78+
sig do
79+
params(
80+
arg0: Integer,
81+
arg1: Integer,
82+
)
83+
.returns(T.nilable(String))
84+
end
85+
sig do
86+
params(
87+
arg0: T.any(T::Range[Integer], Regexp),
88+
)
89+
.returns(T.nilable(String))
90+
end
91+
sig do
92+
params(
93+
arg0: Regexp,
94+
arg1: Integer,
95+
)
96+
.returns(T.nilable(String))
97+
end
98+
sig do
99+
params(
100+
arg0: Regexp,
101+
arg1: T.any(String, Symbol),
102+
)
103+
.returns(T.nilable(String))
104+
end
105+
sig do
106+
params(
107+
arg0: String,
108+
)
109+
.returns(T.nilable(String))
110+
end
111+
def slice(arg0, arg1=T.unsafe(nil)); end
112+
end

Library/Homebrew/tap_constants.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
HOMEBREW_TAP_FORMULA_REGEX = T.let(%r{^([\w-]+)/([\w-]+)/([\w+-.@]+)$}, Regexp)
66
# Match taps' casks, e.g. `someuser/sometap/somecask`
77
HOMEBREW_TAP_CASK_REGEX = T.let(%r{^([\w-]+)/([\w-]+)/([a-z0-9\-_]+)$}, Regexp)
8-
# Match main cask taps' casks, e.g. `homebrew/cask/somecask` or `somecask`
9-
HOMEBREW_MAIN_TAP_CASK_REGEX = T.let(%r{^(?:[Hh]omebrew/(?:homebrew-)?cask/)?(?<token>[a-z0-9\-_]+)$}, Regexp)
8+
# Match default cask taps' casks, e.g. `homebrew/cask/somecask` or `somecask`
9+
HOMEBREW_DEFAULT_TAP_CASK_REGEX = T.let(
10+
%r{^(?:[Hh]omebrew/(?:homebrew-)?cask/)?(?<token>[a-z0-9\-_]+)$}, Regexp
11+
)
1012
# Match taps' directory paths, e.g. `HOMEBREW_LIBRARY/Taps/someuser/sometap`
1113
HOMEBREW_TAP_DIR_REGEX = T.let(
1214
%r{#{Regexp.escape(HOMEBREW_LIBRARY.to_s)}/Taps/(?<user>[\w-]+)/(?<repo>[\w-]+)}, Regexp

Library/Homebrew/test/cask/cask_loader_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@
3737

3838
it "warns when using the short token" do
3939
expect do
40-
expect(described_class.for("version-newest")).to be_a Cask::CaskLoader::FromTapPathLoader
40+
expect(described_class.for("version-newest")).to be_a Cask::CaskLoader::FromPathLoader
4141
end.to output(/version-newest was renamed to version-latest/).to_stderr
4242
end
4343

4444
it "warns when using the full token" do
4545
expect do
46-
expect(described_class.for("homebrew/cask/version-newest")).to be_a Cask::CaskLoader::FromTapPathLoader
46+
expect(described_class.for("homebrew/cask/version-newest")).to be_a Cask::CaskLoader::FromPathLoader
4747
end.to output(/version-newest was renamed to version-latest/).to_stderr
4848
end
4949
end

0 commit comments

Comments
 (0)