Enable Sorbet after running a developer command

We have no commands with Sorbet disabled and have had Sorbet enabled
for developers for a decent amount of time. As a result, we can enable
it for everyone who has run a developer command.

This also allows a bunch of `raise TypeError`s to be removed in favour
of relying on Sorbet here instead.
This commit is contained in:
Mike McQuaid 2023-09-01 19:37:32 +01:00
parent ec9bb2fe68
commit 8775465872
No known key found for this signature in database
GPG Key ID: 3338A31AFDB1D829
5 changed files with 29 additions and 85 deletions

View File

@ -912,27 +912,6 @@ then
export HOMEBREW_DEVELOPER_COMMAND="1" export HOMEBREW_DEVELOPER_COMMAND="1"
fi fi
if [[ -n "${HOMEBREW_DEVELOPER}" || -n "${HOMEBREW_DEVELOPER_COMMAND}" ]]
then
# Always run with Sorbet for Homebrew developers or Homebrew developer commands.
export HOMEBREW_SORBET_RUNTIME="1"
fi
# NO_SORBET_RUNTIME_COMMANDS are currently failing with Sorbet for homebrew/core.
# TODO: fix this and remove this if block.
if [[ -n "${HOMEBREW_SORBET_RUNTIME}" ]]
then
NO_SORBET_RUNTIME_COMMANDS=(
)
if check-array-membership "${HOMEBREW_COMMAND}" "${NO_SORBET_RUNTIME_COMMANDS[@]}"
then
unset HOMEBREW_SORBET_RUNTIME
fi
unset NO_SORBET_RUNTIME_COMMANDS
fi
# Provide a (temporary, undocumented) way to disable Sorbet globally if needed # Provide a (temporary, undocumented) way to disable Sorbet globally if needed
# to avoid reverting the above. # to avoid reverting the above.
if [[ -n "${HOMEBREW_NO_SORBET_RUNTIME}" ]] if [[ -n "${HOMEBREW_NO_SORBET_RUNTIME}" ]]
@ -957,6 +936,12 @@ EOS
export HOMEBREW_DEV_CMD_RUN="1" export HOMEBREW_DEV_CMD_RUN="1"
fi fi
if [[ -n "${HOMEBREW_DEVELOPER}" || -n "${HOMEBREW_DEV_CMD_RUN}" ]]
then
# Always run with Sorbet for Homebrew developers or when a Homebrew developer command has been run.
export HOMEBREW_SORBET_RUNTIME="1"
fi
if [[ -f "${HOMEBREW_LIBRARY}/Homebrew/cmd/${HOMEBREW_COMMAND}.sh" ]] if [[ -f "${HOMEBREW_LIBRARY}/Homebrew/cmd/${HOMEBREW_COMMAND}.sh" ]]
then then
HOMEBREW_BASH_COMMAND="${HOMEBREW_LIBRARY}/Homebrew/cmd/${HOMEBREW_COMMAND}.sh" HOMEBREW_BASH_COMMAND="${HOMEBREW_LIBRARY}/Homebrew/cmd/${HOMEBREW_COMMAND}.sh"

View File

@ -126,6 +126,10 @@ class DependencyCollector
sig { void } sig { void }
def init_global_dep_tree_if_needed!; end def init_global_dep_tree_if_needed!; end
sig {
params(spec: T.any(String, Resource, Symbol, Requirement, Dependency, Class),
tags: T::Array[Symbol]).returns(T.any(Dependency, Requirement, NilClass))
}
def parse_spec(spec, tags) def parse_spec(spec, tags)
raise ArgumentError, "Implicit dependencies cannot be manually specified" if tags.include?(:implicit) raise ArgumentError, "Implicit dependencies cannot be manually specified" if tags.include?(:implicit)
@ -140,8 +144,6 @@ class DependencyCollector
spec spec
when Class when Class
parse_class_spec(spec, tags) parse_class_spec(spec, tags)
else
raise TypeError, "Unsupported type #{spec.class.name} for #{spec.inspect}"
end end
end end

View File

@ -194,14 +194,11 @@ class Resource < Downloadable
def version(val = nil) def version(val = nil)
return super() if val.nil? return super() if val.nil?
@version = case T.unsafe(val) @version = case val
when String when String
val.blank? ? Version::NULL : Version.new(val) val.blank? ? Version::NULL : Version.new(val)
when Version when Version
val val
else
# TODO: This can probably go if/when typechecking is enforced in taps.
raise TypeError, "version '#{val.inspect}' should be a string"
end end
end end

View File

