Skip to content

Commit 714bf64

Browse files
committed
bundle: narrow types
Updates some Object usage to more specific types. Some changes include: - Change `exit_early_check` to return String errors so that it has the same return signature as `full_check` - Make `CheckResult` into a `T::Struct` for better type checking - `entries` consist of `Dsl::Entry` which avoids having to `T.cast`
1 parent 19f50a5 commit 714bf64

10 files changed

Lines changed: 46 additions & 49 deletions

File tree

Library/Homebrew/bundle/brew.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,11 @@ def failure_reason(name, no_upgrade:)
490490

491491
sig {
492492
override.params(
493-
entries: T::Array[Object],
493+
entries: T::Array[Dsl::Entry],
494494
exit_on_first_error: T::Boolean,
495495
no_upgrade: T::Boolean,
496496
verbose: T::Boolean,
497-
).returns(T::Array[Object])
497+
).returns(T::Array[String])
498498
}
499499
def find_actionable(entries, exit_on_first_error: false, no_upgrade: false, verbose: false)
500500
requested = instance_of?(Homebrew::Bundle::Brew) ? checkable_entries(entries) : format_checkable(entries)

Library/Homebrew/bundle/brew_services.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def lookup_old_name(service_name)
155155
old_name
156156
end
157157

158-
sig { params(entries: T::Array[Object]).returns(T::Array[Object]) }
158+
sig { params(entries: T::Array[Dsl::Entry]).returns(T::Array[Object]) }
159159
def format_checkable(entries)
160160
checkable_entries(entries)
161161
end

Library/Homebrew/bundle/checker.rb

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
module Homebrew
99
module Bundle
1010
module Checker
11-
CheckResult = Struct.new :work_to_be_done, :errors
11+
class CheckResult < T::Struct
12+
const :work_to_be_done, T::Boolean
13+
const :errors, T::Array[String]
14+
end
15+
1216
CheckStep = T.type_alias { Symbol }
1317

