diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index 7b09968858..f1ca45af7f 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -297,15 +297,9 @@ Sorbet/ConstantsFromStrings: Style/AccessModifierDeclarations: Enabled: false -# don't group nicely documented or private attr_readers +# Conflicts with type signatures on `attr_*`s. Style/AccessorGrouping: - Exclude: - - 'Homebrew/formula.rb' - - 'Homebrew/formulary.rb' - - 'Homebrew/migrator.rb' - - 'Homebrew/resource.rb' - - 'Homebrew/system_command.rb' - - 'Homebrew/tap.rb' + Enabled: false # make rspec formatting more flexible Style/BlockDelimiters: diff --git a/Library/Homebrew/bintray.rb b/Library/Homebrew/bintray.rb index ea50ed3479..7277cfdebc 100644 --- a/Library/Homebrew/bintray.rb +++ b/Library/Homebrew/bintray.rb @@ -8,6 +8,8 @@ require "json" # # @api private class Bintray + extend T::Sig + include Context API_URL = "https://api.bintray.com" @@ -15,6 +17,7 @@ class Bintray class Error < RuntimeError end + sig { returns(String) } def inspect "#" end diff --git a/Library/Homebrew/cask/artifact/abstract_artifact.rb b/Library/Homebrew/cask/artifact/abstract_artifact.rb index 50c2b325e5..9d6e5d1381 100644 --- a/Library/Homebrew/cask/artifact/abstract_artifact.rb +++ b/Library/Homebrew/cask/artifact/abstract_artifact.rb @@ -7,6 +7,8 @@ module Cask # # @api private class AbstractArtifact + extend T::Sig + include Comparable extend Predicable @@ -132,6 +134,7 @@ module Cask cask.config end + sig { returns(String) } def to_s "#{summarize} (#{self.class.english_name})" end diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index baa8467a37..51505e70c9 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -15,6 +15,8 @@ module Cask # # @api private class AbstractUninstall < AbstractArtifact + extend T::Sig + ORDERED_DIRECTIVES = [ :early_script, :launchctl, @@ -53,6 +55,7 @@ module Cask directives.to_h end + sig { returns(String) } def summarize to_h.flat_map { |key, val| Array(val).map { |v| "#{key.inspect} => #{v.inspect}" } }.join(", ") end @@ -128,6 +131,7 @@ module Cask end end + sig { returns(String) } def automation_access_instructions "Enable Automation Access for “Terminal > System Events” in " \ "“System Preferences > Security > Privacy > Automation” if you haven't already." diff --git a/Library/Homebrew/cask/artifact/artifact.rb b/Library/Homebrew/cask/artifact/artifact.rb index f6b350a82d..8d083a1bd5 100644 --- a/Library/Homebrew/cask/artifact/artifact.rb +++ b/Library/Homebrew/cask/artifact/artifact.rb @@ -12,6 +12,9 @@ module Cask # # @api private class Artifact < Moved + extend T::Sig + + sig { returns(String) } def self.english_name "Generic Artifact" end diff --git a/Library/Homebrew/cask/artifact/mdimporter.rb b/Library/Homebrew/cask/artifact/mdimporter.rb index 226a01e1cc..5a4ce2d052 100644 --- a/Library/Homebrew/cask/artifact/mdimporter.rb +++ b/Library/Homebrew/cask/artifact/mdimporter.rb @@ -9,6 +9,9 @@ module Cask # # @api private class Mdimporter < Moved + extend T::Sig + + sig { returns(String) } def self.english_name "Spotlight metadata importer" end diff --git a/Library/Homebrew/cask/artifact/moved.rb b/Library/Homebrew/cask/artifact/moved.rb index 6acb7d7827..bd9287ad29 100644 --- a/Library/Homebrew/cask/artifact/moved.rb +++ b/Library/Homebrew/cask/artifact/moved.rb @@ -9,6 +9,9 @@ module Cask # # @api private class Moved < Relocated + extend T::Sig + + sig { returns(String) } def self.english_description "#{english_name}s" end diff --git a/Library/Homebrew/cask/artifact/prefpane.rb b/Library/Homebrew/cask/artifact/prefpane.rb index aed47644e1..8dc2df4559 100644 --- a/Library/Homebrew/cask/artifact/prefpane.rb +++ b/Library/Homebrew/cask/artifact/prefpane.rb @@ -9,6 +9,9 @@ module Cask # # @api private class Prefpane < Moved + extend T::Sig + + sig { returns(String) } def self.english_name "Preference Pane" end diff --git a/Library/Homebrew/cask/artifact/qlplugin.rb b/Library/Homebrew/cask/artifact/qlplugin.rb index e0c26a6dc8..d50956d8ca 100644 --- a/Library/Homebrew/cask/artifact/qlplugin.rb +++ b/Library/Homebrew/cask/artifact/qlplugin.rb @@ -9,6 +9,9 @@ module Cask # # @api private class Qlplugin < Moved + extend T::Sig + + sig { returns(String) } def self.english_name "QuickLook Plugin" end diff --git a/Library/Homebrew/cask/artifact/relocated.rb b/Library/Homebrew/cask/artifact/relocated.rb index 5c9dd0dbd5..f5e61e9677 100644 --- a/Library/Homebrew/cask/artifact/relocated.rb +++ b/Library/Homebrew/cask/artifact/relocated.rb @@ -12,6 +12,8 @@ module Cask # # @api private class Relocated < AbstractArtifact + extend T::Sig + def self.from_args(cask, *args) source_string, target_hash = args @@ -49,6 +51,7 @@ module Cask end end + sig { returns(String) } def summarize target_string = @target_string.empty? ? "" : " -> #{@target_string}" "#{@source_string}#{target_string}" diff --git a/Library/Homebrew/cask/artifact/stage_only.rb b/Library/Homebrew/cask/artifact/stage_only.rb index c67cac6d3b..b475b00a86 100644 --- a/Library/Homebrew/cask/artifact/stage_only.rb +++ b/Library/Homebrew/cask/artifact/stage_only.rb @@ -9,16 +9,20 @@ module Cask # # @api private class StageOnly < AbstractArtifact + extend T::Sig + def self.from_args(cask, *args) raise CaskInvalidError.new(cask.token, "'stage_only' takes only a single argument: true") if args != [true] new(cask) end + sig { returns(T::Array[T::Boolean]) } def to_a [true] end + sig { returns(String) } def summarize "true" end diff --git a/Library/Homebrew/cask/artifact/suite.rb b/Library/Homebrew/cask/artifact/suite.rb index a236a602e0..043b4f0b9e 100644 --- a/Library/Homebrew/cask/artifact/suite.rb +++ b/Library/Homebrew/cask/artifact/suite.rb @@ -9,10 +9,14 @@ module Cask # # @api private class Suite < Moved + extend T::Sig + + sig { returns(String) } def self.english_name "App Suite" end + sig { returns(Symbol) } def self.dirmethod :appdir end diff --git a/Library/Homebrew/cask/artifact/symlinked.rb b/Library/Homebrew/cask/artifact/symlinked.rb index 68e8dbe181..bb423e69d4 100644 --- a/Library/Homebrew/cask/artifact/symlinked.rb +++ b/Library/Homebrew/cask/artifact/symlinked.rb @@ -9,10 +9,14 @@ module Cask # # @api private class Symlinked < Relocated + extend T::Sig + + sig { returns(String) } def self.link_type_english_name "Symlink" end + sig { returns(String) } def self.english_description "#{english_name} #{link_type_english_name}s" end diff --git a/Library/Homebrew/cask/audit.rb b/Library/Homebrew/cask/audit.rb index 7e2297becc..a9603a50e8 100644 --- a/Library/Homebrew/cask/audit.rb +++ b/Library/Homebrew/cask/audit.rb @@ -13,6 +13,8 @@ module Cask # # @api private class Audit + extend T::Sig + extend Predicable attr_reader :cask, :download @@ -117,6 +119,7 @@ module Cask end end + sig { returns(String) } def summary summary = ["audit for #{cask}: #{result}"] @@ -416,6 +419,7 @@ module Cask core_tap.formula_names end + sig { returns(String) } def core_formula_url "#{core_tap.default_remote}/blob/HEAD/Formula/#{cask.token}.rb" end diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index 8858922a0b..92f28cb702 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -12,6 +12,8 @@ module Cask # # @api private class Cask + extend T::Sig + extend Enumerable extend Forwardable extend Searchable @@ -64,6 +66,7 @@ module Cask define_method(method_name) { |&block| @dsl.send(method_name, &block) } end + sig { returns(T::Array[[String, String]]) } def timestamped_versions Pathname.glob(metadata_timestamped_path(version: "*", timestamp: "*")) .map { |p| p.relative_path_from(p.parent.parent) } @@ -89,6 +92,7 @@ module Cask !versions.empty? end + sig { returns(T.nilable(Time)) } def install_time _, time = timestamped_versions.last return unless time diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 8ec015a931..b49ad9275e 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -90,6 +90,8 @@ module Cask # Loads a cask from a URI. class FromURILoader < FromPathLoader + extend T::Sig + def self.can_load?(ref) uri_regex = ::URI::DEFAULT_PARSER.make_regexp return false unless ref.to_s.match?(Regexp.new("\\A#{uri_regex.source}\\Z", uri_regex.options)) @@ -103,6 +105,7 @@ module Cask attr_reader :url + sig { params(url: T.any(URI::Generic, String)).void } def initialize(url) @url = URI(url) super Cache.path/File.basename(@url.path) @@ -177,10 +180,13 @@ module Cask # Pseudo-loader which raises an error when trying to load the corresponding cask. class NullLoader < FromPathLoader + extend T::Sig + def self.can_load?(*) true end + sig { params(ref: T.any(String, Pathname)).void } def initialize(ref) token = File.basename(ref, ".rb") super CaskLoader.default_path(token) diff --git a/Library/Homebrew/cask/cmd.rb b/Library/Homebrew/cask/cmd.rb index 5c62cb73ea..c5dc653c5f 100644 --- a/Library/Homebrew/cask/cmd.rb +++ b/Library/Homebrew/cask/cmd.rb @@ -38,6 +38,8 @@ module Cask # # @api private class Cmd + extend T::Sig + include Context ALIASES = { @@ -61,6 +63,7 @@ module Cask Cmd::Upgrade => "brew upgrade --cask", }.freeze + sig { returns(String) } def self.description max_command_length = Cmd.commands.map(&:length).max diff --git a/Library/Homebrew/cask/cmd/--cache.rb b/Library/Homebrew/cask/cmd/--cache.rb index 613841f7c3..8a85ba5a85 100644 --- a/Library/Homebrew/cask/cmd/--cache.rb +++ b/Library/Homebrew/cask/cmd/--cache.rb @@ -7,18 +7,24 @@ module Cask # # @api private class Cache < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { returns(String) } def self.description "Display the file used to cache a ." end + sig { returns(String) } def self.command_name "--cache" end + sig { void } def run casks.each do |cask| puts self.class.cached_location(cask) diff --git a/Library/Homebrew/cask/cmd/abstract_command.rb b/Library/Homebrew/cask/cmd/abstract_command.rb index cf4ca79a0d..acea33ce58 100644 --- a/Library/Homebrew/cask/cmd/abstract_command.rb +++ b/Library/Homebrew/cask/cmd/abstract_command.rb @@ -9,16 +9,22 @@ module Cask # # @api private class AbstractCommand + extend T::Sig + extend T::Helpers + include Homebrew::Search + sig { returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named nil end + sig { returns(T.nilable(Integer)) } def self.max_named nil end + sig { returns(String) } def self.banner_args if min_named == :cask && max_named != 1 " " @@ -29,6 +35,7 @@ module Cask end end + sig { returns(String) } def self.banner_headline "`#{command_name}` []#{banner_args}" end @@ -72,24 +79,29 @@ module Cask end end + sig { returns(String) } def self.command_name @command_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase end + sig { returns(T::Boolean) } def self.abstract? name.split("::").last.match?(/^Abstract[^a-z]/) end + sig { returns(T::Boolean) } def self.visible? true end + sig { returns(String) } def self.help parser.generate_help_text end + sig { returns(String) } def self.short_description - description.split(".").first + description[/\A[^.]*\./] end def self.run(*args) diff --git a/Library/Homebrew/cask/cmd/abstract_internal_command.rb b/Library/Homebrew/cask/cmd/abstract_internal_command.rb index 7ccc3937b7..a0a45e8b1b 100644 --- a/Library/Homebrew/cask/cmd/abstract_internal_command.rb +++ b/Library/Homebrew/cask/cmd/abstract_internal_command.rb @@ -7,10 +7,14 @@ module Cask # # @api private class AbstractInternalCommand < AbstractCommand + extend T::Sig + + sig { returns(String) } def self.command_name super.sub(/^internal_/i, "_") end + sig { returns(T::Boolean) } def self.visible? false end diff --git a/Library/Homebrew/cask/cmd/audit.rb b/Library/Homebrew/cask/cmd/audit.rb index 6deeb84f8e..dcfd98741c 100644 --- a/Library/Homebrew/cask/cmd/audit.rb +++ b/Library/Homebrew/cask/cmd/audit.rb @@ -9,6 +9,9 @@ module Cask # # @api private class Audit < AbstractCommand + extend T::Sig + + sig { returns(String) } def self.description <<~EOS Check for Homebrew coding style violations. This should be run before @@ -37,6 +40,7 @@ module Cask end end + sig { void } def run require "cask/auditor" diff --git a/Library/Homebrew/cask/cmd/cat.rb b/Library/Homebrew/cask/cmd/cat.rb index fb79443000..d5d2afdc6a 100644 --- a/Library/Homebrew/cask/cmd/cat.rb +++ b/Library/Homebrew/cask/cmd/cat.rb @@ -7,14 +7,19 @@ module Cask # # @api private class Cat < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { returns(String) } def self.description "Dump raw source of a to the standard output." end + sig { void } def run casks.each do |cask| if Homebrew::EnvConfig.bat? diff --git a/Library/Homebrew/cask/cmd/create.rb b/Library/Homebrew/cask/cmd/create.rb index 7ae14dc7d5..c03b1611ff 100644 --- a/Library/Homebrew/cask/cmd/create.rb +++ b/Library/Homebrew/cask/cmd/create.rb @@ -7,14 +7,19 @@ module Cask # # @api private class Create < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { override.returns(T.nilable(Integer)) } def self.max_named 1 end + sig { returns(String) } def self.description "Creates the given and opens it in an editor." end @@ -25,6 +30,7 @@ module Cask raise UsageError, "Only one cask can be created at a time." end + sig { void } def run cask_token = args.named.first cask_path = CaskLoader.path(cask_token) diff --git a/Library/Homebrew/cask/cmd/doctor.rb b/Library/Homebrew/cask/cmd/doctor.rb index 0c80dcef21..c2565191ad 100644 --- a/Library/Homebrew/cask/cmd/doctor.rb +++ b/Library/Homebrew/cask/cmd/doctor.rb @@ -7,14 +7,19 @@ module Cask # # @api private class Doctor < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(Integer)) } def self.max_named 0 end + sig { returns(String) } def self.description "Checks for configuration issues." end + sig { void } def run require "diagnostic" diff --git a/Library/Homebrew/cask/cmd/edit.rb b/Library/Homebrew/cask/cmd/edit.rb index bea10bf630..ca01e711c3 100644 --- a/Library/Homebrew/cask/cmd/edit.rb +++ b/Library/Homebrew/cask/cmd/edit.rb @@ -7,14 +7,19 @@ module Cask # # @api private class Edit < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { override.returns(T.nilable(Integer)) } def self.max_named 1 end + sig { returns(String) } def self.description "Open the given for editing." end @@ -25,6 +30,7 @@ module Cask raise UsageError, "Only one cask can be edited at a time." end + sig { void } def run exec_editor cask_path rescue CaskUnavailableError => e diff --git a/Library/Homebrew/cask/cmd/fetch.rb b/Library/Homebrew/cask/cmd/fetch.rb index d9b3351832..7add6ae1dc 100644 --- a/Library/Homebrew/cask/cmd/fetch.rb +++ b/Library/Homebrew/cask/cmd/fetch.rb @@ -7,6 +7,9 @@ module Cask # # @api private class Fetch < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end @@ -18,10 +21,12 @@ module Cask end end + sig { returns(String) } def self.description "Downloads remote application files to local cache." end + sig { void } def run require "cask/download" require "cask/installer" diff --git a/Library/Homebrew/cask/cmd/help.rb b/Library/Homebrew/cask/cmd/help.rb index 721ac40842..7a3a2cba4d 100644 --- a/Library/Homebrew/cask/cmd/help.rb +++ b/Library/Homebrew/cask/cmd/help.rb @@ -7,14 +7,19 @@ module Cask # # @api private class Help < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(Integer)) } def self.max_named 1 end + sig { returns(String) } def self.description "Print help for `cask` commands." end + sig { void } def run if args.named.empty? puts Cmd.parser.generate_help_text diff --git a/Library/Homebrew/cask/cmd/home.rb b/Library/Homebrew/cask/cmd/home.rb index 8087f21faa..6beaf0ac2c 100644 --- a/Library/Homebrew/cask/cmd/home.rb +++ b/Library/Homebrew/cask/cmd/home.rb @@ -7,10 +7,14 @@ module Cask # # @api private class Home < AbstractCommand + extend T::Sig + + sig { returns(String) } def self.description "Opens the homepage of the given . If no cask is given, opens the Homebrew homepage." end + sig { void } def run if casks.none? odebug "Opening project homepage" diff --git a/Library/Homebrew/cask/cmd/info.rb b/Library/Homebrew/cask/cmd/info.rb index e4e0797f72..1ffebfa177 100644 --- a/Library/Homebrew/cask/cmd/info.rb +++ b/Library/Homebrew/cask/cmd/info.rb @@ -9,10 +9,14 @@ module Cask # # @api private class Info < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { returns(String) } def self.description "Displays information about the given ." end @@ -42,6 +46,7 @@ module Cask end end + sig { void } def run if args.json == "v1" puts JSON.generate(args.named.to_casks.map(&:to_h)) diff --git a/Library/Homebrew/cask/cmd/install.rb b/Library/Homebrew/cask/cmd/install.rb index a5ad63d19c..6dceac2767 100644 --- a/Library/Homebrew/cask/cmd/install.rb +++ b/Library/Homebrew/cask/cmd/install.rb @@ -7,10 +7,14 @@ module Cask # # @api private class Install < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { returns(String) } def self.description "Installs the given ." end @@ -34,6 +38,7 @@ module Cask end end + sig { void } def run self.class.install_casks( *casks, diff --git a/Library/Homebrew/cask/cmd/internal_help.rb b/Library/Homebrew/cask/cmd/internal_help.rb index 2091f48f95..3f6476e29a 100644 --- a/Library/Homebrew/cask/cmd/internal_help.rb +++ b/Library/Homebrew/cask/cmd/internal_help.rb @@ -7,14 +7,19 @@ module Cask # # @api private class InternalHelp < AbstractInternalCommand + extend T::Sig + + sig { override.returns(T.nilable(Integer)) } def self.max_named 0 end + sig { returns(String) } def self.description "Print help for unstable internal-use commands." end + sig { void } def run max_command_len = Cmd.commands.map(&:length).max puts "Unstable Internal-use Commands:\n\n" diff --git a/Library/Homebrew/cask/cmd/internal_stanza.rb b/Library/Homebrew/cask/cmd/internal_stanza.rb index 95335690e1..3183588b82 100644 --- a/Library/Homebrew/cask/cmd/internal_stanza.rb +++ b/Library/Homebrew/cask/cmd/internal_stanza.rb @@ -9,6 +9,8 @@ module Cask # # @api private class InternalStanza < AbstractInternalCommand + extend T::Sig + # Syntax # # brew cask _stanza [ --quiet ] [ --table | --yaml ] [ ... ] @@ -24,14 +26,17 @@ module Cask (DSL::ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key) + DSL::ARTIFACT_BLOCK_CLASSES.map(&:dsl_key)).freeze + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named 1 end + sig { returns(String) } def self.banner_args " []" end + sig { returns(String) } def self.description <<~EOS Extract and render a specific stanza for the given . @@ -80,6 +85,7 @@ module Cask EOS end + sig { void } def run if ARTIFACTS.include?(stanza) artifact_name = stanza diff --git a/Library/Homebrew/cask/cmd/list.rb b/Library/Homebrew/cask/cmd/list.rb index 859d650a9c..7c780c2464 100644 --- a/Library/Homebrew/cask/cmd/list.rb +++ b/Library/Homebrew/cask/cmd/list.rb @@ -9,6 +9,9 @@ module Cask # # @api private class List < AbstractCommand + extend T::Sig + + sig { returns(String) } def self.description "Lists installed casks or the casks provided in the arguments." end @@ -26,6 +29,7 @@ module Cask end end + sig { void } def run self.class.list_casks( *casks, diff --git a/Library/Homebrew/cask/cmd/outdated.rb b/Library/Homebrew/cask/cmd/outdated.rb index ff35a1f2d6..791f465333 100644 --- a/Library/Homebrew/cask/cmd/outdated.rb +++ b/Library/Homebrew/cask/cmd/outdated.rb @@ -7,6 +7,9 @@ module Cask # # @api private class Outdated < AbstractCommand + extend T::Sig + + sig { returns(String) } def self.description "List the outdated installed casks." end @@ -20,6 +23,7 @@ module Cask end end + sig { void } def run outdated_casks = casks(alternative: -> { Caskroom.casks(config: Config.from_args(args)) }).select do |cask| odebug "Checking update info of Cask #{cask}" diff --git a/Library/Homebrew/cask/cmd/reinstall.rb b/Library/Homebrew/cask/cmd/reinstall.rb index 79e0dccc44..5d0af86177 100644 --- a/Library/Homebrew/cask/cmd/reinstall.rb +++ b/Library/Homebrew/cask/cmd/reinstall.rb @@ -7,10 +7,14 @@ module Cask # # @api private class Reinstall < Install + extend T::Sig + + sig { returns(String) } def self.description "Reinstalls the given ." end + sig { void } def run self.class.reinstall_casks( *casks, diff --git a/Library/Homebrew/cask/cmd/style.rb b/Library/Homebrew/cask/cmd/style.rb index 1d07156306..f0f1c34995 100644 --- a/Library/Homebrew/cask/cmd/style.rb +++ b/Library/Homebrew/cask/cmd/style.rb @@ -10,6 +10,9 @@ module Cask # # @api private class Style < AbstractCommand + extend T::Sig + + sig { returns(String) } def self.description "Checks style of the given using RuboCop." end @@ -21,6 +24,7 @@ module Cask end end + sig { void } def run success = Homebrew::Style.check_style_and_print( cask_paths, diff --git a/Library/Homebrew/cask/cmd/uninstall.rb b/Library/Homebrew/cask/cmd/uninstall.rb index 8011193348..4fd6ac8980 100644 --- a/Library/Homebrew/cask/cmd/uninstall.rb +++ b/Library/Homebrew/cask/cmd/uninstall.rb @@ -7,10 +7,14 @@ module Cask # # @api private class Uninstall < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { returns(String) } def self.description "Uninstalls the given ." end @@ -23,6 +27,7 @@ module Cask end end + sig { void } def run self.class.uninstall_casks( *casks, diff --git a/Library/Homebrew/cask/cmd/upgrade.rb b/Library/Homebrew/cask/cmd/upgrade.rb index 56bcbd529c..8199486527 100644 --- a/Library/Homebrew/cask/cmd/upgrade.rb +++ b/Library/Homebrew/cask/cmd/upgrade.rb @@ -10,6 +10,9 @@ module Cask # # @api private class Upgrade < AbstractCommand + extend T::Sig + + sig { returns(String) } def self.description "Upgrades all outdated casks or the specified casks." end @@ -36,6 +39,7 @@ module Cask end end + sig { void } def run verbose = ($stdout.tty? || args.verbose?) && !args.quiet? self.class.upgrade_casks( diff --git a/Library/Homebrew/cask/cmd/zap.rb b/Library/Homebrew/cask/cmd/zap.rb index 2898883ef6..d5b5dc3c80 100644 --- a/Library/Homebrew/cask/cmd/zap.rb +++ b/Library/Homebrew/cask/cmd/zap.rb @@ -7,10 +7,14 @@ module Cask # # @api private class Zap < AbstractCommand + extend T::Sig + + sig { override.returns(T.nilable(T.any(Integer, Symbol))) } def self.min_named :cask end + sig { returns(String) } def self.description <<~EOS Zaps all files associated with the given . Implicitly also performs all actions associated with `uninstall`. @@ -26,6 +30,7 @@ module Cask end end + sig { void } def run require "cask/installer" diff --git a/Library/Homebrew/cask/denylist.rb b/Library/Homebrew/cask/denylist.rb index 8cbc9c37a2..c6fd811c7d 100644 --- a/Library/Homebrew/cask/denylist.rb +++ b/Library/Homebrew/cask/denylist.rb @@ -1,4 +1,4 @@ -# typed: true +# typed: strict # frozen_string_literal: true module Cask @@ -6,6 +6,9 @@ module Cask # # @api private module Denylist + extend T::Sig + + sig { params(name: String).returns(T.nilable(String)) } def self.reason(name) case name when /^adobe-(after|illustrator|indesign|photoshop|premiere)/ diff --git a/Library/Homebrew/cask/dsl/version.rb b/Library/Homebrew/cask/dsl/version.rb index a43658b182..e2574db729 100644 --- a/Library/Homebrew/cask/dsl/version.rb +++ b/Library/Homebrew/cask/dsl/version.rb @@ -7,6 +7,8 @@ module Cask # # @api private class Version < ::String + extend T::Sig + DIVIDERS = { "." => :dots, "-" => :hyphens, @@ -62,6 +64,7 @@ module Cask attr_reader :raw_version + sig { params(raw_version: T.nilable(T.any(String, Symbol))).void } def initialize(raw_version) @raw_version = raw_version super(raw_version.to_s) @@ -73,6 +76,7 @@ module Cask raw_version.scan(INVALID_CHARACTERS) end + sig { returns(T::Boolean) } def unstable? return false if latest? @@ -84,6 +88,7 @@ module Cask false end + sig { returns(T::Boolean) } def latest? to_s == "latest" end @@ -134,6 +139,7 @@ module Cask private + sig { returns(T.self_type) } def version return self if empty? || latest? diff --git a/Library/Homebrew/cask/exceptions.rb b/Library/Homebrew/cask/exceptions.rb index 645ea8a0e4..b5576e9dee 100644 --- a/Library/Homebrew/cask/exceptions.rb +++ b/Library/Homebrew/cask/exceptions.rb @@ -11,12 +11,15 @@ module Cask # # @api private class MultipleCaskErrors < CaskError + extend T::Sig + def initialize(errors) super() @errors = errors end + sig { returns(String) } def to_s <<~EOS Problems with multiple casks: @@ -29,12 +32,18 @@ module Cask # # @api private class AbstractCaskErrorWithToken < CaskError - attr_reader :token, :reason + extend T::Sig + + sig { returns(String) } + attr_reader :token + + sig { returns(String) } + attr_reader :reason def initialize(token, reason = nil) super() - @token = token + @token = token.to_s @reason = reason.to_s end end @@ -43,6 +52,9 @@ module Cask # # @api private class CaskNotInstalledError < AbstractCaskErrorWithToken + extend T::Sig + + sig { returns(String) } def to_s "Cask '#{token}' is not installed." end @@ -52,6 +64,8 @@ module Cask # # @api private class CaskConflictError < AbstractCaskErrorWithToken + extend T::Sig + attr_reader :conflicting_cask def initialize(token, conflicting_cask) @@ -59,6 +73,7 @@ module Cask @conflicting_cask = conflicting_cask end + sig { returns(String) } def to_s "Cask '#{token}' conflicts with '#{conflicting_cask}'." end @@ -68,6 +83,9 @@ module Cask # # @api private class CaskUnavailableError < AbstractCaskErrorWithToken + extend T::Sig + + sig { returns(String) } def to_s "Cask '#{token}' is unavailable#{reason.empty? ? "." : ": #{reason}"}" end @@ -77,6 +95,9 @@ module Cask # # @api private class CaskUnreadableError < CaskUnavailableError + extend T::Sig + + sig { returns(String) } def to_s "Cask '#{token}' is unreadable#{reason.empty? ? "." : ": #{reason}"}" end @@ -86,6 +107,9 @@ module Cask # # @api private class CaskAlreadyCreatedError < AbstractCaskErrorWithToken + extend T::Sig + + sig { returns(String) } def to_s %Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew cask edit #{token}")} to edit it.) end @@ -95,6 +119,9 @@ module Cask # # @api private class CaskAlreadyInstalledError < AbstractCaskErrorWithToken + extend T::Sig + + sig { returns(String) } def to_s <<~EOS Cask '#{token}' is already installed. @@ -109,6 +136,9 @@ module Cask # # @api private class CaskX11DependencyError < AbstractCaskErrorWithToken + extend T::Sig + + sig { returns(String) } def to_s <<~EOS Cask '#{token}' requires XQuartz/X11, which can be installed using Homebrew Cask by running: @@ -124,6 +154,9 @@ module Cask # # @api private class CaskCyclicDependencyError < AbstractCaskErrorWithToken + extend T::Sig + + sig { returns(String) } def to_s "Cask '#{token}' includes cyclic dependencies on other Casks#{reason.empty? ? "." : ": #{reason}"}" end @@ -133,6 +166,9 @@ module Cask # # @api private class CaskSelfReferencingDependencyError < CaskCyclicDependencyError + extend T::Sig + + sig { returns(String) } def to_s "Cask '#{token}' depends on itself." end @@ -142,6 +178,9 @@ module Cask # # @api private class CaskUnspecifiedError < CaskError + extend T::Sig + + sig { returns(String) } def to_s "This command requires a Cask token." end @@ -151,6 +190,9 @@ module Cask # # @api private class CaskInvalidError < AbstractCaskErrorWithToken + extend T::Sig + + sig { returns(String) } def to_s "Cask '#{token}' definition is invalid#{reason.empty? ? "." : ": #{reason}"}" end @@ -182,6 +224,9 @@ module Cask # # @api private class CaskSha256MissingError < CaskSha256Error + extend T::Sig + + sig { returns(String) } def to_s <<~EOS Cask '#{token}' requires a checksum: @@ -194,6 +239,8 @@ module Cask # # @api private class CaskSha256MismatchError < CaskSha256Error + extend T::Sig + attr_reader :path def initialize(token, expected, actual, path) @@ -201,6 +248,7 @@ module Cask @path = path end + sig { returns(String) } def to_s <<~EOS Checksum for Cask '#{token}' does not match. @@ -218,6 +266,9 @@ module Cask # # @api private class CaskNoShasumError < CaskSha256Error + extend T::Sig + + sig { returns(String) } def to_s <<~EOS Cask '#{token}' does not have a sha256 checksum defined and was not installed. @@ -230,6 +281,8 @@ module Cask # # @api private class CaskQuarantineError < CaskError + extend T::Sig + attr_reader :path, :reason def initialize(path, reason) @@ -239,6 +292,7 @@ module Cask @reason = reason end + sig { returns(String) } def to_s s = +"Failed to quarantine #{path}." @@ -256,6 +310,9 @@ module Cask # # @api private class CaskQuarantinePropagationError < CaskQuarantineError + extend T::Sig + + sig { returns(String) } def to_s s = +"Failed to quarantine one or more files within #{path}." @@ -273,6 +330,9 @@ module Cask # # @api private class CaskQuarantineReleaseError < CaskQuarantineError + extend T::Sig + + sig { returns(String) } def to_s s = +"Failed to release #{path} from quarantine." diff --git a/Library/Homebrew/cask/installer.rb b/Library/Homebrew/cask/installer.rb index f0310a1197..481307d800 100644 --- a/Library/Homebrew/cask/installer.rb +++ b/Library/Homebrew/cask/installer.rb @@ -18,6 +18,8 @@ module Cask # # @api private class Installer + extend T::Sig + extend Predicable # TODO: it is unwise for Cask::Staged to be a module, when we are # dealing with both staged and unstaged casks here. This should @@ -142,6 +144,7 @@ module Cask Installer.new(installed_cask, binaries: binaries?, verbose: verbose?, force: true, upgrade: upgrade?).uninstall end + sig { returns(String) } def summary s = +"" s << "#{Homebrew::EnvConfig.install_badge} " unless Homebrew::EnvConfig.no_emoji? diff --git a/Library/Homebrew/cask/quarantine.rb b/Library/Homebrew/cask/quarantine.rb index 14e74c7af0..de24b35d33 100644 --- a/Library/Homebrew/cask/quarantine.rb +++ b/Library/Homebrew/cask/quarantine.rb @@ -9,6 +9,8 @@ module Cask # # @api private module Quarantine + extend T::Sig + module_function QUARANTINE_ATTRIBUTE = "com.apple.quarantine" @@ -25,6 +27,7 @@ module Cask end private :xattr + sig { returns(Symbol) } def check_quarantine_support odebug "Checking quarantine support" diff --git a/Library/Homebrew/cask/utils.rb b/Library/Homebrew/cask/utils.rb index 47f804df23..c9e831aebe 100644 --- a/Library/Homebrew/cask/utils.rb +++ b/Library/Homebrew/cask/utils.rb @@ -13,6 +13,8 @@ module Cask # # @api private module Utils + extend T::Sig + def self.gain_permissions_remove(path, command: SystemCommand) if path.respond_to?(:rmtree) && path.exist? gain_permissions(path, ["-R"], command) do |p| @@ -72,10 +74,12 @@ module Cask end end + sig { params(path: Pathname).returns(T::Boolean) } def self.path_occupied?(path) - File.exist?(path) || File.symlink?(path) + path.exist? || path.symlink? end + sig { returns(String) } def self.error_message_with_suggestions <<~EOS Follow the instructions here: diff --git a/Library/Homebrew/cli/args.rb b/Library/Homebrew/cli/args.rb index 1a779dcbdf..d8f69c6077 100644 --- a/Library/Homebrew/cli/args.rb +++ b/Library/Homebrew/cli/args.rb @@ -7,11 +7,14 @@ require "ostruct" module Homebrew module CLI class Args < OpenStruct + extend T::Sig + attr_reader :options_only, :flags_only # undefine tap to allow --tap argument undef tap + sig { void } def initialize super() @@ -131,6 +134,7 @@ module Homebrew flag_with_value.delete_prefix(arg_prefix) end + sig { returns(Context::ContextStruct) } def context Context::ContextStruct.new(debug: debug?, quiet: quiet?, verbose: verbose?) end diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index f9653219f7..a758d4ece9 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -14,6 +14,8 @@ OPTION_DESC_WIDTH = 43 module Homebrew module CLI class Parser + extend T::Sig + attr_reader :processed_options, :hide_from_man_page def self.from_cmd_path(cmd_path) @@ -94,6 +96,7 @@ module Homebrew ] end + sig { returns(T::Array[[String, String, String]]) } def self.global_options [ ["-d", "--debug", "Display any debugging information."], @@ -103,6 +106,9 @@ module Homebrew ] end + # FIXME: Block should be `T.nilable(T.proc.bind(Parser).void)`. + # See https://github.com/sorbet/sorbet/issues/498. + sig { params(block: T.proc.bind(Parser).void).void.checked(:never) } def initialize(&block) @parser = OptionParser.new @@ -331,6 +337,7 @@ module Homebrew end end + sig { void } def formula_options @formula_options = true end @@ -367,6 +374,7 @@ module Homebrew end end + sig { void } def hide_from_man_page! @hide_from_man_page = true end @@ -454,20 +462,24 @@ module Homebrew end def check_named_args(args) - min_exception = case @min_named_type - when :cask - Cask::CaskUnspecifiedError - when :formula - FormulaUnspecifiedError - when :formula_or_cask - FormulaOrCaskUnspecifiedError - when :keg - KegUnspecifiedError - else - MinNamedArgumentsError.new(@min_named_args) + exception = if @min_named_args && args.size < @min_named_args + case @min_named_type + when :cask + Cask::CaskUnspecifiedError + when :formula + FormulaUnspecifiedError + when :formula_or_cask + FormulaOrCaskUnspecifiedError + when :keg + KegUnspecifiedError + else + MinNamedArgumentsError.new(@min_named_args) + end + elsif @max_named_args && args.size > @max_named_args + MaxNamedArgumentsError.new(@max_named_args) end - raise min_exception if @min_named_args && args.size < @min_named_args - raise MaxNamedArgumentsError, @max_named_args if @max_named_args && args.size > @max_named_args + + raise exception if exception end def process_option(*args) @@ -535,6 +547,9 @@ module Homebrew end class MaxNamedArgumentsError < UsageError + extend T::Sig + + sig { params(maximum: Integer).void } def initialize(maximum) super case maximum when 0 @@ -546,6 +561,9 @@ module Homebrew end class MinNamedArgumentsError < UsageError + extend T::Sig + + sig { params(minimum: Integer).void } def initialize(minimum) super "This command requires at least #{minimum} named #{"argument".pluralize(minimum)}." end diff --git a/Library/Homebrew/cmd/--cache.rb b/Library/Homebrew/cmd/--cache.rb index 3a52708065..78e6df0fa5 100644 --- a/Library/Homebrew/cmd/--cache.rb +++ b/Library/Homebrew/cmd/--cache.rb @@ -6,10 +6,13 @@ require "cli/parser" require "cask/download" module Homebrew + extend T::Sig + extend Fetch module_function + sig { returns(CLI::Parser) } def __cache_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/--caskroom.rb b/Library/Homebrew/cmd/--caskroom.rb index b53574fd0a..6facedc9c8 100644 --- a/Library/Homebrew/cmd/--caskroom.rb +++ b/Library/Homebrew/cmd/--caskroom.rb @@ -1,9 +1,12 @@ -# typed: false +# typed: strict # frozen_string_literal: true module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def __caskroom_args Homebrew::CLI::Parser.new do usage_banner <<~EOS @@ -17,6 +20,7 @@ module Homebrew end end + sig { void } def __caskroom args = __caskroom_args.parse diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index 45b609ca53..b4448f573e 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -7,8 +7,11 @@ require "utils/shell" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def __env_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/--prefix.rb b/Library/Homebrew/cmd/--prefix.rb index b451a24f7b..42410ab30a 100644 --- a/Library/Homebrew/cmd/--prefix.rb +++ b/Library/Homebrew/cmd/--prefix.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def __prefix_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/--repository.rb b/Library/Homebrew/cmd/--repository.rb index 042c39b36d..c27c4589fd 100644 --- a/Library/Homebrew/cmd/--repository.rb +++ b/Library/Homebrew/cmd/--repository.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def __repository_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/--version.rb b/Library/Homebrew/cmd/--version.rb index 93595a9a3d..531b0b119c 100644 --- a/Library/Homebrew/cmd/--version.rb +++ b/Library/Homebrew/cmd/--version.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def __version_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/analytics.rb b/Library/Homebrew/cmd/analytics.rb index 957b175b85..12e545f352 100644 --- a/Library/Homebrew/cmd/analytics.rb +++ b/Library/Homebrew/cmd/analytics.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def analytics_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/cleanup.rb b/Library/Homebrew/cmd/cleanup.rb index c0294392d7..0c7ac6df81 100644 --- a/Library/Homebrew/cmd/cleanup.rb +++ b/Library/Homebrew/cmd/cleanup.rb @@ -5,8 +5,11 @@ require "cleanup" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def cleanup_args Homebrew::CLI::Parser.new do days = Homebrew::EnvConfig::ENVS[:HOMEBREW_CLEANUP_MAX_AGE_DAYS][:default] diff --git a/Library/Homebrew/cmd/commands.rb b/Library/Homebrew/cmd/commands.rb index cbcb36a495..92fed7e063 100644 --- a/Library/Homebrew/cmd/commands.rb +++ b/Library/Homebrew/cmd/commands.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def commands_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/config.rb b/Library/Homebrew/cmd/config.rb index 562d9a9f1c..970af3093a 100644 --- a/Library/Homebrew/cmd/config.rb +++ b/Library/Homebrew/cmd/config.rb @@ -5,8 +5,11 @@ require "system_config" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def config_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index a5f8ade23a..42e50c984a 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -8,10 +8,13 @@ require "cask/caskroom" require "dependencies_helpers" module Homebrew + extend T::Sig + extend DependenciesHelpers module_function + sig { returns(CLI::Parser) } def deps_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/desc.rb b/Library/Homebrew/cmd/desc.rb index e9616f1749..b2b0b8675e 100644 --- a/Library/Homebrew/cmd/desc.rb +++ b/Library/Homebrew/cmd/desc.rb @@ -7,10 +7,13 @@ require "description_cache_store" require "cli/parser" module Homebrew + extend T::Sig + module_function extend Search + sig { returns(CLI::Parser) } def desc_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/doctor.rb b/Library/Homebrew/cmd/doctor.rb index 5d10f9f655..5a3136f147 100644 --- a/Library/Homebrew/cmd/doctor.rb +++ b/Library/Homebrew/cmd/doctor.rb @@ -6,8 +6,11 @@ require "cli/parser" require "cask/caskroom" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def doctor_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index 9baa5cec4e..ac03b5df07 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -6,10 +6,13 @@ require "fetch" require "cli/parser" module Homebrew + extend T::Sig + extend Fetch module_function + sig { returns(CLI::Parser) } def fetch_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/gist-logs.rb b/Library/Homebrew/cmd/gist-logs.rb index 7d3064c7e5..d590fb3526 100644 --- a/Library/Homebrew/cmd/gist-logs.rb +++ b/Library/Homebrew/cmd/gist-logs.rb @@ -9,10 +9,13 @@ require "socket" require "cli/parser" module Homebrew + extend T::Sig + extend Install module_function + sig { returns(CLI::Parser) } def gist_logs_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/home.rb b/Library/Homebrew/cmd/home.rb index 2c147bb6d6..2308392968 100644 --- a/Library/Homebrew/cmd/home.rb +++ b/Library/Homebrew/cmd/home.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def home_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb index ae94558803..74b0f3f46b 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -13,12 +13,15 @@ require "utils/spdx" require "deprecate_disable" module Homebrew + extend T::Sig + module_function VALID_DAYS = %w[30 90 365].freeze VALID_FORMULA_CATEGORIES = %w[install install-on-request build-error].freeze VALID_CATEGORIES = (VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze + sig { returns(CLI::Parser) } def info_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 3f72fa2b28..436f607172 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -14,10 +14,13 @@ require "cli/parser" require "upgrade" module Homebrew + extend T::Sig + extend Search module_function + sig { returns(CLI::Parser) } def install_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/leaves.rb b/Library/Homebrew/cmd/leaves.rb index 7cb1497367..f4c2c471a7 100644 --- a/Library/Homebrew/cmd/leaves.rb +++ b/Library/Homebrew/cmd/leaves.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def leaves_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/link.rb b/Library/Homebrew/cmd/link.rb index 6666f5576d..98a265d610 100644 --- a/Library/Homebrew/cmd/link.rb +++ b/Library/Homebrew/cmd/link.rb @@ -7,8 +7,11 @@ require "cli/parser" require "unlink" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def link_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb index 8fe034844e..83788413bc 100644 --- a/Library/Homebrew/cmd/list.rb +++ b/Library/Homebrew/cmd/list.rb @@ -7,8 +7,11 @@ require "cli/parser" require "cask/cmd" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def list_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/log.rb b/Library/Homebrew/cmd/log.rb index f2d8b1c4e1..5a24d9d1be 100644 --- a/Library/Homebrew/cmd/log.rb +++ b/Library/Homebrew/cmd/log.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def log_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/migrate.rb b/Library/Homebrew/cmd/migrate.rb index f400036c78..b5bf51a008 100644 --- a/Library/Homebrew/cmd/migrate.rb +++ b/Library/Homebrew/cmd/migrate.rb @@ -5,8 +5,11 @@ require "migrator" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def migrate_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/missing.rb b/Library/Homebrew/cmd/missing.rb index 4345227585..4ab86a49fc 100644 --- a/Library/Homebrew/cmd/missing.rb +++ b/Library/Homebrew/cmd/missing.rb @@ -7,8 +7,11 @@ require "diagnostic" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def missing_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/options.rb b/Library/Homebrew/cmd/options.rb index 6ecc3c7fc9..b94c0aa6f3 100644 --- a/Library/Homebrew/cmd/options.rb +++ b/Library/Homebrew/cmd/options.rb @@ -7,8 +7,11 @@ require "cli/parser" require "commands" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def options_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb index 623f434729..d3261a337a 100644 --- a/Library/Homebrew/cmd/outdated.rb +++ b/Library/Homebrew/cmd/outdated.rb @@ -8,8 +8,11 @@ require "cask/cmd" require "cask/caskroom" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def outdated_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/pin.rb b/Library/Homebrew/cmd/pin.rb index 0ca4458d92..b777ac3b5f 100644 --- a/Library/Homebrew/cmd/pin.rb +++ b/Library/Homebrew/cmd/pin.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def pin_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/postinstall.rb b/Library/Homebrew/cmd/postinstall.rb index 1b4885a36a..4bbee46b66 100644 --- a/Library/Homebrew/cmd/postinstall.rb +++ b/Library/Homebrew/cmd/postinstall.rb @@ -6,8 +6,11 @@ require "formula_installer" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def postinstall_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/readall.rb b/Library/Homebrew/cmd/readall.rb index 5bfa660543..7a2361036c 100644 --- a/Library/Homebrew/cmd/readall.rb +++ b/Library/Homebrew/cmd/readall.rb @@ -5,8 +5,11 @@ require "readall" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def readall_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb index 93e4c12936..4bc7a230c2 100644 --- a/Library/Homebrew/cmd/reinstall.rb +++ b/Library/Homebrew/cmd/reinstall.rb @@ -14,8 +14,11 @@ require "cask/macos" require "upgrade" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def reinstall_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/search.rb b/Library/Homebrew/cmd/search.rb index beaa14edad..7fc967ecb0 100644 --- a/Library/Homebrew/cmd/search.rb +++ b/Library/Homebrew/cmd/search.rb @@ -8,6 +8,8 @@ require "cli/parser" require "search" module Homebrew + extend T::Sig + module_function extend Search @@ -25,6 +27,7 @@ module Homebrew }, }.freeze + sig { returns(CLI::Parser) } def search_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/switch.rb b/Library/Homebrew/cmd/switch.rb index 0877f51d09..a78ef0a907 100644 --- a/Library/Homebrew/cmd/switch.rb +++ b/Library/Homebrew/cmd/switch.rb @@ -6,8 +6,11 @@ require "keg" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def switch_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/tap-info.rb b/Library/Homebrew/cmd/tap-info.rb index 6c01e4172a..81284e8c0d 100644 --- a/Library/Homebrew/cmd/tap-info.rb +++ b/Library/Homebrew/cmd/tap-info.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def tap_info_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb index df6f428ff1..86e7a0fc1b 100644 --- a/Library/Homebrew/cmd/tap.rb +++ b/Library/Homebrew/cmd/tap.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def tap_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index 2fadf91c50..ce2b3df3c2 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -11,8 +11,11 @@ require "cask/cask_loader" require "uninstall" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def uninstall_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/unlink.rb b/Library/Homebrew/cmd/unlink.rb index 2abbc3d947..1036b8eaf9 100644 --- a/Library/Homebrew/cmd/unlink.rb +++ b/Library/Homebrew/cmd/unlink.rb @@ -6,8 +6,11 @@ require "cli/parser" require "unlink" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def unlink_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/unpin.rb b/Library/Homebrew/cmd/unpin.rb index 77bf7b1576..1f650adae1 100644 --- a/Library/Homebrew/cmd/unpin.rb +++ b/Library/Homebrew/cmd/unpin.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def unpin_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/untap.rb b/Library/Homebrew/cmd/untap.rb index b8f6a93016..d3e70e7e5e 100644 --- a/Library/Homebrew/cmd/untap.rb +++ b/Library/Homebrew/cmd/untap.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def untap_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index b4efd2d7f5..24406a4764 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -10,6 +10,8 @@ require "description_cache_store" require "cli/parser" module Homebrew + extend T::Sig + module_function def update_preinstall_header(args:) @@ -19,6 +21,7 @@ module Homebrew end end + sig { returns(CLI::Parser) } def update_report_args Homebrew::CLI::Parser.new do usage_banner <<~EOS @@ -413,10 +416,13 @@ class Reporter end class ReporterHub + extend T::Sig + extend Forwardable attr_reader :reporters + sig { void } def initialize @hash = {} @reporters = [] diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index b7a53cbd40..ce8ec7bf8a 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -10,8 +10,11 @@ require "cask/utils" require "cask/macos" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def upgrade_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 8b2f912436..ae0a28ed57 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -11,10 +11,13 @@ require "cask/caskroom" require "dependencies_helpers" module Homebrew + extend T::Sig + extend DependenciesHelpers module_function + sig { returns(CLI::Parser) } def uses_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/config.rb b/Library/Homebrew/config.rb index feecc8373a..566be1eae6 100644 --- a/Library/Homebrew/config.rb +++ b/Library/Homebrew/config.rb @@ -4,28 +4,36 @@ raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"] # Path to `bin/brew` main executable in `HOMEBREW_PREFIX` -HOMEBREW_BREW_FILE = Pathname.new(ENV["HOMEBREW_BREW_FILE"]).freeze +HOMEBREW_BREW_FILE = Pathname(ENV["HOMEBREW_BREW_FILE"]).freeze class MissingEnvironmentVariables < RuntimeError; end -def get_env_or_raise(env) - raise MissingEnvironmentVariables, "#{env} was not exported!" unless ENV[env] +# Helper module for getting environment variables which must be set. +# +# @api private +module EnvVar + extend T::Sig - ENV[env] + sig { params(env: String).returns(String) } + def self.[](env) + raise MissingEnvironmentVariables, "#{env} was not exported!" unless ENV[env] + + ENV.fetch(env) + end end require "extend/git_repository" # Where we link under -HOMEBREW_PREFIX = Pathname.new(get_env_or_raise("HOMEBREW_PREFIX")).freeze +HOMEBREW_PREFIX = Pathname(EnvVar["HOMEBREW_PREFIX"]).freeze # Where `.git` is found -HOMEBREW_REPOSITORY = Pathname.new(get_env_or_raise("HOMEBREW_REPOSITORY")) - .extend(GitRepositoryExtension) - .freeze +HOMEBREW_REPOSITORY = Pathname(EnvVar["HOMEBREW_REPOSITORY"]) + .extend(GitRepositoryExtension) + .freeze # Where we store most of Homebrew, taps, and various metadata -HOMEBREW_LIBRARY = Pathname.new(get_env_or_raise("HOMEBREW_LIBRARY")).freeze +HOMEBREW_LIBRARY = Pathname(EnvVar["HOMEBREW_LIBRARY"]).freeze # Where shim scripts for various build and SCM tools are stored HOMEBREW_SHIMS_PATH = (HOMEBREW_LIBRARY/"Homebrew/shims").freeze @@ -43,19 +51,19 @@ HOMEBREW_PINNED_KEGS = (HOMEBREW_PREFIX/"var/homebrew/pinned").freeze HOMEBREW_LOCKS = (HOMEBREW_PREFIX/"var/homebrew/locks").freeze # Where we store built products -HOMEBREW_CELLAR = Pathname.new(get_env_or_raise("HOMEBREW_CELLAR")).freeze +HOMEBREW_CELLAR = Pathname(EnvVar["HOMEBREW_CELLAR"]).freeze # Where downloads (bottles, source tarballs, etc.) are cached -HOMEBREW_CACHE = Pathname.new(get_env_or_raise("HOMEBREW_CACHE")).freeze +HOMEBREW_CACHE = Pathname(EnvVar["HOMEBREW_CACHE"]).freeze # Where brews installed via URL are cached HOMEBREW_CACHE_FORMULA = (HOMEBREW_CACHE/"Formula").freeze # Where build, postinstall, and test logs of formulae are written to -HOMEBREW_LOGS = Pathname.new(get_env_or_raise("HOMEBREW_LOGS")).expand_path.freeze +HOMEBREW_LOGS = Pathname(EnvVar["HOMEBREW_LOGS"]).expand_path.freeze # Must use `/tmp` instead of `TMPDIR` because long paths break Unix domain sockets -HOMEBREW_TEMP = Pathname.new(get_env_or_raise("HOMEBREW_TEMP")).yield_self do |tmp| +HOMEBREW_TEMP = Pathname(EnvVar["HOMEBREW_TEMP"]).yield_self do |tmp| tmp.mkpath unless tmp.exist? tmp.realpath end.freeze diff --git a/Library/Homebrew/cxxstdlib.rb b/Library/Homebrew/cxxstdlib.rb index 8750b0c187..e6ef4838d6 100644 --- a/Library/Homebrew/cxxstdlib.rb +++ b/Library/Homebrew/cxxstdlib.rb @@ -5,6 +5,8 @@ require "compilers" # Combination of C++ standard library and compiler. class CxxStdlib + extend T::Sig + include CompilerConstants # Error for when a formula's dependency was built with a different C++ standard library. @@ -72,6 +74,7 @@ class CxxStdlib type.to_s.gsub(/cxx$/, "c++") end + sig { returns(String) } def inspect "#<#{self.class.name}: #{compiler} #{type}>" end diff --git a/Library/Homebrew/debrew.rb b/Library/Homebrew/debrew.rb index 54a5b9af03..de551abc90 100644 --- a/Library/Homebrew/debrew.rb +++ b/Library/Homebrew/debrew.rb @@ -41,10 +41,13 @@ module Debrew # Module for displaying a debugging menu. class Menu + extend T::Sig + Entry = Struct.new(:name, :action) attr_accessor :prompt, :entries + sig { void } def initialize @entries = [] end diff --git a/Library/Homebrew/dependencies.rb b/Library/Homebrew/dependencies.rb index 2764048ce0..b3a12d9bff 100644 --- a/Library/Homebrew/dependencies.rb +++ b/Library/Homebrew/dependencies.rb @@ -8,6 +8,8 @@ require "cask_dependent" # # @api private class Dependencies < SimpleDelegator + extend T::Sig + def initialize(*args) super(args) end @@ -34,6 +36,7 @@ class Dependencies < SimpleDelegator build + required + recommended end + sig { returns(String) } def inspect "#<#{self.class.name}: #{to_a}>" end @@ -43,6 +46,8 @@ end # # @api private class Requirements < SimpleDelegator + extend T::Sig + def initialize(*args) super(Set.new(args)) end @@ -59,6 +64,7 @@ class Requirements < SimpleDelegator self end + sig { returns(String) } def inspect "#<#{self.class.name}: {#{to_a.join(", ")}}>" end diff --git a/Library/Homebrew/dependency.rb b/Library/Homebrew/dependency.rb index 99b8a0a1ee..aa22361478 100644 --- a/Library/Homebrew/dependency.rb +++ b/Library/Homebrew/dependency.rb @@ -7,6 +7,8 @@ require "dependable" # # @api private class Dependency + extend T::Sig + extend Forwardable include Dependable @@ -64,6 +66,7 @@ class Dependency env_proc&.call end + sig { returns(String) } def inspect "#<#{self.class.name}: #{name.inspect} #{tags.inspect}>" end @@ -78,6 +81,8 @@ class Dependency end class << self + extend T::Sig + # Expand the dependencies of each dependent recursively, optionally yielding # `[dependent, dep]` pairs to allow callers to apply arbitrary filters to # the list. @@ -126,16 +131,19 @@ class Dependency end # Prune a dependency and its dependencies recursively. + sig { void } def prune throw(:action, :prune) end # Prune a single dependency but do not prune its dependencies. + sig { void } def skip throw(:action, :skip) end # Keep a dependency, but prune its dependencies. + sig { void } def keep_but_prune_recursive_deps throw(:action, :keep_but_prune_recursive_deps) end diff --git a/Library/Homebrew/dependency_collector.rb b/Library/Homebrew/dependency_collector.rb index 80b8dbab0f..356437c7a9 100644 --- a/Library/Homebrew/dependency_collector.rb +++ b/Library/Homebrew/dependency_collector.rb @@ -18,10 +18,13 @@ require "extend/cachable" # This class is used by `depends_on` in the formula DSL to turn dependency # specifications into the proper kinds of dependencies and requirements. class DependencyCollector + extend T::Sig + extend Cachable attr_reader :deps, :requirements + sig { void } def initialize @deps = Dependencies.new @requirements = Requirements.new diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 7dc0887d62..e961495ba8 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -18,8 +18,11 @@ require "cli/parser" require "json" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def audit_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 4f6d117609..b940b0d934 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -40,8 +40,11 @@ EOS MAXIMUM_STRING_MATCHES = 100 module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def bottle_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/bump-cask-pr.rb b/Library/Homebrew/dev-cmd/bump-cask-pr.rb index a9ecedc589..2bb3e15d27 100644 --- a/Library/Homebrew/dev-cmd/bump-cask-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-cask-pr.rb @@ -6,8 +6,11 @@ require "cli/parser" require "utils/tar" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def bump_cask_pr_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index dc4bb5a06b..b3f6550f3b 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -7,8 +7,11 @@ require "utils/pypi" require "utils/tar" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def bump_formula_pr_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/bump-revision.rb b/Library/Homebrew/dev-cmd/bump-revision.rb index aa53caaf47..745fef7717 100644 --- a/Library/Homebrew/dev-cmd/bump-revision.rb +++ b/Library/Homebrew/dev-cmd/bump-revision.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def bump_revision_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index 543d751863..e5a9695b8f 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def bump_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/cat.rb b/Library/Homebrew/dev-cmd/cat.rb index 3415e03e6e..a0410216fe 100644 --- a/Library/Homebrew/dev-cmd/cat.rb +++ b/Library/Homebrew/dev-cmd/cat.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def cat_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/command.rb b/Library/Homebrew/dev-cmd/command.rb index 7c2f6e37ce..9beb128138 100644 --- a/Library/Homebrew/dev-cmd/command.rb +++ b/Library/Homebrew/dev-cmd/command.rb @@ -5,8 +5,11 @@ require "commands" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def command_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index 177ba878e8..ecedb06f26 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -8,8 +8,11 @@ require "cli/parser" require "utils/pypi" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def create_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb b/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb index dc80f45fb4..4353beeb77 100644 --- a/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb +++ b/Library/Homebrew/dev-cmd/dispatch-build-bottle.rb @@ -5,8 +5,11 @@ require "cli/parser" require "utils/github" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def dispatch_build_bottle_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/diy.rb b/Library/Homebrew/dev-cmd/diy.rb index 31f57440c8..56c1ee437d 100644 --- a/Library/Homebrew/dev-cmd/diy.rb +++ b/Library/Homebrew/dev-cmd/diy.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def diy_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/edit.rb b/Library/Homebrew/dev-cmd/edit.rb index f963aeb237..5526e9809e 100644 --- a/Library/Homebrew/dev-cmd/edit.rb +++ b/Library/Homebrew/dev-cmd/edit.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def edit_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/extract.rb b/Library/Homebrew/dev-cmd/extract.rb index 7bd9820d18..63f518f69f 100644 --- a/Library/Homebrew/dev-cmd/extract.rb +++ b/Library/Homebrew/dev-cmd/extract.rb @@ -76,8 +76,11 @@ ensure end module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def extract_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/formula.rb b/Library/Homebrew/dev-cmd/formula.rb index b5e7ccaec1..cee7263e9a 100644 --- a/Library/Homebrew/dev-cmd/formula.rb +++ b/Library/Homebrew/dev-cmd/formula.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def formula_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/install-bundler-gems.rb b/Library/Homebrew/dev-cmd/install-bundler-gems.rb index b15b49ee97..ce80576cb1 100644 --- a/Library/Homebrew/dev-cmd/install-bundler-gems.rb +++ b/Library/Homebrew/dev-cmd/install-bundler-gems.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def install_bundler_gems_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/irb.rb b/Library/Homebrew/dev-cmd/irb.rb index c5a0a29b8b..b5b09f9b1c 100644 --- a/Library/Homebrew/dev-cmd/irb.rb +++ b/Library/Homebrew/dev-cmd/irb.rb @@ -16,8 +16,11 @@ class String end module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def irb_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/linkage.rb b/Library/Homebrew/dev-cmd/linkage.rb index 631e9ec65b..4f161f8039 100644 --- a/Library/Homebrew/dev-cmd/linkage.rb +++ b/Library/Homebrew/dev-cmd/linkage.rb @@ -6,8 +6,11 @@ require "linkage_checker" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def linkage_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/livecheck.rb b/Library/Homebrew/dev-cmd/livecheck.rb index d177768026..2e6ab72334 100644 --- a/Library/Homebrew/dev-cmd/livecheck.rb +++ b/Library/Homebrew/dev-cmd/livecheck.rb @@ -7,6 +7,8 @@ require "livecheck/livecheck" require "livecheck/strategy" module Homebrew + extend T::Sig + module_function WATCHLIST_PATH = ( @@ -14,6 +16,7 @@ module Homebrew "#{Dir.home}/.brew_livecheck_watchlist" ).freeze + sig { returns(CLI::Parser) } def livecheck_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/man.rb b/Library/Homebrew/dev-cmd/man.rb index 0a17cdc96a..6a3e27c372 100644 --- a/Library/Homebrew/dev-cmd/man.rb +++ b/Library/Homebrew/dev-cmd/man.rb @@ -7,12 +7,15 @@ require "ostruct" require "cli/parser" module Homebrew + extend T::Sig + module_function SOURCE_PATH = (HOMEBREW_LIBRARY_PATH/"manpages").freeze TARGET_MAN_PATH = (HOMEBREW_REPOSITORY/"manpages").freeze TARGET_DOC_PATH = (HOMEBREW_REPOSITORY/"docs").freeze + sig { returns(CLI::Parser) } def man_args Homebrew::CLI::Parser.new do usage_banner <<~EOS @@ -210,6 +213,7 @@ module Homebrew lines end + sig { returns(String) } def global_cask_options_manpage lines = ["These options are applicable to subcommands accepting a `--cask` flag and all `cask` commands.\n"] lines += Homebrew::CLI::Parser.global_cask_options.map do |_, long, description:, **| @@ -218,6 +222,7 @@ module Homebrew lines.join("\n") end + sig { returns(String) } def global_options_manpage lines = ["These options are applicable across multiple subcommands.\n"] lines += Homebrew::CLI::Parser.global_options.map do |short, long, desc| @@ -226,6 +231,7 @@ module Homebrew lines.join("\n") end + sig { returns(String) } def env_vars_manpage lines = Homebrew::EnvConfig::ENVS.flat_map do |env, hash| entry = " * `#{env}`:\n #{hash[:description]}\n" diff --git a/Library/Homebrew/dev-cmd/mirror.rb b/Library/Homebrew/dev-cmd/mirror.rb index 7790c32fed..70400ee846 100644 --- a/Library/Homebrew/dev-cmd/mirror.rb +++ b/Library/Homebrew/dev-cmd/mirror.rb @@ -5,8 +5,11 @@ require "bintray" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def mirror_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/pr-automerge.rb b/Library/Homebrew/dev-cmd/pr-automerge.rb index 16634dd450..aac304e288 100644 --- a/Library/Homebrew/dev-cmd/pr-automerge.rb +++ b/Library/Homebrew/dev-cmd/pr-automerge.rb @@ -5,8 +5,11 @@ require "cli/parser" require "utils/github" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def pr_automerge_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/pr-publish.rb b/Library/Homebrew/dev-cmd/pr-publish.rb index 86b675293b..de376b1cee 100644 --- a/Library/Homebrew/dev-cmd/pr-publish.rb +++ b/Library/Homebrew/dev-cmd/pr-publish.rb @@ -5,8 +5,11 @@ require "cli/parser" require "utils/github" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def pr_publish_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb index a11704972f..82a6a7f4ae 100644 --- a/Library/Homebrew/dev-cmd/pr-pull.rb +++ b/Library/Homebrew/dev-cmd/pr-pull.rb @@ -8,8 +8,11 @@ require "tmpdir" require "formula" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def pr_pull_args Homebrew::CLI::Parser.new do usage_banner <<~EOS @@ -418,6 +421,8 @@ module Homebrew end class GitHubArtifactDownloadStrategy < AbstractFileDownloadStrategy + extend T::Sig + def fetch ohai "Downloading #{url}" if cached_location.exist? @@ -441,6 +446,7 @@ class GitHubArtifactDownloadStrategy < AbstractFileDownloadStrategy private + sig { returns(String) } def resolved_basename "artifact.zip" end diff --git a/Library/Homebrew/dev-cmd/pr-upload.rb b/Library/Homebrew/dev-cmd/pr-upload.rb index 23ed9e9cef..d26a6c0cfe 100644 --- a/Library/Homebrew/dev-cmd/pr-upload.rb +++ b/Library/Homebrew/dev-cmd/pr-upload.rb @@ -5,8 +5,11 @@ require "cli/parser" require "bintray" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def pr_upload_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/prof.rb b/Library/Homebrew/dev-cmd/prof.rb index 2c40d0b7fc..add6a5ae01 100644 --- a/Library/Homebrew/dev-cmd/prof.rb +++ b/Library/Homebrew/dev-cmd/prof.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def prof_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/pull.rb b/Library/Homebrew/dev-cmd/pull.rb index ce279b1f80..8c1b8b2b5c 100644 --- a/Library/Homebrew/dev-cmd/pull.rb +++ b/Library/Homebrew/dev-cmd/pull.rb @@ -12,8 +12,11 @@ require "pkg_version" require "formula_info" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def pull_args Homebrew::CLI::Parser.new do hide_from_man_page! diff --git a/Library/Homebrew/dev-cmd/release-notes.rb b/Library/Homebrew/dev-cmd/release-notes.rb index 7288d85e12..bde64f84de 100644 --- a/Library/Homebrew/dev-cmd/release-notes.rb +++ b/Library/Homebrew/dev-cmd/release-notes.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def release_notes_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/ruby.rb b/Library/Homebrew/dev-cmd/ruby.rb index 4e4f014d08..47475f39e3 100644 --- a/Library/Homebrew/dev-cmd/ruby.rb +++ b/Library/Homebrew/dev-cmd/ruby.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def ruby_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/sh.rb b/Library/Homebrew/dev-cmd/sh.rb index a1f35adc14..eb0af7cd84 100644 --- a/Library/Homebrew/dev-cmd/sh.rb +++ b/Library/Homebrew/dev-cmd/sh.rb @@ -6,8 +6,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def sh_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/sponsors.rb b/Library/Homebrew/dev-cmd/sponsors.rb index 0e3bece7d2..b6d03a839d 100644 --- a/Library/Homebrew/dev-cmd/sponsors.rb +++ b/Library/Homebrew/dev-cmd/sponsors.rb @@ -5,8 +5,11 @@ require "cli/parser" require "utils/github" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def sponsors_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/style.rb b/Library/Homebrew/dev-cmd/style.rb index 8b3d5439a2..611ab05ce0 100644 --- a/Library/Homebrew/dev-cmd/style.rb +++ b/Library/Homebrew/dev-cmd/style.rb @@ -7,8 +7,11 @@ require "style" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def style_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/tap-new.rb b/Library/Homebrew/dev-cmd/tap-new.rb index d9c9f3b5e8..883263d58a 100644 --- a/Library/Homebrew/dev-cmd/tap-new.rb +++ b/Library/Homebrew/dev-cmd/tap-new.rb @@ -5,8 +5,11 @@ require "tap" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def tap_new_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb index 087f5f5510..8933ec8ae1 100644 --- a/Library/Homebrew/dev-cmd/test.rb +++ b/Library/Homebrew/dev-cmd/test.rb @@ -7,8 +7,11 @@ require "timeout" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def test_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index 428177807e..c9f47b220a 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -5,8 +5,11 @@ require "cli/parser" require "fileutils" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def tests_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/typecheck.rb b/Library/Homebrew/dev-cmd/typecheck.rb index c8c45fa88b..2914b518c6 100644 --- a/Library/Homebrew/dev-cmd/typecheck.rb +++ b/Library/Homebrew/dev-cmd/typecheck.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def typecheck_args Homebrew::CLI::Parser.new do usage_banner <<~EOS @@ -13,6 +16,8 @@ module Homebrew Check for typechecking errors using Sorbet. EOS + switch "--fix", + description: "Automatically fix type errors." switch "-q", "--quiet", description: "Silence all non-critical errors." switch "--update", @@ -51,6 +56,7 @@ module Homebrew srb_exec = %w[bundle exec srb tc] srb_exec << "--quiet" if args.quiet? + srb_exec << "--autocorrect" if args.fix? srb_exec += ["--ignore", args.ignore] if args.ignore.present? if args.file.present? || args.dir.present? cd("sorbet") diff --git a/Library/Homebrew/dev-cmd/unpack.rb b/Library/Homebrew/dev-cmd/unpack.rb index e88b9ef2cc..529bfcc046 100644 --- a/Library/Homebrew/dev-cmd/unpack.rb +++ b/Library/Homebrew/dev-cmd/unpack.rb @@ -6,8 +6,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def unpack_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/update-license-data.rb b/Library/Homebrew/dev-cmd/update-license-data.rb index 6d11bca358..bb3220074b 100644 --- a/Library/Homebrew/dev-cmd/update-license-data.rb +++ b/Library/Homebrew/dev-cmd/update-license-data.rb @@ -5,8 +5,11 @@ require "cli/parser" require "utils/spdx" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def update_license_data_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/update-python-resources.rb b/Library/Homebrew/dev-cmd/update-python-resources.rb index e109887bbc..e8017c3766 100644 --- a/Library/Homebrew/dev-cmd/update-python-resources.rb +++ b/Library/Homebrew/dev-cmd/update-python-resources.rb @@ -5,8 +5,11 @@ require "cli/parser" require "utils/pypi" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def update_python_resources_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/update-test.rb b/Library/Homebrew/dev-cmd/update-test.rb index f6c3adce43..789ec21aa9 100644 --- a/Library/Homebrew/dev-cmd/update-test.rb +++ b/Library/Homebrew/dev-cmd/update-test.rb @@ -4,8 +4,11 @@ require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def update_test_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/dev-cmd/vendor-gems.rb b/Library/Homebrew/dev-cmd/vendor-gems.rb index f42945f2b2..9f028e5dc7 100644 --- a/Library/Homebrew/dev-cmd/vendor-gems.rb +++ b/Library/Homebrew/dev-cmd/vendor-gems.rb @@ -5,8 +5,11 @@ require "formula" require "cli/parser" module Homebrew + extend T::Sig + module_function + sig { returns(CLI::Parser) } def vendor_gems_args Homebrew::CLI::Parser.new do usage_banner <<~EOS diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 0964ca0be1..2280206eb4 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -48,6 +48,8 @@ module Homebrew # Diagnostic checks. class Checks + extend T::Sig + def initialize(verbose: true) @verbose = verbose end @@ -71,6 +73,7 @@ module Homebrew path.gsub(ENV["HOME"], "~") end + sig { returns(String) } def none_string "" end diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index d7a2b69f50..eb4a48389b 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -17,6 +17,8 @@ require "utils/curl" # # @api private class AbstractDownloadStrategy + extend T::Sig + extend Forwardable include FileUtils include Context @@ -55,6 +57,7 @@ class AbstractDownloadStrategy # TODO: Deprecate once we have an explicitly documented alternative. # # @api public + sig { void } def shutup! @quiet = true end @@ -586,6 +589,8 @@ end # # @api public class SubversionDownloadStrategy < VCSDownloadStrategy + extend T::Sig + def initialize(url, name, version, **meta) super @url = @url.sub("svn+http://", "") @@ -602,6 +607,7 @@ class SubversionDownloadStrategy < VCSDownloadStrategy end # (see AbstractDownloadStrategy#source_modified_time) + sig { returns(Time) } def source_modified_time time = if Version.create(Utils::Svn.version) >= Version.create("1.9") out, = silent_command("svn", args: ["info", "--show-item", "last-changed-date"], chdir: cached_location) @@ -660,6 +666,7 @@ class SubversionDownloadStrategy < VCSDownloadStrategy end end + sig { returns(String) } def cache_tag head? ? "svn-HEAD" : "svn" end @@ -706,6 +713,7 @@ class GitDownloadStrategy < VCSDownloadStrategy end # (see AbstractDownloadStrategy#source_modified_time) + sig { returns(Time) } def source_modified_time out, = silent_command("git", args: ["--git-dir", git_dir, "show", "-s", "--format=%cD"]) Time.parse(out) @@ -719,10 +727,12 @@ class GitDownloadStrategy < VCSDownloadStrategy private + sig { returns(String) } def cache_tag "git" end + sig { returns(Integer) } def cache_version 0 end @@ -770,6 +780,7 @@ class GitDownloadStrategy < VCSDownloadStrategy (cached_location/".gitmodules").exist? end + sig { returns(T::Array[String]) } def clone_args args = %w[clone] args << "--depth" << "1" if shallow_clone? @@ -783,6 +794,7 @@ class GitDownloadStrategy < VCSDownloadStrategy args << @url << cached_location end + sig { returns(String) } def refspec case @ref_type when :branch then "+refs/heads/#{@ref}:refs/remotes/origin/#{@ref}" @@ -953,6 +965,8 @@ end # # @api public class CVSDownloadStrategy < VCSDownloadStrategy + extend T::Sig + def initialize(url, name, version, **meta) super @url = @url.sub(%r{^cvs://}, "") @@ -967,6 +981,7 @@ class CVSDownloadStrategy < VCSDownloadStrategy end # (see AbstractDownloadStrategy#source_modified_time) + sig { returns(Time) } def source_modified_time # Filter CVS's files because the timestamp for each of them is the moment # of clone. @@ -987,6 +1002,7 @@ class CVSDownloadStrategy < VCSDownloadStrategy { "PATH" => PATH.new("/usr/bin", Formula["cvs"].opt_bin, ENV["PATH"]) } end + sig { returns(String) } def cache_tag "cvs" end @@ -1026,12 +1042,15 @@ end # # @api public class MercurialDownloadStrategy < VCSDownloadStrategy + extend T::Sig + def initialize(url, name, version, **meta) super @url = @url.sub(%r{^hg://}, "") end # (see AbstractDownloadStrategy#source_modified_time) + sig { returns(Time) } def source_modified_time out, = silent_command("hg", args: ["tip", "--template", "{date|isodate}", "-R", cached_location]) @@ -1051,6 +1070,7 @@ class MercurialDownloadStrategy < VCSDownloadStrategy { "PATH" => PATH.new(Formula["mercurial"].opt_bin, ENV["PATH"]) } end + sig { returns(String) } def cache_tag "hg" end @@ -1081,12 +1101,15 @@ end # # @api public class BazaarDownloadStrategy < VCSDownloadStrategy + extend T::Sig + def initialize(url, name, version, **meta) super @url.sub!(%r{^bzr://}, "") end # (see AbstractDownloadStrategy#source_modified_time) + sig { returns(Time) } def source_modified_time out, = silent_command("bzr", args: ["log", "-l", "1", "--timezone=utc", cached_location]) timestamp = out.chomp @@ -1110,6 +1133,7 @@ class BazaarDownloadStrategy < VCSDownloadStrategy } end + sig { returns(String) } def cache_tag "bzr" end @@ -1135,12 +1159,15 @@ end # # @api public class FossilDownloadStrategy < VCSDownloadStrategy + extend T::Sig + def initialize(url, name, version, **meta) super @url = @url.sub(%r{^fossil://}, "") end # (see AbstractDownloadStrategy#source_modified_time) + sig { returns(Time) } def source_modified_time out, = silent_command("fossil", args: ["info", "tip", "-R", cached_location]) Time.parse(out[/^uuid: +\h+ (.+)$/, 1]) @@ -1162,6 +1189,7 @@ class FossilDownloadStrategy < VCSDownloadStrategy { "PATH" => PATH.new(Formula["fossil"].opt_bin, ENV["PATH"]) } end + sig { returns(String) } def cache_tag "fossil" end diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb index 278cd0f3e9..a4e6a4e25f 100644 --- a/Library/Homebrew/env_config.rb +++ b/Library/Homebrew/env_config.rb @@ -6,6 +6,8 @@ module Homebrew # # @api private module EnvConfig + extend T::Sig + module_function ENVS = { @@ -358,10 +360,12 @@ module Homebrew .to_s end + sig { returns(T::Array[String]) } def cask_opts Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", "")) end + sig { returns(T::Boolean) } def cask_opts_binaries? cask_opts.reverse_each do |opt| return true if opt == "--binaries" @@ -371,6 +375,7 @@ module Homebrew true end + sig { returns(T::Boolean) } def cask_opts_quarantine? cask_opts.reverse_each do |opt| return true if opt == "--quarantine" @@ -380,6 +385,7 @@ module Homebrew true end + sig { returns(T::Boolean) } def cask_opts_require_sha? cask_opts.include?("--require-sha") end diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index f48dfed104..fadca48894 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -6,6 +6,8 @@ require "utils" # Raised when a command is used wrong. class UsageError < RuntimeError + extend T::Sig + attr_reader :reason def initialize(reason = nil) @@ -14,6 +16,7 @@ class UsageError < RuntimeError @reason = reason end + sig { returns(String) } def to_s s = "Invalid usage" s += ": #{reason}" if reason @@ -78,6 +81,8 @@ end # Raised when neither a formula nor a cask with the given name is available. class FormulaOrCaskUnavailableError < RuntimeError + extend T::Sig + attr_reader :name def initialize(name) @@ -86,6 +91,7 @@ class FormulaOrCaskUnavailableError < RuntimeError @name = name end + sig { returns(String) } def to_s "No available formula or cask with the name \"#{name}\"." end @@ -93,14 +99,18 @@ end # Raised when a formula is not available. class FormulaUnavailableError < FormulaOrCaskUnavailableError + extend T::Sig + attr_accessor :dependent + sig { returns(T.nilable(String)) } def dependent_s - "(dependency of #{dependent})" if dependent && dependent != name + " (dependency of #{dependent})" if dependent && dependent != name end + sig { returns(String) } def to_s - "No available formula with the name \"#{name}\" #{dependent_s}" + "No available formula with the name \"#{name}\"#{dependent_s}." end end @@ -108,6 +118,8 @@ end # # @api private module FormulaClassUnavailableErrorModule + extend T::Sig + attr_reader :path, :class_name, :class_list def to_s @@ -119,6 +131,7 @@ module FormulaClassUnavailableErrorModule private + sig { returns(String) } def class_list_s formula_class_list = class_list.select { |klass| klass < Formula } if class_list.empty? @@ -151,8 +164,11 @@ end # # @api private module FormulaUnreadableErrorModule + extend T::Sig + attr_reader :formula_error + sig { returns(String) } def to_s "#{name}: " + formula_error.to_s end @@ -327,6 +343,8 @@ end # Raised when a formula conflicts with another one. class FormulaConflictError < RuntimeError + extend T::Sig + attr_reader :formula, :conflicts def initialize(formula, conflicts) @@ -342,6 +360,7 @@ class FormulaConflictError < RuntimeError message.join end + sig { returns(String) } def message message = [] message << "Cannot install #{formula.full_name} because conflicting formulae are installed." @@ -549,6 +568,8 @@ end # Raised by {Kernel#safe_system} in `utils.rb`. class ErrorDuringExecution < RuntimeError + extend T::Sig + attr_reader :cmd, :status, :output def initialize(cmd, status:, output: nil, secrets: []) @@ -583,6 +604,7 @@ class ErrorDuringExecution < RuntimeError super s.freeze end + sig { returns(String) } def stderr Array(output).select { |type,| type == :stderr }.map(&:last).join end diff --git a/Library/Homebrew/extend/ENV/std.rb b/Library/Homebrew/extend/ENV/std.rb index 30dfaeef20..bea1efc156 100644 --- a/Library/Homebrew/extend/ENV/std.rb +++ b/Library/Homebrew/extend/ENV/std.rb @@ -6,6 +6,8 @@ require "extend/ENV/shared" # @private module Stdenv + extend T::Sig + include SharedEnvExtension # @private @@ -58,6 +60,7 @@ module Stdenv [] end + sig { returns(T.nilable(PATH)) } def determine_pkg_config_libdir PATH.new( HOMEBREW_PREFIX/"lib/pkgconfig", diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index 966e5e7c87..4b1ba40b84 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -15,6 +15,8 @@ require "development_tools" # 7. Simpler formulae that *just work* # 8. Build-system agnostic configuration of the toolchain module Superenv + extend T::Sig + include SharedEnvExtension # @private @@ -103,6 +105,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_path path = PATH.new(Superenv.bin) @@ -125,6 +128,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_pkg_config_path PATH.new( deps.map { |d| d.opt_lib/"pkgconfig" }, @@ -132,6 +136,7 @@ module Superenv ).existing end + sig { returns(T.nilable(PATH)) } def determine_pkg_config_libdir PATH.new( homebrew_extra_pkg_config_paths, @@ -142,6 +147,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_aclocal_path PATH.new( keg_only_deps.map { |d| d.opt_share/"aclocal" }, @@ -154,6 +160,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_isystem_paths PATH.new( HOMEBREW_PREFIX/"include", @@ -161,6 +168,7 @@ module Superenv ).existing end + sig { returns(T.nilable(PATH)) } def determine_include_paths PATH.new(keg_only_deps.map(&:opt_include)).existing end @@ -169,6 +177,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_library_paths paths = [ keg_only_deps.map(&:opt_lib), @@ -182,6 +191,7 @@ module Superenv deps.map(&:name).join(",") end + sig { returns(T.nilable(PATH)) } def determine_cmake_prefix_path PATH.new( keg_only_deps.map(&:opt_prefix), @@ -193,6 +203,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_cmake_include_path PATH.new(homebrew_extra_cmake_include_paths).existing end @@ -201,6 +212,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_cmake_library_path PATH.new(homebrew_extra_cmake_library_paths).existing end @@ -209,6 +221,7 @@ module Superenv [] end + sig { returns(T.nilable(PATH)) } def determine_cmake_frameworks_path PATH.new( deps.map(&:opt_frameworks), diff --git a/Library/Homebrew/extend/os/linux/development_tools.rb b/Library/Homebrew/extend/os/linux/development_tools.rb index 4e3bc56c9e..e1120688eb 100644 --- a/Library/Homebrew/extend/os/linux/development_tools.rb +++ b/Library/Homebrew/extend/os/linux/development_tools.rb @@ -3,6 +3,8 @@ class DevelopmentTools class << self + extend T::Sig + def locate(tool) (@locate ||= {}).fetch(tool) do |key| @locate[key] = if (path = HOMEBREW_PREFIX/"bin/#{tool}").executable? @@ -13,6 +15,7 @@ class DevelopmentTools end end + sig { returns(Symbol) } def default_compiler :gcc end diff --git a/Library/Homebrew/extend/os/linux/extend/ENV/super.rb b/Library/Homebrew/extend/os/linux/extend/ENV/super.rb index a3fda016ef..ebf600ad0d 100644 --- a/Library/Homebrew/extend/os/linux/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/linux/extend/ENV/super.rb @@ -2,6 +2,8 @@ # frozen_string_literal: true module Superenv + extend T::Sig + # @private def self.bin (HOMEBREW_SHIMS_PATH/"linux/super").realpath @@ -34,6 +36,7 @@ module Superenv ) end + sig { returns(T.nilable(String)) } def determine_dynamic_linker_path path = "#{HOMEBREW_PREFIX}/lib/ld.so" return unless File.readable? path diff --git a/Library/Homebrew/extend/os/linux/requirements/osxfuse_requirement.rb b/Library/Homebrew/extend/os/linux/requirements/osxfuse_requirement.rb index 1f4d2ce132..05a764d10c 100644 --- a/Library/Homebrew/extend/os/linux/requirements/osxfuse_requirement.rb +++ b/Library/Homebrew/extend/os/linux/requirements/osxfuse_requirement.rb @@ -4,6 +4,8 @@ require "requirement" class OsxfuseRequirement < Requirement + extend T::Sig + download "https://github.com/libfuse/libfuse" satisfy(build_env: false) do @@ -20,6 +22,7 @@ class OsxfuseRequirement < Requirement false end + sig { returns(String) } def message msg = "libfuse is required for this software.\n" if libfuse_formula_exists? @@ -33,6 +36,7 @@ class OsxfuseRequirement < Requirement private + sig { returns(T::Boolean) } def libfuse_formula_exists? begin Formula["libfuse"] diff --git a/Library/Homebrew/extend/os/mac/development_tools.rb b/Library/Homebrew/extend/os/mac/development_tools.rb index 15ea337b26..f101a31056 100644 --- a/Library/Homebrew/extend/os/mac/development_tools.rb +++ b/Library/Homebrew/extend/os/mac/development_tools.rb @@ -6,6 +6,8 @@ require "os/mac/xcode" # @private class DevelopmentTools class << self + extend T::Sig + alias generic_locate locate undef installed?, default_compiler, curl_handles_most_https_certificates?, subversion_handles_most_https_certificates? @@ -28,22 +30,26 @@ class DevelopmentTools MacOS::Xcode.installed? || MacOS::CLT.installed? end + sig { returns(Symbol) } def default_compiler :clang end + sig { returns(T::Boolean) } def curl_handles_most_https_certificates? # The system Curl is too old for some modern HTTPS certificates on # older macOS versions. ENV["HOMEBREW_SYSTEM_CURL_TOO_OLD"].nil? end + sig { returns(T::Boolean) } def subversion_handles_most_https_certificates? # The system Subversion is too old for some HTTPS certificates on # older macOS versions. MacOS.version >= :sierra end + sig { returns(String) } def installation_instructions <<~EOS Install the Command Line Tools: @@ -51,6 +57,7 @@ class DevelopmentTools EOS end + sig { returns(String) } def custom_installation_instructions <<~EOS Install GNU's GCC: diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb b/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb index 633768d805..d882025a2b 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/shared.rb @@ -2,6 +2,9 @@ # frozen_string_literal: true module SharedEnvExtension + extend T::Sig + + sig { returns(T::Boolean) } def no_weak_imports_support? return false unless compiler == :clang diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb index 999c916b70..4e541a2be9 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb @@ -2,6 +2,8 @@ # frozen_string_literal: true module Superenv + extend T::Sig + class << self undef bin @@ -44,6 +46,7 @@ module Superenv end # @private + sig { returns(T::Boolean) } def libxml2_include_needed? return false if deps.any? { |d| d.name == "libxml2" } return false if Pathname("#{self["HOMEBREW_SDKROOT"]}/usr/include/libxml").directory? diff --git a/Library/Homebrew/extend/os/mac/requirements/osxfuse_requirement.rb b/Library/Homebrew/extend/os/mac/requirements/osxfuse_requirement.rb index 3ae4716a47..30510cdb20 100644 --- a/Library/Homebrew/extend/os/mac/requirements/osxfuse_requirement.rb +++ b/Library/Homebrew/extend/os/mac/requirements/osxfuse_requirement.rb @@ -4,10 +4,13 @@ require "requirement" class OsxfuseRequirement < Requirement + extend T::Sig + download "https://osxfuse.github.io/" satisfy(build_env: false) { self.class.binary_osxfuse_installed? } + sig { returns(T::Boolean) } def self.binary_osxfuse_installed? File.exist?("/usr/local/include/osxfuse/fuse.h") && !File.symlink?("/usr/local/include/osxfuse") diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index 6c22d6d201..c237a7133b 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -5,6 +5,8 @@ require "resource" require "metafiles" module DiskUsageExtension + extend T::Sig + def disk_usage return @disk_usage if @disk_usage @@ -19,6 +21,7 @@ module DiskUsageExtension @file_count end + sig { returns(String) } def abv out = +"" compute_disk_usage @@ -71,6 +74,8 @@ end # Homebrew extends Ruby's `Pathname` to make our code more readable. # @see https://ruby-doc.org/stdlib-2.6.3/libdoc/pathname/rdoc/Pathname.html Ruby's Pathname API class Pathname + extend T::Sig + include DiskUsageExtension # @private @@ -282,16 +287,19 @@ class Pathname Dir.chdir(self) { yield self } end + sig { returns(T::Array[Pathname]) } def subdirs children.select(&:directory?) end # @private + sig { returns(Pathname) } def resolved_path symlink? ? dirname.join(readlink) : self end # @private + sig { returns(T::Boolean) } def resolved_path_exists? link = readlink rescue ArgumentError @@ -398,18 +406,22 @@ class Pathname end end + sig { returns(T::Boolean) } def ds_store? basename.to_s == ".DS_Store" end + sig { returns(T::Boolean) } def binary_executable? false end + sig { returns(T::Boolean) } def mach_o_bundle? false end + sig { returns(T::Boolean) } def dylib? false end @@ -420,10 +432,13 @@ require "extend/os/pathname" # @private module ObserverPathnameExtension class << self + extend T::Sig + include Context attr_accessor :n, :d + sig { void } def reset_counts! @n = @d = 0 @put_verbose_trimmed_warning = false diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 7b5e0fde35..10e5347b86 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -52,6 +52,8 @@ require "utils/spdx" # end # end class Formula + extend T::Sig + include FileUtils include Utils::Inreplace include Utils::Shebang @@ -286,6 +288,7 @@ class Formula path end + sig { returns(T.nilable(String)) } def installed_alias_name File.basename(installed_alias_path) if installed_alias_path end @@ -354,6 +357,7 @@ class Formula # The Bottle object for the currently active {SoftwareSpec}. # @private + sig { returns(T.nilable(Bottle)) } def bottle Bottle.new(self, bottle_specification) if bottled? end @@ -407,6 +411,7 @@ class Formula end # The {PkgVersion} for this formula with {version} and {#revision} information. + sig { returns(PkgVersion) } def pkg_version PkgVersion.new(version, revision) end @@ -600,8 +605,9 @@ class Formula # The parent of the prefix; the named directory in the cellar containing all # installed versions of this software. # @private + sig { returns(Pathname) } def rack - Pathname.new("#{HOMEBREW_CELLAR}/#{name}") + HOMEBREW_CELLAR/name end # All currently installed prefix directories. @@ -888,6 +894,7 @@ class Formula end # The prefix, if any, to use in filenames for logging current activity. + sig { returns(String) } def active_log_prefix if active_log_type "#{active_log_type}." @@ -936,6 +943,7 @@ class Formula end # The generated launchd {.plist} service name. + sig { returns(String) } def plist_name "homebrew.mxcl.#{name}" end @@ -958,8 +966,9 @@ class Formula # This is the preferred way to refer to a formula in plists or from another # formula, as the path is stable even when the software is updated. #
args << "--with-readline=#{Formula["readline"].opt_prefix}" if build.with? "readline"
+ sig { returns(Pathname) } def opt_prefix - Pathname.new("#{HOMEBREW_PREFIX}/opt/#{name}") + HOMEBREW_PREFIX/"opt"/name end def opt_bin @@ -1004,6 +1013,7 @@ class Formula # Defaults to true so overridden version does not have to check if bottles # are supported. # Replaced by {.pour_bottle?}'s `satisfy` method if it is specified. + sig { returns(T::Boolean) } def pour_bottle? true end @@ -1160,11 +1170,13 @@ class Formula # @return [String, Symbol] delegate disable_reason: :"self.class" + sig { returns(T::Boolean) } def skip_cxxstdlib_check? false end # @private + sig { returns(T::Boolean) } def require_universal_deps? false end @@ -1365,6 +1377,7 @@ class Formula end # @private + sig { returns(String) } def inspect "#" end @@ -1396,6 +1409,7 @@ class Formula # 3rd party installs. # Note that there isn't a std_autotools variant because autotools is a lot # less consistent and the standard parameters are more memorable. + sig { returns(T::Array[String]) } def std_cmake_args args = %W[ -DCMAKE_C_FLAGS_RELEASE=-DNDEBUG @@ -1423,6 +1437,7 @@ class Formula end # Standard parameters for cabal-v2 builds. + sig { returns(T::Array[String]) } def std_cabal_v2_args # cabal-install's dependency-resolution backtracking strategy can # easily need more than the default 2,000 maximum number of @@ -1434,6 +1449,7 @@ class Formula end # Standard parameters for meson builds. + sig { returns(T::Array[String]) } def std_meson_args ["--prefix=#{prefix}", "--libdir=#{lib}", "--buildtype=release", "--wrap-mode=nofallback"] end @@ -1869,6 +1885,7 @@ class Formula end # @private + sig { returns(T::Boolean) } def test_defined? false end diff --git a/Library/Homebrew/formula_creator.rb b/Library/Homebrew/formula_creator.rb index f30b7082ff..fd9472c2db 100644 --- a/Library/Homebrew/formula_creator.rb +++ b/Library/Homebrew/formula_creator.rb @@ -9,6 +9,8 @@ module Homebrew # # @api private class FormulaCreator + extend T::Sig + attr_reader :args, :url, :sha256, :desc, :homepage attr_accessor :name, :version, :tap, :path, :mode, :license @@ -88,6 +90,7 @@ module Homebrew path.write ERB.new(template, trim_mode: ">").result(binding) end + sig { returns(String) } def template <<~ERB # Documentation: https://docs.brew.sh/Formula-Cookbook diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index aae10e1af1..364aed2746 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -28,6 +28,8 @@ require "unlink" # # @api private class FormulaInstaller + extend T::Sig + include FormulaCellarChecks extend Predicable @@ -776,6 +778,7 @@ class FormulaInstaller unlock end + sig { returns(String) } def summary s = +"" s << "#{Homebrew::EnvConfig.install_badge} " unless Homebrew::EnvConfig.no_emoji? diff --git a/Library/Homebrew/formula_support.rb b/Library/Homebrew/formula_support.rb index 287ffd0f0c..fce3bed2bc 100644 --- a/Library/Homebrew/formula_support.rb +++ b/Library/Homebrew/formula_support.rb @@ -7,6 +7,8 @@ FormulaConflict = Struct.new(:name, :reason) # Used to annotate formulae that duplicate macOS-provided software # or cause conflicts when linked in. class KegOnlyReason + extend T::Sig + attr_reader :reason def initialize(reason, explanation) @@ -30,6 +32,7 @@ class KegOnlyReason provided_by_macos? || shadowed_by_macos? end + sig { returns(T::Boolean) } def applicable? # macOS reasons aren't applicable on other OSs # (see extend/os/mac/formula_support for override on macOS) diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 3be8bbd3ef..efe4ef24b4 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -10,10 +10,13 @@ require "tab" # # @api private module Formulary + extend T::Sig + extend Cachable URL_START_REGEX = %r{(https?|ftp|file)://}.freeze + sig { void } def self.enable_factory_cache! @factory_cache = true end @@ -208,8 +211,11 @@ module Formulary # Loads formulae from URLs. class FromUrlLoader < FormulaLoader + extend T::Sig + attr_reader :url + sig { params(url: T.any(URI::Generic, String)).void } def initialize(url) @url = url uri = URI(url) diff --git a/Library/Homebrew/hardware.rb b/Library/Homebrew/hardware.rb index 11c78eaf58..88625b72a3 100644 --- a/Library/Homebrew/hardware.rb +++ b/Library/Homebrew/hardware.rb @@ -13,6 +13,8 @@ module Hardware PPC_64BIT_ARCHS = [:ppc64, :ppc64le, :ppc970].freeze class << self + extend T::Sig + def optimization_flags @optimization_flags ||= { native: arch_flag("native"), @@ -29,6 +31,7 @@ module Hardware end alias generic_optimization_flags optimization_flags + sig { returns(Symbol) } def arch_32_bit if arm? :arm @@ -41,6 +44,7 @@ module Hardware end end + sig { returns(Symbol) } def arch_64_bit if arm? :arm64 @@ -70,6 +74,7 @@ module Hardware [arch].extend ArchitectureListExtension end + sig { returns(Symbol) } def type case RUBY_PLATFORM when /x86_64/, /i\d86/ then :intel @@ -79,6 +84,7 @@ module Hardware end end + sig { returns(Symbol) } def family :dunno end @@ -98,6 +104,7 @@ module Hardware end end + sig { returns(T::Boolean) } def sse4? RUBY_PLATFORM.to_s.include?("x86_64") end @@ -156,6 +163,7 @@ module Hardware "-march=#{arch}" end + sig { returns(T::Boolean) } def in_rosetta2? false end diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index d46d0dc67e..d968c0c5e3 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -11,6 +11,8 @@ require "extend/cachable" # # @api private class Keg + extend T::Sig + extend Cachable # Error for when a keg is already linked. @@ -39,6 +41,9 @@ class Keg # Error for when a file already exists or belongs to another keg. class ConflictError < LinkError + extend T::Sig + + sig { returns(String) } def suggestion conflict = Keg.for(dst) rescue NotAKegError, Errno::ENOENT @@ -50,6 +55,7 @@ class Keg EOS end + sig { returns(String) } def to_s s = [] s << "Could not symlink #{src}" @@ -67,6 +73,9 @@ class Keg # Error for when a directory is not writable. class DirectoryNotWritableError < LinkError + extend T::Sig + + sig { returns(String) } def to_s <<~EOS Could not symlink #{src} @@ -226,6 +235,7 @@ class Keg alias to_path to_s + sig { returns(String) } def inspect "#<#{self.class.name}:#{path}>" end @@ -235,6 +245,7 @@ class Keg end alias eql? == + sig { returns(T::Boolean) } def empty_installation? Pathname.glob("#{path}/*") do |file| return false if file.directory? && !file.children.reject(&:ds_store?).empty? @@ -411,6 +422,7 @@ class Keg end end + sig { returns(T::Boolean) } def plist_installed? !Dir["#{path}/*.plist"].empty? end @@ -419,10 +431,12 @@ class Keg (path/"lib/python2.7/site-packages").directory? end + sig { returns(T::Boolean) } def python_pth_files_installed? !Dir["#{path}/lib/python2.7/site-packages/*.pth"].empty? end + sig { returns(T::Array[Pathname]) } def apps app_prefix = optlinked? ? opt_record : path Pathname.glob("#{app_prefix}/{,libexec/}*.app") diff --git a/Library/Homebrew/language/node.rb b/Library/Homebrew/language/node.rb index e30c9ba744..1e5e48f7b5 100644 --- a/Library/Homebrew/language/node.rb +++ b/Library/Homebrew/language/node.rb @@ -6,6 +6,9 @@ module Language # # @api public module Node + extend T::Sig + + sig { returns(String) } def self.npm_cache_config "cache=#{HOMEBREW_CACHE}/npm_cache" end @@ -73,6 +76,7 @@ module Language args end + sig { returns(T::Array[String]) } def self.local_npm_install_args setup_npm_environment # npm install args for local style module format diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index a60343a704..5b44de4412 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -114,6 +114,8 @@ module Language # Mixin module for {Formula} adding virtualenv support features. module Virtualenv + extend T::Sig + def self.included(base) base.class_eval do resource "homebrew-virtualenv" do @@ -215,6 +217,7 @@ module Language venv end + sig { returns(T::Array[String]) } def python_names %w[python python3 pypy pypy3] + Formula.names.select { |name| name.start_with? "python@" } end diff --git a/Library/Homebrew/linkage_checker.rb b/Library/Homebrew/linkage_checker.rb index 67ab46e093..d1a898cfd6 100644 --- a/Library/Homebrew/linkage_checker.rb +++ b/Library/Homebrew/linkage_checker.rb @@ -10,6 +10,8 @@ require "fiddle" # # @api private class LinkageChecker + extend T::Sig + attr_reader :undeclared_deps, :keg, :formula, :store def initialize(keg, formula = nil, cache_db:, rebuild_cache: false) @@ -78,6 +80,7 @@ class LinkageChecker puts "Unexpected non-missing linkage detected" if unexpected_present_dylibs.present? end + sig { returns(T::Boolean) } def broken_library_linkage? issues = [@broken_deps, @unwanted_system_dylibs, @version_conflict_deps] [issues, unexpected_broken_dylibs, unexpected_present_dylibs].flatten.any?(&:present?) diff --git a/Library/Homebrew/locale.rb b/Library/Homebrew/locale.rb index 7a9ee544ca..fcfa56f80f 100644 --- a/Library/Homebrew/locale.rb +++ b/Library/Homebrew/locale.rb @@ -7,7 +7,9 @@ # # @api private class Locale - # Error when a string cannot be parsed to a {Locale}. + extend T::Sig + + # Error when a string cannot be parsed to a `Locale`. class ParserError < StandardError end @@ -34,6 +36,7 @@ class Locale raise ParserError, "'#{string}' cannot be parsed to a #{self}" end + sig { params(string: String).returns(T.nilable(T.attached_class)) } def self.try_parse(string) return if string.blank? @@ -107,6 +110,7 @@ class Locale locale_groups.find { |locales| locales.any? { |locale| include?(locale) } } end + sig { returns(String) } def to_s [@language, @region, @script].compact.join("-") end diff --git a/Library/Homebrew/messages.rb b/Library/Homebrew/messages.rb index fee41654da..e212896790 100644 --- a/Library/Homebrew/messages.rb +++ b/Library/Homebrew/messages.rb @@ -4,8 +4,11 @@ # A {Messages} object collects messages that may need to be displayed together # at the end of a multi-step `brew` command run. class Messages + extend T::Sig + attr_reader :caveats, :formula_count, :install_times + sig { void } def initialize @caveats = [] @formula_count = 0 diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 4713960d24..688a743bbf 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -9,6 +9,8 @@ require "tab" # # @api private class Migrator + extend T::Sig + include Context # Error for when a migration is necessary. @@ -155,6 +157,7 @@ class Migrator end end + sig { returns(T::Boolean) } def from_same_tap_user? formula_tap_user = formula.tap.user if formula.tap old_tap_user = nil diff --git a/Library/Homebrew/mktemp.rb b/Library/Homebrew/mktemp.rb index 5b7704d97e..e5e0277e2c 100644 --- a/Library/Homebrew/mktemp.rb +++ b/Library/Homebrew/mktemp.rb @@ -4,6 +4,8 @@ # Performs {Formula#mktemp}'s functionality, and tracks the results. # Each instance is only intended to be used once. class Mktemp + extend T::Sig + include FileUtils # Path to the tmpdir used in this run, as a {Pathname}. @@ -16,6 +18,7 @@ class Mktemp end # Instructs this {Mktemp} to retain the staged files. + sig { void } def retain! @retain = true end @@ -26,10 +29,12 @@ class Mktemp end # Instructs this Mktemp to not emit messages when retention is triggered. + sig { void } def quiet! @quiet = true end + sig { returns(String) } def to_s "[Mktemp: #{tmpdir} retain=#{@retain} quiet=#{@quiet}]" end diff --git a/Library/Homebrew/options.rb b/Library/Homebrew/options.rb index 9e4a229ed1..5102e36661 100644 --- a/Library/Homebrew/options.rb +++ b/Library/Homebrew/options.rb @@ -5,6 +5,8 @@ # # @api private class Option + extend T::Sig + attr_reader :name, :description, :flag def initialize(name, description = "") @@ -32,6 +34,7 @@ class Option name.hash end + sig { returns(String) } def inspect "#<#{self.class.name}: #{flag.inspect}>" end @@ -41,6 +44,8 @@ end # # @api private class DeprecatedOption + extend T::Sig + attr_reader :old, :current def initialize(old, current) @@ -48,10 +53,12 @@ class DeprecatedOption @current = current end + sig { returns(String) } def old_flag "--#{old}" end + sig { returns(String) } def current_flag "--#{current}" end @@ -66,6 +73,8 @@ end # # @api private class Options + extend T::Sig + include Enumerable def self.create(array) @@ -119,6 +128,7 @@ class Options alias to_ary to_a + sig { returns(String) } def inspect "#<#{self.class.name}: #{to_a.inspect}>" end diff --git a/Library/Homebrew/os/linux.rb b/Library/Homebrew/os/linux.rb index 17d2fee346..039e6ab98f 100644 --- a/Library/Homebrew/os/linux.rb +++ b/Library/Homebrew/os/linux.rb @@ -4,8 +4,11 @@ module OS # Helper module for querying system information on Linux. module Linux + extend T::Sig + module_function + sig { returns(String) } def os_version if which("lsb_release") description = Utils.popen_read("lsb_release -d") diff --git a/Library/Homebrew/os/linux/glibc.rb b/Library/Homebrew/os/linux/glibc.rb index 49df817c37..77b06fa757 100644 --- a/Library/Homebrew/os/linux/glibc.rb +++ b/Library/Homebrew/os/linux/glibc.rb @@ -7,6 +7,8 @@ module OS # # @api private module Glibc + extend T::Sig + module_function def system_version @@ -18,6 +20,7 @@ module OS @system_version = Version.new version end + sig { returns(Version) } def minimum_version Version.new "2.13" end diff --git a/Library/Homebrew/os/linux/kernel.rb b/Library/Homebrew/os/linux/kernel.rb index fd535699bc..d74a7412a4 100644 --- a/Library/Homebrew/os/linux/kernel.rb +++ b/Library/Homebrew/os/linux/kernel.rb @@ -7,8 +7,11 @@ module OS # # @api private module Kernel + extend T::Sig + module_function + sig { returns(Version) } def minimum_version Version.new "2.6.32" end diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb index c7cd7e1820..8f6a58aaa6 100644 --- a/Library/Homebrew/os/mac.rb +++ b/Library/Homebrew/os/mac.rb @@ -10,6 +10,8 @@ require "os/mac/keg" module OS # Helper module for querying system information on macOS. module Mac + extend T::Sig + module_function # rubocop:disable Naming/ConstantName @@ -81,6 +83,7 @@ module OS @active_developer_dir ||= Utils.popen_read("/usr/bin/xcode-select", "-print-path").strip end + sig { returns(T::Boolean) } def sdk_root_needed? if MacOS::CLT.installed? # If there's no CLT SDK, return false diff --git a/Library/Homebrew/os/mac/sdk.rb b/Library/Homebrew/os/mac/sdk.rb index 3a94bc9709..b4a7ff9806 100644 --- a/Library/Homebrew/os/mac/sdk.rb +++ b/Library/Homebrew/os/mac/sdk.rb @@ -92,6 +92,9 @@ module OS # # @api private class XcodeSDKLocator < BaseSDKLocator + extend T::Sig + + sig { returns(Symbol) } def source :xcode end @@ -115,6 +118,9 @@ module OS # # @api private class CLTSDKLocator < BaseSDKLocator + extend T::Sig + + sig { returns(Symbol) } def source :clt end diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index f79ab66384..a2c833655b 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -7,15 +7,18 @@ module OS # # @api private module Xcode + extend T::Sig + module_function - DEFAULT_BUNDLE_PATH = Pathname.new("/Applications/Xcode.app").freeze + DEFAULT_BUNDLE_PATH = Pathname("/Applications/Xcode.app").freeze BUNDLE_ID = "com.apple.dt.Xcode" OLD_BUNDLE_ID = "com.apple.Xcode" # Bump these when a new version is available from the App Store and our # CI systems have been updated. # This may be a beta version for a beta macOS. + sig { returns(String) } def latest_version latest_stable = "12.2" case MacOS.version @@ -39,6 +42,7 @@ module OS # without this. Generally this will be the first Xcode release on that # macOS version (which may initially be a beta if that version of macOS is # also in beta). + sig { returns(String) } def minimum_version case MacOS.version when "11.0" then "12.0" @@ -93,8 +97,9 @@ module OS end end + sig { returns(Pathname) } def toolchain_path - Pathname.new("#{prefix}/Toolchains/XcodeDefault.xctoolchain") + Pathname("#{prefix}/Toolchains/XcodeDefault.xctoolchain") end def bundle_path @@ -107,6 +112,7 @@ module OS MacOS.app_with_bundle_id(BUNDLE_ID, OLD_BUNDLE_ID) end + sig { returns(T::Boolean) } def installed? !prefix.nil? end @@ -123,6 +129,7 @@ module OS sdk(v)&.path end + sig { returns(String) } def update_instructions if OS::Mac.prerelease? <<~EOS @@ -174,6 +181,7 @@ module OS detect_version_from_clang_version end + sig { returns(String) } def detect_version_from_clang_version return "dunno" if DevelopmentTools.clang_version.null? @@ -208,6 +216,8 @@ module OS # # @api private module CLT + extend T::Sig + module_function # The original Mavericks CLT package ID @@ -216,6 +226,7 @@ module OS PKG_PATH = "/Library/Developer/CommandLineTools" # Returns true even if outdated tools are installed. + sig { returns(T::Boolean) } def installed? !version.null? end @@ -240,6 +251,7 @@ module OS sdk(v)&.path end + sig { returns(String) } def update_instructions software_update_location = if MacOS.version >= "10.14" "System Preferences" @@ -262,6 +274,7 @@ module OS # Bump these when the new version is distributed through Software Update # and our CI systems have been updated. + sig { returns(String) } def latest_clang_version case MacOS.version when "11.0" then "1200.0.32.27" @@ -278,6 +291,7 @@ module OS # Bump these if things are badly broken (e.g. no SDK for this macOS) # without this. Generally this will be the first stable CLT release on # that macOS version. + sig { returns(String) } def minimum_version case MacOS.version when "11.0" then "12.0.0" @@ -295,6 +309,7 @@ module OS version < minimum_version end + sig { returns(T::Boolean) } def outdated? clang_version = detect_clang_version return false unless clang_version diff --git a/Library/Homebrew/os/mac/xquartz.rb b/Library/Homebrew/os/mac/xquartz.rb index c056a27529..00819de600 100644 --- a/Library/Homebrew/os/mac/xquartz.rb +++ b/Library/Homebrew/os/mac/xquartz.rb @@ -7,9 +7,11 @@ module OS # # @api private module XQuartz + extend T::Sig + module_function - DEFAULT_BUNDLE_PATH = Pathname.new("Applications/Utilities/XQuartz.app").freeze + DEFAULT_BUNDLE_PATH = Pathname("Applications/Utilities/XQuartz.app").freeze FORGE_BUNDLE_ID = "org.macosforge.xquartz.X11" FORGE_PKG_ID = "org.macosforge.xquartz.pkg" @@ -52,6 +54,7 @@ module OS end end + sig { returns(String) } def minimum_version # Update this a little later than latest_version to give people # time to upgrade. @@ -59,6 +62,7 @@ module OS end # @see https://www.xquartz.org/releases/index.html + sig { returns(String) } def latest_version "2.7.11" end diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb index 61d00d6a08..1157c61005 100644 --- a/Library/Homebrew/patch.rb +++ b/Library/Homebrew/patch.rb @@ -60,6 +60,8 @@ end # # @api private class EmbeddedPatch + extend T::Sig + attr_writer :owner attr_reader :strip @@ -67,6 +69,7 @@ class EmbeddedPatch @strip = strip end + sig { returns(T::Boolean) } def external? false end @@ -79,6 +82,7 @@ class EmbeddedPatch Utils.safe_popen_write("patch", *args) { |p| p.write(data) } end + sig { returns(String) } def inspect "#<#{self.class.name}: #{strip.inspect}>" end @@ -88,6 +92,8 @@ end # # @api private class DATAPatch < EmbeddedPatch + extend T::Sig + attr_accessor :path def initialize(strip) @@ -95,6 +101,7 @@ class DATAPatch < EmbeddedPatch @path = nil end + sig { returns(String) } def contents data = +"" path.open("rb") do |f| @@ -128,6 +135,8 @@ end # # @api private class ExternalPatch + extend T::Sig + extend Forwardable attr_reader :resource, :strip @@ -141,6 +150,7 @@ class ExternalPatch @resource = Resource::PatchResource.new(&block) end + sig { returns(T::Boolean) } def external? true end @@ -181,6 +191,7 @@ class ExternalPatch raise BuildError.new(f, cmd, args, ENV.to_hash) end + sig { returns(String) } def inspect "#<#{self.class.name}: #{strip.inspect} #{url.inspect}>" end diff --git a/Library/Homebrew/requirement.rb b/Library/Homebrew/requirement.rb index 1f10e4aee7..93863c3086 100644 --- a/Library/Homebrew/requirement.rb +++ b/Library/Homebrew/requirement.rb @@ -12,6 +12,8 @@ require "build_environment" # # @api private class Requirement + extend T::Sig + include Dependable attr_reader :tags, :name, :cask, :download @@ -35,6 +37,7 @@ class Requirement end # The message to show when the requirement is not met. + sig { returns(String) } def message _, _, class_name = self.class.to_s.rpartition "::" s = "#{class_name} unsatisfied!\n" @@ -121,6 +124,7 @@ class Requirement name.hash ^ tags.hash end + sig { returns(String) } def inspect "#<#{self.class.name}: #{tags.inspect}>" end @@ -155,6 +159,8 @@ class Requirement end class << self + extend T::Sig + include BuildEnvironment::DSL attr_reader :env_proc, :build @@ -241,6 +247,7 @@ class Requirement end # Used to prune requirements when calling expand with a block. + sig { void } def prune throw(:prune, true) end diff --git a/Library/Homebrew/requirements/arch_requirement.rb b/Library/Homebrew/requirements/arch_requirement.rb index ec6a213174..8c65b44fa6 100644 --- a/Library/Homebrew/requirements/arch_requirement.rb +++ b/Library/Homebrew/requirements/arch_requirement.rb @@ -7,6 +7,8 @@ require "requirement" # # @api private class ArchRequirement < Requirement + extend T::Sig + fatal true attr_reader :arch @@ -24,6 +26,7 @@ class ArchRequirement < Requirement end end + sig { returns(String) } def message "The #{@arch} architecture is required for this software." end @@ -32,6 +35,7 @@ class ArchRequirement < Requirement "#<#{self.class.name}: arch=#{@arch.to_s.inspect} #{tags.inspect}>" end + sig { returns(String) } def display_s "#{@arch} architecture" end diff --git a/Library/Homebrew/requirements/codesign_requirement.rb b/Library/Homebrew/requirements/codesign_requirement.rb index 54fb9352a2..06caebda71 100644 --- a/Library/Homebrew/requirements/codesign_requirement.rb +++ b/Library/Homebrew/requirements/codesign_requirement.rb @@ -5,6 +5,8 @@ # # @api private class CodesignRequirement < Requirement + extend T::Sig + fatal true def initialize(tags) @@ -26,6 +28,7 @@ class CodesignRequirement < Requirement end end + sig { returns(String) } def message message = "#{@identity} identity must be available to build with #{@with}" message += ":\n#{@url}" if @url.present? diff --git a/Library/Homebrew/requirements/java_requirement.rb b/Library/Homebrew/requirements/java_requirement.rb index 3edab63aa8..fdee4f4e03 100644 --- a/Library/Homebrew/requirements/java_requirement.rb +++ b/Library/Homebrew/requirements/java_requirement.rb @@ -7,6 +7,8 @@ require "language/java" # # @api private class JavaRequirement < Requirement + extend T::Sig + fatal true attr_reader :java_home, :version @@ -37,6 +39,7 @@ class JavaRequirement < Requirement @cask = suggestion.token end + sig { returns(String) } def message version_string = " #{@version}" if @version s = "Java#{version_string} is required for this software.\n" @@ -44,6 +47,7 @@ class JavaRequirement < Requirement s end + sig { returns(String) } def inspect "#<#{self.class.name}: version=#{@version.inspect} #{tags.inspect}>" end @@ -64,6 +68,9 @@ class JavaRequirement < Requirement private CaskSuggestion = Struct.new(:token, :title) do + extend T::Sig + + sig { returns(String) } def to_str title_string = " #{title}" if title <<~EOS diff --git a/Library/Homebrew/requirements/linux_requirement.rb b/Library/Homebrew/requirements/linux_requirement.rb index 1a0e496282..410c39bcc4 100644 --- a/Library/Homebrew/requirements/linux_requirement.rb +++ b/Library/Homebrew/requirements/linux_requirement.rb @@ -5,10 +5,13 @@ # # @api private class LinuxRequirement < Requirement + extend T::Sig + fatal true satisfy(build_env: false) { OS.linux? } + sig { returns(String) } def message "Linux is required for this software." end diff --git a/Library/Homebrew/requirements/macos_requirement.rb b/Library/Homebrew/requirements/macos_requirement.rb index c00750b9a2..e628588f0c 100644 --- a/Library/Homebrew/requirements/macos_requirement.rb +++ b/Library/Homebrew/requirements/macos_requirement.rb @@ -7,6 +7,8 @@ require "requirement" # # @api private class MacOSRequirement < Requirement + extend T::Sig + fatal true attr_reader :comparator, :version @@ -66,10 +68,12 @@ class MacOSRequirement < Requirement end end + sig { returns(String) } def inspect "#<#{self.class.name}: version#{@comparator}#{@version.to_s.inspect} #{tags.inspect}>" end + sig { returns(String) } def display_s return "macOS" unless version_specified? diff --git a/Library/Homebrew/requirements/tuntap_requirement.rb b/Library/Homebrew/requirements/tuntap_requirement.rb index 40075a947b..3599dcff4c 100644 --- a/Library/Homebrew/requirements/tuntap_requirement.rb +++ b/Library/Homebrew/requirements/tuntap_requirement.rb @@ -7,10 +7,13 @@ require "requirement" # # @api private class TuntapRequirement < Requirement + extend T::Sig + fatal true cask "tuntap" satisfy(build_env: false) { self.class.binary_tuntap_installed? } + sig { returns(T::Boolean) } def self.binary_tuntap_installed? %w[ /Library/Extensions/tun.kext diff --git a/Library/Homebrew/requirements/x11_requirement.rb b/Library/Homebrew/requirements/x11_requirement.rb index 4418f2f8ef..d55a0ef984 100644 --- a/Library/Homebrew/requirements/x11_requirement.rb +++ b/Library/Homebrew/requirements/x11_requirement.rb @@ -7,6 +7,8 @@ require "requirement" # # @api private class X11Requirement < Requirement + extend T::Sig + include Comparable fatal true @@ -16,10 +18,12 @@ class X11Requirement < Requirement env { ENV.x11 } + sig { returns(String) } def min_version "1.12.2" end + sig { returns(String) } def min_xdpyinfo_version "1.3.0" end @@ -38,6 +42,7 @@ class X11Requirement < Requirement false end + sig { returns(String) } def message "X11 is required for this software, either Xorg #{min_version} or " \ "xdpyinfo #{min_xdpyinfo_version}, or newer. #{super}" @@ -48,6 +53,11 @@ class X11Requirement < Requirement 0 end + + sig { returns(String) } + def inspect + "#<#{self.class.name}: #{tags.inspect}>" + end end require "extend/os/requirements/x11_requirement" diff --git a/Library/Homebrew/requirements/xcode_requirement.rb b/Library/Homebrew/requirements/xcode_requirement.rb index b3e6973cfd..775d62fc56 100644 --- a/Library/Homebrew/requirements/xcode_requirement.rb +++ b/Library/Homebrew/requirements/xcode_requirement.rb @@ -7,6 +7,8 @@ require "requirement" # # @api private class XcodeRequirement < Requirement + extend T::Sig + fatal true attr_reader :version @@ -25,6 +27,7 @@ class XcodeRequirement < Requirement MacOS::Xcode.version >= @version end + sig { returns(String) } def message version = " #{@version}" if @version message = <<~EOS @@ -45,6 +48,7 @@ class XcodeRequirement < Requirement end end + sig { returns(String) } def inspect "#<#{self.class.name}: version>=#{@version.inspect} #{tags.inspect}>" end diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index f9c536467c..7e16b3582e 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -253,6 +253,8 @@ end # # @api private class ResourceStageContext + extend T::Sig + extend Forwardable # The {Resource} that is being staged. @@ -268,6 +270,7 @@ class ResourceStageContext @staging = staging end + sig { returns(String) } def to_s "<#{self.class}: resource=#{resource} staging=#{staging}>" end diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index e5c5651439..24a89b54ae 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -3,6 +3,8 @@ require_relative "load_path" +require "utils/sorbet" + require "rubocop-performance" require "rubocop-rspec" require "rubocop-sorbet" diff --git a/Library/Homebrew/rubocops/cask/ast/cask_header.rb b/Library/Homebrew/rubocops/cask/ast/cask_header.rb index a869967a5b..addb8a718c 100644 --- a/Library/Homebrew/rubocops/cask/ast/cask_header.rb +++ b/Library/Homebrew/rubocops/cask/ast/cask_header.rb @@ -7,6 +7,8 @@ module RuboCop # This class wraps the AST method node that represents the cask header. It # includes various helper methods to aid cops in their analysis. class CaskHeader + extend T::Sig + def initialize(method_node) @method_node = method_node end @@ -25,6 +27,7 @@ module RuboCop @source_range ||= method_node.loc.expression end + sig { returns(String) } def preferred_header_str "cask '#{cask_token}'" end diff --git a/Library/Homebrew/rubocops/cask/extend/string.rb b/Library/Homebrew/rubocops/cask/extend/string.rb index e89bed3af4..f4e4ee3be0 100644 --- a/Library/Homebrew/rubocops/cask/extend/string.rb +++ b/Library/Homebrew/rubocops/cask/extend/string.rb @@ -3,6 +3,9 @@ # Utility method extensions for String. class String + extend T::Sig + + sig { returns(String) } def undent gsub(/^.{#{(slice(/^ +/) || '').length}}/, "") end diff --git a/Library/Homebrew/rubocops/cask/no_dsl_version.rb b/Library/Homebrew/rubocops/cask/no_dsl_version.rb index 2d2aca942b..7866e52fe6 100644 --- a/Library/Homebrew/rubocops/cask/no_dsl_version.rb +++ b/Library/Homebrew/rubocops/cask/no_dsl_version.rb @@ -19,6 +19,8 @@ module RuboCop # ... # end class NoDslVersion < Cop + extend T::Sig + extend Forwardable include CaskHelp @@ -56,6 +58,7 @@ module RuboCop message: error_msg) end + sig { returns(String) } def error_msg format(MESSAGE, preferred: preferred_header_str, current: header_str) end diff --git a/Library/Homebrew/rubocops/patches.rb b/Library/Homebrew/rubocops/patches.rb index 8d85bd9f93..57c746df52 100644 --- a/Library/Homebrew/rubocops/patches.rb +++ b/Library/Homebrew/rubocops/patches.rb @@ -9,6 +9,8 @@ module RuboCop module FormulaAudit # This cop audits `patch`es in formulae. class Patches < FormulaCop + extend T::Sig + def audit_formula(node, _class_node, _parent_class_node, body) @full_source_content = source_buffer(node).source @@ -121,6 +123,7 @@ module RuboCop (send nil? :patch (:sym :DATA)) AST + sig { returns(T::Boolean) } def patch_end? /^__END__$/.match?(@full_source_content) end diff --git a/Library/Homebrew/rubocops/urls.rb b/Library/Homebrew/rubocops/urls.rb index 3c7b855da0..62e347666b 100644 --- a/Library/Homebrew/rubocops/urls.rb +++ b/Library/Homebrew/rubocops/urls.rb @@ -294,6 +294,8 @@ module RuboCop # # @api private class PyPiUrls < FormulaCop + extend T::Sig + def audit_formula(_node, _class_node, _parent_class_node, body_node) urls = find_every_func_call_by_name(body_node, :url) mirrors = find_every_func_call_by_name(body_node, :mirror) @@ -312,6 +314,7 @@ module RuboCop end end + sig { params(url: String).returns(String) } def get_pypi_url(url) package_file = File.basename(url) package_name = package_file.match(/^(.+)-[a-z0-9.]+$/)[1] diff --git a/Library/Homebrew/sandbox.rb b/Library/Homebrew/sandbox.rb index 54d0a76682..2f79ae6a86 100644 --- a/Library/Homebrew/sandbox.rb +++ b/Library/Homebrew/sandbox.rb @@ -8,13 +8,17 @@ require "tempfile" # # @api private class Sandbox + extend T::Sig + SANDBOX_EXEC = "/usr/bin/sandbox-exec" private_constant :SANDBOX_EXEC + sig { returns(T::Boolean) } def self.available? OS.mac? && File.executable?(SANDBOX_EXEC) end + sig { void } def initialize @profile = SandboxProfile.new end @@ -146,6 +150,8 @@ class Sandbox # Configuration profile for a sandbox. class SandboxProfile + extend T::Sig + SEATBELT_ERB = <<~ERB (version 1) (debug deny) ; log all denied operations to /var/log/system.log @@ -169,6 +175,7 @@ class Sandbox attr_reader :rules + sig { void } def initialize @rules = [] end diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index 8a6ed260e6..14067d5a6e 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -14,6 +14,8 @@ require "global" require "os/mac/version" class SoftwareSpec + extend T::Sig + extend Forwardable PREDEFINED_OPTIONS = { @@ -78,6 +80,7 @@ class SoftwareSpec @bottle_disable_reason.unneeded? end + sig { returns(T::Boolean) } def bottle_disabled? @bottle_disable_reason ? true : false end @@ -247,6 +250,8 @@ end class Bottle class Filename + extend T::Sig + attr_reader :name, :version, :tag, :rebuild def self.create(formula, tag, rebuild) @@ -260,11 +265,13 @@ class Bottle @rebuild = rebuild end + sig { returns(String) } def to_s "#{name}--#{version}#{extname}" end alias to_str to_s + sig { returns(String) } def json "#{name}--#{version}.#{tag}.bottle.json" end @@ -273,6 +280,7 @@ class Bottle ERB::Util.url_encode("#{name}-#{version}#{extname}") end + sig { returns(String) } def extname s = rebuild.positive? ? ".#{rebuild}" : "" ".#{tag}.bottle#{s}.tar.gz" @@ -327,12 +335,15 @@ class Bottle end class BottleSpecification + extend T::Sig + DEFAULT_PREFIX = Homebrew::DEFAULT_PREFIX attr_rw :prefix, :cellar, :rebuild attr_accessor :tap attr_reader :checksum, :collector, :root_url_specs + sig { void } def initialize @rebuild = 0 @prefix = Homebrew::DEFAULT_PREFIX @@ -355,6 +366,7 @@ class BottleSpecification end # Does the {Bottle} this {BottleSpecification} belongs to need to be relocated? + sig { returns(T::Boolean) } def skip_relocation? cellar == :any_skip_relocation end diff --git a/Library/Homebrew/style.rb b/Library/Homebrew/style.rb index 40a11b50cf..3f10decf18 100644 --- a/Library/Homebrew/style.rb +++ b/Library/Homebrew/style.rb @@ -269,6 +269,8 @@ module Homebrew # Source location of a style offense. class LineLocation + extend T::Sig + attr_reader :line, :column def initialize(json) @@ -276,6 +278,7 @@ module Homebrew @column = json["column"] end + sig { returns(String) } def to_s "#{line}: col #{column}" end diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index 3d83ec5c0a..a9ef6cf6b5 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -15,6 +15,8 @@ using HashValidator # # @api private class SystemCommand + extend T::Sig + # Helper functions for calling {SystemCommand.run}. module Mixin def system_command(*args) @@ -39,6 +41,7 @@ class SystemCommand run(command, **options, must_succeed: true) end + sig { returns(SystemCommand::Result) } def run! puts redact_secrets(command.shelljoin.gsub('\=', "="), @secrets) if verbose? || debug? diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb index 02230bb9b4..6702c71635 100644 --- a/Library/Homebrew/system_config.rb +++ b/Library/Homebrew/system_config.rb @@ -12,6 +12,8 @@ require "system_command" # @api private module SystemConfig class << self + extend T::Sig + include SystemCommand::Mixin def clang @@ -30,34 +32,42 @@ module SystemConfig end end + sig { returns(String) } def head HOMEBREW_REPOSITORY.git_head || "(none)" end + sig { returns(String) } def last_commit HOMEBREW_REPOSITORY.git_last_commit || "never" end + sig { returns(String) } def origin HOMEBREW_REPOSITORY.git_origin || "(none)" end + sig { returns(String) } def core_tap_head CoreTap.instance.git_head || "(none)" end + sig { returns(String) } def core_tap_last_commit CoreTap.instance.git_last_commit || "never" end + sig { returns(String) } def core_tap_branch CoreTap.instance.git_branch || "(none)" end + sig { returns(String) } def core_tap_origin CoreTap.instance.remote || "(none)" end + sig { returns(String) } def describe_clang return "N/A" if clang.null? @@ -76,6 +86,7 @@ module SystemConfig end end + sig { returns(String) } def describe_homebrew_ruby_version case RUBY_VERSION when /^1\.[89]/, /^2\.0/ @@ -85,20 +96,24 @@ module SystemConfig end end + sig { returns(String) } def describe_homebrew_ruby "#{describe_homebrew_ruby_version} => #{RUBY_PATH}" end + sig { returns(T.nilable(String)) } def hardware return if Hardware::CPU.type == :dunno "CPU: #{Hardware.cores_as_words}-core #{Hardware::CPU.bits}-bit #{Hardware::CPU.family}" end + sig { returns(String) } def kernel `uname -m`.chomp end + sig { returns(String) } def describe_java return "N/A" unless which "java" @@ -108,12 +123,14 @@ module SystemConfig err[/java version "([\d._]+)"/, 1] || "N/A" end + sig { returns(String) } def describe_git return "N/A" unless Utils::Git.available? "#{Utils::Git.version} => #{Utils::Git.path}" end + sig { returns(String) } def describe_curl out, = system_command(curl_executable, args: ["--version"]) diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 4d6a4a7728..8b732cae14 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -12,6 +12,8 @@ require "extend/cachable" # hash and creates an attribute for each key and value. Rather than calling # `new` directly, use one of the class methods like {Tab.create}. class Tab < OpenStruct + extend T::Sig + extend Cachable FILENAME = "INSTALL_RECEIPT.json" @@ -324,6 +326,7 @@ class Tab < OpenStruct versions["version_scheme"] || 0 end + sig { returns(Time) } def source_modified_time Time.at(super || 0) end @@ -362,6 +365,7 @@ class Tab < OpenStruct tabfile.atomic_write(to_json) end + sig { returns(String) } def to_s s = [] s << if poured_from_bottle diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index 3e40bad395..2eae5745e2 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -12,6 +12,8 @@ require "description_cache_store" # {#user} represents the GitHub username and {#repo} represents the repository # name without the leading `homebrew-`. class Tap + extend T::Sig + extend Cachable TAP_DIRECTORY = (HOMEBREW_LIBRARY/"Taps").freeze @@ -123,6 +125,7 @@ class Tap end # The default remote path to this {Tap}. + sig { returns(String) } def default_remote "https://github.com/#{full_name}" end @@ -176,6 +179,7 @@ class Tap # The issues URL of this {Tap}. # e.g. `https://github.com/user/homebrew-repo/issues` + sig { returns(T.nilable(String)) } def issues_url return unless official? || !custom_remote? @@ -186,6 +190,7 @@ class Tap name end + sig { returns(String) } def version_string return "N/A" unless installed? @@ -227,6 +232,7 @@ class Tap end # @private + sig { returns(T::Boolean) } def core_tap? false end @@ -595,6 +601,7 @@ class Tap end # An array of all tap cmd directory {Pathname}s. + sig { returns(T::Array[Pathname]) } def self.cmd_directories Pathname.glob TAP_DIRECTORY/"*/*/cmd" end @@ -633,7 +640,10 @@ end # A specialized {Tap} class for the core formulae. class CoreTap < Tap + extend T::Sig + # @private + sig { void } def initialize super "Homebrew", "core" end @@ -660,26 +670,31 @@ class CoreTap < Tap end # @private + sig { void } def uninstall raise "Tap#uninstall is not available for CoreTap" end # @private + sig { void } def pin raise "Tap#pin is not available for CoreTap" end # @private + sig { void } def unpin raise "Tap#unpin is not available for CoreTap" end # @private + sig { returns(T::Boolean) } def pinned? false end # @private + sig { returns(T::Boolean) } def core_tap? true end diff --git a/Library/Homebrew/test/exceptions_spec.rb b/Library/Homebrew/test/exceptions_spec.rb index e938c843c7..fee12d3fbb 100644 --- a/Library/Homebrew/test/exceptions_spec.rb +++ b/Library/Homebrew/test/exceptions_spec.rb @@ -48,12 +48,12 @@ describe FormulaUnavailableError do it "returns a string if there is a dependent" do subject.dependent = "foobar" - expect(subject.dependent_s).to eq("(dependency of foobar)") + expect(subject.dependent_s).to eq(" (dependency of foobar)") end end context "without a dependent" do - its(:to_s) { is_expected.to eq('No available formula with the name "foo" ') } + its(:to_s) { is_expected.to eq('No available formula with the name "foo".') } end context "with a dependent" do @@ -62,7 +62,7 @@ describe FormulaUnavailableError do end its(:to_s) { - expect(subject.to_s).to eq('No available formula with the name "foo" (dependency of foobar)') + expect(subject.to_s).to eq('No available formula with the name "foo" (dependency of foobar).') } end end diff --git a/Library/Homebrew/test/rubocop_spec.rb b/Library/Homebrew/test/rubocop_spec.rb index 83ae2ddf68..1526df7506 100644 --- a/Library/Homebrew/test/rubocop_spec.rb +++ b/Library/Homebrew/test/rubocop_spec.rb @@ -10,11 +10,12 @@ describe "RuboCop" do ENV.delete(key) if key.start_with?("HOMEBREW_") end - ENV["XDG_CACHE_HOME"] = "#{HOMEBREW_CACHE}/style" + ENV["XDG_CACHE_HOME"] = (HOMEBREW_CACHE.realpath/"style").to_s end it "loads all Formula cops without errors" do - stdout, _, status = Open3.capture3("rubocop", TEST_FIXTURE_DIR/"testball.rb") + stdout, stderr, status = Open3.capture3("rubocop", TEST_FIXTURE_DIR/"testball.rb") + expect(stderr).to be_empty expect(stdout).to include("no offenses detected") expect(status).to be_a_success end diff --git a/Library/Homebrew/unpack_strategy/air.rb b/Library/Homebrew/unpack_strategy/air.rb index 8d6e73cd1c..9f8bd8c473 100644 --- a/Library/Homebrew/unpack_strategy/air.rb +++ b/Library/Homebrew/unpack_strategy/air.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking Adobe Air archives. class Air + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".air"] end @@ -28,6 +31,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! AIR_APPLICATION_INSTALLER, args: ["-silent", "-location", unpack_dir, path], diff --git a/Library/Homebrew/unpack_strategy/bazaar.rb b/Library/Homebrew/unpack_strategy/bazaar.rb index f50957a124..12fbd503d0 100644 --- a/Library/Homebrew/unpack_strategy/bazaar.rb +++ b/Library/Homebrew/unpack_strategy/bazaar.rb @@ -6,6 +6,8 @@ require_relative "directory" module UnpackStrategy # Strategy for unpacking Bazaar archives. class Bazaar < Directory + extend T::Sig + using Magic def self.can_extract?(path) @@ -14,11 +16,12 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) super # The export command doesn't work on checkouts (see https://bugs.launchpad.net/bzr/+bug/897511). - FileUtils.rm_r unpack_dir/".bzr" + (unpack_dir/".bzr").rmtree end end end diff --git a/Library/Homebrew/unpack_strategy/bzip2.rb b/Library/Homebrew/unpack_strategy/bzip2.rb index 79d25aaa5b..6b05e4dc15 100644 --- a/Library/Homebrew/unpack_strategy/bzip2.rb +++ b/Library/Homebrew/unpack_strategy/bzip2.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking bzip2 archives. class Bzip2 + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".bz2"] end @@ -18,6 +21,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) FileUtils.cp path, unpack_dir/basename, preserve: true quiet_flags = verbose ? [] : ["-q"] diff --git a/Library/Homebrew/unpack_strategy/cab.rb b/Library/Homebrew/unpack_strategy/cab.rb index 00b0831288..89feaf0df6 100644 --- a/Library/Homebrew/unpack_strategy/cab.rb +++ b/Library/Homebrew/unpack_strategy/cab.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking Cabinet archives. class Cab + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".cab"] end @@ -16,6 +19,7 @@ module UnpackStrategy path.magic_number.match?(/\AMSCF/n) end + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "cabextract", args: ["-d", unpack_dir, "--", path], diff --git a/Library/Homebrew/unpack_strategy/compress.rb b/Library/Homebrew/unpack_strategy/compress.rb index 8e83fa057a..65f9ea8728 100644 --- a/Library/Homebrew/unpack_strategy/compress.rb +++ b/Library/Homebrew/unpack_strategy/compress.rb @@ -6,8 +6,11 @@ require_relative "tar" module UnpackStrategy # Strategy for unpacking compress archives. class Compress < Tar + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".Z"] end diff --git a/Library/Homebrew/unpack_strategy/directory.rb b/Library/Homebrew/unpack_strategy/directory.rb index 0e8c68b593..02772dcc68 100644 --- a/Library/Homebrew/unpack_strategy/directory.rb +++ b/Library/Homebrew/unpack_strategy/directory.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking directories. class Directory + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [] end @@ -18,6 +21,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) path.children.each do |child| system_command! "cp", diff --git a/Library/Homebrew/unpack_strategy/dmg.rb b/Library/Homebrew/unpack_strategy/dmg.rb index 1d2e8de5ce..db6f3285d5 100644 --- a/Library/Homebrew/unpack_strategy/dmg.rb +++ b/Library/Homebrew/unpack_strategy/dmg.rb @@ -6,6 +6,8 @@ require "tempfile" module UnpackStrategy # Strategy for unpacking disk images. class Dmg + extend T::Sig + include UnpackStrategy # Helper module for listing the contents of a volume mounted from a disk image. @@ -54,6 +56,8 @@ module UnpackStrategy # Strategy for unpacking a volume mounted from a disk image. class Mount + extend T::Sig + using Bom include UnpackStrategy @@ -82,6 +86,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) Tempfile.open(["", ".bom"]) do |bomfile| bomfile.close @@ -105,6 +110,7 @@ module UnpackStrategy end private_constant :Mount + sig { returns(T::Array[String]) } def self.extensions [".dmg"] end @@ -116,6 +122,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) mount(verbose: verbose) do |mounts| raise "No mounts found in '#{path}'; perhaps this is a bad disk image?" if mounts.empty? diff --git a/Library/Homebrew/unpack_strategy/executable.rb b/Library/Homebrew/unpack_strategy/executable.rb index a592cce52f..1daeb7d0f7 100644 --- a/Library/Homebrew/unpack_strategy/executable.rb +++ b/Library/Homebrew/unpack_strategy/executable.rb @@ -6,8 +6,11 @@ require_relative "uncompressed" module UnpackStrategy # Strategy for unpacking executables. class Executable < Uncompressed + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".sh", ".bash"] end diff --git a/Library/Homebrew/unpack_strategy/fossil.rb b/Library/Homebrew/unpack_strategy/fossil.rb index f421ee1be8..869a056285 100644 --- a/Library/Homebrew/unpack_strategy/fossil.rb +++ b/Library/Homebrew/unpack_strategy/fossil.rb @@ -6,11 +6,14 @@ require "system_command" module UnpackStrategy # Strategy for unpacking Fossil repositories. class Fossil + extend T::Sig + include UnpackStrategy extend SystemCommand::Mixin using Magic + sig { returns(T::Array[String]) } def self.extensions [] end @@ -25,6 +28,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) args = if @ref_type && @ref [@ref] diff --git a/Library/Homebrew/unpack_strategy/generic_unar.rb b/Library/Homebrew/unpack_strategy/generic_unar.rb index 7b0a0a53bd..4628cd517d 100644 --- a/Library/Homebrew/unpack_strategy/generic_unar.rb +++ b/Library/Homebrew/unpack_strategy/generic_unar.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking archives with `unar`. class GenericUnar + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [] end @@ -22,6 +25,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "unar", args: [ diff --git a/Library/Homebrew/unpack_strategy/gzip.rb b/Library/Homebrew/unpack_strategy/gzip.rb index 4797fbaa24..983d995a98 100644 --- a/Library/Homebrew/unpack_strategy/gzip.rb +++ b/Library/Homebrew/unpack_strategy/gzip.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking gzip archives. class Gzip + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".gz"] end @@ -18,6 +21,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) FileUtils.cp path, unpack_dir/basename, preserve: true quiet_flags = verbose ? [] : ["-q"] diff --git a/Library/Homebrew/unpack_strategy/jar.rb b/Library/Homebrew/unpack_strategy/jar.rb index ee05a876a1..d4170a8689 100644 --- a/Library/Homebrew/unpack_strategy/jar.rb +++ b/Library/Homebrew/unpack_strategy/jar.rb @@ -6,8 +6,11 @@ require_relative "uncompressed" module UnpackStrategy # Strategy for unpacking Java archives. class Jar < Uncompressed + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".apk", ".jar"] end diff --git a/Library/Homebrew/unpack_strategy/lha.rb b/Library/Homebrew/unpack_strategy/lha.rb index 70c3e5f709..7b92af7290 100644 --- a/Library/Homebrew/unpack_strategy/lha.rb +++ b/Library/Homebrew/unpack_strategy/lha.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking LHa archives. class Lha + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".lha", ".lzh"] end @@ -22,6 +25,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "lha", args: ["xq2w=#{unpack_dir}", path], diff --git a/Library/Homebrew/unpack_strategy/lua_rock.rb b/Library/Homebrew/unpack_strategy/lua_rock.rb index 1336b856de..6150e2788e 100644 --- a/Library/Homebrew/unpack_strategy/lua_rock.rb +++ b/Library/Homebrew/unpack_strategy/lua_rock.rb @@ -6,8 +6,11 @@ require_relative "uncompressed" module UnpackStrategy # Strategy for unpacking LuaRock archives. class LuaRock < Uncompressed + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".rock"] end diff --git a/Library/Homebrew/unpack_strategy/lzip.rb b/Library/Homebrew/unpack_strategy/lzip.rb index a27663e4d5..71f561c9df 100644 --- a/Library/Homebrew/unpack_strategy/lzip.rb +++ b/Library/Homebrew/unpack_strategy/lzip.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking lzip archives. class Lzip + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".lz"] end @@ -22,6 +25,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) FileUtils.cp path, unpack_dir/basename, preserve: true quiet_flags = verbose ? [] : ["-q"] diff --git a/Library/Homebrew/unpack_strategy/lzma.rb b/Library/Homebrew/unpack_strategy/lzma.rb index e14de8e993..21a9cd4e31 100644 --- a/Library/Homebrew/unpack_strategy/lzma.rb +++ b/Library/Homebrew/unpack_strategy/lzma.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking LZMA archives. class Lzma + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".lzma"] end @@ -16,6 +19,7 @@ module UnpackStrategy path.magic_number.match?(/\A\]\000\000\200\000/n) end + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) FileUtils.cp path, unpack_dir/basename, preserve: true quiet_flags = verbose ? [] : ["-q"] diff --git a/Library/Homebrew/unpack_strategy/microsoft_office_xml.rb b/Library/Homebrew/unpack_strategy/microsoft_office_xml.rb index 5d97e6f222..616d78bc06 100644 --- a/Library/Homebrew/unpack_strategy/microsoft_office_xml.rb +++ b/Library/Homebrew/unpack_strategy/microsoft_office_xml.rb @@ -6,8 +6,11 @@ require_relative "uncompressed" module UnpackStrategy # Strategy for unpacking Microsoft Office documents. class MicrosoftOfficeXml < Uncompressed + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [ ".doc", ".docx", diff --git a/Library/Homebrew/unpack_strategy/otf.rb b/Library/Homebrew/unpack_strategy/otf.rb index 1a0538d942..e94eb15029 100644 --- a/Library/Homebrew/unpack_strategy/otf.rb +++ b/Library/Homebrew/unpack_strategy/otf.rb @@ -6,8 +6,11 @@ require_relative "uncompressed" module UnpackStrategy # Strategy for unpacking OpenType fonts. class Otf < Uncompressed + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".otf"] end diff --git a/Library/Homebrew/unpack_strategy/p7zip.rb b/Library/Homebrew/unpack_strategy/p7zip.rb index 5aca009f53..3a5ef46f00 100644 --- a/Library/Homebrew/unpack_strategy/p7zip.rb +++ b/Library/Homebrew/unpack_strategy/p7zip.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking P7ZIP archives. class P7Zip + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".7z"] end @@ -22,6 +25,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "7zr", args: ["x", "-y", "-bd", "-bso0", path, "-o#{unpack_dir}"], diff --git a/Library/Homebrew/unpack_strategy/pax.rb b/Library/Homebrew/unpack_strategy/pax.rb index e914d41baf..4067132c80 100644 --- a/Library/Homebrew/unpack_strategy/pax.rb +++ b/Library/Homebrew/unpack_strategy/pax.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking pax archives. class Pax + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".pax"] end @@ -18,6 +21,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "pax", args: ["-rf", path], diff --git a/Library/Homebrew/unpack_strategy/pkg.rb b/Library/Homebrew/unpack_strategy/pkg.rb index 20bf5057e8..220b86a58c 100644 --- a/Library/Homebrew/unpack_strategy/pkg.rb +++ b/Library/Homebrew/unpack_strategy/pkg.rb @@ -6,8 +6,11 @@ require_relative "uncompressed" module UnpackStrategy # Strategy for unpacking macOS package installers. class Pkg < Uncompressed + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".pkg", ".mkpg"] end diff --git a/Library/Homebrew/unpack_strategy/rar.rb b/Library/Homebrew/unpack_strategy/rar.rb index 71e2dd66a2..7cd1d02635 100644 --- a/Library/Homebrew/unpack_strategy/rar.rb +++ b/Library/Homebrew/unpack_strategy/rar.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking RAR archives. class Rar + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".rar"] end @@ -22,6 +25,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "unrar", args: ["x", "-inul", path, unpack_dir], diff --git a/Library/Homebrew/unpack_strategy/self_extracting_executable.rb b/Library/Homebrew/unpack_strategy/self_extracting_executable.rb index c74166d771..0e99278711 100644 --- a/Library/Homebrew/unpack_strategy/self_extracting_executable.rb +++ b/Library/Homebrew/unpack_strategy/self_extracting_executable.rb @@ -6,8 +6,11 @@ require_relative "generic_unar" module UnpackStrategy # Strategy for unpacking self-extracting executables. class SelfExtractingExecutable < GenericUnar + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [] end diff --git a/Library/Homebrew/unpack_strategy/sit.rb b/Library/Homebrew/unpack_strategy/sit.rb index 5fabbbbfc8..687e7d0e64 100644 --- a/Library/Homebrew/unpack_strategy/sit.rb +++ b/Library/Homebrew/unpack_strategy/sit.rb @@ -6,8 +6,11 @@ require_relative "generic_unar" module UnpackStrategy # Strategy for unpacking Stuffit archives. class Sit < GenericUnar + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".sit"] end diff --git a/Library/Homebrew/unpack_strategy/tar.rb b/Library/Homebrew/unpack_strategy/tar.rb index a31550b75d..a40ad8f45e 100644 --- a/Library/Homebrew/unpack_strategy/tar.rb +++ b/Library/Homebrew/unpack_strategy/tar.rb @@ -6,11 +6,14 @@ require "system_command" module UnpackStrategy # Strategy for unpacking tar archives. class Tar + extend T::Sig + include UnpackStrategy extend SystemCommand::Mixin using Magic + sig { returns(T::Array[String]) } def self.extensions [ ".tar", @@ -33,6 +36,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) Dir.mktmpdir do |tmpdir| tar_path = path diff --git a/Library/Homebrew/unpack_strategy/ttf.rb b/Library/Homebrew/unpack_strategy/ttf.rb index b45755a428..38b44879de 100644 --- a/Library/Homebrew/unpack_strategy/ttf.rb +++ b/Library/Homebrew/unpack_strategy/ttf.rb @@ -6,8 +6,11 @@ require_relative "uncompressed" module UnpackStrategy # Strategy for unpacking TrueType fonts. class Ttf < Uncompressed + extend T::Sig + using Magic + sig { returns(T::Array[String]) } def self.extensions [".ttc", ".ttf"] end diff --git a/Library/Homebrew/unpack_strategy/uncompressed.rb b/Library/Homebrew/unpack_strategy/uncompressed.rb index 1c869d998e..16ced6ca16 100644 --- a/Library/Homebrew/unpack_strategy/uncompressed.rb +++ b/Library/Homebrew/unpack_strategy/uncompressed.rb @@ -4,6 +4,8 @@ module UnpackStrategy # Strategy for unpacking uncompressed files. class Uncompressed + extend T::Sig + include UnpackStrategy def extract_nestedly(prioritise_extension: false, **options) @@ -12,6 +14,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) FileUtils.cp path, unpack_dir/basename, preserve: true, verbose: verbose end diff --git a/Library/Homebrew/unpack_strategy/xar.rb b/Library/Homebrew/unpack_strategy/xar.rb index 2f5f4794a3..ce35a0683a 100644 --- a/Library/Homebrew/unpack_strategy/xar.rb +++ b/Library/Homebrew/unpack_strategy/xar.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking xar archives. class Xar + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".xar"] end @@ -18,6 +21,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) system_command! "xar", args: ["-x", "-f", path, "-C", unpack_dir], diff --git a/Library/Homebrew/unpack_strategy/xz.rb b/Library/Homebrew/unpack_strategy/xz.rb index 86f50d2a38..ec81be5673 100644 --- a/Library/Homebrew/unpack_strategy/xz.rb +++ b/Library/Homebrew/unpack_strategy/xz.rb @@ -4,10 +4,13 @@ module UnpackStrategy # Strategy for unpacking xz archives. class Xz + extend T::Sig + include UnpackStrategy using Magic + sig { returns(T::Array[String]) } def self.extensions [".xz"] end @@ -22,6 +25,7 @@ module UnpackStrategy private + sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) } def extract_to_dir(unpack_dir, basename:, verbose:) FileUtils.cp path, unpack_dir/basename, preserve: true quiet_flags = verbose ? [] : ["-q"] diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 45f46f3962..a66263ac4e 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -80,6 +80,8 @@ module Homebrew end module Kernel + extend T::Sig + def require?(path) return false if path.nil? @@ -383,6 +385,7 @@ module Kernel trap("INT", std_trap) end + sig { returns(String) } def capture_stderr old = $stderr $stderr = StringIO.new @@ -500,6 +503,7 @@ module Kernel end end + sig { returns(String) } def shell_profile Utils::Shell.profile end diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 9524db7218..5ae0e106f5 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -9,6 +9,8 @@ module Utils # @api private module Analytics class << self + extend T::Sig + include Context def report(type, metadata = {}) @@ -191,6 +193,7 @@ module Utils get_analytics(json, args: args) end + sig { returns(String) } def custom_prefix_label "custom-prefix" end @@ -339,16 +342,19 @@ module Utils format("%.2f", percent: percent) end + sig { returns(String) } def formula_path "formula" end alias generic_formula_path formula_path + sig { returns(String) } def analytics_path "analytics" end alias generic_analytics_path analytics_path + sig { returns(String) } def cask_path "cask" end diff --git a/Library/Homebrew/utils/bottles.rb b/Library/Homebrew/utils/bottles.rb index fff38c4561..99c727cbd1 100644 --- a/Library/Homebrew/utils/bottles.rb +++ b/Library/Homebrew/utils/bottles.rb @@ -9,6 +9,8 @@ module Utils # @api private module Bottles class << self + extend T::Sig + def tag @tag ||= "#{ENV["HOMEBREW_PROCESSOR"]}_#{ENV["HOMEBREW_SYSTEM"]}".downcase.to_sym end @@ -30,6 +32,7 @@ module Utils bottle_ext && bottle_url_ext && bottle_ext != bottle_url_ext end + sig { returns(Regexp) } def native_regex /(\.#{Regexp.escape(tag.to_s)}\.bottle\.(\d+\.)?tar\.gz)$/o end @@ -93,10 +96,13 @@ module Utils # Collector for bottle specifications. class Collector + extend T::Sig + extend Forwardable def_delegators :@checksums, :keys, :[], :[]=, :key?, :each_key + sig { void } def initialize @checksums = {} end diff --git a/Library/Homebrew/utils/gems.rb b/Library/Homebrew/utils/gems.rb index 866054123f..0985d6de2d 100644 --- a/Library/Homebrew/utils/gems.rb +++ b/Library/Homebrew/utils/gems.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true # Never `require` anything in this file (except English). It needs to be able to @@ -57,7 +57,7 @@ module Homebrew # Add necessary Ruby and Gem binary directories to PATH. gem_bindir ||= Gem.bindir - paths = ENV["PATH"].split(":") + paths = ENV.fetch("PATH").split(":") paths.unshift(gem_bindir) unless paths.include?(gem_bindir) paths.unshift(ruby_bindir) unless paths.include?(ruby_bindir) ENV["PATH"] = paths.compact.join(":") @@ -85,8 +85,8 @@ module Homebrew end def find_in_path(executable) - ENV["PATH"].split(":").find do |path| - File.executable?("#{path}/#{executable}") + ENV.fetch("PATH").split(":").find do |path| + File.executable?(File.join(path, executable)) end end @@ -104,9 +104,9 @@ module Homebrew def install_bundler_gems! install_bundler! - ENV["BUNDLE_GEMFILE"] = "#{ENV["HOMEBREW_LIBRARY"]}/Homebrew/Gemfile" + ENV["BUNDLE_GEMFILE"] = File.join(ENV.fetch("HOMEBREW_LIBRARY"), "Homebrew", "Gemfile") @bundle_installed ||= begin - bundle = "#{find_in_path(:bundle)}/bundle" + bundle = File.join(find_in_path("bundle"), "bundle") bundle_check_output = `#{bundle} check 2>&1` bundle_check_failed = !$CHILD_STATUS.success? diff --git a/Library/Homebrew/utils/gems.rbi b/Library/Homebrew/utils/gems.rbi new file mode 100644 index 0000000000..47c3ced643 --- /dev/null +++ b/Library/Homebrew/utils/gems.rbi @@ -0,0 +1,27 @@ +# typed: strict + +module Homebrew + sig { returns(String) } + def ruby_bindir; end + + sig { returns(String) } + def gem_user_bindir; end + + sig { params(message: String).void } + def ohai_if_defined(message); end + + sig { params(message: String).returns(T.noreturn) } + def odie_if_defined(message); end + + sig { params(name: String, version: T.nilable(String), executable: String, setup_gem_environment: T::Boolean).void } + def install_gem_setup_path!(name, version: nil, executable: name, setup_gem_environment: true); end + + sig { params(executable: String).returns(T.nilable(String)) } + def find_in_path(executable); end + + sig { void } + def install_bundler!; end + + sig { void } + def install_bundler_gems!; end +end diff --git a/Library/Homebrew/utils/github.rb b/Library/Homebrew/utils/github.rb index 124ba70255..dc2e263c59 100644 --- a/Library/Homebrew/utils/github.rb +++ b/Library/Homebrew/utils/github.rb @@ -10,6 +10,8 @@ require "utils/shell" # # @api private module GitHub + extend T::Sig + module_function API_URL = "https://api.github.com" @@ -129,6 +131,7 @@ module GitHub end end + sig { returns(Symbol) } def api_credentials_type if Homebrew::EnvConfig.github_api_token :env_token diff --git a/Library/Homebrew/utils/github/actions.rb b/Library/Homebrew/utils/github/actions.rb index 3dc7bf6401..b3e2a1e2b3 100644 --- a/Library/Homebrew/utils/github/actions.rb +++ b/Library/Homebrew/utils/github/actions.rb @@ -17,6 +17,8 @@ module GitHub # Helper class for formatting annotations on GitHub Actions. class Annotation + extend T::Sig + def self.path_relative_to_workspace(path) workspace = Pathname(ENV.fetch("GITHUB_WORKSPACE", Dir.pwd)).realpath path = Pathname(path) @@ -35,6 +37,7 @@ module GitHub @column = Integer(column) if column end + sig { returns(String) } def to_s file = "file=#{Actions.escape(@file.to_s)}" if @file line = "line=#{@line}" if @line diff --git a/Library/Homebrew/utils/sorbet.rb b/Library/Homebrew/utils/sorbet.rb index cbc85f5465..2f91f50bb8 100644 --- a/Library/Homebrew/utils/sorbet.rb +++ b/Library/Homebrew/utils/sorbet.rb @@ -1,4 +1,4 @@ -# typed: strict +# typed: true # frozen_string_literal: true if ENV["HOMEBREW_SORBET_RUNTIME"] @@ -7,7 +7,11 @@ if ENV["HOMEBREW_SORBET_RUNTIME"] require "sorbet-runtime" else # Explicitly prevent `sorbet-runtime` from being loaded. - ENV["GEM_SKIP"] = "sorbet-runtime" + def gem(name, *) + raise Gem::LoadError if name == "sorbet-runtime" + + super + end require "sorbet-runtime-stub" end diff --git a/Library/Homebrew/version.rb b/Library/Homebrew/version.rb index 07ef21714c..08c0d76021 100644 --- a/Library/Homebrew/version.rb +++ b/Library/Homebrew/version.rb @@ -7,6 +7,8 @@ require "version/null" # # @api private class Version + extend T::Sig + include Comparable def self.formula_optionally_versioned_regex(name, full: true) @@ -15,6 +17,8 @@ class Version # A part of a {Version}. class Token + extend T::Sig + include Comparable def self.create(val) @@ -48,6 +52,7 @@ class Version @value = value end + sig { returns(String) } def inspect "#<#{self.class.name} #{value.inspect}>" end @@ -69,6 +74,7 @@ class Version end alias to_str to_s + sig { returns(T::Boolean) } def numeric? false end @@ -76,6 +82,8 @@ class Version # A pseudo-token representing the absence of a token. class NullToken < Token + extend T::Sig + def initialize super(nil) end @@ -95,10 +103,12 @@ class Version end end + sig { returns(T::Boolean) } def null? true end + sig { returns(String) } def inspect "#<#{self.class.name}>" end @@ -133,6 +143,7 @@ class Version # A token consisting of only numbers. class NumericToken < Token PATTERN = /[0-9]+/i.freeze + extend T::Sig def initialize(value) super @@ -153,6 +164,7 @@ class Version end end + sig { returns(T::Boolean) } def numeric? true end @@ -588,6 +600,8 @@ end # # @api private class HeadVersion < Version + extend T::Sig + attr_reader :commit def initialize(*) @@ -604,6 +618,7 @@ class HeadVersion < Version end end + sig { returns(T::Boolean) } def head? true end diff --git a/Library/Homebrew/version/null.rb b/Library/Homebrew/version/null.rb index f08d0765af..cf72179875 100644 --- a/Library/Homebrew/version/null.rb +++ b/Library/Homebrew/version/null.rb @@ -4,6 +4,8 @@ class Version # Represents the absence of a version. NULL = Class.new do + extend T::Sig + include Comparable def <=>(_other) @@ -18,19 +20,23 @@ class Version false end + sig { returns(T::Boolean) } def detected_from_url? false end + sig { returns(T::Boolean) } def head? false end + sig { returns(T::Boolean) } def null? true end # For {OS::Mac::Version} compatibility. + sig { returns(T::Boolean) } def requires_nehalem_cpu? false end @@ -51,27 +57,33 @@ class Version NULL_TOKEN end + sig { returns(Version) } def major_minor self end + sig { returns(Version) } def major_minor_patch self end + sig { returns(Float) } def to_f Float::NAN end + sig { returns(Integer) } def to_i 0 end + sig { returns(String) } def to_s "" end alias_method :to_str, :to_s + sig { returns(String) } def inspect "#" end diff --git a/docs/Manpage.md b/docs/Manpage.md index 4fb7f93ab7..5574ec9d87 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -70,58 +70,58 @@ Homebrew Cask provides a friendly CLI workflow for the administration of macOS a Commands: - `--cache` - Display the file used to cache a *`cask`* + Display the file used to cache a *`cask`*. - `audit` - Check *`cask`* for Homebrew coding style violations + Check *`cask`* for Homebrew coding style violations. - `cat` - Dump raw source of a *`cask`* to the standard output + Dump raw source of a *`cask`* to the standard output. - `create` - Creates the given *`cask`* and opens it in an editor + Creates the given *`cask`* and opens it in an editor. - `doctor` - Checks for configuration issues + Checks for configuration issues. - `edit` - Open the given *`cask`* for editing + Open the given *`cask`* for editing. - `fetch` - Downloads remote application files to local cache + Downloads remote application files to local cache. - `help` - Print help for `cask` commands + Print help for `cask` commands. - `home` - Opens the homepage of the given *`cask`* + Opens the homepage of the given *`cask`*. - `info` - Displays information about the given *`cask`* + Displays information about the given *`cask`*. - `install` - Installs the given *`cask`* + Installs the given *`cask`*. - `list` - Lists installed casks or the casks provided in the arguments + Lists installed casks or the casks provided in the arguments. - `outdated` - List the outdated installed casks + List the outdated installed casks. - `reinstall` - Reinstalls the given *`cask`* + Reinstalls the given *`cask`*. - `style` - Checks style of the given *`cask`* using RuboCop + Checks style of the given *`cask`* using RuboCop. - `uninstall` - Uninstalls the given *`cask`* + Uninstalls the given *`cask`*. - `upgrade` - Upgrades all outdated casks or the specified casks + Upgrades all outdated casks or the specified casks. - `zap` - Zaps all files associated with the given *`cask`* + Zaps all files associated with the given *`cask`*. See also: `man brew` @@ -1279,6 +1279,8 @@ Run Homebrew's unit and integration tests. Check for typechecking errors using Sorbet. +* `--fix`: + Automatically fix type errors. * `-q`, `--quiet`: Silence all non-critical errors. * `--update`: diff --git a/manpages/brew.1 b/manpages/brew.1 index d62b6a8664..30dbbc65e4 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -70,109 +70,109 @@ Commands: \fB\-\-cache\fR . .br -Display the file used to cache a \fIcask\fR +Display the file used to cache a \fIcask\fR\. . .IP "\(bu" 4 \fBaudit\fR . .br -Check \fIcask\fR for Homebrew coding style violations +Check \fIcask\fR for Homebrew coding style violations\. . .IP "\(bu" 4 \fBcat\fR . .br -Dump raw source of a \fIcask\fR to the standard output +Dump raw source of a \fIcask\fR to the standard output\. . .IP "\(bu" 4 \fBcreate\fR . .br -Creates the given \fIcask\fR and opens it in an editor +Creates the given \fIcask\fR and opens it in an editor\. . .IP "\(bu" 4 \fBdoctor\fR . .br -Checks for configuration issues +Checks for configuration issues\. . .IP "\(bu" 4 \fBedit\fR . .br -Open the given \fIcask\fR for editing +Open the given \fIcask\fR for editing\. . .IP "\(bu" 4 \fBfetch\fR . .br -Downloads remote application files to local cache +Downloads remote application files to local cache\. . .IP "\(bu" 4 \fBhelp\fR . .br -Print help for \fBcask\fR commands +Print help for \fBcask\fR commands\. . .IP "\(bu" 4 \fBhome\fR . .br -Opens the homepage of the given \fIcask\fR +Opens the homepage of the given \fIcask\fR\. . .IP "\(bu" 4 \fBinfo\fR . .br -Displays information about the given \fIcask\fR +Displays information about the given \fIcask\fR\. . .IP "\(bu" 4 \fBinstall\fR . .br -Installs the given \fIcask\fR +Installs the given \fIcask\fR\. . .IP "\(bu" 4 \fBlist\fR . .br -Lists installed casks or the casks provided in the arguments +Lists installed casks or the casks provided in the arguments\. . .IP "\(bu" 4 \fBoutdated\fR . .br -List the outdated installed casks +List the outdated installed casks\. . .IP "\(bu" 4 \fBreinstall\fR . .br -Reinstalls the given \fIcask\fR +Reinstalls the given \fIcask\fR\. . .IP "\(bu" 4 \fBstyle\fR . .br -Checks style of the given \fIcask\fR using RuboCop +Checks style of the given \fIcask\fR using RuboCop\. . .IP "\(bu" 4 \fBuninstall\fR . .br -Uninstalls the given \fIcask\fR +Uninstalls the given \fIcask\fR\. . .IP "\(bu" 4 \fBupgrade\fR . .br -Upgrades all outdated casks or the specified casks +Upgrades all outdated casks or the specified casks\. . .IP "\(bu" 4 \fBzap\fR . .br -Zaps all files associated with the given \fIcask\fR +Zaps all files associated with the given \fIcask\fR\. . .IP "" 0 . @@ -1777,6 +1777,10 @@ Randomise tests with the specified \fIvalue\fR instead of a random seed\. Check for typechecking errors using Sorbet\. . .TP +\fB\-\-fix\fR +Automatically fix type errors\. +. +.TP \fB\-q\fR, \fB\-\-quiet\fR Silence all non\-critical errors\. .