@ -80,75 +80,63 @@ module Homebrew
end end
command ||= on_system_conditional(macos: macos, linux: linux) command ||= on_system_conditional(macos: macos, linux: linux)
case T.unsafe(command) case command
when nil when nil
@run @run
when String, Pathname when String, Pathname
@run = [command] @run = [command]
when Array when Array
@run = command @run = command
else
raise TypeError, "Service#run expects an Array"
end end
end end
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) } sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) }
def working_dir(path = nil) def working_dir(path = nil)
case T.unsafe(path) case path
when nil when nil
@working_dir @working_dir
when String, Pathname when String, Pathname
@working_dir = path.to_s @working_dir = path.to_s
else
raise TypeError, "Service#working_dir expects a String"
end end
end end
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) } sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) }
def root_dir(path = nil) def root_dir(path = nil)
case T.unsafe(path) case path
when nil when nil
@root_dir @root_dir
when String, Pathname when String, Pathname
@root_dir = path.to_s @root_dir = path.to_s
else
raise TypeError, "Service#root_dir expects a String or Pathname"
end end
end end
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) } sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) }
def input_path(path = nil) def input_path(path = nil)
case T.unsafe(path) case path
when nil when nil
@input_path @input_path
when String, Pathname when String, Pathname
@input_path = path.to_s @input_path = path.to_s
else
raise TypeError, "Service#input_path expects a String or Pathname"
end end
end end
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) } sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) }
def log_path(path = nil) def log_path(path = nil)
case T.unsafe(path) case path
when nil when nil
@log_path @log_path
when String, Pathname when String, Pathname
@log_path = path.to_s @log_path = path.to_s
else
raise TypeError, "Service#log_path expects a String"
end end
end end
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) } sig { params(path: T.nilable(T.any(String, Pathname))).returns(T.nilable(String)) }
def error_log_path(path = nil) def error_log_path(path = nil)
case T.unsafe(path) case path
when nil when nil
@error_log_path @error_log_path
when String, Pathname when String, Pathname
@error_log_path = path.to_s @error_log_path = path.to_s
else
raise TypeError, "Service#error_log_path expects a String"
end end
end end
@ -157,7 +145,7 @@ module Homebrew
.returns(T.nilable(T::Hash[Symbol, T.untyped])) .returns(T.nilable(T::Hash[Symbol, T.untyped]))
} }
def keep_alive(value = nil) def keep_alive(value = nil)
case T.unsafe(value) case value
when nil when nil
@keep_alive @keep_alive
when true, false when true, false
@ -169,20 +157,16 @@ module Homebrew
end end
@keep_alive = value @keep_alive = value
else
raise TypeError, "Service#keep_alive expects a Boolean or Hash"
end end
end end
sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) } sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) }
def require_root(value = nil) def require_root(value = nil)
case T.unsafe(value) case value
when nil when nil
@require_root @require_root
when true, false when true, false
@require_root = value @require_root = value
else
raise TypeError, "Service#require_root expects a Boolean"
end end
end end
@ -195,19 +179,17 @@ module Homebrew
sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) } sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) }
def run_at_load(value = nil) def run_at_load(value = nil)
case T.unsafe(value) case value
when nil when nil
@run_at_load @run_at_load
when true, false when true, false
@run_at_load = value @run_at_load = value
else
raise TypeError, "Service#run_at_load expects a Boolean"
end end
end end
sig { params(value: T.nilable(String)).returns(T.nilable(T::Hash[Symbol, String])) } sig { params(value: T.nilable(String)).returns(T.nilable(T::Hash[Symbol, String])) }
def sockets(value = nil) def sockets(value = nil)
case T.unsafe(value) case value
when nil when nil
@sockets @sockets
when String when String
@ -216,8 +198,6 @@ module Homebrew
type, host, port = match.captures type, host, port = match.captures
@sockets = { host: host, port: port, type: type } @sockets = { host: host, port: port, type: type }
else
raise TypeError, "Service#sockets expects a String"
end end
end end
@ -230,31 +210,27 @@ module Homebrew
sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) } sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) }
def launch_only_once(value = nil) def launch_only_once(value = nil)
case T.unsafe(value) case value
when nil when nil
@launch_only_once @launch_only_once
when true, false when true, false
@launch_only_once = value @launch_only_once = value
else
raise TypeError, "Service#launch_only_once expects a Boolean"
end end
end end
sig { params(value: T.nilable(Integer)).returns(T.nilable(Integer)) } sig { params(value: T.nilable(Integer)).returns(T.nilable(Integer)) }
def restart_delay(value = nil) def restart_delay(value = nil)
case T.unsafe(value) case value
when nil when nil
@restart_delay @restart_delay
when Integer when Integer
@restart_delay = value @restart_delay = value
else
raise TypeError, "Service#restart_delay expects an Integer"
end end
end end
sig { params(value: T.nilable(Symbol)).returns(T.nilable(Symbol)) } sig { params(value: T.nilable(Symbol)).returns(T.nilable(Symbol)) }
def process_type(value = nil) def process_type(value = nil)
case T.unsafe(value) case value
when nil when nil
@process_type @process_type
when :background, :standard, :interactive, :adaptive when :background, :standard, :interactive, :adaptive
@ -263,46 +239,38 @@ module Homebrew
raise TypeError, "Service#process_type allows: " \ raise TypeError, "Service#process_type allows: " \
"'#{PROCESS_TYPE_BACKGROUND}'/'#{PROCESS_TYPE_STANDARD}'/" \ "'#{PROCESS_TYPE_BACKGROUND}'/'#{PROCESS_TYPE_STANDARD}'/" \
"'#{PROCESS_TYPE_INTERACTIVE}'/'#{PROCESS_TYPE_ADAPTIVE}'" "'#{PROCESS_TYPE_INTERACTIVE}'/'#{PROCESS_TYPE_ADAPTIVE}'"
else
raise TypeError, "Service#process_type expects a Symbol"
end end
end end
sig { params(value: T.nilable(Symbol)).returns(T.nilable(Symbol)) } sig { params(value: T.nilable(Symbol)).returns(T.nilable(Symbol)) }
def run_type(value = nil) def run_type(value = nil)
case T.unsafe(value) case value
when nil when nil
@run_type @run_type
when :immediate, :interval, :cron when :immediate, :interval, :cron
@run_type = value @run_type = value
when Symbol when Symbol
raise TypeError, "Service#run_type allows: '#{RUN_TYPE_IMMEDIATE}'/'#{RUN_TYPE_INTERVAL}'/'#{RUN_TYPE_CRON}'" raise TypeError, "Service#run_type allows: '#{RUN_TYPE_IMMEDIATE}'/'#{RUN_TYPE_INTERVAL}'/'#{RUN_TYPE_CRON}'"
else
raise TypeError, "Service#run_type expects a Symbol"
end end
end end
sig { params(value: T.nilable(Integer)).returns(T.nilable(Integer)) } sig { params(value: T.nilable(Integer)).returns(T.nilable(Integer)) }
def interval(value = nil) def interval(value = nil)
case T.unsafe(value) case value
when nil when nil
@interval @interval
when Integer when Integer
@interval = value @interval = value
else
raise TypeError, "Service#interval expects an Integer"
end end
end end
sig { params(value: T.nilable(String)).returns(T.nilable(Hash)) } sig { params(value: T.nilable(String)).returns(T.nilable(Hash)) }
def cron(value = nil) def cron(value = nil)
case T.unsafe(value) case value
when nil when nil
@cron @cron
when String when String
@cron = parse_cron(T.must(value)) @cron = parse_cron(T.must(value))
else
raise TypeError, "Service#cron expects a String"
end end
end end
@ -354,23 +322,19 @@ module Homebrew
sig { params(variables: T::Hash[Symbol, String]).returns(T.nilable(T::Hash[Symbol, String])) } sig { params(variables: T::Hash[Symbol, String]).returns(T.nilable(T::Hash[Symbol, String])) }
def environment_variables(variables = {}) def environment_variables(variables = {})
case T.unsafe(variables) case variables
when Hash when Hash
@environment_variables = variables.transform_values(&:to_s) @environment_variables = variables.transform_values(&:to_s)
else
raise TypeError, "Service#environment_variables expects a hash"
end end
end end
sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) } sig { params(value: T.nilable(T::Boolean)).returns(T.nilable(T::Boolean)) }
def macos_legacy_timers(value = nil) def macos_legacy_timers(value = nil)
case T.unsafe(value) case value
when nil when nil
@macos_legacy_timers @macos_legacy_timers
when true, false when true, false
@macos_legacy_timers = value @macos_legacy_timers = value
else
raise TypeError, "Service#macos_legacy_timers expects a Boolean"
end end
end end

View File

@ -24,8 +24,6 @@ class Version
sig { params(val: String).returns(Token) } sig { params(val: String).returns(Token) }
def self.create(val) def self.create(val)
raise TypeError, "Token value must be a string; got a #{val.class} (#{val})" unless val.respond_to?(:to_str)
case val case val
when /\A#{AlphaToken::PATTERN}\z/o then AlphaToken when /\A#{AlphaToken::PATTERN}\z/o then AlphaToken
when /\A#{BetaToken::PATTERN}\z/o then BetaToken when /\A#{BetaToken::PATTERN}\z/o then BetaToken
@ -492,8 +490,6 @@ class Version
sig { params(val: T.any(PkgVersion, String, Version), detected_from_url: T::Boolean).void } sig { params(val: T.any(PkgVersion, String, Version), detected_from_url: T::Boolean).void }
def initialize(val, detected_from_url: false) def initialize(val, detected_from_url: false)
raise TypeError, "Version value must be a string; got a #{val.class} (#{val})" unless val.respond_to?(:to_str)
version = val.to_str version = val.to_str
raise ArgumentError, "Version must not be empty" if version.blank? raise ArgumentError, "Version must not be empty" if version.blank?