diff --git a/Library/Homebrew/cask/caskroom.rb b/Library/Homebrew/cask/caskroom.rb index 321b2997eb4e0..eb3c6566ca494 100644 --- a/Library/Homebrew/cask/caskroom.rb +++ b/Library/Homebrew/cask/caskroom.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true require "utils/user" @@ -10,7 +10,7 @@ module Cask module Caskroom sig { returns(Pathname) } def self.path - @path ||= HOMEBREW_PREFIX/"Caskroom" + @path ||= T.let(HOMEBREW_PREFIX/"Caskroom", T.nilable(Pathname)) end # Return all paths for installed casks. diff --git a/Library/Homebrew/cask/config.rb b/Library/Homebrew/cask/config.rb index a091d84a6de5b..e34e4417975cd 100644 --- a/Library/Homebrew/cask/config.rb +++ b/Library/Homebrew/cask/config.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true require "json" @@ -12,24 +12,28 @@ module Cask # # @api internal class Config - DEFAULT_DIRS = { - appdir: "/Applications", - keyboard_layoutdir: "/Library/Keyboard Layouts", - colorpickerdir: "~/Library/ColorPickers", - prefpanedir: "~/Library/PreferencePanes", - qlplugindir: "~/Library/QuickLook", - mdimporterdir: "~/Library/Spotlight", - dictionarydir: "~/Library/Dictionaries", - fontdir: "~/Library/Fonts", - servicedir: "~/Library/Services", - input_methoddir: "~/Library/Input Methods", - internet_plugindir: "~/Library/Internet Plug-Ins", - audio_unit_plugindir: "~/Library/Audio/Plug-Ins/Components", - vst_plugindir: "~/Library/Audio/Plug-Ins/VST", - vst3_plugindir: "~/Library/Audio/Plug-Ins/VST3", - screen_saverdir: "~/Library/Screen Savers", - }.freeze - + DEFAULT_DIRS = T.let( + { + appdir: "/Applications", + keyboard_layoutdir: "/Library/Keyboard Layouts", + colorpickerdir: "~/Library/ColorPickers", + prefpanedir: "~/Library/PreferencePanes", + qlplugindir: "~/Library/QuickLook", + mdimporterdir: "~/Library/Spotlight", + dictionarydir: "~/Library/Dictionaries", + fontdir: "~/Library/Fonts", + servicedir: "~/Library/Services", + input_methoddir: "~/Library/Input Methods", + internet_plugindir: "~/Library/Internet Plug-Ins", + audio_unit_plugindir: "~/Library/Audio/Plug-Ins/Components", + vst_plugindir: "~/Library/Audio/Plug-Ins/VST", + vst3_plugindir: "~/Library/Audio/Plug-Ins/VST3", + screen_saverdir: "~/Library/Screen Savers", + }.freeze, + T::Hash[Symbol, String], + ) + + sig { returns(T::Hash[Symbol, T.untyped]) } def self.defaults { languages: LazyObject.new { MacOS.languages }, @@ -72,8 +76,13 @@ def self.from_json(json, ignore_invalid_keys: false) end sig { - params(config: T::Enumerable[[T.any(String, Symbol), T.any(String, Pathname, T::Array[String])]]) - .returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) + params( + config: T::Enumerable[ + [T.any(String, Symbol), T.any(String, Pathname, T::Array[String])], + ], + ).returns( + T::Hash[Symbol, T.any(String, Pathname, T::Array[String])], + ) } def self.canonicalize(config) config.to_h do |k, v| @@ -104,9 +113,22 @@ def self.canonicalize(config) ).void } def initialize(default: nil, env: nil, explicit: {}, ignore_invalid_keys: false) - @default = self.class.canonicalize(self.class.defaults.merge(default)) if default - @env = self.class.canonicalize(env) if env - @explicit = self.class.canonicalize(explicit) + if default + @default = T.let( + self.class.canonicalize(self.class.defaults.merge(default)), + T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), + ) + end + if env + @env = T.let( + self.class.canonicalize(env), + T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), + ) + end + @explicit = T.let( + self.class.canonicalize(explicit), + T::Hash[Symbol, T.any(String, Pathname, T::Array[String])], + ) if ignore_invalid_keys @env&.delete_if { |key, _| self.class.defaults.keys.exclude?(key) } @@ -144,12 +166,12 @@ def env sig { returns(Pathname) } def binarydir - @binarydir ||= HOMEBREW_PREFIX/"bin" + @binarydir ||= T.let(HOMEBREW_PREFIX/"bin", T.nilable(Pathname)) end sig { returns(Pathname) } def manpagedir - @manpagedir ||= HOMEBREW_PREFIX/"share/man" + @manpagedir ||= T.let(HOMEBREW_PREFIX/"share/man", T.nilable(Pathname)) end sig { returns(T::Array[String]) } @@ -167,6 +189,7 @@ def languages end end + sig { params(languages: T::Array[String]).void } def languages=(languages) explicit[:languages] = languages end diff --git a/Library/Homebrew/cask/list.rb b/Library/Homebrew/cask/list.rb index 519123f876d98..87aa1460f1daa 100644 --- a/Library/Homebrew/cask/list.rb +++ b/Library/Homebrew/cask/list.rb @@ -1,10 +1,11 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true require "cask/artifact/relocated" module Cask class List + sig { params(casks: Cask, one: T::Boolean, full_name: T::Boolean, versions: T::Boolean).void } def self.list_casks(*casks, one: false, full_name: false, versions: false) output = if casks.any? casks.each do |cask| @@ -27,6 +28,7 @@ def self.list_casks(*casks, one: false, full_name: false, versions: false) end end + sig { params(cask: Cask).void } def self.list_artifacts(cask) cask.artifacts.group_by(&:class).sort_by { |klass, _| klass.english_name }.each do |klass, artifacts| next if [Artifact::Uninstall, Artifact::Zap].include? klass @@ -41,6 +43,7 @@ def self.list_artifacts(cask) end end + sig { params(cask: Cask).returns(String) } def self.format_versioned(cask) "#{cask}#{cask.installed_version&.prepend(" ")}" end diff --git a/Library/Homebrew/rubocops/cask/constants/stanza.rb b/Library/Homebrew/rubocops/cask/constants/stanza.rb index 2e911fc9e2de2..f55e9c61fba84 100644 --- a/Library/Homebrew/rubocops/cask/constants/stanza.rb +++ b/Library/Homebrew/rubocops/cask/constants/stanza.rb @@ -1,70 +1,81 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true module RuboCop module Cask # Constants available globally for use in all cask cops. module Constants - ON_SYSTEM_METHODS = [:arm, :intel, *MacOSVersion::SYMBOLS.keys].map { |option| :"on_#{option}" }.freeze - ON_SYSTEM_METHODS_STANZA_ORDER = [ - :arm, - :intel, - *MacOSVersion::SYMBOLS.reverse_each.to_h.keys, # Oldest OS blocks first since that's more common in Casks. - ].map { |option, _| :"on_#{option}" }.freeze - - STANZA_GROUPS = [ - [:arch, :on_arch_conditional], - [:version, :sha256], - ON_SYSTEM_METHODS_STANZA_ORDER, - [:language], - [:url, :appcast, :name, :desc, :homepage], - [:livecheck], - [:deprecate!, :disable!], + ON_SYSTEM_METHODS = T.let( + [:arm, :intel, *MacOSVersion::SYMBOLS.keys].map { |option| :"on_#{option}" }.freeze, + T::Array[Symbol], + ) + ON_SYSTEM_METHODS_STANZA_ORDER = T.let( [ - :auto_updates, - :conflicts_with, - :depends_on, - :container, - ], + :arm, + :intel, + *MacOSVersion::SYMBOLS.reverse_each.to_h.keys, # Oldest OS blocks first since that's more common in Casks. + ].map { |option, _| :"on_#{option}" }.freeze, + T::Array[Symbol], + ) + + STANZA_GROUPS = T.let( [ - :suite, - :app, - :pkg, - :installer, - :binary, - :manpage, - :colorpicker, - :dictionary, - :font, - :input_method, - :internet_plugin, - :keyboard_layout, - :prefpane, - :qlplugin, - :mdimporter, - :screen_saver, - :service, - :audio_unit_plugin, - :vst_plugin, - :vst3_plugin, - :artifact, - :stage_only, - ], - [:preflight], - [:postflight], - [:uninstall_preflight], - [:uninstall_postflight], - [:uninstall], - [:zap], - [:caveats], - ].freeze + [:arch, :on_arch_conditional], + [:version, :sha256], + ON_SYSTEM_METHODS_STANZA_ORDER, + [:language], + [:url, :appcast, :name, :desc, :homepage], + [:livecheck], + [:deprecate!, :disable!], + [ + :auto_updates, + :conflicts_with, + :depends_on, + :container, + ], + [ + :suite, + :app, + :pkg, + :installer, + :binary, + :manpage, + :colorpicker, + :dictionary, + :font, + :input_method, + :internet_plugin, + :keyboard_layout, + :prefpane, + :qlplugin, + :mdimporter, + :screen_saver, + :service, + :audio_unit_plugin, + :vst_plugin, + :vst3_plugin, + :artifact, + :stage_only, + ], + [:preflight], + [:postflight], + [:uninstall_preflight], + [:uninstall_postflight], + [:uninstall], + [:zap], + [:caveats], + ].freeze, + T::Array[T::Array[Symbol]], + ) - STANZA_GROUP_HASH = + STANZA_GROUP_HASH = T.let( STANZA_GROUPS.each_with_object({}) do |stanza_group, hash| stanza_group.each { |stanza| hash[stanza] = stanza_group } - end.freeze + end.freeze, + T::Hash[Symbol, T::Array[Symbol]], + ) - STANZA_ORDER = STANZA_GROUPS.flatten.freeze + STANZA_ORDER = T.let(STANZA_GROUPS.flatten.freeze, T::Array[Symbol]) UNINSTALL_METHODS_ORDER = [ :early_script, diff --git a/Library/Homebrew/rubocops/cask/mixin/cask_help.rb b/Library/Homebrew/rubocops/cask/mixin/cask_help.rb index a173e6e027a5f..61bd3643a8a90 100644 --- a/Library/Homebrew/rubocops/cask/mixin/cask_help.rb +++ b/Library/Homebrew/rubocops/cask/mixin/cask_help.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true module RuboCop @@ -26,16 +26,31 @@ def on_block(block_node) return unless block_node.cask_block? - @file_path = processed_source.file_path + @file_path = T.let(processed_source.file_path, T.nilable(String)) cask_block = RuboCop::Cask::AST::CaskBlock.new(block_node, comments) on_cask(cask_block) end + sig { + params( + cask_stanzas: T::Array[RuboCop::Cask::AST::Stanza], + ).returns( + T::Array[RuboCop::Cask::AST::Stanza], + ) + } def on_system_methods(cask_stanzas) cask_stanzas.select(&:on_system_block?) end + sig { + params( + block_node: RuboCop::AST::BlockNode, + comments: T::Array[String], + ).returns( + T::Array[RuboCop::Cask::AST::Stanza], + ) + } def inner_stanzas(block_node, comments) block_contents = block_node.child_nodes.select(&:begin_type?) inner_nodes = block_contents.map(&:child_nodes).flatten.select(&:send_type?) @@ -44,7 +59,7 @@ def inner_stanzas(block_node, comments) sig { returns(T.nilable(String)) } def cask_tap - return unless (match_obj = @file_path.match(%r{/(homebrew-\w+)/})) + return unless (match_obj = @file_path&.match(%r{/(homebrew-\w+)/})) match_obj[1] end diff --git a/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb b/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb index bd4122dcd35a7..ef0d8c5a4e2b1 100644 --- a/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb +++ b/Library/Homebrew/rubocops/cask/shared_filelist_glob.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true module RuboCop @@ -7,6 +7,7 @@ module Cask class SharedFilelistGlob < Base extend AutoCorrector + sig { params(node: RuboCop::AST::SendNode).void } def on_send(node) return if node.method_name != :zap