Skip to content

cmd: set typed: strict #20130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions Library/Homebrew/cmd/fetch.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# typed: true # rubocop:todo Sorbet/StrictSigil
# typed: strict
# frozen_string_literal: true

require "abstract_command"
require "formula"
require "fetch"
require "cask/download"
require "retryable_download"
require "download_queue"

module Homebrew
module Cmd
Expand Down Expand Up @@ -69,15 +70,16 @@ class FetchCmd < AbstractCommand
named_args [:formula, :cask], min: 1
end

sig { returns(Integer) }
def concurrency
@concurrency ||= args.concurrency&.to_i || 1
@concurrency ||= T.let(args.concurrency&.to_i || 1, T.nilable(Integer))
end

sig { returns(DownloadQueue) }
def download_queue
@download_queue ||= begin
require "download_queue"
@download_queue ||= T.let(begin
DownloadQueue.new(concurrency)
end
end, T.nilable(DownloadQueue))
end

class Spinner
Expand All @@ -96,8 +98,8 @@ class Spinner

sig { void }
def initialize
@start = Time.now
@i = 0
@start = T.let(Time.now, Time)
@i = T.let(0, Integer)
end

sig { returns(String) }
Expand Down Expand Up @@ -136,7 +138,7 @@ def run
bucket.each do |formula_or_cask|
case formula_or_cask
when Formula
formula = T.cast(formula_or_cask, Formula)
formula = formula_or_cask
ref = formula.loaded_from_api? ? formula.full_name : formula.path

os_arch_combinations.each do |os, arch|
Expand Down Expand Up @@ -189,7 +191,9 @@ def run

next if fetched_bottle

fetch_downloadable(formula.resource)
if (resource = formula.resource)
fetch_downloadable(resource)
end

formula.resources.each do |r|
fetch_downloadable(r)
Expand Down Expand Up @@ -231,7 +235,7 @@ def run
end
else
spinner = Spinner.new
remaining_downloads = downloads.dup
remaining_downloads = downloads.dup.to_a
previous_pending_line_count = 0

begin
Expand Down Expand Up @@ -332,10 +336,13 @@ def run

private

sig { returns(T::Hash[T.any(Resource, Bottle, Cask::Download), Concurrent::Promises::Future]) }
def downloads
@downloads ||= {}
@downloads ||= T.let({}, T.nilable(T::Hash[T.any(Resource, Bottle, Cask::Download),
Concurrent::Promises::Future]))
end

sig { params(downloadable: T.any(Resource, Bottle, Cask::Download)).void }
def fetch_downloadable(downloadable)
downloads[downloadable] ||= begin
tries = args.retry? ? {} : { tries: 1 }
Expand Down
43 changes: 29 additions & 14 deletions Library/Homebrew/cmd/info.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true # rubocop:todo Sorbet/StrictSigil
# typed: strict
# frozen_string_literal: true