1418
CORE_CHECKS = T.let([
@@ -34,7 +38,7 @@ def self.check(global: false, file: nil, exit_on_first_error: false, no_upgrade:
3438
@dsl = T.let(@dsl, T.nilable(Homebrew::Bundle::Dsl))
3539
@dsl ||= Brewfile.read(global:, file:)
3640

37-
errors = T.let([], T::Array[Object])
41+
errors = T.let([], T::Array[String])
3842
enumerator = exit_on_first_error ? :find : :map
3943

4044
work_to_be_done = CORE_CHECKS.public_send(enumerator) do |check_step|
@@ -46,15 +50,15 @@ def self.check(global: false, file: nil, exit_on_first_error: false, no_upgrade:
4650

4751
work_to_be_done = Array(work_to_be_done).flatten.any?
4852

49-
CheckResult.new work_to_be_done, errors
53+
CheckResult.new(work_to_be_done:, errors:)
5054
end
5155

5256
sig {
5357
params(
5458
exit_on_first_error: T::Boolean,
5559
no_upgrade: T::Boolean,
5660
verbose: T::Boolean,
57-
).returns(T::Array[Object])
61+
).returns(T::Array[String])
5862
}
5963
def self.apps_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
6064
extension_errors(:apps_to_install, exit_on_first_error:, no_upgrade:, verbose:)
@@ -65,7 +69,7 @@ def self.apps_to_install(exit_on_first_error: false, no_upgrade: false, verbose:
6569
exit_on_first_error: T::Boolean,
6670
no_upgrade: T::Boolean,
6771
verbose: T::Boolean,
68-
).returns(T::Array[Object])
72+
).returns(T::Array[String])
6973
}
7074
def self.formulae_to_start(exit_on_first_error: false, no_upgrade: false, verbose: false)
7175
raise ArgumentError, "dsl is unset!" unless @dsl
@@ -81,7 +85,7 @@ def self.formulae_to_start(exit_on_first_error: false, no_upgrade: false, verbos
8185
exit_on_first_error: T::Boolean,
8286
no_upgrade: T::Boolean,
8387
verbose: T::Boolean,
84-
).returns(T::Array[Object])
88+
).returns(T::Array[String])
8589
}
8690
def self.taps_to_tap(exit_on_first_error: false, no_upgrade: false, verbose: false)
8791
package_type_errors(:tap, exit_on_first_error:, no_upgrade:, verbose:)
@@ -92,7 +96,7 @@ def self.taps_to_tap(exit_on_first_error: false, no_upgrade: false, verbose: fal
9296
exit_on_first_error: T::Boolean,
9397
no_upgrade: T::Boolean,
9498
verbose: T::Boolean,
95-
).returns(T::Array[Object])
99+
).returns(T::Array[String])
96100
}
97101
def self.casks_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
98102
package_type_errors(:cask, exit_on_first_error:, no_upgrade:, verbose:)
@@ -103,7 +107,7 @@ def self.casks_to_install(exit_on_first_error: false, no_upgrade: false, verbose
103107
exit_on_first_error: T::Boolean,
104108
no_upgrade: T::Boolean,
105109
verbose: T::Boolean,
106-
).returns(T::Array[Object])
110+
).returns(T::Array[String])
107111
}
108112
def self.formulae_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
109113
package_type_errors(:brew, exit_on_first_error:, no_upgrade:, verbose:)
@@ -114,7 +118,7 @@ def self.formulae_to_install(exit_on_first_error: false, no_upgrade: false, verb
114118
exit_on_first_error: T::Boolean,
115119
no_upgrade: T::Boolean,
116120
verbose: T::Boolean,
117-
).returns(T::Array[Object])
121+
).returns(T::Array[String])
118122
}
119123
def self.registered_extensions_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
120124
extension_errors(:registered_extensions_to_install, exit_on_first_error:, no_upgrade:, verbose:)
@@ -126,13 +130,13 @@ def self.registered_extensions_to_install(exit_on_first_error: false, no_upgrade
126130
exit_on_first_error: T::Boolean,
127131
no_upgrade: T::Boolean,
128132
verbose: T::Boolean,
129-
).returns(T::Array[Object])
133+
).returns(T::Array[String])
130134
}
131135
def self.extension_errors(step, exit_on_first_error:, no_upgrade:, verbose:)
132136
raise ArgumentError, "dsl is unset!" unless @dsl
133137

134138
matching_extensions = Homebrew::Bundle.extensions.select { |extension| extension.legacy_check_step == step }
135-
errors = T.let([], T::Array[Object])
139+
errors = T.let([], T::Array[String])
136140

137141
matching_extensions.each do |extension|
138142
check_errors = extension.check(
@@ -162,7 +166,7 @@ def self.reset!
162166
exit_on_first_error: T::Boolean,
163167
no_upgrade: T::Boolean,
164168
verbose: T::Boolean,
165-
).returns(T::Array[Object])
169+
).returns(T::Array[String])
166170
}
167171
def self.package_type_errors(type, exit_on_first_error:, no_upgrade:, verbose:)
168172
raise ArgumentError, "dsl is unset!" unless @dsl

Library/Homebrew/bundle/extensions/extension.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,11 @@ def self.dump_output(describe: false, no_restart: false)
217217

218218
sig {
219219
params(
220-
entries: T::Array[Object],
220+
entries: T::Array[Dsl::Entry],
221221
exit_on_first_error: T::Boolean,
222222
no_upgrade: T::Boolean,
223223
verbose: T::Boolean,
224-
).returns(T::Array[Object])
224+
).returns(T::Array[String])
225225
}
226226
def self.check(entries, exit_on_first_error: false, no_upgrade: false, verbose: false)
227227
new.find_actionable(entries, exit_on_first_error:, no_upgrade:, verbose:)

Library/Homebrew/bundle/extensions/flatpak.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,11 @@ def package_installed?(name, with: nil, remote: nil)
356356
end
357357
end
358358

