Fix some specs

This commit is contained in:
Douglas Eichelberger 2025-09-06 22:04:22 -07:00
parent e79760ec2c
commit 3b65ca4f85
No known key found for this signature in database
GPG Key ID: F90193CBD547EB81
14 changed files with 53 additions and 48 deletions

View File

@ -9,7 +9,7 @@ class BottleSpecification
attr_reader :collector attr_reader :collector
sig { returns(T::Hash[String, T.untyped]) } sig { returns(T::Hash[Symbol, T.untyped]) }
attr_reader :root_url_specs attr_reader :root_url_specs
sig { returns(String) } sig { returns(String) }
@ -20,7 +20,7 @@ class BottleSpecification
@rebuild = T.let(0, Integer) @rebuild = T.let(0, Integer)
@repository = T.let(Homebrew::DEFAULT_REPOSITORY, String) @repository = T.let(Homebrew::DEFAULT_REPOSITORY, String)
@collector = T.let(Utils::Bottles::Collector.new, Utils::Bottles::Collector) @collector = T.let(Utils::Bottles::Collector.new, Utils::Bottles::Collector)
@root_url_specs = T.let({}, T::Hash[String, T.untyped]) @root_url_specs = T.let({}, T::Hash[Symbol, T.untyped])
@root_url = T.let(nil, T.nilable(String)) @root_url = T.let(nil, T.nilable(String))
end end

View File

@ -37,11 +37,11 @@ module Homebrew
private private
sig { returns(T::Hash[Symbol, T::Array[String]]) } sig { returns(T::Hash[Symbol, T.nilable(T::Array[String])]) }
def skipped_entries def skipped_entries
return @skipped_entries if @skipped_entries return @skipped_entries if @skipped_entries
@skipped_entries ||= T.let({}, T.nilable(T::Hash[Symbol, T::Array[String]])) @skipped_entries ||= T.let({}, T.nilable(T::Hash[Symbol, T.nilable(T::Array[String])]))
[:brew, :cask, :mas, :tap, :whalebrew].each do |type| [:brew, :cask, :mas, :tap, :whalebrew].each do |type|
@skipped_entries[type] = @skipped_entries[type] =
ENV["HOMEBREW_BUNDLE_#{type.to_s.upcase}_SKIP"]&.split ENV["HOMEBREW_BUNDLE_#{type.to_s.upcase}_SKIP"]&.split

View File

