refactor: Enable strict typing in download_strategy

This commit is contained in:
Douglas Eichelberger 2025-03-12 11:39:01 -07:00
parent 6ac3311f17
commit 1ca5299f40
No known key found for this signature in database
GPG Key ID: F90193CBD547EB81
12 changed files with 312 additions and 162 deletions

View File

@ -20,7 +20,7 @@ module Cask
sig { returns(T.nilable(T.any(Symbol, String))) } sig { returns(T.nilable(T.any(Symbol, String))) }
attr_reader :user_agent attr_reader :user_agent
sig { returns(T.any(T::Class[T.anything], Symbol, NilClass)) } sig { returns(T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass)) }
attr_reader :using attr_reader :using
sig { returns(T.nilable(String)) } sig { returns(T.nilable(String)) }
@ -35,7 +35,7 @@ module Cask
# @api public # @api public
verified: T.nilable(String), verified: T.nilable(String),
# @api public # @api public
using: T.any(Class, Symbol, NilClass), using: T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass),
# @api public # @api public
tag: T.nilable(String), tag: T.nilable(String),
# @api public # @api public
@ -186,7 +186,7 @@ module Cask
params( params(
uri: T.nilable(T.any(URI::Generic, String)), uri: T.nilable(T.any(URI::Generic, String)),
verified: T.nilable(String), verified: T.nilable(String),
using: T.any(Class, Symbol, NilClass), using: T.any(T::Class[AbstractDownloadStrategy], Symbol, NilClass),
tag: T.nilable(String), tag: T.nilable(String),
branch: T.nilable(String), branch: T.nilable(String),
revisions: T.nilable(T::Array[String]), revisions: T.nilable(T::Array[String]),

View File

@ -115,7 +115,7 @@ module Homebrew
strategy = DownloadStrategyDetector.detect(url) strategy = DownloadStrategyDetector.detect(url)
downloader = strategy.new(url, token, version.to_s, cache: Cask::Cache.path) downloader = strategy.new(url, token, version.to_s, cache: Cask::Cache.path)
downloader.fetch downloader.fetch
downloader.cached_location.sha256 downloader.cached_location!.sha256
end end
[url.gsub(version.to_s, "\#{version}"), sha256] [url.gsub(version.to_s, "\#{version}"), sha256]

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,7 @@ module Downloadable
sig { overridable.returns(Pathname) } sig { overridable.returns(Pathname) }
def cached_download def cached_download
downloader.cached_location downloader.cached_location!
end end
sig { overridable.void } sig { overridable.void }

View File

@ -56,7 +56,7 @@ class Cask::URL
sig { returns(T.nilable(T.any(::String, ::Symbol))) } sig { returns(T.nilable(T.any(::String, ::Symbol))) }
def user_agent; end def user_agent; end
sig { returns(T.nilable(T.any(::Symbol, T::Class[T.anything]))) } sig { returns(T.nilable(T.any(::Symbol, T::Class[::AbstractDownloadStrategy]))) }
def using; end def using; end
sig { returns(T.nilable(::String)) } sig { returns(T.nilable(::String)) }

View File

@ -3,7 +3,7 @@
require "download_strategy" require "download_strategy"
RSpec.describe AbstractDownloadStrategy do RSpec.describe AbstractDownloadStrategy do
subject(:strategy) { described_class.new(url, name, version, **specs) } subject(:strategy) { Class.new(described_class).new(url, name, version, **specs) }
let(:specs) { {} } let(:specs) { {} }
let(:name) { "foo" } let(:name) { "foo" }

View File

@ -6,7 +6,7 @@ RSpec.describe DownloadStrategyDetector do
describe "::detect" do describe "::detect" do
subject(:strategy_detector) { described_class.detect(url, strategy) } subject(:strategy_detector) { described_class.detect(url, strategy) }
let(:url) { Object.new } let(:url) { "invalidurl" }
let(:strategy) { nil } let(:strategy) { nil }
context "when given Git URL" do context "when given Git URL" do

View File

@ -17,6 +17,8 @@ RSpec.describe SubversionDownloadStrategy do
it "adds the appropriate svn args" do it "adds the appropriate svn args" do
expect(strategy).to receive(:system_command!) expect(strategy).to receive(:system_command!)
.with("svn", hash_including(args: array_including("--trust-server-cert", "--non-interactive"))) .with("svn", hash_including(args: array_including("--trust-server-cert", "--non-interactive")))
.and_return(instance_double(SystemCommand::Result))
strategy.fetch strategy.fetch
end end
end end
@ -27,6 +29,7 @@ RSpec.describe SubversionDownloadStrategy do
it "adds svn arguments for :revision" do it "adds svn arguments for :revision" do
expect(strategy).to receive(:system_command!) expect(strategy).to receive(:system_command!)
.with("svn", hash_including(args: array_including_cons("-r", "10"))) .with("svn", hash_including(args: array_including_cons("-r", "10")))
.and_return(instance_double(SystemCommand::Result))
strategy.fetch strategy.fetch
end end

View File

@ -9,7 +9,7 @@ RSpec.describe VCSDownloadStrategy do
describe "#cached_location" do describe "#cached_location" do
it "returns the path of the cached resource" do it "returns the path of the cached resource" do
allow_any_instance_of(described_class).to receive(:cache_tag).and_return("foo") allow_any_instance_of(described_class).to receive(:cache_tag).and_return("foo")
downloader = described_class.new(url, "baz", version) downloader = Class.new(described_class).new(url, "baz", version)
expect(downloader.cached_location).to eq(HOMEBREW_CACHE/"baz--foo") expect(downloader.cached_location).to eq(HOMEBREW_CACHE/"baz--foo")
end end
end end

View File

@ -1,16 +1,20 @@
# typed: true # rubocop:todo Sorbet/StrictSigil # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require "version" require "version"
class URL class URL
attr_reader :specs, :using sig { returns(T::Hash[Symbol, T.untyped]) }
attr_reader :specs
sig { returns(T.any(NilClass, Symbol, T::Class[AbstractDownloadStrategy])) }
attr_reader :using
sig { params(url: String, specs: T::Hash[Symbol, T.untyped]).void } sig { params(url: String, specs: T::Hash[Symbol, T.untyped]).void }
def initialize(url, specs = {}) def initialize(url, specs = {})
@url = url.freeze @url = T.let(url.freeze, String)
@specs = specs.dup @specs = T.let(specs.dup, T::Hash[Symbol, T.untyped])
@using = @specs.delete(:using) @using = T.let(@specs.delete(:using), T.any(NilClass, Symbol, T::Class[AbstractDownloadStrategy]))
@specs.freeze @specs.freeze
end end
@ -19,13 +23,14 @@ class URL
@url @url
end end
sig { returns(T.class_of(AbstractDownloadStrategy)) } sig { returns(T::Class[AbstractDownloadStrategy]) }
def download_strategy def download_strategy
@download_strategy ||= DownloadStrategyDetector.detect(@url, @using) @download_strategy ||=
T.let(DownloadStrategyDetector.detect(@url, @using), T.nilable(T::Class[AbstractDownloadStrategy]))
end end
sig { returns(Version) } sig { returns(Version) }
def version def version
@version ||= Version.detect(@url, **@specs) @version ||= T.let(Version.detect(@url, **@specs), T.nilable(Version))
end end
end end

View File

@ -211,7 +211,7 @@ module Utils
end end
sig { sig {
params( overridable.params(
args: String, args: String,
print_stdout: T.any(T::Boolean, Symbol), print_stdout: T.any(T::Boolean, Symbol),
options: T.untyped, options: T.untyped,
@ -264,7 +264,7 @@ module Utils
curl(*args, **options) curl(*args, **options)
end end
sig { params(args: String, options: T.untyped).returns(SystemCommand::Result) } sig { overridable.params(args: String, options: T.untyped).returns(SystemCommand::Result) }
def curl_output(*args, **options) def curl_output(*args, **options)
curl_with_workarounds(*args, print_stderr: false, show_output: true, **options) curl_with_workarounds(*args, print_stderr: false, show_output: true, **options)
end end

View File

@ -31,14 +31,14 @@ class GitHubArtifactDownloadStrategy < AbstractFileDownloadStrategy
@token = T.let(token, String) @token = T.let(token, String)
end end
sig { params(timeout: T.nilable(Integer)).void } sig { override.params(timeout: T.any(Float, Integer, NilClass)).void }
def fetch(timeout: nil) def fetch(timeout: nil)
ohai "Downloading #{url}" ohai "Downloading #{url}"
if cached_location.exist? if cached_location.exist?
puts "Already downloaded: #{cached_location}" puts "Already downloaded: #{cached_location}"
else else
begin begin
Utils::Curl.curl("--location", "--create-dirs", "--output", temporary_path, url, Utils::Curl.curl("--location", "--create-dirs", "--output", temporary_path.to_s, url,
"--header", "Authorization: token #{@token}", "--header", "Authorization: token #{@token}",
secrets: [@token], secrets: [@token],
timeout:) timeout:)
@ -46,7 +46,7 @@ class GitHubArtifactDownloadStrategy < AbstractFileDownloadStrategy
raise CurlDownloadStrategyError, url raise CurlDownloadStrategyError, url
end end
cached_location.dirname.mkpath cached_location.dirname.mkpath
temporary_path.rename(cached_location) temporary_path.rename(cached_location.to_s)
end end
symlink_location.dirname.mkpath symlink_location.dirname.mkpath