diff --git a/.gitignore b/.gitignore index 459a668d06ee0..58bd229b00650 100644 --- a/.gitignore +++ b/.gitignore @@ -53,25 +53,6 @@ !**/vendor/bundle/ruby/*/gems/*/lib !**/vendor/bundle/ruby/*/gems/addressable-*/data !**/vendor/bundle/ruby/*/gems/public_suffix-*/data -!**/vendor/bundle/ruby/*/gems/rubocop-performance-*/config -!**/vendor/bundle/ruby/*/gems/rubocop-rails-*/config -!**/vendor/bundle/ruby/*/gems/rubocop-rspec-*/config -!**/vendor/bundle/ruby/*/gems/rubocop-sorbet-*/config - -# Ignore activesupport, except the ones we need. -**/vendor/bundle/ruby/*/gems/activesupport-*/lib/**/* -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/ -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/ -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/*/ -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/array/access.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/enumerable.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/file/atomic.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/hash/deep_merge.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/hash/deep_transform_values.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/hash/keys.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/object/deep_dup.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/object/duplicable.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/string/exclude.rb # Ignore partially included gems where we don't need all files **/vendor/gems/mechanize-*/.* @@ -89,6 +70,7 @@ **/vendor/gems/mechanize-*/test/ # Ignore dependencies we don't wish to vendor +**/vendor/bundle/ruby/*/gems/activesupport-*/ **/vendor/bundle/ruby/*/gems/ast-*/ **/vendor/bundle/ruby/*/gems/bootsnap-*/ **/vendor/bundle/ruby/*/gems/bundler-*/ diff --git a/Library/Homebrew/cask/artifact/abstract_artifact.rb b/Library/Homebrew/cask/artifact/abstract_artifact.rb index 7e86cf4ac58a7..dcfddaca46223 100644 --- a/Library/Homebrew/cask/artifact/abstract_artifact.rb +++ b/Library/Homebrew/cask/artifact/abstract_artifact.rb @@ -2,7 +2,7 @@ # frozen_string_literal: true require "attrable" -require "active_support/core_ext/object/deep_dup" +require "extend/object/deep_dup" module Cask module Artifact diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index db0dbe3551937..a08431eb93409 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -6,6 +6,7 @@ require "utils/user" require "cask/artifact/abstract_artifact" require "cask/pkg" +require "extend/hash/keys" module Cask module Artifact diff --git a/Library/Homebrew/cask/artifact/installer.rb b/Library/Homebrew/cask/artifact/installer.rb index 69de947bea375..810a48b9f784d 100644 --- a/Library/Homebrew/cask/artifact/installer.rb +++ b/Library/Homebrew/cask/artifact/installer.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "cask/artifact/abstract_artifact" +require "extend/hash/keys" module Cask module Artifact diff --git a/Library/Homebrew/cask/artifact/pkg.rb b/Library/Homebrew/cask/artifact/pkg.rb index 0d2610f29f620..5bf94b6ee6525 100644 --- a/Library/Homebrew/cask/artifact/pkg.rb +++ b/Library/Homebrew/cask/artifact/pkg.rb @@ -5,6 +5,7 @@ require "utils/user" require "cask/artifact/abstract_artifact" +require "extend/hash/keys" module Cask module Artifact diff --git a/Library/Homebrew/cask/artifact/relocated.rb b/Library/Homebrew/cask/artifact/relocated.rb index ecb6ba3242b1e..345699031dcdd 100644 --- a/Library/Homebrew/cask/artifact/relocated.rb +++ b/Library/Homebrew/cask/artifact/relocated.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "cask/artifact/abstract_artifact" +require "extend/hash/keys" module Cask module Artifact diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 9adcb5ad8c58c..9516792de8ebc 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -5,6 +5,7 @@ require "cask/cask" require "uri" require "utils/curl" +require "extend/hash/keys" module Cask # Loads a cask from various sources. diff --git a/Library/Homebrew/cask/config.rb b/Library/Homebrew/cask/config.rb index b546a44f48102..ac11934b7a756 100644 --- a/Library/Homebrew/cask/config.rb +++ b/Library/Homebrew/cask/config.rb @@ -5,6 +5,7 @@ require "lazy_object" require "locale" +require "extend/hash/keys" module Cask # Configuration for installing casks. diff --git a/Library/Homebrew/cask/dsl/conflicts_with.rb b/Library/Homebrew/cask/dsl/conflicts_with.rb index 40b19f60568bd..1b177198fd378 100644 --- a/Library/Homebrew/cask/dsl/conflicts_with.rb +++ b/Library/Homebrew/cask/dsl/conflicts_with.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "delegate" +require "extend/hash/keys" module Cask class DSL diff --git a/Library/Homebrew/cli/parser.rb b/Library/Homebrew/cli/parser.rb index 4bb9aec91cdb7..1f2f4cdc186e7 100644 --- a/Library/Homebrew/cli/parser.rb +++ b/Library/Homebrew/cli/parser.rb @@ -126,9 +126,9 @@ def initialize(&block) # Filter out Sorbet runtime type checking method calls. cmd_location = T.must(caller_locations).select do |location| T.must(location.path).exclude?("/gems/sorbet-runtime-") - end.second - @command_name = cmd_location.label.chomp("_args").tr("_", "-") - @is_dev_cmd = cmd_location.absolute_path.start_with?(Commands::HOMEBREW_DEV_CMD_PATH) + end.fetch(1) + @command_name = T.must(cmd_location.label).chomp("_args").tr("_", "-") + @is_dev_cmd = T.must(cmd_location.absolute_path).start_with?(Commands::HOMEBREW_DEV_CMD_PATH) @constraints = [] @conflicts = [] diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 524674708d60e..7ebc235b33236 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -11,6 +11,7 @@ require "erb" require "utils/gzip" require "api" +require "extend/hash/deep_merge" BOTTLE_ERB = <<-EOS.freeze bottle do diff --git a/Library/Homebrew/dev-cmd/pr-upload.rb b/Library/Homebrew/dev-cmd/pr-upload.rb index 971a191e72fb9..5f6fa25633dd1 100644 --- a/Library/Homebrew/dev-cmd/pr-upload.rb +++ b/Library/Homebrew/dev-cmd/pr-upload.rb @@ -5,6 +5,7 @@ require "formula" require "github_packages" require "github_releases" +require "extend/hash/deep_merge" module Homebrew module_function diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 4f9becfad999a..af8931b6fe60f 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -360,7 +360,7 @@ def parse_basename(url, search_query: true) end if search_query && (uri_query = uri.query.presence) - components[:query] = URI.decode_www_form(uri_query).map(&:second) + components[:query] = URI.decode_www_form(uri_query).map { _2 } end else components[:path] = [url] diff --git a/Library/Homebrew/extend/array.rb b/Library/Homebrew/extend/array.rb index 2755ee92bf5a6..152033304bae3 100644 --- a/Library/Homebrew/extend/array.rb +++ b/Library/Homebrew/extend/array.rb @@ -1,7 +1,27 @@ -# typed: true +# typed: strict # frozen_string_literal: true class Array + # Equal to self[1]. + # + # %w( a b c d e ).second # => "b" + def second = self[1] + + # Equal to self[2]. + # + # %w( a b c d e ).third # => "c" + def third = self[2] + + # Equal to self[3]. + # + # %w( a b c d e ).fourth # => "d" + def fourth = self[3] + + # Equal to self[4]. + # + # %w( a b c d e ).fifth # => "e" + def fifth = self[4] + # Converts the array to a comma-separated sentence where the last element is # joined by the connector word. # @@ -48,6 +68,7 @@ class Array # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + sig { params(words_connector: String, two_words_connector: String, last_word_connector: String).returns(String) } def to_sentence(words_connector: ", ", two_words_connector: " and ", last_word_connector: " and ") case length when 0 diff --git a/Library/Homebrew/extend/array.rbi b/Library/Homebrew/extend/array.rbi new file mode 100644 index 0000000000000..3d9e293bd459b --- /dev/null +++ b/Library/Homebrew/extend/array.rbi @@ -0,0 +1,15 @@ +# typed: strict + +class Array + sig { returns(T.nilable(Elem)) } + def second; end + + sig { returns(T.nilable(Elem)) } + def third; end + + sig { returns(T.nilable(Elem)) } + def fourth; end + + sig { returns(T.nilable(Elem)) } + def fifth; end +end diff --git a/Library/Homebrew/extend/enumerable.rb b/Library/Homebrew/extend/enumerable.rb new file mode 100644 index 0000000000000..77b499b2ddc79 --- /dev/null +++ b/Library/Homebrew/extend/enumerable.rb @@ -0,0 +1,30 @@ +# typed: strict +# frozen_string_literal: true + +module Enumerable + # The negative of the Enumerable#include?. Returns +true+ if the + # collection does not include the object. + sig { params(object: T.untyped).returns(T::Boolean) } + def exclude?(object) = !include?(object) + + # Returns a new +Array+ without the blank items. + # Uses Object#blank? for determining if an item is blank. + # + # [1, "", nil, 2, " ", [], {}, false, true].compact_blank + # # => [1, 2, true] + # + # Set.new([nil, "", 1, false]).compact_blank + # # => [1] + # + # When called on a +Hash+, returns a new +Hash+ without the blank values. + # + # { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank + # # => { b: 1, f: true } + sig { returns(T.self_type) } + def compact_blank = T.unsafe(self).reject(&:blank?) +end + +class Hash + # Hash#reject has its own definition, so this needs one too. + def compact_blank = reject { |_k, v| T.unsafe(v).blank? } +end diff --git a/Library/Homebrew/extend/enumerable.rbi b/Library/Homebrew/extend/enumerable.rbi new file mode 100644 index 0000000000000..207de60eb603d --- /dev/null +++ b/Library/Homebrew/extend/enumerable.rbi @@ -0,0 +1,6 @@ +# typed: strict + +class Hash + sig { returns(T::Hash[Hash::K, Hash::V]) } + def compact_blank; end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/file/atomic.rb b/Library/Homebrew/extend/file/atomic.rb similarity index 75% rename from Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/file/atomic.rb rename to Library/Homebrew/extend/file/atomic.rb index 9deceb1bb44d5..b57c9cc8504c9 100644 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/file/atomic.rb +++ b/Library/Homebrew/extend/file/atomic.rb @@ -1,3 +1,4 @@ +# typed: strict # frozen_string_literal: true require "fileutils" @@ -18,7 +19,14 @@ class File # File.atomic_write('/data/something.important', '/data/tmp') do |file| # file.write('hello') # end - def self.atomic_write(file_name, temp_dir = dirname(file_name)) + sig { + type_parameters(:out).params( + file_name: T.any(Pathname, String), + temp_dir: String, + _block: T.proc.params(arg0: Tempfile).returns(T.type_parameter(:out)), + ).returns(T.type_parameter(:out)) + } + def self.atomic_write(file_name, temp_dir = dirname(file_name), &_block) require "tempfile" unless defined?(Tempfile) Tempfile.open(".#{basename(file_name)}", temp_dir) do |temp_file| @@ -38,32 +46,35 @@ def self.atomic_write(file_name, temp_dir = dirname(file_name)) if old_stat # Set correct permissions on new file begin - chown(old_stat.uid, old_stat.gid, temp_file.path) + chown(old_stat.uid, old_stat.gid, T.must(temp_file.path)) # This operation will affect filesystem ACL's - chmod(old_stat.mode, temp_file.path) + chmod(old_stat.mode, T.must(temp_file.path)) rescue Errno::EPERM, Errno::EACCES # Changing file ownership failed, moving on. end end # Overwrite original file with temp file - rename(temp_file.path, file_name) + rename(T.must(temp_file.path), file_name) return_val end end # Private utility method. - def self.probe_stat_in(dir) #:nodoc: + sig { params(dir: String).returns(T.nilable(File::Stat)) } + private_class_method def self.probe_stat_in(dir) # :nodoc: basename = [ ".permissions_check", Thread.current.object_id, Process.pid, - rand(1000000) + rand(1_000_000), ].join(".") file_name = join(dir, basename) FileUtils.touch(file_name) stat(file_name) + rescue Errno::ENOENT + file_name = nil ensure FileUtils.rm_f(file_name) if file_name end diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/deep_merge.rb b/Library/Homebrew/extend/hash/deep_merge.rb similarity index 81% rename from Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/deep_merge.rb rename to Library/Homebrew/extend/hash/deep_merge.rb index 9bc50b7bc63bf..01ecbe926044c 100644 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/deep_merge.rb +++ b/Library/Homebrew/extend/hash/deep_merge.rb @@ -1,3 +1,4 @@ +# typed: strict # frozen_string_literal: true class Hash @@ -22,10 +23,10 @@ def deep_merge(other_hash, &block) # Same as +deep_merge+, but modifies +self+. def deep_merge!(other_hash, &block) merge!(other_hash) do |key, this_val, other_val| - if this_val.is_a?(Hash) && other_val.is_a?(Hash) - this_val.deep_merge(other_val, &block) - elsif block_given? - block.call(key, this_val, other_val) + if T.unsafe(this_val).is_a?(Hash) && other_val.is_a?(Hash) + T.unsafe(this_val).deep_merge(other_val, &block) + elsif block + yield(key, this_val, other_val) else other_val end diff --git a/Library/Homebrew/extend/hash/deep_merge.rbi b/Library/Homebrew/extend/hash/deep_merge.rbi new file mode 100644 index 0000000000000..ed5f3a9b6ce8e --- /dev/null +++ b/Library/Homebrew/extend/hash/deep_merge.rbi @@ -0,0 +1,20 @@ +# typed: strict +# frozen_string_literal: true + +class Hash + sig do + type_parameters(:k2).params( + other_hash: T::Hash[T.type_parameter(:k2), T.untyped], + block: T.nilable(T.proc.params(k: T.untyped, v1: T.untyped, v2: T.untyped).returns(T.untyped)) + ).returns(T::Hash[T.any(Hash::K, T.type_parameter(:k2)), T.untyped]) + end + def deep_merge(other_hash, &block); end + + sig do + type_parameters(:k2).params( + other_hash: T::Hash[T.type_parameter(:k2), T.untyped], + block: T.nilable(T.proc.params(k: T.untyped, v1: T.untyped, v2: T.untyped).returns(T.untyped)) + ).returns(T::Hash[T.any(Hash::K, T.type_parameter(:k2)), T.untyped]) + end + def deep_merge!(other_hash, &block); end +end diff --git a/Library/Homebrew/extend/hash/deep_transform_values.rb b/Library/Homebrew/extend/hash/deep_transform_values.rb new file mode 100644 index 0000000000000..608e3c73a87f4 --- /dev/null +++ b/Library/Homebrew/extend/hash/deep_transform_values.rb @@ -0,0 +1,46 @@ +# typed: strict +# frozen_string_literal: true + +class Hash + # Returns a new hash with all values converted by the block operation. + # This includes the values from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_transform_values{ |value| value.to_s.upcase } + # # => {person: {name: "ROB", age: "28"}} + def deep_transform_values(&block) = _deep_transform_values_in_object(self, &block) + + # Destructively converts all values by using the block operation. + # This includes the values from the root hash and from all + # nested hashes and arrays. + def deep_transform_values!(&block) = _deep_transform_values_in_object!(self, &block) + + private + + # Support methods for deep transforming nested hashes and arrays. + sig { params(object: T.anything, block: T.proc.params(v: T.untyped).returns(T.untyped)).returns(T.untyped) } + def _deep_transform_values_in_object(object, &block) + case object + when Hash + object.transform_values { |value| _deep_transform_values_in_object(value, &block) } + when Array + object.map { |e| _deep_transform_values_in_object(e, &block) } + else + yield(object) + end + end + + sig { params(object: T.anything, block: T.proc.params(v: T.untyped).returns(T.untyped)).returns(T.untyped) } + def _deep_transform_values_in_object!(object, &block) + case object + when Hash + object.transform_values! { |value| _deep_transform_values_in_object!(value, &block) } + when Array + object.map! { |e| _deep_transform_values_in_object!(e, &block) } + else + yield(object) + end + end +end diff --git a/Library/Homebrew/extend/hash/deep_transform_values.rbi b/Library/Homebrew/extend/hash/deep_transform_values.rbi new file mode 100644 index 0000000000000..29c8d273e2935 --- /dev/null +++ b/Library/Homebrew/extend/hash/deep_transform_values.rbi @@ -0,0 +1,17 @@ +# typed: strict + +class Hash + sig { + type_parameters(:out).params( + block: T.proc.params(o: Hash::V).returns(T.type_parameter(:out)) + ).returns(T::Hash[Hash::K, T.type_parameter(:out)]) + } + def deep_transform_values(&block); end + + sig { + type_parameters(:out).params( + block: T.proc.params(o: Hash::V).returns(T.type_parameter(:out)) + ).returns(T::Hash[Hash::K, T.type_parameter(:out)]) + } + def deep_transform_values!(&block); end +end diff --git a/Library/Homebrew/extend/hash/keys.rb b/Library/Homebrew/extend/hash/keys.rb new file mode 100644 index 0000000000000..caa742d3b2e03 --- /dev/null +++ b/Library/Homebrew/extend/hash/keys.rb @@ -0,0 +1,117 @@ +# typed: strict +# frozen_string_literal: true + +class Hash + # Validates all keys in a hash match *valid_keys, raising + # +ArgumentError+ on a mismatch. + # + # Note that keys are treated differently than HashWithIndifferentAccess, + # meaning that string and symbol keys will not match. + # + # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) + # # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age" + # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') + # # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'" + # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing + sig { params(valid_keys: T.untyped).void } + def assert_valid_keys(*valid_keys) + valid_keys.flatten! + each_key do |k| + next if valid_keys.include?(k) + + raise ArgumentError, + "Unknown key: #{T.unsafe(k).inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(", ")}" + end + end + + # Returns a new hash with all keys converted by the block operation. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_transform_keys{ |key| key.to_s.upcase } + # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}} + def deep_transform_keys(&block) = _deep_transform_keys_in_object(self, &block) + + # Destructively converts all keys by using the block operation. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_transform_keys!(&block) = _deep_transform_keys_in_object!(self, &block) + + # Returns a new hash with all keys converted to strings. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_stringify_keys + # # => {"person"=>{"name"=>"Rob", "age"=>"28"}} + def deep_stringify_keys = T.unsafe(self).deep_transform_keys(&:to_s) + + # Destructively converts all keys to strings. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_stringify_keys! = T.unsafe(self).deep_transform_keys!(&:to_s) + + # Returns a new hash with all keys converted to symbols, as long as + # they respond to +to_sym+. This includes the keys from the root hash + # and from all nested hashes and arrays. + # + # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } + # + # hash.deep_symbolize_keys + # # => {:person=>{:name=>"Rob", :age=>"28"}} + def deep_symbolize_keys + deep_transform_keys do |key| + T.unsafe(key).to_sym + rescue + key + end + end + + # Destructively converts all keys to symbols, as long as they respond + # to +to_sym+. This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_symbolize_keys! + deep_transform_keys! do |key| + T.unsafe(key).to_sym + rescue + key + end + end + + private + + # Support methods for deep transforming nested hashes and arrays. + sig { params(object: T.anything, block: T.proc.params(k: T.untyped).returns(T.untyped)).returns(T.untyped) } + def _deep_transform_keys_in_object(object, &block) + case object + when Hash + object.each_with_object({}) do |(key, value), result| + result[yield(key)] = _deep_transform_keys_in_object(value, &block) + end + when Array + object.map { |e| _deep_transform_keys_in_object(e, &block) } + else + object + end + end + + sig { params(object: T.anything, block: T.proc.params(k: T.untyped).returns(T.untyped)).returns(T.untyped) } + def _deep_transform_keys_in_object!(object, &block) + case object + when Hash + # We can't use `each_key` here because we're updating the hash in-place + object.keys.each do |key| # rubocop:disable Style/HashEachMethods + value = object.delete(key) + object[yield(key)] = _deep_transform_keys_in_object!(value, &block) + end + object + when Array + object.map! { |e| _deep_transform_keys_in_object!(e, &block) } + else + object + end + end +end diff --git a/Library/Homebrew/extend/hash/keys.rbi b/Library/Homebrew/extend/hash/keys.rbi new file mode 100644 index 0000000000000..581c876f7fa8d --- /dev/null +++ b/Library/Homebrew/extend/hash/keys.rbi @@ -0,0 +1,30 @@ +# typed: strict +# frozen_string_literal: true + +class Hash + sig { + type_parameters(:out).params( + block: T.proc.params(o: K).returns(T.type_parameter(:out)) + ).returns(T::Hash[T.type_parameter(:out), V]) + } + def deep_transform_keys(&block); end + + sig { + type_parameters(:out).params( + block: T.proc.params(o: K).returns(T.type_parameter(:out)) + ).returns(T::Hash[T.type_parameter(:out), V]) + } + def deep_transform_keys!(&block); end + + sig { returns(T::Hash[String, V]) } + def deep_stringify_keys; end + + sig { returns(T::Hash[String, V]) } + def deep_stringify_keys!; end + + sig { returns(T::Hash[Symbol, V]) } + def deep_symbolize_keys; end + + sig { returns(T::Hash[Symbol, V]) } + def deep_symbolize_keys!; end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/object/deep_dup.rb b/Library/Homebrew/extend/object/deep_dup.rb similarity index 58% rename from Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/object/deep_dup.rb rename to Library/Homebrew/extend/object/deep_dup.rb index 5c903917f5f06..24262d1a5a155 100644 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/object/deep_dup.rb +++ b/Library/Homebrew/extend/object/deep_dup.rb @@ -1,6 +1,7 @@ +# typed: strict # frozen_string_literal: true -require "active_support/core_ext/object/duplicable" +require "extend/object/duplicable" class Object # Returns a deep copy of object if it's duplicable. If it's @@ -12,6 +13,7 @@ class Object # # object.instance_variable_defined?(:@a) # => false # dup.instance_variable_defined?(:@a) # => true + sig { returns(T.self_type) } def deep_dup duplicable? ? dup : self end @@ -26,8 +28,9 @@ class Array # # array[1][2] # => nil # dup[1][2] # => 4 + sig { returns(T.self_type) } def deep_dup - map(&:deep_dup) + T.unsafe(self).map(&:deep_dup) end end @@ -40,16 +43,35 @@ class Hash # # hash[:a][:c] # => nil # dup[:a][:c] # => "c" + sig { returns(T.self_type) } def deep_dup hash = dup each_pair do |key, value| - if (::String === key && key.frozen?) || ::Symbol === key - hash[key] = value.deep_dup + case key + when ::String, ::Symbol + hash[key] = T.unsafe(value).deep_dup else hash.delete(key) - hash[key.deep_dup] = value.deep_dup + hash[T.unsafe(key).deep_dup] = T.unsafe(value).deep_dup end end hash end end + +class Module + # Returns a copy of module or class if it's anonymous. If it's + # named, returns +self+. + # + # Object.deep_dup == Object # => true + # klass = Class.new + # klass.deep_dup == klass # => false + sig { returns(T.self_type) } + def deep_dup + if name.nil? + super + else + self + end + end +end diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/object/duplicable.rb b/Library/Homebrew/extend/object/duplicable.rb similarity index 58% rename from Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/object/duplicable.rb rename to Library/Homebrew/extend/object/duplicable.rb index 3ebcdca02b73c..d5f566cb52e64 100644 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/object/duplicable.rb +++ b/Library/Homebrew/extend/object/duplicable.rb @@ -1,3 +1,4 @@ +# typed: strict # frozen_string_literal: true #-- @@ -23,27 +24,34 @@ class Object # # False for method objects; # true otherwise. - def duplicable? - true - end + sig { returns(T::Boolean) } + def duplicable? = true end class Method # Methods are not duplicable: # - # method(:puts).duplicable? # => false - # method(:puts).dup # => TypeError: allocator undefined for Method - def duplicable? - false - end + # method(:puts).duplicable? # => false + # method(:puts).dup # => TypeError: allocator undefined for Method + sig { returns(FalseClass) } + def duplicable? = false end class UnboundMethod # Unbound methods are not duplicable: # - # method(:puts).unbind.duplicable? # => false - # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod - def duplicable? - false - end + # method(:puts).unbind.duplicable? # => false + # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod + sig { returns(FalseClass) } + def duplicable? = false +end + +require "singleton" + +module Singleton + # Singleton instances are not duplicable: + # + # Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton + sig { returns(FalseClass) } + def duplicable? = false end diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index c2b5a8a933296..82fdd38fcba1f 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -4,6 +4,7 @@ require "context" require "resource" require "metafiles" +require "extend/file/atomic" module DiskUsageExtension sig { returns(Integer) } diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/string/exclude.rb b/Library/Homebrew/extend/string.rb similarity index 71% rename from Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/string/exclude.rb rename to Library/Homebrew/extend/string.rb index 8e462689f1cc2..6beadc7272f67 100644 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/string/exclude.rb +++ b/Library/Homebrew/extend/string.rb @@ -1,3 +1,4 @@ +# typed: strict # frozen_string_literal: true class String @@ -7,7 +8,6 @@ class String # "hello".exclude? "lo" # => false # "hello".exclude? "ol" # => true # "hello".exclude? ?h # => false - def exclude?(string) - !include?(string) - end + sig { params(string: String).returns(T::Boolean) } + def exclude?(string) = !include?(string) end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index d99a518595fd9..4d7a21cf960bd 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -566,7 +566,7 @@ def expand_requirements unsatisfied_reqs = Hash.new { |h, k| h[k] = [] } formulae = [formula] formula_deps_map = formula.recursive_dependencies - .index_by(&:name) + .each_with_object({}) { |dep, h| h[dep.name] = dep } while (f = formulae.pop) runtime_requirements = runtime_requirements(f) @@ -1208,7 +1208,7 @@ def fetch_bottle_tab formula.fetch_bottle_tab @bottle_tab_runtime_dependencies = formula.bottle_tab_attributes .fetch("runtime_dependencies", []) - .index_by { |dep| dep["full_name"] } + .each_with_object({}) { |dep, h| h[dep["full_name"]] = dep } .freeze true rescue DownloadError, ArgumentError diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index f473dcb08a5e9..5063333823207 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -8,8 +8,8 @@ require "service" require "utils/curl" require "deprecate_disable" - -require "active_support/core_ext/hash/deep_transform_values" +require "extend/hash/deep_transform_values" +require "extend/hash/keys" # The {Formulary} is responsible for creating instances of {Formula}. # It is not meant to be used directly from formulae. diff --git a/Library/Homebrew/github_packages.rb b/Library/Homebrew/github_packages.rb index 9d3fc79bcb845..1bcd1ccb59131 100644 --- a/Library/Homebrew/github_packages.rb +++ b/Library/Homebrew/github_packages.rb @@ -4,6 +4,7 @@ require "utils/curl" require "json" require "zlib" +require "extend/hash/keys" # GitHub Packages client. # diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index d747954e2bdae..0a04c785cde9a 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -10,14 +10,10 @@ require "forwardable" require "set" -# Only require "core_ext" here to ensure we're only requiring the minimum of -# what we need. -require "active_support/core_ext/array/access" -require "active_support/core_ext/enumerable" -require "active_support/core_ext/file/atomic" -require "active_support/core_ext/hash/deep_merge" -require "active_support/core_ext/hash/keys" -require "active_support/core_ext/string/exclude" +require "extend/array" +require "extend/blank" +require "extend/enumerable" +require "extend/string" HOMEBREW_API_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_API_DEFAULT_DOMAIN").freeze HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_BOTTLE_DEFAULT_DOMAIN").freeze @@ -70,8 +66,6 @@ %r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})] HOMEBREW_BOTTLES_EXTNAME_REGEX = /\.([a-z0-9_]+)\.bottle\.(?:(\d+)\.)?tar\.gz$/ -require "extend/module" -require "extend/blank" require "env_config" require "macos_version" require "os" @@ -130,7 +124,6 @@ def auto_update_command? end require "context" -require "extend/array" require "git_repository" require "extend/pathname" require "cli/args" diff --git a/Library/Homebrew/livecheck/strategy/gnu.rb b/Library/Homebrew/livecheck/strategy/gnu.rb index 90c39af566d40..090d8d0be1725 100644 --- a/Library/Homebrew/livecheck/strategy/gnu.rb +++ b/Library/Homebrew/livecheck/strategy/gnu.rb @@ -1,4 +1,4 @@ -# typed: true +# typed: strict # frozen_string_literal: true module Homebrew @@ -32,11 +32,11 @@ class Gnu NICE_NAME = "GNU" # The `Regexp` used to determine if the strategy applies to the URL. - URL_MATCH_REGEX = %r{ + URL_MATCH_REGEX = T.let(%r{ ^https?:// (?:(?:[^/]+?\.)*gnu\.org/(?:gnu|software)/(?[^/]+)/ |(?[^/]+)\.gnu\.org/?$) - }ix + }ix, Regexp) # Whether the strategy can be applied to the provided URL. # diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index 187b69236835e..3e5daa64c331e 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -2,6 +2,5 @@ # frozen_string_literal: true require_relative "standalone" -require_relative "extend/module" require "rubocops/all" diff --git a/Library/Homebrew/rubocops/shell_commands.rb b/Library/Homebrew/rubocops/shell_commands.rb index 2a431fd19227d..1672b414e5e03 100644 --- a/Library/Homebrew/rubocops/shell_commands.rb +++ b/Library/Homebrew/rubocops/shell_commands.rb @@ -1,7 +1,7 @@ # typed: true # frozen_string_literal: true -require "active_support/core_ext/array/access" +require "extend/array" require "rubocops/shared/helper_functions" require "shellwords" diff --git a/Library/Homebrew/standalone/sorbet.rb b/Library/Homebrew/standalone/sorbet.rb index 4aaa7e965ac29..d15116a8f1e4b 100644 --- a/Library/Homebrew/standalone/sorbet.rb +++ b/Library/Homebrew/standalone/sorbet.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "sorbet-runtime" +require "extend/module" # Disable runtime checking unless enabled. # In the future we should consider not doing this monkey patch, diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index d38503bde7da5..44225a085bc4e 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -92,7 +92,7 @@ def self.from_file_content(content, path) end if attributes["source"]["spec"].nil? - version = PkgVersion.parse path.to_s.split("/").second_to_last + version = PkgVersion.parse(File.basename(File.dirname(path))) attributes["source"]["spec"] = if version.head? "head" else diff --git a/Library/Homebrew/utils/gems.rb b/Library/Homebrew/utils/gems.rb index c6762c4985651..5479d3f419f7d 100644 --- a/Library/Homebrew/utils/gems.rb +++ b/Library/Homebrew/utils/gems.rb @@ -12,9 +12,9 @@ module Homebrew # After updating this, run `brew vendor-gems --update=--bundler`. HOMEBREW_BUNDLER_VERSION = "2.4.18" - # Bump this whenever a committed vendored gem is later added to gitignore. + # Bump this whenever a committed vendored gem is later added to or exclusion removed from gitignore. # This will trigger it to reinstall properly if `brew install-bundler-gems` needs it. - VENDOR_VERSION = 4 + VENDOR_VERSION = 5 private_constant :VENDOR_VERSION RUBY_BUNDLE_VENDOR_DIRECTORY = (HOMEBREW_LIBRARY_PATH/"vendor/bundle/ruby").freeze diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/MIT-LICENSE b/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/MIT-LICENSE deleted file mode 100644 index 0a0ce3889a0c1..0000000000000 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2005-2022 David Heinemeier Hansson - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/array/access.rb b/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/array/access.rb deleted file mode 100644 index ea01e5891c397..0000000000000 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/array/access.rb +++ /dev/null @@ -1,104 +0,0 @@ -# frozen_string_literal: true - -class Array - # Returns the tail of the array from +position+. - # - # %w( a b c d ).from(0) # => ["a", "b", "c", "d"] - # %w( a b c d ).from(2) # => ["c", "d"] - # %w( a b c d ).from(10) # => [] - # %w().from(0) # => [] - # %w( a b c d ).from(-2) # => ["c", "d"] - # %w( a b c ).from(-10) # => [] - def from(position) - self[position, length] || [] - end - - # Returns the beginning of the array up to +position+. - # - # %w( a b c d ).to(0) # => ["a"] - # %w( a b c d ).to(2) # => ["a", "b", "c"] - # %w( a b c d ).to(10) # => ["a", "b", "c", "d"] - # %w().to(0) # => [] - # %w( a b c d ).to(-2) # => ["a", "b", "c"] - # %w( a b c ).to(-10) # => [] - def to(position) - if position >= 0 - take position + 1 - else - self[0..position] - end - end - - # Returns a new array that includes the passed elements. - # - # [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ] - # [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ] - def including(*elements) - self + elements.flatten(1) - end - - # Returns a copy of the Array excluding the specified elements. - # - # ["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"] - # [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ] - # - # Note: This is an optimization of Enumerable#excluding that uses Array#- - # instead of Array#reject for performance reasons. - def excluding(*elements) - self - elements.flatten(1) - end - - # Alias for #excluding. - def without(*elements) - excluding(*elements) - end - - # Equal to self[1]. - # - # %w( a b c d e ).second # => "b" - def second - self[1] - end - - # Equal to self[2]. - # - # %w( a b c d e ).third # => "c" - def third - self[2] - end - - # Equal to self[3]. - # - # %w( a b c d e ).fourth # => "d" - def fourth - self[3] - end - - # Equal to self[4]. - # - # %w( a b c d e ).fifth # => "e" - def fifth - self[4] - end - - # Equal to self[41]. Also known as accessing "the reddit". - # - # (1..42).to_a.forty_two # => 42 - def forty_two - self[41] - end - - # Equal to self[-3]. - # - # %w( a b c d e ).third_to_last # => "c" - def third_to_last - self[-3] - end - - # Equal to self[-2]. - # - # %w( a b c d e ).second_to_last # => "d" - def second_to_last - self[-2] - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/enumerable.rb b/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/enumerable.rb deleted file mode 100644 index 97c918a71f89e..0000000000000 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/enumerable.rb +++ /dev/null @@ -1,260 +0,0 @@ -# frozen_string_literal: true - -module Enumerable - INDEX_WITH_DEFAULT = Object.new - private_constant :INDEX_WITH_DEFAULT - - # Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements - # when we omit an identity. - - # :stopdoc: - - # We can't use Refinements here because Refinements with Module which will be prepended - # doesn't work well https://bugs.ruby-lang.org/issues/13446 - alias :_original_sum_with_required_identity :sum - private :_original_sum_with_required_identity - - # :startdoc: - - # Calculates a sum from the elements. - # - # payments.sum { |p| p.price * p.tax_rate } - # payments.sum(&:price) - # - # The latter is a shortcut for: - # - # payments.inject(0) { |sum, p| sum + p.price } - # - # It can also calculate the sum without the use of a block. - # - # [5, 15, 10].sum # => 30 - # ['foo', 'bar'].sum # => "foobar" - # [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5] - # - # The default sum of an empty list is zero. You can override this default: - # - # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0) - def sum(identity = nil, &block) - if identity - _original_sum_with_required_identity(identity, &block) - elsif block_given? - map(&block).sum(identity) - else - inject(:+) || 0 - end - end - - # Convert an enumerable to a hash, using the block result as the key and the - # element as the value. - # - # people.index_by(&:login) - # # => { "nextangle" => , "chade-" => , ...} - # - # people.index_by { |person| "#{person.first_name} #{person.last_name}" } - # # => { "Chade- Fowlersburg-e" => , "David Heinemeier Hansson" => , ...} - def index_by - if block_given? - result = {} - each { |elem| result[yield(elem)] = elem } - result - else - to_enum(:index_by) { size if respond_to?(:size) } - end - end - - # Convert an enumerable to a hash, using the element as the key and the block - # result as the value. - # - # post = Post.new(title: "hey there", body: "what's up?") - # - # %i( title body ).index_with { |attr_name| post.public_send(attr_name) } - # # => { title: "hey there", body: "what's up?" } - # - # If an argument is passed instead of a block, it will be used as the value - # for all elements: - # - # %i( created_at updated_at ).index_with(Time.now) - # # => { created_at: 2020-03-09 22:31:47, updated_at: 2020-03-09 22:31:47 } - def index_with(default = INDEX_WITH_DEFAULT) - if block_given? - result = {} - each { |elem| result[elem] = yield(elem) } - result - elsif default != INDEX_WITH_DEFAULT - result = {} - each { |elem| result[elem] = default } - result - else - to_enum(:index_with) { size if respond_to?(:size) } - end - end - - # Returns +true+ if the enumerable has more than 1 element. Functionally - # equivalent to enum.to_a.size > 1. Can be called with a block too, - # much like any?, so people.many? { |p| p.age > 26 } returns +true+ - # if more than one person is over 26. - def many? - cnt = 0 - if block_given? - any? do |element| - cnt += 1 if yield element - cnt > 1 - end - else - any? { (cnt += 1) > 1 } - end - end - - # Returns a new array that includes the passed elements. - # - # [ 1, 2, 3 ].including(4, 5) - # # => [ 1, 2, 3, 4, 5 ] - # - # ["David", "Rafael"].including %w[ Aaron Todd ] - # # => ["David", "Rafael", "Aaron", "Todd"] - def including(*elements) - to_a.including(*elements) - end - - # The negative of the Enumerable#include?. Returns +true+ if the - # collection does not include the object. - def exclude?(object) - !include?(object) - end - - # Returns a copy of the enumerable excluding the specified elements. - # - # ["David", "Rafael", "Aaron", "Todd"].excluding "Aaron", "Todd" - # # => ["David", "Rafael"] - # - # ["David", "Rafael", "Aaron", "Todd"].excluding %w[ Aaron Todd ] - # # => ["David", "Rafael"] - # - # {foo: 1, bar: 2, baz: 3}.excluding :bar - # # => {foo: 1, baz: 3} - def excluding(*elements) - elements.flatten!(1) - reject { |element| elements.include?(element) } - end - - # Alias for #excluding. - def without(*elements) - excluding(*elements) - end - - # Extract the given key from each element in the enumerable. - # - # [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) - # # => ["David", "Rafael", "Aaron"] - # - # [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name) - # # => [[1, "David"], [2, "Rafael"]] - def pluck(*keys) - if keys.many? - map { |element| keys.map { |key| element[key] } } - else - key = keys.first - map { |element| element[key] } - end - end - - # Extract the given key from the first element in the enumerable. - # - # [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pick(:name) - # # => "David" - # - # [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pick(:id, :name) - # # => [1, "David"] - def pick(*keys) - return if none? - - if keys.many? - keys.map { |key| first[key] } - else - first[keys.first] - end - end - - # Returns a new +Array+ without the blank items. - # Uses Object#blank? for determining if an item is blank. - # - # [1, "", nil, 2, " ", [], {}, false, true].compact_blank - # # => [1, 2, true] - # - # Set.new([nil, "", 1, 2]) - # # => [2, 1] (or [1, 2]) - # - # When called on a +Hash+, returns a new +Hash+ without the blank values. - # - # { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank - # #=> { b: 1, f: true } - def compact_blank - reject(&:blank?) - end -end - -class Hash - # Hash#reject has its own definition, so this needs one too. - def compact_blank #:nodoc: - reject { |_k, v| v.blank? } - end - - # Removes all blank values from the +Hash+ in place and returns self. - # Uses Object#blank? for determining if a value is blank. - # - # h = { a: "", b: 1, c: nil, d: [], e: false, f: true } - # h.compact_blank! - # # => { b: 1, f: true } - def compact_blank! - # use delete_if rather than reject! because it always returns self even if nothing changed - delete_if { |_k, v| v.blank? } - end -end - -class Range #:nodoc: - # Optimize range sum to use arithmetic progression if a block is not given and - # we have a range of numeric values. - def sum(identity = nil) - if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer)) - super - else - actual_last = exclude_end? ? (last - 1) : last - if actual_last >= first - sum = identity || 0 - sum + (actual_last - first + 1) * (actual_last + first) / 2 - else - identity || 0 - end - end - end -end - -# Using Refinements here in order not to expose our internal method -using Module.new { - refine Array do - alias :orig_sum :sum - end -} - -class Array #:nodoc: - # Array#sum was added in Ruby 2.4 but it only works with Numeric elements. - def sum(init = nil, &block) - if init.is_a?(Numeric) || first.is_a?(Numeric) - init ||= 0 - orig_sum(init, &block) - else - super - end - end - - # Removes all blank elements from the +Array+ in place and returns self. - # Uses Object#blank? for determining if an item is blank. - # - # a = [1, "", nil, 2, " ", [], {}, false, true] - # a.compact_blank! - # # => [1, 2, true] - def compact_blank! - # use delete_if rather than reject! because it always returns self even if nothing changed - delete_if(&:blank?) - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/deep_transform_values.rb b/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/deep_transform_values.rb deleted file mode 100644 index 8ad85c0a6d8eb..0000000000000 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/deep_transform_values.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -class Hash - # Returns a new hash with all values converted by the block operation. - # This includes the values from the root hash and from all - # nested hashes and arrays. - # - # hash = { person: { name: 'Rob', age: '28' } } - # - # hash.deep_transform_values{ |value| value.to_s.upcase } - # # => {person: {name: "ROB", age: "28"}} - def deep_transform_values(&block) - _deep_transform_values_in_object(self, &block) - end - - # Destructively converts all values by using the block operation. - # This includes the values from the root hash and from all - # nested hashes and arrays. - def deep_transform_values!(&block) - _deep_transform_values_in_object!(self, &block) - end - - private - # Support methods for deep transforming nested hashes and arrays. - def _deep_transform_values_in_object(object, &block) - case object - when Hash - object.transform_values { |value| _deep_transform_values_in_object(value, &block) } - when Array - object.map { |e| _deep_transform_values_in_object(e, &block) } - else - yield(object) - end - end - - def _deep_transform_values_in_object!(object, &block) - case object - when Hash - object.transform_values! { |value| _deep_transform_values_in_object!(value, &block) } - when Array - object.map! { |e| _deep_transform_values_in_object!(e, &block) } - else - yield(object) - end - end -end diff --git a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/keys.rb b/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/keys.rb deleted file mode 100644 index f2db61f386e63..0000000000000 --- a/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/keys.rb +++ /dev/null @@ -1,143 +0,0 @@ -# frozen_string_literal: true - -class Hash - # Returns a new hash with all keys converted to strings. - # - # hash = { name: 'Rob', age: '28' } - # - # hash.stringify_keys - # # => {"name"=>"Rob", "age"=>"28"} - def stringify_keys - transform_keys(&:to_s) - end - - # Destructively converts all keys to strings. Same as - # +stringify_keys+, but modifies +self+. - def stringify_keys! - transform_keys!(&:to_s) - end - - # Returns a new hash with all keys converted to symbols, as long as - # they respond to +to_sym+. - # - # hash = { 'name' => 'Rob', 'age' => '28' } - # - # hash.symbolize_keys - # # => {:name=>"Rob", :age=>"28"} - def symbolize_keys - transform_keys { |key| key.to_sym rescue key } - end - alias_method :to_options, :symbolize_keys - - # Destructively converts all keys to symbols, as long as they respond - # to +to_sym+. Same as +symbolize_keys+, but modifies +self+. - def symbolize_keys! - transform_keys! { |key| key.to_sym rescue key } - end - alias_method :to_options!, :symbolize_keys! - - # Validates all keys in a hash match *valid_keys, raising - # +ArgumentError+ on a mismatch. - # - # Note that keys are treated differently than HashWithIndifferentAccess, - # meaning that string and symbol keys will not match. - # - # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age" - # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'" - # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing - def assert_valid_keys(*valid_keys) - valid_keys.flatten! - each_key do |k| - unless valid_keys.include?(k) - raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}") - end - end - end - - # Returns a new hash with all keys converted by the block operation. - # This includes the keys from the root hash and from all - # nested hashes and arrays. - # - # hash = { person: { name: 'Rob', age: '28' } } - # - # hash.deep_transform_keys{ |key| key.to_s.upcase } - # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}} - def deep_transform_keys(&block) - _deep_transform_keys_in_object(self, &block) - end - - # Destructively converts all keys by using the block operation. - # This includes the keys from the root hash and from all - # nested hashes and arrays. - def deep_transform_keys!(&block) - _deep_transform_keys_in_object!(self, &block) - end - - # Returns a new hash with all keys converted to strings. - # This includes the keys from the root hash and from all - # nested hashes and arrays. - # - # hash = { person: { name: 'Rob', age: '28' } } - # - # hash.deep_stringify_keys - # # => {"person"=>{"name"=>"Rob", "age"=>"28"}} - def deep_stringify_keys - deep_transform_keys(&:to_s) - end - - # Destructively converts all keys to strings. - # This includes the keys from the root hash and from all - # nested hashes and arrays. - def deep_stringify_keys! - deep_transform_keys!(&:to_s) - end - - # Returns a new hash with all keys converted to symbols, as long as - # they respond to +to_sym+. This includes the keys from the root hash - # and from all nested hashes and arrays. - # - # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } - # - # hash.deep_symbolize_keys - # # => {:person=>{:name=>"Rob", :age=>"28"}} - def deep_symbolize_keys - deep_transform_keys { |key| key.to_sym rescue key } - end - - # Destructively converts all keys to symbols, as long as they respond - # to +to_sym+. This includes the keys from the root hash and from all - # nested hashes and arrays. - def deep_symbolize_keys! - deep_transform_keys! { |key| key.to_sym rescue key } - end - - private - # Support methods for deep transforming nested hashes and arrays. - def _deep_transform_keys_in_object(object, &block) - case object - when Hash - object.each_with_object({}) do |(key, value), result| - result[yield(key)] = _deep_transform_keys_in_object(value, &block) - end - when Array - object.map { |e| _deep_transform_keys_in_object(e, &block) } - else - object - end - end - - def _deep_transform_keys_in_object!(object, &block) - case object - when Hash - object.keys.each do |key| - value = object.delete(key) - object[yield(key)] = _deep_transform_keys_in_object!(value, &block) - end - object - when Array - object.map! { |e| _deep_transform_keys_in_object!(e, &block) } - else - object - end - end -end