require "abstract_command"
Expand All @@ -18,7 +18,7 @@
class Info < AbstractCommand
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
VALID_CATEGORIES = T.let((VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze, T::Array[String])

cmd_args do
description <<~EOS
Expand Down Expand Up @@ -96,21 +96,25 @@
end

print_analytics
elsif args.json
elsif (json = args.json)
all = args.eval_all?

print_json(all)
print_json(json, all)
elsif args.github?
raise FormulaOrCaskUnspecifiedError if args.no_named?

exec_browser(*args.named.to_formulae_and_casks.map { |f| github_info(f) })
exec_browser(*args.named.to_formulae_and_casks.map do |formula_keg_or_cask|
formula_or_cask = T.cast(formula_keg_or_cask, T.any(Formula, Cask::Cask))
github_info(formula_or_cask)

Check warning on line 108 in Library/Homebrew/cmd/info.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/info.rb#L106-L108

Added lines #L106 - L108 were not covered by tests
end)
elsif args.no_named?
print_statistics
else
print_info
end
end

sig { params(remote: String, path: String).returns(String) }
def github_remote_path(remote, path)
if remote =~ %r{^(?:https?://|git(?:@|://))github\.com[:/](.+)/(.+?)(?:\.git)?$}
"https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/blob/HEAD/#{path}"
Expand Down Expand Up @@ -175,6 +179,7 @@
end
end

sig { params(version: T.any(T::Boolean, String)).returns(Symbol) }
def json_version(version)
version_hash = {
true => :default,
Expand All @@ -187,11 +192,11 @@
version_hash[version]
end

sig { params(all: T::Boolean).void }
def print_json(all)
sig { params(json: T.any(T::Boolean, String), all: T::Boolean).void }
def print_json(json, all)
raise FormulaOrCaskUnspecifiedError if !(all || args.installed?) && args.no_named?

json = case json_version(args.json)
json = case json_version(json)
when :v1, :default
raise UsageError, "Cannot specify `--cask` when using `--json=v1`!" if args.cask?

Expand Down Expand Up @@ -240,25 +245,31 @@
puts JSON.pretty_generate(json)
end

sig { params(formula_or_cask: T.any(Formula, Cask::Cask)).returns(String) }
def github_info(formula_or_cask)
return formula_or_cask.path if formula_or_cask.tap.blank? || formula_or_cask.tap.remote.blank?

path = case formula_or_cask
when Formula
formula = formula_or_cask
formula.path.relative_path_from(T.must(formula.tap).path)
tap = formula.tap

Check warning on line 253 in Library/Homebrew/cmd/info.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/info.rb#L253

Added line #L253 was not covered by tests
return formula.path.to_s if tap.blank? || tap.remote.blank?

formula.path.relative_path_from(tap.path)

Check warning on line 256 in Library/Homebrew/cmd/info.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/info.rb#L256

Added line #L256 was not covered by tests
when Cask::Cask
cask = formula_or_cask
tap = cask.tap

Check warning on line 259 in Library/Homebrew/cmd/info.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/info.rb#L259

Added line #L259 was not covered by tests
return cask.sourcefile_path.to_s if tap.blank? || tap.remote.blank?

if cask.sourcefile_path.blank? || cask.sourcefile_path.extname != ".rb"
return "#{cask.tap.default_remote}/blob/HEAD/#{cask.tap.relative_cask_path(cask.token)}"
return "#{tap.default_remote}/blob/HEAD/#{tap.relative_cask_path(cask.token)}"
end

cask.sourcefile_path.relative_path_from(cask.tap.path)
cask.sourcefile_path.relative_path_from(tap.path)

Check warning on line 266 in Library/Homebrew/cmd/info.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/info.rb#L266

Added line #L266 was not covered by tests
end

github_remote_path(formula_or_cask.tap.remote, path)
github_remote_path(tap.remote, path)

Check warning on line 269 in Library/Homebrew/cmd/info.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/info.rb#L269

Added line #L269 was not covered by tests
end

sig { params(formula: Formula).void }
def info_formula(formula)
specs = []

Expand Down Expand Up @@ -356,6 +367,7 @@
Utils::Analytics.formula_output(formula, args:)
end

sig { params(dependencies: T::Array[Dependency]).returns(String) }
def decorate_dependencies(dependencies)
deps_status = dependencies.map do |dep|
if dep.satisfied?([])
Expand All @@ -367,6 +379,7 @@
deps_status.join(", ")
end

sig { params(requirements: T::Array[Requirement]).returns(String) }
def decorate_requirements(requirements)
req_status = requirements.map do |req|
req_s = req.display_s
Expand All @@ -375,12 +388,14 @@
req_status.join(", ")
end

sig { params(dep: Dependency).returns(String) }
def dep_display_s(dep)
return dep.name if dep.option_tags.empty?

"#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}"
end

sig { params(cask: Cask::Cask).void }
def info_cask(cask)
require "cask/info"

Expand Down
Loading