Skip to content

Commit ec56bbf

Browse files
committed
Improve extend/* Sorbet typing
1 parent 0df52b9 commit ec56bbf

File tree

7 files changed

+165
-87
lines changed

7 files changed

+165
-87
lines changed

Library/Homebrew/extend/kernel.rb

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
# frozen_string_literal: true
33

44
# Contains shorthand Homebrew utility methods like `ohai`, `opoo`, `odisabled`.
5-
# TODO: move these out of `Kernel`.
5+
# TODO: move these out of `Kernel` into `Homebrew::GlobalMethods` and add
6+
# necessary Sorbet and global Kernel inclusions.
67

78
module Kernel
89
sig { params(env: T.nilable(String)).returns(T::Boolean) }
@@ -13,23 +14,25 @@ def superenv?(env)
1314
end
1415
private :superenv?
1516

17+
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T::Boolean) }
1618
def require?(path)
1719
return false if path.nil?
1820

1921
if defined?(Warnings)
2022
# Work around require warning when done repeatedly:
2123
# https://bugs.ruby-lang.org/issues/21091
2224
Warnings.ignore(/already initialized constant/, /previous definition of/) do
23-
require path
25+
require path.to_s
2426
end
2527
else
26-
require path
28+
require path.to_s
2729
end
2830
true
2931
rescue LoadError
3032
false
3133
end
3234

35+
sig { params(title: String).returns(String) }
3336
def ohai_title(title)
3437
verbose = if respond_to?(:verbose?)
3538
T.unsafe(self).verbose?
@@ -42,7 +45,7 @@ def ohai_title(title)
4245
end
4346

4447
def ohai(title, *sput)
45-
puts ohai_title(title)
48+
puts ohai_title(title.to_s)
4649
puts sput
4750
end
4851

@@ -55,10 +58,11 @@ def odebug(title, *sput, always_display: false)
5558

5659
return if !debug && !always_display
5760

58-
$stderr.puts Formatter.headline(title, color: :magenta)
61+
$stderr.puts Formatter.headline(title.to_s, color: :magenta)
5962
$stderr.puts sput unless sput.empty?
6063
end
6164

65+
sig { params(title: String, truncate: T.any(Symbol, T::Boolean)).returns(String) }
6266
def oh1_title(title, truncate: :auto)
6367
verbose = if respond_to?(:verbose?)
6468
T.unsafe(self).verbose?
@@ -70,6 +74,7 @@ def oh1_title(title, truncate: :auto)
7074
Formatter.headline(title, color: :green)
7175
end
7276

77+
sig { params(title: String, truncate: T.any(Symbol, T::Boolean)).void }
7378
def oh1(title, truncate: :auto)
7479
puts oh1_title(title, truncate:)
7580
end
@@ -134,6 +139,10 @@ def odie(error)
134139
end
135140

136141
# Output a deprecation warning/error message.
142+
sig {
143+
params(method: String, replacement: T.nilable(T.any(String, Symbol)), disable: T::Boolean,
144+
disable_on: T.nilable(Time), disable_for_developers: T::Boolean, caller: T::Array[String]).void
145+
}
137146
def odeprecated(method, replacement = nil,
138147
disable: false,
139148
disable_on: nil,
@@ -213,12 +222,20 @@ def odeprecated(method, replacement = nil,
213222
end
214223
end
215224

216-
def odisabled(method, replacement = nil, **options)
217-
options = { disable: true, caller: }.merge(options)
225+
sig {
226+
params(method: String, replacement: T.nilable(T.any(String, Symbol)), disable: T::Boolean,
227+
disable_on: T.nilable(Time), disable_for_developers: T::Boolean, caller: T::Array[String]).void
228+
}
229+
def odisabled(method, replacement = nil,
230+
disable: false,
231+
disable_on: nil,
232+
disable_for_developers: true,
233+
caller: send(:caller))
218234
# This odeprecated should stick around indefinitely.
219-
odeprecated(method, replacement, **options)
235+
odeprecated(method, replacement, disable:, disable_on:, disable_for_developers:, caller:)
220236
end
221237

238+
sig { params(formula: T.any(String, Formula)).returns(String) }
222239
def pretty_installed(formula)
223240
if !$stdout.tty?
224241
formula.to_s
@@ -229,6 +246,7 @@ def pretty_installed(formula)
229246
end
230247
end
231248

249+
sig { params(formula: T.any(String, Formula)).returns(String) }
232250
def pretty_outdated(formula)
233251
if !$stdout.tty?
234252
formula.to_s
@@ -239,6 +257,7 @@ def pretty_outdated(formula)
239257
end
240258
end
241259

260+
sig { params(formula: T.any(String, Formula)).returns(String) }
242261
def pretty_uninstalled(formula)
243262
if !$stdout.tty?
244263
formula.to_s
@@ -249,6 +268,7 @@ def pretty_uninstalled(formula)
249268
end
250269
end
251270

271+
sig { params(seconds: T.nilable(T.any(Integer, Float))).returns(String) }
252272
def pretty_duration(seconds)
253273
seconds = seconds.to_i
254274
res = +""
@@ -266,9 +286,10 @@ def pretty_duration(seconds)
266286
res.freeze
267287
end
268288

289+
sig { params(formula: T.nilable(Formula)).void }
269290
def interactive_shell(formula = nil)
270291
unless formula.nil?
271-
ENV["HOMEBREW_DEBUG_PREFIX"] = formula.prefix
292+
ENV["HOMEBREW_DEBUG_PREFIX"] = formula.prefix.to_s
272293
ENV["HOMEBREW_DEBUG_INSTALL"] = formula.full_name
273294
end
274295

@@ -295,6 +316,7 @@ def with_custom_locale(locale, &block)
295316

296317
# Kernel.system but with exceptions.
297318
def safe_system(cmd, *args, **options)
319+
# TODO: migrate to utils.rb Homebrew.safe_system
298320
require "utils"
299321

300322
return if Homebrew.system(cmd, *args, **options)
@@ -306,6 +328,7 @@ def safe_system(cmd, *args, **options)
306328
#
307329
# @api internal
308330
def quiet_system(cmd, *args)
331+
# TODO: migrate to utils.rb Homebrew.quiet_system
309332
require "utils"
310333

311334
Homebrew._system(cmd, *args) do
@@ -367,11 +390,13 @@ def which_editor(silent: false)
367390
editor
368391
end
369392

370-
def exec_editor(*args)
371-
puts "Editing #{args.join "\n"}"
372-
with_homebrew_path { safe_system(*which_editor.shellsplit, *args) }
393+
sig { params(filename: T.any(String, Pathname)).void }
394+
def exec_editor(filename)
395+
puts "Editing #{filename}"
396+
with_homebrew_path { safe_system(*which_editor.shellsplit, filename) }
373397
end
374398

399+
sig { params(args: T.any(String, Pathname)).void }
375400
def exec_browser(*args)
376401
browser = Homebrew::EnvConfig.browser
377402
browser ||= OS::PATH_OPEN if defined?(OS::PATH_OPEN)
@@ -384,7 +409,7 @@ def exec_browser(*args)
384409
end
385410
end
386411

387-
IGNORE_INTERRUPTS_MUTEX = Thread::Mutex.new.freeze
412+
IGNORE_INTERRUPTS_MUTEX = T.let(Thread::Mutex.new.freeze, Thread::Mutex)
388413

389414
def ignore_interrupts
390415
IGNORE_INTERRUPTS_MUTEX.synchronize do
@@ -417,6 +442,10 @@ def redirect_stdout(file)
417442

418443
# Ensure the given formula is installed
419444
# This is useful for installing a utility formula (e.g. `shellcheck` for `brew style`)
445+
sig {
446+
params(formula_or_name: T.any(String, Formula), reason: String, latest: T::Boolean, output_to_stderr: T::Boolean,
447+
quiet: T::Boolean).returns(Formula)
448+
}
420449
def ensure_formula_installed!(formula_or_name, reason: "", latest: false,
421450
output_to_stderr: true, quiet: false)
422451
if output_to_stderr || quiet
@@ -456,6 +485,7 @@ def ensure_formula_installed!(formula_or_name, reason: "", latest: false,
456485
end
457486

458487
# Ensure the given executable is exist otherwise install the brewed version
488+
sig { params(name: String, formula_name: T.nilable(String), reason: String, latest: T::Boolean).returns(T.nilable(Pathname)) }
459489
def ensure_executable!(name, formula_name = nil, reason: "", latest: false)
460490
formula_name ||= name
461491

@@ -472,10 +502,12 @@ def ensure_executable!(name, formula_name = nil, reason: "", latest: false)
472502
ensure_formula_installed!(formula_name, reason:, latest:).opt_bin/name
473503
end
474504

505+
sig { returns(T::Array[Pathname]) }
475506
def paths
476-
@paths ||= ORIGINAL_PATHS.uniq.map(&:to_s)
507+
@paths ||= T.let(ORIGINAL_PATHS.uniq.map(&:to_s), T.nilable(T::Array[Pathname]))
477508
end
478509

510+
sig { params(size_in_bytes: T.any(Integer, Float)).returns(String) }
479511
def disk_usage_readable(size_in_bytes)
480512
if size_in_bytes.abs >= 1_073_741_824
481513
size = size_in_bytes.to_f / 1_073_741_824
@@ -509,6 +541,7 @@ def number_readable(number)
509541
# preserving character encoding validity. The returned string will
510542
# be not much longer than the specified max_bytes, though the exact
511543
# shortfall or overrun may vary.
544+
sig { params(str: String, max_bytes: Integer, options: T::Hash[Symbol, T.untyped]).returns(String) }
512545
def truncate_text_to_approximate_size(str, max_bytes, options = {})
513546
front_weight = options.fetch(:front_weight, 0.5)
514547
raise "opts[:front_weight] must be between 0.0 and 1.0" if front_weight < 0.0 || front_weight > 1.0
@@ -530,7 +563,7 @@ def truncate_text_to_approximate_size(str, max_bytes, options = {})
530563
front = bytes[0..(n_front_bytes - 1)]
531564
back = bytes[-n_back_bytes..]
532565
end
533-
out = front + glue_bytes + back
566+
out = T.must(front) + glue_bytes + T.must(back)
534567
out.force_encoding("UTF-8")
535568
out.encode!("UTF-16", invalid: :replace)
536569
out.encode!("UTF-8")
@@ -568,6 +601,7 @@ def with_env(hash)
568601
end
569602
end
570603

604+
sig { returns(T.proc.params(a: String, b: String).returns(Integer)) }
571605
def tap_and_name_comparison
572606
proc do |a, b|
573607
if a.include?("/") && b.exclude?("/")
@@ -580,6 +614,7 @@ def tap_and_name_comparison
580614
end
581615
end
582616

617+
sig { params(input: String, secrets: T::Array[String]).returns(String) }
583618
def redact_secrets(input, secrets)
584619
secrets.compact
585620
.reduce(input) { |str, secret| str.gsub secret, "******" }

0 commit comments

Comments
 (0)