359-
sig { params(entries: T::Array[Object]).returns(T::Array[String]) }
359+
sig { params(entries: T::Array[Dsl::Entry]).returns(T::Array[String]) }
360360
def cleanup_items(entries)
361361
return [].freeze unless package_manager_installed?
362362

363363
kept_flatpaks = entries.filter_map do |entry|
364-
entry = T.cast(entry, Dsl::Entry)
365364
entry.name if entry.type == type
366365
end
367366

@@ -379,10 +378,9 @@ def cleanup!(flatpaks)
379378
end
380379
end
381380

382-
sig { override.params(entries: T::Array[Object]).returns(T::Array[Object]) }
381+
sig { override.params(entries: T::Array[Dsl::Entry]).returns(T::Array[Object]) }
383382
def format_checkable(entries)
384383
checkable_entries(entries).map do |entry|
385-
entry = T.cast(entry, Dsl::Entry)
386384
{ name: entry.name, options: entry.options }
387385
end
388386
end

Library/Homebrew/bundle/extensions/mac_app_store.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,21 +264,21 @@ def parse_cleanup_item(item)
264264
end
265265
end
266266

267-
sig { override.params(entries: T::Array[Object]).returns(T::Array[Object]) }
267+
sig { override.params(entries: T::Array[Dsl::Entry]).returns(T::Array[Object]) }
268268
def format_checkable(entries)
269269
checkable_entries(entries).map do |entry|
270-
entry = T.cast(entry, Dsl::Entry)
271270
[T.cast(entry.options.fetch(:id), Integer), entry.name]
272271
end
273272
end
274273

275-
sig { override.params(packages: CheckablePackages, no_upgrade: T::Boolean).returns(T::Array[Object]) }
274+
sig { override.params(packages: CheckablePackages, no_upgrade: T::Boolean).returns(T::Array[String]) }
276275
def exit_early_check(packages, no_upgrade:)
277-
work_to_be_done = (packages.is_a?(Hash) ? packages.to_a : packages).find do |id, _name|
278-
!installed_and_up_to_date?(id, no_upgrade:)
279-
end
276+
(packages.is_a?(Hash) ? packages.to_a : packages).each do |id, name|
277+
next if installed_and_up_to_date?(id, no_upgrade:)
280278

281-
Array(work_to_be_done)
279+
return [failure_reason(name, no_upgrade:)]
280+
end
281+
[]
282282
end
283283

284284
sig { override.params(packages: CheckablePackages, no_upgrade: T::Boolean).returns(T::Array[String]) }

Library/Homebrew/bundle/extensions/uv.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,9 @@ def uninstall_package!(name, executable: Pathname.new(""))
229229
end
230230
end
231231

232-
sig { override.params(entries: T::Array[Object]).returns(T::Array[Object]) }
232+
sig { override.params(entries: T::Array[Dsl::Entry]).returns(T::Array[Object]) }
233233
def format_checkable(entries)
234234
checkable_entries(entries).map do |entry|
235-
entry = T.cast(entry, Dsl::Entry)
236235
with = if entry.options.is_a?(Hash)
237236
value = entry.options[:with]
238237
value.is_a?(Array) ? value : []

Library/Homebrew/bundle/extensions/winget.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,10 +516,9 @@ def parse_cleanup_item(item)
516516
end
517517
end
518518

519-
sig { override.params(entries: T::Array[Object]).returns(T::Array[Object]) }
519+
sig { override.params(entries: T::Array[Dsl::Entry]).returns(T::Array[Object]) }
520520
def format_checkable(entries)
521521
checkable_entries(entries).map do |entry|
522-
entry = T.cast(entry, Dsl::Entry)
523522
App.new(id: T.cast(entry.options.fetch(:id), String), name: entry.name,
524523
source: T.cast(entry.options.fetch(:source), String))
525524
end