@ -12,6 +12,7 @@ module Cask
# #
# @api internal # @api internal
class Config class Config
ConfigValue = T.type_alias { T.any(LazyObject, String, Pathname, T::Array[String]) }
DEFAULT_DIRS = T.let( DEFAULT_DIRS = T.let(
{ {
appdir: "/Applications", appdir: "/Applications",
@ -33,7 +34,7 @@ module Cask
T::Hash[Symbol, String], T::Hash[Symbol, String],
) )
sig { returns(T::Hash[Symbol, String]) } sig { returns(T::Hash[Symbol, T.any(LazyObject, String)]) }
def self.defaults def self.defaults
{ {
languages: LazyObject.new { ::OS::Mac.languages }, languages: LazyObject.new { ::OS::Mac.languages },
@ -79,12 +80,11 @@ module Cask
sig { sig {
params( params(
config: T::Enumerable[ config: T.any(
[T.any(String, Symbol), T.any(String, Pathname, T::Array[String])], T::Hash[Symbol, T.any(LazyObject, String)],
], T::Enumerable[[T.any(String, Symbol), ConfigValue]],
).returns( ),
T::Hash[Symbol, T.any(String, Pathname, T::Array[String])], ).returns(T::Hash[Symbol, ConfigValue])
)
} }
def self.canonicalize(config) def self.canonicalize(config)
config.to_h do |k, v| config.to_h do |k, v|
@ -93,7 +93,7 @@ module Cask
if DEFAULT_DIRS.key?(key) if DEFAULT_DIRS.key?(key)
raise TypeError, "Invalid path for default dir #{k}: #{v.inspect}" if v.is_a?(Array) raise TypeError, "Invalid path for default dir #{k}: #{v.inspect}" if v.is_a?(Array)
[key, Pathname(v).expand_path] [key, Pathname(v.to_s).expand_path]
else else
[key, v] [key, v]
end end
@ -103,14 +103,14 @@ module Cask
# Get the explicit configuration. # Get the explicit configuration.
# #
# @api internal # @api internal
sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) } sig { returns(T::Hash[Symbol, ConfigValue]) }
attr_accessor :explicit attr_accessor :explicit
sig { sig {
params( params(
default: T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), default: T.nilable(T::Hash[Symbol, ConfigValue]),
env: T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), env: T.nilable(T::Hash[Symbol, ConfigValue]),
explicit: T::Hash[Symbol, T.any(String, Pathname, T::Array[String])], explicit: T::Hash[Symbol, ConfigValue],
ignore_invalid_keys: T::Boolean, ignore_invalid_keys: T::Boolean,
).void ).void
} }
@ -118,18 +118,18 @@ module Cask
if default if default
@default = T.let( @default = T.let(
self.class.canonicalize(self.class.defaults.merge(default)), self.class.canonicalize(self.class.defaults.merge(default)),
T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), T.nilable(T::Hash[Symbol, ConfigValue]),
) )
end end
if env if env
@env = T.let( @env = T.let(
self.class.canonicalize(env), self.class.canonicalize(env),
T.nilable(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]), T.nilable(T::Hash[Symbol, ConfigValue]),
) )
end end
@explicit = T.let( @explicit = T.let(
self.class.canonicalize(explicit), self.class.canonicalize(explicit),
T::Hash[Symbol, T.any(String, Pathname, T::Array[String])], T::Hash[Symbol, ConfigValue],
) )
if ignore_invalid_keys if ignore_invalid_keys
@ -142,12 +142,12 @@ module Cask
@explicit.assert_valid_keys(*self.class.defaults.keys) @explicit.assert_valid_keys(*self.class.defaults.keys)
end end
sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) } sig { returns(T::Hash[Symbol, ConfigValue]) }
def default def default
@default ||= self.class.canonicalize(self.class.defaults) @default ||= self.class.canonicalize(self.class.defaults)
end end
sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) } sig { returns(T::Hash[Symbol, ConfigValue]) }
def env def env
@env ||= self.class.canonicalize( @env ||= self.class.canonicalize(
Homebrew::EnvConfig.cask_opts Homebrew::EnvConfig.cask_opts

View File

@ -135,7 +135,7 @@ class DependencyCollector
sig { sig {
params(spec: T.any(String, Resource, Symbol, Requirement, Dependency, Class), params(spec: T.any(String, Resource, Symbol, Requirement, Dependency, Class),
tags: T::Array[Symbol]).returns(T.any(Dependency, Requirement, Array, NilClass)) tags: T::Array[T.any(String, Symbol)]).returns(T.any(Dependency, Requirement, Array, NilClass))
} }
def parse_spec(spec, tags) def parse_spec(spec, tags)
raise ArgumentError, "Implicit dependencies cannot be manually specified" if tags.include?(:implicit) raise ArgumentError, "Implicit dependencies cannot be manually specified" if tags.include?(:implicit)

View File

@ -643,7 +643,7 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
args args
end end
sig { returns(T::Hash[Symbol, String]) } sig { returns(T::Hash[Symbol, T.any(String, Symbol)]) }
def _curl_opts def _curl_opts
return { user_agent: meta.fetch(:user_agent) } if meta.key?(:user_agent) return { user_agent: meta.fetch(:user_agent) } if meta.key?(:user_agent)

View File

@ -283,7 +283,7 @@ module Kernel
# @api public # @api public
sig { sig {
type_parameters(:U) type_parameters(:U)
.params(hash: T::Hash[Object, String], _block: T.proc.returns(T.type_parameter(:U))) .params(hash: T::Hash[Object, T.nilable(String)], _block: T.proc.returns(T.type_parameter(:U)))
.returns(T.type_parameter(:U)) .returns(T.type_parameter(:U))
} }
def with_env(hash, &_block) def with_env(hash, &_block)

View File

@ -3963,7 +3963,7 @@ class Formula
# ``` # ```
# #
# @api public # @api public
sig { params(dep: T.any(String, Symbol, T::Hash[String, T.untyped], T::Class[Requirement])).void } sig { params(dep: T.any(String, Symbol, T::Hash[T.any(String, Symbol), T.untyped], T::Class[Requirement])).void }
def depends_on(dep) def depends_on(dep)
specs.each { |spec| spec.depends_on(dep) } specs.each { |spec| spec.depends_on(dep) }
end end

View File

@ -28,4 +28,7 @@ class LazyObject < Delegator
__getobj__.is_a?(klass) || super __getobj__.is_a?(klass) || super
end end
def class = __getobj__.class
def to_s = __getobj__.to_s
end end

View File

@ -15,10 +15,10 @@ class XcodeRequirement < Requirement
xcode_installed_version! xcode_installed_version!
end end
sig { params(tags: T::Array[String]).void } sig { params(tags: T::Array[T.any(String, Symbol)]).void }
def initialize(tags = []) def initialize(tags = [])
version = tags.shift if tags.first.to_s.match?(/(\d\.)+\d/) version = tags.shift if tags.first.to_s.match?(/(\d\.)+\d/)
@version = T.let(version, T.nilable(String)) @version = T.let(version.to_s, T.nilable(String))
super super
end end

View File

@ -13,7 +13,7 @@ class SBOM
include Utils::Output::Mixin include Utils::Output::Mixin
FILENAME = "sbom.spdx.json" FILENAME = "sbom.spdx.json"
SCHEMA_FILE = (HOMEBREW_LIBRARY_PATH/"data/schemas/sbom.json").freeze SCHEMA_FILE = T.let((HOMEBREW_LIBRARY_PATH/"data/schemas/sbom.json").freeze, Pathname)
# Instantiates a {SBOM} for a new installation of a formula. # Instantiates a {SBOM} for a new installation of a formula.
sig { params(formula: Formula, tab: Tab).returns(T.attached_class) } sig { params(formula: Formula, tab: Tab).returns(T.attached_class) }
@ -85,7 +85,7 @@ class SBOM
sig { returns(T::Hash[String, T.untyped]) } sig { returns(T::Hash[String, T.untyped]) }
def self.schema def self.schema
@schema ||= JSON.parse(SCHEMA_FILE.read, freeze: true) @schema ||= T.let(JSON.parse(SCHEMA_FILE.read, freeze: true), T.nilable(T::Hash[String, T.untyped]))
end end
sig { params(bottling: T::Boolean).returns(T::Array[T::Hash[String, T.untyped]]) } sig { params(bottling: T::Boolean).returns(T::Array[T::Hash[String, T.untyped]]) }
@ -134,17 +134,17 @@ class SBOM
attr_reader :name, :homebrew_version, :time, :stdlib, :source, :built_on, :license attr_reader :name, :homebrew_version, :time, :stdlib, :source, :built_on, :license
attr_accessor :spdxfile attr_accessor :spdxfile
sig { params(attributes: Hash).void } sig { params(attributes: T::Hash[Symbol, T.untyped]).void }
def initialize(attributes = {}) def initialize(attributes = {})
attributes.each { |key, value| instance_variable_set(:"@#{key}", value) } attributes.each { |key, value| instance_variable_set(:"@#{key}", value) }
end end
sig { sig {
params( params(
runtime_dependency_declaration: T::Array[Hash], runtime_dependency_declaration: T::Array[T::Hash[Symbol, T.untyped]],
compiler_declaration: Hash, compiler_declaration: T::Hash[String, T.untyped],
bottling: T::Boolean, bottling: T::Boolean,
).returns(T::Array[Hash]) ).returns(T::Array[T::Hash[Symbol, T.untyped]])
} }
def generate_relations_json(runtime_dependency_declaration, compiler_declaration, bottling:) def generate_relations_json(runtime_dependency_declaration, compiler_declaration, bottling:)
runtime = runtime_dependency_declaration.map do |dependency| runtime = runtime_dependency_declaration.map do |dependency|
@ -167,7 +167,7 @@ class SBOM
spdxElementId: "SPDXRef-File-#{name}", spdxElementId: "SPDXRef-File-#{name}",
relationshipType: "PACKAGE_OF", relationshipType: "PACKAGE_OF",
relatedSpdxElement: "SPDXRef-Archive-#{name}-src", relatedSpdxElement: "SPDXRef-Archive-#{name}-src",
}], T::Array[Hash]) }], T::Array[T::Hash[Symbol, T.untyped]])
unless bottling unless bottling
base << { base << {
@ -189,16 +189,11 @@ class SBOM
end end
sig { sig {
params(runtime_dependency_declaration: T::Array[Hash], params(
compiler_declaration: Hash, runtime_dependency_declaration: T::Array[T::Hash[Symbol, T.untyped]],
bottling: T::Boolean).returns( compiler_declaration: T::Hash[String, T.untyped],
T::Array[ bottling: T::Boolean,
T::Hash[ ).returns(T::Array[T::Hash[Symbol, T.untyped]])
Symbol,
T.any(String, T::Array[T::Hash[Symbol, String]]),
],
],
)
} }
def generate_packages_json(runtime_dependency_declaration, compiler_declaration, bottling:) def generate_packages_json(runtime_dependency_declaration, compiler_declaration, bottling:)
bottle = [] bottle = []
@ -302,7 +297,7 @@ class SBOM
end end
end end
sig { params(bottling: T::Boolean).returns(T::Hash[Symbol, T.any(String, T::Array[T::Hash[Symbol, String]])]) } sig { params(bottling: T::Boolean).returns(T::Hash[Symbol, T.anything]) }
def to_spdx_sbom(bottling:) def to_spdx_sbom(bottling:)
runtime_full = full_spdx_runtime_dependencies(bottling:) runtime_full = full_spdx_runtime_dependencies(bottling:)

View File

@ -242,7 +242,7 @@ class SoftwareSpec
@build = BuildOptions.new(Options.create(@flags), options) @build = BuildOptions.new(Options.create(@flags), options)
end end
sig { params(spec: T.any(String, Symbol, T::Hash[String, T.untyped], T::Class[Requirement], Dependable)).void } sig { params(spec: T.any(String, Symbol, T::Hash[T.any(String, Symbol), T.untyped], T::Class[Requirement], Dependable)).void }
def depends_on(spec) def depends_on(spec)
dep = dependency_collector.add(spec) dep = dependency_collector.add(spec)
add_dep_option(dep) if dep add_dep_option(dep) if dep

View File

@ -478,7 +478,7 @@ class SystemCommand
sig { sig {
params( params(
command: T::Array[String], command: T::Array[String],
output: T::Array[[Symbol, String]], output: T::Array[[T.any(String, Symbol), String]],
status: Process::Status, status: Process::Status,
secrets: T::Array[String], secrets: T::Array[String],
).void ).void

View File

@ -67,7 +67,7 @@ RSpec.describe CurlDownloadStrategy do
context "with a generalized fake user agent" do context "with a generalized fake user agent" do
alias_matcher :a_string_matching, :match alias_matcher :a_string_matching, :match
let(:specs) { { user_agent: :fake } } let(:specs) { { user_agent: "fake" } }
it "adds the appropriate curl args" do it "adds the appropriate curl args" do
expect(strategy).to receive(:system_command) expect(strategy).to receive(:system_command)

View File

@ -33,6 +33,13 @@ module T
recursively_valid?(obj) recursively_valid?(obj)
end end
end end
class TypedHash < TypedEnumerable
# overrides Base
def valid?(obj)
recursively_valid?(obj)
end
end
end end
end end