diff --git a/Library/Homebrew/cask/download.rb b/Library/Homebrew/cask/download.rb index baec2eb63f..0c73efd33a 100644 --- a/Library/Homebrew/cask/download.rb +++ b/Library/Homebrew/cask/download.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true require "downloadable" @@ -13,8 +13,10 @@ module Cask include Context + sig { returns(::Cask::Cask) } attr_reader :cask + sig { params(cask: ::Cask::Cask, quarantine: T.nilable(T::Boolean)).void } def initialize(cask, quarantine: nil) super() @@ -29,9 +31,9 @@ module Cask sig { override.returns(T.nilable(::URL)) } def url - return if cask.url.nil? + return if (cask_url = cask.url).nil? - @url ||= ::URL.new(cask.url.to_s, cask.url.specs) + @url ||= ::URL.new(cask_url.to_s, cask_url.specs) end sig { override.returns(T.nilable(::Checksum)) } @@ -70,12 +72,14 @@ module Cask downloaded_path end + sig { params(timeout: T.any(Float, Integer, NilClass)).returns([T.nilable(Time), Integer]) } def time_file_size(timeout: nil) raise ArgumentError, "not supported for this download strategy" unless downloader.is_a?(CurlDownloadStrategy) T.cast(downloader, CurlDownloadStrategy).resolved_time_file_size(timeout:) end + sig { returns(Pathname) } def basename downloader.basename end @@ -102,6 +106,7 @@ module Cask private + sig { params(path: Pathname).void } def quarantine(path) return if @quarantine.nil? return unless Quarantine.available? diff --git a/Library/Homebrew/downloadable.rb b/Library/Homebrew/downloadable.rb index c04bd8aaac..8000da4022 100644 --- a/Library/Homebrew/downloadable.rb +++ b/Library/Homebrew/downloadable.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true require "url" @@ -23,9 +23,16 @@ module Downloadable sig { void } def initialize + @url = T.let(nil, T.nilable(URL)) + @checksum = T.let(nil, T.nilable(Checksum)) @mirrors = T.let([], T::Array[String]) + @version = T.let(nil, T.nilable(Version)) + @download_strategy = T.let(nil, T.nilable(T::Class[AbstractDownloadStrategy])) + @downloader = T.let(nil, T.nilable(AbstractDownloadStrategy)) + @download_name = T.let(nil, T.nilable(String)) end + sig { params(other: Object).void } def initialize_dup(other) super @checksum = @checksum.dup @@ -46,7 +53,8 @@ module Downloadable sig { returns(String) } def download_type - T.must(self.class.name&.split("::")&.last).gsub(/([[:lower:]])([[:upper:]])/, '\1 \2').downcase + class_name = T.let(self.class, T::Class[Downloadable]).name&.split("::")&.last + T.must(class_name).gsub(/([[:lower:]])([[:upper:]])/, '\1 \2').downcase end sig(:final) { returns(T::Boolean) } @@ -72,9 +80,9 @@ module Downloadable version unless version&.null? end - sig { overridable.returns(T.class_of(AbstractDownloadStrategy)) } + sig { overridable.returns(T::Class[AbstractDownloadStrategy]) } def download_strategy - @download_strategy ||= determine_url&.download_strategy + @download_strategy ||= T.must(determine_url).download_strategy end sig { overridable.returns(AbstractDownloadStrategy) } @@ -129,7 +137,7 @@ module Downloadable sig { overridable.returns(String) } def download_name - @download_name ||= File.basename(determine_url.to_s) + @download_name ||= File.basename(determine_url.to_s).freeze end private diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 1017c7af9b..2b37c2ec43 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -25,15 +25,19 @@ class Resource sig { params(name: T.nilable(String), block: T.nilable(T.proc.bind(Resource).void)).void } def initialize(name = nil, &block) super() - # Ensure this is synced with `initialize_dup` and `freeze` (excluding simple objects like integers and booleans) + # Generally ensure this is synced with `initialize_dup` and `freeze` + # (excluding simple objects like integers & booleans, weak refs like `owner` or permafrozen objects) @name = name + @source_modified_time = nil @patches = [] + @owner = nil @livecheck = Livecheck.new(self) @livecheck_defined = false @insecure = false instance_eval(&block) if block end + sig { params(other: Object).void } def initialize_dup(other) super @name = @name.dup @@ -108,7 +112,7 @@ class Resource current_working_directory = Pathname.pwd stage_resource(download_name, debug_symbols:) do |staging| downloader.stage do - @source_modified_time = downloader.source_modified_time + @source_modified_time = downloader.source_modified_time.freeze apply_patches if block_given? yield ResourceStageContext.new(self, staging) diff --git a/Library/Homebrew/retryable_download.rb b/Library/Homebrew/retryable_download.rb index a7c7f40d23..63fd5ff5fe 100644 --- a/Library/Homebrew/retryable_download.rb +++ b/Library/Homebrew/retryable_download.rb @@ -1,4 +1,4 @@ -# typed: true # rubocop:todo Sorbet/StrictSigil +# typed: strict # frozen_string_literal: true module Homebrew @@ -23,7 +23,7 @@ module Homebrew super() @downloadable = downloadable - @try = 0 + @try = T.let(0, Integer) @tries = tries end @@ -42,7 +42,7 @@ module Homebrew sig { override.returns(T.nilable(Version)) } def version = downloadable.version - sig { override.returns(T.class_of(AbstractDownloadStrategy)) } + sig { override.returns(T::Class[AbstractDownloadStrategy]) } def download_strategy = downloadable.download_strategy sig { override.returns(AbstractDownloadStrategy) }