Library/Homebrew/bundle/package_type.rb

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ def self.install!(name, preinstall: true, no_upgrade: false, verbose: false, for
8686

8787
sig {
8888
params(
89-
entries: T::Array[Object],
89+
entries: T::Array[Dsl::Entry],
9090
exit_on_first_error: T::Boolean,
9191
no_upgrade: T::Boolean,
9292
verbose: T::Boolean,
93-
).returns(T::Array[Object])
93+
).returns(T::Array[String])
9494
}
9595
def self.check(entries, exit_on_first_error: false, no_upgrade: false, verbose: false)
9696
new.find_actionable(entries, exit_on_first_error:, no_upgrade:, verbose:)
@@ -107,13 +107,14 @@ def self.dump_output(describe: false, no_restart: false)
107107
dump
108108
end
109109

110-
sig { params(packages: T::Array[Object], no_upgrade: T::Boolean).returns(T::Array[Object]) }
110+
sig { params(packages: T::Array[Object], no_upgrade: T::Boolean).returns(T::Array[String]) }
111111
def exit_early_check(packages, no_upgrade:)
112-
work_to_be_done = packages.find do |pkg|
113-
!installed_and_up_to_date?(pkg, no_upgrade:)
114-
end
112+
packages.each do |pkg|
113+
next if installed_and_up_to_date?(pkg, no_upgrade:)
115114

116-
Array(work_to_be_done)
115+
return [failure_reason(pkg, no_upgrade:)]
116+
end
117+
[]
117118
end
118119

119120
sig { overridable.params(name: Object, no_upgrade: T::Boolean).returns(String) }
@@ -132,24 +133,20 @@ def full_check(packages, no_upgrade:)
132133
.map { |pkg| failure_reason(pkg, no_upgrade:) }
133134
end
134135

135-
sig { params(all_entries: T::Array[Object]).returns(T::Array[Object]) }
136+
sig { params(all_entries: T::Array[Dsl::Entry]).returns(T::Array[Dsl::Entry]) }
136137
def checkable_entries(all_entries)
137138
require "bundle/skipper"
138139
all_entries.filter_map do |entry|
139-
entry = T.cast(entry, Dsl::Entry)
140140
next if entry.type != self.class.type
141141
next if Bundle::Skipper.skip?(entry)
142142

143143
entry
144144
end
145145
end
146146

147-
sig { params(entries: T::Array[Object]).returns(T::Array[Object]) }
147+
sig { params(entries: T::Array[Dsl::Entry]).returns(T::Array[Object]) }
148148
def format_checkable(entries)
149-
checkable_entries(entries).map do |entry|
150-
entry = T.cast(entry, Dsl::Entry)
151-
entry.name
152-
end
149+
checkable_entries(entries).map(&:name)
153150
end
154151

155152
sig { params(_pkg: Object, no_upgrade: T::Boolean).returns(T::Boolean) }
@@ -159,11 +156,11 @@ def installed_and_up_to_date?(_pkg, no_upgrade: false)
159156

160157
sig {
161158
params(
162-
entries: T::Array[Object],
159+
entries: T::Array[Dsl::Entry],
163160
exit_on_first_error: T::Boolean,
164161
no_upgrade: T::Boolean,
165162
verbose: T::Boolean,
166-
).returns(T::Array[Object])
163+
).returns(T::Array[String])
167164
}
168165
def find_actionable(entries, exit_on_first_error: false, no_upgrade: false, verbose: false)
169166
requested = format_checkable(entries)

Library/Homebrew/bundle/tap.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def taps
161161
end
162162

163163
sig {
164-
override.params(entries: T::Array[Object], exit_on_first_error: T::Boolean,
164+
override.params(entries: T::Array[Dsl::Entry], exit_on_first_error: T::Boolean,
165165
no_upgrade: T::Boolean, verbose: T::Boolean).returns(T::Array[String])
166166
}
167167
def find_actionable(entries, exit_on_first_error: false, no_upgrade: false, verbose: false)

0 commit comments

Comments
 (0)