From 08e12b2383c887cae0689b859b0864e7dd196f38 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Wed, 10 Jan 2024 12:07:04 -0800 Subject: [PATCH 01/24] Remove ActiveSupport Array access core extensions --- .gitignore | 1 - Library/Homebrew/cli/parser.rb | 6 +- Library/Homebrew/download_strategy.rb | 2 +- Library/Homebrew/extend/array.rb | 14 ++- Library/Homebrew/extend/array.rbi | 9 ++ Library/Homebrew/global.rb | 3 +- Library/Homebrew/tab.rb | 2 +- Library/Homebrew/utils/gems.rb | 2 +- .../active_support/core_ext/array/access.rb | 104 ------------------ 9 files changed, 29 insertions(+), 114 deletions(-) create mode 100644 Library/Homebrew/extend/array.rbi delete mode 100644 Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/array/access.rb diff --git a/.gitignore b/.gitignore index 459a668d06ee0..7e87d158507c4 100644 --- a/.gitignore +++ b/.gitignore @@ -63,7 +63,6 @@ !**/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 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/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 4f9becfad999a..17ce9fac20068 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 { _1.fetch(1) } end else components[:path] = [url] diff --git a/Library/Homebrew/extend/array.rb b/Library/Homebrew/extend/array.rb index 2755ee92bf5a6..468149e00c920 100644 --- a/Library/Homebrew/extend/array.rb +++ b/Library/Homebrew/extend/array.rb @@ -1,7 +1,18 @@ -# 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] + # Converts the array to a comma-separated sentence where the last element is # joined by the connector word. # @@ -48,6 +59,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..5255357eadbda --- /dev/null +++ b/Library/Homebrew/extend/array.rbi @@ -0,0 +1,9 @@ +# typed: strict + +class Array + sig { returns(T.nilable(Elem)) } + def second; end + + sig { returns(T.nilable(Elem)) } + def third; end +end diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index d747954e2bdae..fa07be12e70f3 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -12,7 +12,6 @@ # 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" @@ -71,6 +70,7 @@ HOMEBREW_BOTTLES_EXTNAME_REGEX = /\.([a-z0-9_]+)\.bottle\.(?:(\d+)\.)?tar\.gz$/ require "extend/module" +require "extend/array" require "extend/blank" require "env_config" require "macos_version" @@ -130,7 +130,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/tab.rb b/Library/Homebrew/tab.rb index d38503bde7da5..25033917e5bdf 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 path.to_s.split("/")[-2] attributes["source"]["spec"] = if version.head? "head" else diff --git a/Library/Homebrew/utils/gems.rb b/Library/Homebrew/utils/gems.rb index c6762c4985651..54c9786e04748 100644 --- a/Library/Homebrew/utils/gems.rb +++ b/Library/Homebrew/utils/gems.rb @@ -14,7 +14,7 @@ module Homebrew # Bump this whenever a committed vendored gem is later added to 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/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 From 5546f778e564c84a3230208dcd5ab75a0cbc1be5 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Wed, 10 Jan 2024 12:57:40 -0800 Subject: [PATCH 02/24] Extend Module when requiring sorbet --- Library/Homebrew/extend/array.rb | 1 - Library/Homebrew/global.rb | 1 - Library/Homebrew/rubocops.rb | 1 - Library/Homebrew/standalone/sorbet.rb | 1 + 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Library/Homebrew/extend/array.rb b/Library/Homebrew/extend/array.rb index 468149e00c920..7e4b430db92d7 100644 --- a/Library/Homebrew/extend/array.rb +++ b/Library/Homebrew/extend/array.rb @@ -2,7 +2,6 @@ # frozen_string_literal: true class Array - # Equal to self[1]. # # %w( a b c d e ).second # => "b" diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index fa07be12e70f3..960817893fa12 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -69,7 +69,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/array" require "extend/blank" require "env_config" 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/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, From f8de5dfd6039184aa57e9853102e381f6c98d3e2 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Wed, 10 Jan 2024 12:11:55 -0800 Subject: [PATCH 03/24] Copy enumerable file --- Library/Homebrew/extend/enumerable.rb | 260 ++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 Library/Homebrew/extend/enumerable.rb diff --git a/Library/Homebrew/extend/enumerable.rb b/Library/Homebrew/extend/enumerable.rb new file mode 100644 index 0000000000000..97c918a71f89e --- /dev/null +++ b/Library/Homebrew/extend/enumerable.rb @@ -0,0 +1,260 @@ +# 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 From b60d951d48fc24a88e3b5fcf4430a13662967ea4 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Wed, 10 Jan 2024 12:15:49 -0800 Subject: [PATCH 04/24] Update from upstream, remove unused methods --- Library/Homebrew/extend/enumerable.rb | 223 +------------------------- 1 file changed, 7 insertions(+), 216 deletions(-) diff --git a/Library/Homebrew/extend/enumerable.rb b/Library/Homebrew/extend/enumerable.rb index 97c918a71f89e..d5a0ab9012b08 100644 --- a/Library/Homebrew/extend/enumerable.rb +++ b/Library/Homebrew/extend/enumerable.rb @@ -1,49 +1,6 @@ # 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. # @@ -62,132 +19,25 @@ def index_by 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] + # [1, "", nil, 2, " ", [], {}, false, true].compact_blank + # # => [1, 2, true] # - # Set.new([nil, "", 1, 2]) - # # => [2, 1] (or [1, 2]) + # 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 } + # { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank + # # => { b: 1, f: true } def compact_blank reject(&:blank?) end @@ -195,66 +45,7 @@ def compact_blank class Hash # Hash#reject has its own definition, so this needs one too. - def compact_blank #:nodoc: + 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 From 2e21efff46a7181feceaf07d83c9cbeaa3cc6c71 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 11 Jan 2024 13:42:38 -0800 Subject: [PATCH 05/24] Add ActiveSupport String#exclude? to extend/ --- .gitignore | 1 - Library/Homebrew/download_strategy.rb | 2 +- .../core_ext/string/exclude.rb => extend/string.rb} | 6 +++--- Library/Homebrew/global.rb | 4 +--- Library/Homebrew/livecheck/strategy/gnu.rb | 6 +++--- 5 files changed, 8 insertions(+), 11 deletions(-) rename Library/Homebrew/{vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/string/exclude.rb => extend/string.rb} (71%) diff --git a/.gitignore b/.gitignore index 7e87d158507c4..b89793014d141 100644 --- a/.gitignore +++ b/.gitignore @@ -70,7 +70,6 @@ !**/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-*/.* diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 17ce9fac20068..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 { _1.fetch(1) } + components[:query] = URI.decode_www_form(uri_query).map { _2 } end else components[:path] = [url] 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/global.rb b/Library/Homebrew/global.rb index 960817893fa12..830c263174395 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -10,13 +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/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" HOMEBREW_API_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_API_DEFAULT_DOMAIN").freeze HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_BOTTLE_DEFAULT_DOMAIN").freeze @@ -71,6 +68,7 @@ require "extend/array" require "extend/blank" +require "extend/string" require "env_config" require "macos_version" require "os" diff --git a/Library/Homebrew/livecheck/strategy/gnu.rb b/Library/Homebrew/livecheck/strategy/gnu.rb index 90c39af566d40..40b485274c819 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.freeze, Regexp) # Whether the strategy can be applied to the provided URL. # From 7ae087b24caff4cc56489b558820b0afba819ac9 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger <697964+dduugg@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:58:59 -0800 Subject: [PATCH 06/24] Update Library/Homebrew/utils/gems.rb Co-authored-by: Mike McQuaid --- Library/Homebrew/utils/gems.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/utils/gems.rb b/Library/Homebrew/utils/gems.rb index 54c9786e04748..5479d3f419f7d 100644 --- a/Library/Homebrew/utils/gems.rb +++ b/Library/Homebrew/utils/gems.rb @@ -12,7 +12,7 @@ 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 = 5 private_constant :VENDOR_VERSION From c02520f604f49e8ede0f4bd9eeb1505cbe1bf2a9 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 11 Jan 2024 14:19:44 -0800 Subject: [PATCH 07/24] Fix style/type violations --- .gitignore | 1 - Library/Homebrew/extend/enumerable.rb | 21 +- Library/Homebrew/extend/enumerable.rbi | 17 ++ Library/Homebrew/global.rb | 2 +- .../lib/active_support/core_ext/enumerable.rb | 260 ------------------ 5 files changed, 27 insertions(+), 274 deletions(-) create mode 100644 Library/Homebrew/extend/enumerable.rbi delete mode 100644 Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/enumerable.rb diff --git a/.gitignore b/.gitignore index b89793014d141..99eef04e54a82 100644 --- a/.gitignore +++ b/.gitignore @@ -63,7 +63,6 @@ !**/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/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 diff --git a/Library/Homebrew/extend/enumerable.rb b/Library/Homebrew/extend/enumerable.rb index d5a0ab9012b08..4c3eb14ecbc39 100644 --- a/Library/Homebrew/extend/enumerable.rb +++ b/Library/Homebrew/extend/enumerable.rb @@ -1,3 +1,4 @@ +# typed: strict # frozen_string_literal: true module Enumerable @@ -9,21 +10,20 @@ module Enumerable # # people.index_by { |person| "#{person.first_name} #{person.last_name}" } # # => { "Chade- Fowlersburg-e" => , "David Heinemeier Hansson" => , ...} - def index_by - if block_given? + def index_by(&block) + if block result = {} each { |elem| result[yield(elem)] = elem } result else - to_enum(:index_by) { size if respond_to?(:size) } + T.unsafe(self).to_enum(:index_by) { T.unsafe(self).size if respond_to?(:size) } end end # The negative of the Enumerable#include?. Returns +true+ if the # collection does not include the object. - def exclude?(object) - !include?(object) - end + 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. @@ -38,14 +38,11 @@ def exclude?(object) # # { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank # # => { b: 1, f: true } - def compact_blank - reject(&:blank?) - end + 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 # :nodoc: - reject { |_k, v| v.blank? } - end + def compact_blank = reject { T.unsafe(_2).blank? } end diff --git a/Library/Homebrew/extend/enumerable.rbi b/Library/Homebrew/extend/enumerable.rbi new file mode 100644 index 0000000000000..a95b0bf4bb4fa --- /dev/null +++ b/Library/Homebrew/extend/enumerable.rbi @@ -0,0 +1,17 @@ +# typed: strict + +module Enumerable + requires_ancestor { Object } + + sig { + type_parameters(:key).params( + block: T.nilable(T.proc.params(o: Enumerable::Elem).returns(T.type_parameter(:key))), + ).returns(T::Hash[T.type_parameter(:key), Enumerable::Elem]) + } + def index_by(&block); end +end + +class Hash + sig { returns(T::Hash[Hash::K, Hash::V]) } + def compact_blank; end +end diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index 830c263174395..90e6e2e22aabb 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -10,7 +10,6 @@ require "forwardable" require "set" -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" @@ -68,6 +67,7 @@ require "extend/array" require "extend/blank" +require "extend/enumerable" require "extend/string" require "env_config" require "macos_version" 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 From 79e2379d98ec7fddbbf029e76eac56368a1fab8d Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 11 Jan 2024 14:37:09 -0800 Subject: [PATCH 08/24] Add Array#fourth to resolve cask errors --- Library/Homebrew/extend/array.rb | 5 +++++ Library/Homebrew/extend/array.rbi | 3 +++ 2 files changed, 8 insertions(+) diff --git a/Library/Homebrew/extend/array.rb b/Library/Homebrew/extend/array.rb index 7e4b430db92d7..0163a2bb7f903 100644 --- a/Library/Homebrew/extend/array.rb +++ b/Library/Homebrew/extend/array.rb @@ -12,6 +12,11 @@ def second = self[1] # %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] + # Converts the array to a comma-separated sentence where the last element is # joined by the connector word. # diff --git a/Library/Homebrew/extend/array.rbi b/Library/Homebrew/extend/array.rbi index 5255357eadbda..0c1bb89dd7e18 100644 --- a/Library/Homebrew/extend/array.rbi +++ b/Library/Homebrew/extend/array.rbi @@ -6,4 +6,7 @@ class Array sig { returns(T.nilable(Elem)) } def third; end + + sig { returns(T.nilable(Elem)) } + def fourth; end end From 8e9d294df29b13050aa9767b999545725579abd0 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 11 Jan 2024 15:13:12 -0800 Subject: [PATCH 09/24] Add File.atomic_write to extend/ --- .../core_ext => extend}/file/atomic.rb | 23 ++++++++++++++----- Library/Homebrew/extend/pathname.rb | 1 + Library/Homebrew/global.rb | 1 - Library/Homebrew/rubocops/shell_commands.rb | 2 +- 4 files changed, 19 insertions(+), 8 deletions(-) rename Library/Homebrew/{vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext => extend}/file/atomic.rb (77%) 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 77% 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..eecd212794313 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 { + params( + file_name: T.any(Pathname, String), + temp_dir: String, + _block: T.proc.params(arg0: Tempfile).void, + ).void + } + 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/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/global.rb b/Library/Homebrew/global.rb index 90e6e2e22aabb..6bc52c943385a 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -10,7 +10,6 @@ require "forwardable" require "set" -require "active_support/core_ext/file/atomic" require "active_support/core_ext/hash/deep_merge" require "active_support/core_ext/hash/keys" 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" From 0cdd4eee3b1314a9b92b6a19ed192cec2712176c Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 11 Jan 2024 19:22:16 -0800 Subject: [PATCH 10/24] Add Hash#deep_merge to extend/ --- .gitignore | 2 -- Library/Homebrew/dev-cmd/bottle.rb | 1 + Library/Homebrew/dev-cmd/pr-upload.rb | 1 + Library/Homebrew/extend/array.rb | 5 +++++ Library/Homebrew/extend/array.rbi | 3 +++ .../core_ext => extend}/hash/deep_merge.rb | 9 +++++---- Library/Homebrew/extend/hash/deep_merge.rbi | 20 +++++++++++++++++++ Library/Homebrew/global.rb | 1 - Library/Homebrew/test/rubocop_spec.rb | 2 +- 9 files changed, 36 insertions(+), 8 deletions(-) rename Library/Homebrew/{vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext => extend}/hash/deep_merge.rb (81%) create mode 100644 Library/Homebrew/extend/hash/deep_merge.rbi diff --git a/.gitignore b/.gitignore index 99eef04e54a82..f4692e2200dff 100644 --- a/.gitignore +++ b/.gitignore @@ -63,8 +63,6 @@ !**/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/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 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/extend/array.rb b/Library/Homebrew/extend/array.rb index 0163a2bb7f903..152033304bae3 100644 --- a/Library/Homebrew/extend/array.rb +++ b/Library/Homebrew/extend/array.rb @@ -17,6 +17,11 @@ def third = self[2] # %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. # diff --git a/Library/Homebrew/extend/array.rbi b/Library/Homebrew/extend/array.rbi index 0c1bb89dd7e18..3d9e293bd459b 100644 --- a/Library/Homebrew/extend/array.rbi +++ b/Library/Homebrew/extend/array.rbi @@ -9,4 +9,7 @@ class Array sig { returns(T.nilable(Elem)) } def fourth; end + + sig { returns(T.nilable(Elem)) } + def fifth; 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_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/global.rb b/Library/Homebrew/global.rb index 6bc52c943385a..20e0482bb29f0 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -10,7 +10,6 @@ require "forwardable" require "set" -require "active_support/core_ext/hash/deep_merge" require "active_support/core_ext/hash/keys" HOMEBREW_API_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_API_DEFAULT_DOMAIN").freeze diff --git a/Library/Homebrew/test/rubocop_spec.rb b/Library/Homebrew/test/rubocop_spec.rb index ce163c2d98383..dbf055d8fdda2 100644 --- a/Library/Homebrew/test/rubocop_spec.rb +++ b/Library/Homebrew/test/rubocop_spec.rb @@ -17,7 +17,7 @@ end it "loads all Formula cops without errors" do - stdout, stderr, status = Open3.capture3(RUBY_PATH, "-W0", "-S", "rubocop", TEST_FIXTURE_DIR/"testball.rb") + stdout, stderr, status = Open3.capture3(RUBY_PATH, "-W0", "-S", "rubocop", "-d", TEST_FIXTURE_DIR/"testball.rb") expect(stderr).to be_empty expect(stdout).to include("no offenses detected") expect(status).to be_a_success From a87cdf0d2158132c3c2a397bced591c59748cb34 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 11 Jan 2024 20:03:06 -0800 Subject: [PATCH 11/24] Add Hash#deep_transform_values to extend/ --- .gitignore | 1 - .../hash/deep_transform_values.rb | 1 + .../extend/hash/deep_transform_values.rbi | 22 +++++++++++++++++++ Library/Homebrew/formulary.rb | 2 +- Library/Homebrew/tab.rb | 2 +- 5 files changed, 25 insertions(+), 3 deletions(-) rename Library/Homebrew/{vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext => extend}/hash/deep_transform_values.rb (98%) create mode 100644 Library/Homebrew/extend/hash/deep_transform_values.rbi diff --git a/.gitignore b/.gitignore index f4692e2200dff..12fd4fb18f43b 100644 --- a/.gitignore +++ b/.gitignore @@ -63,7 +63,6 @@ !**/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/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 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/extend/hash/deep_transform_values.rb similarity index 98% rename from Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/deep_transform_values.rb rename to Library/Homebrew/extend/hash/deep_transform_values.rb index 8ad85c0a6d8eb..c3dd789d25c39 100644 --- 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/extend/hash/deep_transform_values.rb @@ -1,3 +1,4 @@ +# typed: strict # frozen_string_literal: true class Hash 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..072474393b828 --- /dev/null +++ b/Library/Homebrew/extend/hash/deep_transform_values.rbi @@ -0,0 +1,22 @@ +# 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 + + sig { params(object: T.anything, block: T.untyped).returns(T.untyped) } + def _deep_transform_values_in_object(object, &block); end + + sig { params(object: T.anything, block: T.untyped).returns(T.untyped) } + def _deep_transform_values_in_object!(object, &block); end +end diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index f473dcb08a5e9..66903113898bc 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -9,7 +9,7 @@ require "utils/curl" require "deprecate_disable" -require "active_support/core_ext/hash/deep_transform_values" +require "extend/hash/deep_transform_values" # The {Formulary} is responsible for creating instances of {Formula}. # It is not meant to be used directly from formulae. diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 25033917e5bdf..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("/")[-2] + version = PkgVersion.parse(File.basename(File.dirname(path))) attributes["source"]["spec"] = if version.head? "head" else From 14f8a086d831ae710a16579abf73802782eeb1f5 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 11 Jan 2024 20:04:14 -0800 Subject: [PATCH 12/24] brew vendor-gems: commit updates. --- Library/Homebrew/extend/hash/deep_merge.rb | 4 +- .../extend/hash/deep_transform_values.rb | 47 +++++++++---------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/Library/Homebrew/extend/hash/deep_merge.rb b/Library/Homebrew/extend/hash/deep_merge.rb index 01ecbe926044c..9804d6d1e3579 100644 --- a/Library/Homebrew/extend/hash/deep_merge.rb +++ b/Library/Homebrew/extend/hash/deep_merge.rb @@ -16,9 +16,7 @@ class Hash # h2 = { b: 250, c: { c1: 200 } } # h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val } # # => { a: 100, b: 450, c: { c1: 300 } } - def deep_merge(other_hash, &block) - dup.deep_merge!(other_hash, &block) - end + def deep_merge(other_hash, &block) = dup.deep_merge!(other_hash, &block) # Same as +deep_merge+, but modifies +self+. def deep_merge!(other_hash, &block) diff --git a/Library/Homebrew/extend/hash/deep_transform_values.rb b/Library/Homebrew/extend/hash/deep_transform_values.rb index c3dd789d25c39..24c91f15aadac 100644 --- a/Library/Homebrew/extend/hash/deep_transform_values.rb +++ b/Library/Homebrew/extend/hash/deep_transform_values.rb @@ -10,38 +10,35 @@ class Hash # # 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 + 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) - end + def deep_transform_values!(&block) = _deep_transform_values_in_object!(self, &block) 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 + + # 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 + 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 From f6c7eb7124166f8e142deac40e317353563f22ef Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 09:38:49 -0800 Subject: [PATCH 13/24] Add hash/keys to extend/ --- .gitignore | 1 - .../cask/artifact/abstract_uninstall.rb | 1 + Library/Homebrew/cask/artifact/installer.rb | 1 + Library/Homebrew/cask/artifact/pkg.rb | 1 + Library/Homebrew/cask/artifact/relocated.rb | 1 + Library/Homebrew/cask/cask_loader.rb | 1 + Library/Homebrew/cask/config.rb | 1 + Library/Homebrew/cask/dsl/conflicts_with.rb | 1 + .../extend/hash/deep_transform_values.rb | 2 + .../extend/hash/deep_transform_values.rbi | 7 +- Library/Homebrew/extend/hash/keys.rb | 116 ++++++++++++++ Library/Homebrew/extend/hash/keys.rbi | 30 ++++ Library/Homebrew/formulary.rb | 2 +- Library/Homebrew/github_packages.rb | 1 + Library/Homebrew/global.rb | 2 - .../lib/active_support/core_ext/hash/keys.rb | 143 ------------------ 16 files changed, 158 insertions(+), 153 deletions(-) create mode 100644 Library/Homebrew/extend/hash/keys.rb create mode 100644 Library/Homebrew/extend/hash/keys.rbi delete mode 100644 Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext/hash/keys.rb diff --git a/.gitignore b/.gitignore index 12fd4fb18f43b..a88cbb4ca780b 100644 --- a/.gitignore +++ b/.gitignore @@ -63,7 +63,6 @@ !**/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/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 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/extend/hash/deep_transform_values.rb b/Library/Homebrew/extend/hash/deep_transform_values.rb index 24c91f15aadac..608e3c73a87f4 100644 --- a/Library/Homebrew/extend/hash/deep_transform_values.rb +++ b/Library/Homebrew/extend/hash/deep_transform_values.rb @@ -20,6 +20,7 @@ def deep_transform_values!(&block) = _deep_transform_values_in_object!(self, &bl 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 @@ -31,6 +32,7 @@ def _deep_transform_values_in_object(object, &block) 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 diff --git a/Library/Homebrew/extend/hash/deep_transform_values.rbi b/Library/Homebrew/extend/hash/deep_transform_values.rbi index 072474393b828..29c8d273e2935 100644 --- a/Library/Homebrew/extend/hash/deep_transform_values.rbi +++ b/Library/Homebrew/extend/hash/deep_transform_values.rbi @@ -7,16 +7,11 @@ class Hash ).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 - - sig { params(object: T.anything, block: T.untyped).returns(T.untyped) } - def _deep_transform_values_in_object(object, &block); end - - sig { params(object: T.anything, block: T.untyped).returns(T.untyped) } - def _deep_transform_values_in_object!(object, &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..6ee0e945fdd2d --- /dev/null +++ b/Library/Homebrew/extend/hash/keys.rb @@ -0,0 +1,116 @@ +# 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 + object.each_key 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 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/formulary.rb b/Library/Homebrew/formulary.rb index 66903113898bc..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 "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 20e0482bb29f0..863f322be0b42 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -10,8 +10,6 @@ require "forwardable" require "set" -require "active_support/core_ext/hash/keys" - HOMEBREW_API_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_API_DEFAULT_DOMAIN").freeze HOMEBREW_BOTTLE_DEFAULT_DOMAIN = ENV.fetch("HOMEBREW_BOTTLE_DEFAULT_DOMAIN").freeze HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ENV.fetch("HOMEBREW_BREW_DEFAULT_GIT_REMOTE").freeze 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 From 8efe73b32c39cbc6eadfc3ba78ea1bbb512f6f34 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 09:53:53 -0800 Subject: [PATCH 14/24] Add Object#deep_dup to extend/ --- .gitignore | 11 +----- .../cask/artifact/abstract_artifact.rb | 2 +- .../core_ext => extend}/object/deep_dup.rb | 38 ++++++++++++++----- .../core_ext => extend}/object/duplicable.rb | 24 ++++++++++-- .../gems/activesupport-6.1.7.6/MIT-LICENSE | 20 ---------- 5 files changed, 51 insertions(+), 44 deletions(-) rename Library/Homebrew/{vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext => extend}/object/deep_dup.rb (56%) rename Library/Homebrew/{vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/lib/active_support/core_ext => extend}/object/duplicable.rb (63%) delete mode 100644 Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/activesupport-6.1.7.6/MIT-LICENSE diff --git a/.gitignore b/.gitignore index a88cbb4ca780b..2172e87ce92e9 100644 --- a/.gitignore +++ b/.gitignore @@ -57,14 +57,7 @@ !**/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/object/deep_dup.rb -!**/vendor/bundle/ruby/*/gems/activesupport-*/lib/active_support/core_ext/object/duplicable.rb +!**/vendor/bundle/ruby/*/gems/sorbet-runtime-*/ # Ignore partially included gems where we don't need all files **/vendor/gems/mechanize-*/.* @@ -82,6 +75,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-*/ @@ -144,7 +138,6 @@ **/vendor/bundle/ruby/*/gems/simplecov_json_formatter-*/ **/vendor/bundle/ruby/*/gems/simpleidn-*/ **/vendor/bundle/ruby/*/gems/sorbet-*/ -!**/vendor/bundle/ruby/*/gems/sorbet-runtime-*/ **/vendor/bundle/ruby/*/gems/spoom-*/ **/vendor/bundle/ruby/*/gems/stackprof-*/ **/vendor/bundle/ruby/*/gems/strscan-*/ 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/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 56% 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..b64eccc5f7026 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,9 +13,8 @@ class Object # # object.instance_variable_defined?(:@a) # => false # dup.instance_variable_defined?(:@a) # => true - def deep_dup - duplicable? ? dup : self - end + sig { returns(T.self_type) } + def deep_dup = duplicable? ? dup : self end class Array @@ -26,9 +26,8 @@ class Array # # array[1][2] # => nil # dup[1][2] # => 4 - def deep_dup - map(&:deep_dup) - end + sig { returns(T.self_type) } + def deep_dup = T.unsafe(self).map(&:deep_dup) end class Hash @@ -40,16 +39,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 63% 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..0ab1d52e83790 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,6 +24,7 @@ class Object # # False for method objects; # true otherwise. + sig { returns(T::Boolean) } def duplicable? true end @@ -31,8 +33,9 @@ def duplicable? class Method # Methods are not duplicable: # - # method(:puts).duplicable? # => false - # method(:puts).dup # => TypeError: allocator undefined for Method + # method(:puts).duplicable? # => false + # method(:puts).dup # => TypeError: allocator undefined for Method + sig { returns(FalseClass) } def duplicable? false end @@ -41,8 +44,21 @@ def duplicable? class UnboundMethod # Unbound methods are not duplicable: # - # method(:puts).unbind.duplicable? # => false - # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod + # method(:puts).unbind.duplicable? # => false + # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod + sig { returns(FalseClass) } + def duplicable? + false + end +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/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. From fa7b8ff0dfd0d86978c0e774e253be3a4de3acfd Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 09:55:02 -0800 Subject: [PATCH 15/24] brew vendor-gems: commit updates. --- Library/Homebrew/vendor/bundle/bundler/setup.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index cf401a00080be..a69c36a13518d 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -39,8 +39,8 @@ def self.extension_api_version $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bindata-2.4.15/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/msgpack-1.7.2") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/msgpack-1.7.2/lib") -$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/bootsnap-1.17.1") -$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bootsnap-1.17.1/lib") +$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/bootsnap-1.17.0") +$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bootsnap-1.17.0/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/byebug-11.1.3") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/byebug-11.1.3/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/coderay-1.1.3/lib") From 179090415255acf27a7b5da889c9742a36bd7fb8 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 10:55:27 -0800 Subject: [PATCH 16/24] Resolve 'Error: can't add a new key into hash during iteration' --- Library/Homebrew/extend/hash/keys.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/extend/hash/keys.rb b/Library/Homebrew/extend/hash/keys.rb index 6ee0e945fdd2d..caa742d3b2e03 100644 --- a/Library/Homebrew/extend/hash/keys.rb +++ b/Library/Homebrew/extend/hash/keys.rb @@ -102,7 +102,8 @@ def _deep_transform_keys_in_object(object, &block) def _deep_transform_keys_in_object!(object, &block) case object when Hash - object.each_key do |key| + # 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 From 4c25250e7278b4f926bab3341c84d8763dbeaf10 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 11:04:33 -0800 Subject: [PATCH 17/24] Improve atomic_write sig --- Library/Homebrew/extend/file/atomic.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/extend/file/atomic.rb b/Library/Homebrew/extend/file/atomic.rb index eecd212794313..b57c9cc8504c9 100644 --- a/Library/Homebrew/extend/file/atomic.rb +++ b/Library/Homebrew/extend/file/atomic.rb @@ -20,11 +20,11 @@ class File # file.write('hello') # end sig { - params( + type_parameters(:out).params( file_name: T.any(Pathname, String), temp_dir: String, - _block: T.proc.params(arg0: Tempfile).void, - ).void + _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) From 44e6b48fd722c9d4e847b0e7a3db1ee7b9ac480f Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 11:21:12 -0800 Subject: [PATCH 18/24] revert bundler/setup changes --- Library/Homebrew/test/rubocop_spec.rb | 2 +- Library/Homebrew/vendor/bundle/bundler/setup.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/test/rubocop_spec.rb b/Library/Homebrew/test/rubocop_spec.rb index dbf055d8fdda2..ce163c2d98383 100644 --- a/Library/Homebrew/test/rubocop_spec.rb +++ b/Library/Homebrew/test/rubocop_spec.rb @@ -17,7 +17,7 @@ end it "loads all Formula cops without errors" do - stdout, stderr, status = Open3.capture3(RUBY_PATH, "-W0", "-S", "rubocop", "-d", TEST_FIXTURE_DIR/"testball.rb") + stdout, stderr, status = Open3.capture3(RUBY_PATH, "-W0", "-S", "rubocop", TEST_FIXTURE_DIR/"testball.rb") expect(stderr).to be_empty expect(stdout).to include("no offenses detected") expect(status).to be_a_success diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index a69c36a13518d..cf401a00080be 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -39,8 +39,8 @@ def self.extension_api_version $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bindata-2.4.15/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/msgpack-1.7.2") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/msgpack-1.7.2/lib") -$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/bootsnap-1.17.0") -$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bootsnap-1.17.0/lib") +$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/bootsnap-1.17.1") +$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bootsnap-1.17.1/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/x86_64-darwin-15/#{Gem.extension_api_version}/byebug-11.1.3") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/byebug-11.1.3/lib") $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/coderay-1.1.3/lib") From 66aff2af7ba8ff3c5e8adea85e552f0f669cc353 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 11:45:19 -0800 Subject: [PATCH 19/24] concise --- Library/Homebrew/extend/object/duplicable.rb | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/extend/object/duplicable.rb b/Library/Homebrew/extend/object/duplicable.rb index 0ab1d52e83790..d5f566cb52e64 100644 --- a/Library/Homebrew/extend/object/duplicable.rb +++ b/Library/Homebrew/extend/object/duplicable.rb @@ -25,9 +25,7 @@ class Object # False for method objects; # true otherwise. sig { returns(T::Boolean) } - def duplicable? - true - end + def duplicable? = true end class Method @@ -36,9 +34,7 @@ class Method # method(:puts).duplicable? # => false # method(:puts).dup # => TypeError: allocator undefined for Method sig { returns(FalseClass) } - def duplicable? - false - end + def duplicable? = false end class UnboundMethod @@ -47,9 +43,7 @@ class UnboundMethod # method(:puts).unbind.duplicable? # => false # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod sig { returns(FalseClass) } - def duplicable? - false - end + def duplicable? = false end require "singleton" @@ -59,7 +53,5 @@ module Singleton # # Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton sig { returns(FalseClass) } - def duplicable? - false - end + def duplicable? = false end From 53bba9c00f5c107da3c8dbd60d69415fe6f0ba84 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 12 Jan 2024 15:17:12 -0800 Subject: [PATCH 20/24] cleanup --- .gitignore | 6 +----- Library/Homebrew/extend/hash/deep_merge.rb | 4 +++- Library/Homebrew/extend/object/deep_dup.rb | 8 ++++++-- Library/Homebrew/global.rb | 9 +++++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 2172e87ce92e9..58bd229b00650 100644 --- a/.gitignore +++ b/.gitignore @@ -53,11 +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 -!**/vendor/bundle/ruby/*/gems/sorbet-runtime-*/ # Ignore partially included gems where we don't need all files **/vendor/gems/mechanize-*/.* @@ -138,6 +133,7 @@ **/vendor/bundle/ruby/*/gems/simplecov_json_formatter-*/ **/vendor/bundle/ruby/*/gems/simpleidn-*/ **/vendor/bundle/ruby/*/gems/sorbet-*/ +!**/vendor/bundle/ruby/*/gems/sorbet-runtime-*/ **/vendor/bundle/ruby/*/gems/spoom-*/ **/vendor/bundle/ruby/*/gems/stackprof-*/ **/vendor/bundle/ruby/*/gems/strscan-*/ diff --git a/Library/Homebrew/extend/hash/deep_merge.rb b/Library/Homebrew/extend/hash/deep_merge.rb index 9804d6d1e3579..01ecbe926044c 100644 --- a/Library/Homebrew/extend/hash/deep_merge.rb +++ b/Library/Homebrew/extend/hash/deep_merge.rb @@ -16,7 +16,9 @@ class Hash # h2 = { b: 250, c: { c1: 200 } } # h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val } # # => { a: 100, b: 450, c: { c1: 300 } } - def deep_merge(other_hash, &block) = dup.deep_merge!(other_hash, &block) + def deep_merge(other_hash, &block) + dup.deep_merge!(other_hash, &block) + end # Same as +deep_merge+, but modifies +self+. def deep_merge!(other_hash, &block) diff --git a/Library/Homebrew/extend/object/deep_dup.rb b/Library/Homebrew/extend/object/deep_dup.rb index b64eccc5f7026..24262d1a5a155 100644 --- a/Library/Homebrew/extend/object/deep_dup.rb +++ b/Library/Homebrew/extend/object/deep_dup.rb @@ -14,7 +14,9 @@ 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 + def deep_dup + duplicable? ? dup : self + end end class Array @@ -27,7 +29,9 @@ class Array # array[1][2] # => nil # dup[1][2] # => 4 sig { returns(T.self_type) } - def deep_dup = T.unsafe(self).map(&:deep_dup) + def deep_dup + T.unsafe(self).map(&:deep_dup) + end end class Hash diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index 863f322be0b42..0a04c785cde9a 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -10,6 +10,11 @@ require "forwardable" require "set" +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 HOMEBREW_BREW_DEFAULT_GIT_REMOTE = ENV.fetch("HOMEBREW_BREW_DEFAULT_GIT_REMOTE").freeze @@ -61,10 +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/array" -require "extend/blank" -require "extend/enumerable" -require "extend/string" require "env_config" require "macos_version" require "os" From df140b329fbaf05a9cab1f4a7418e0aba9a26eff Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 19 Jan 2024 13:38:54 -0800 Subject: [PATCH 21/24] brew style --fix --- Library/Homebrew/livecheck/strategy/gnu.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/livecheck/strategy/gnu.rb b/Library/Homebrew/livecheck/strategy/gnu.rb index 40b485274c819..090d8d0be1725 100644 --- a/Library/Homebrew/livecheck/strategy/gnu.rb +++ b/Library/Homebrew/livecheck/strategy/gnu.rb @@ -36,7 +36,7 @@ class Gnu ^https?:// (?:(?:[^/]+?\.)*gnu\.org/(?:gnu|software)/(?[^/]+)/ |(?[^/]+)\.gnu\.org/?$) - }ix.freeze, Regexp) + }ix, Regexp) # Whether the strategy can be applied to the provided URL. # From 2f8ad2f5e6fdb1527d5bdef95f778a21d1f14c8e Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Mon, 22 Jan 2024 10:03:17 -0800 Subject: [PATCH 22/24] Inline index_by --- Library/Homebrew/extend/enumerable.rb | 18 ------------------ Library/Homebrew/formula_installer.rb | 13 +++++++------ 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/Library/Homebrew/extend/enumerable.rb b/Library/Homebrew/extend/enumerable.rb index 4c3eb14ecbc39..419b1cd20b5ad 100644 --- a/Library/Homebrew/extend/enumerable.rb +++ b/Library/Homebrew/extend/enumerable.rb @@ -2,24 +2,6 @@ # frozen_string_literal: true module Enumerable - # 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(&block) - if block - result = {} - each { |elem| result[yield(elem)] = elem } - result - else - T.unsafe(self).to_enum(:index_by) { T.unsafe(self).size if respond_to?(:size) } - end - end - # The negative of the Enumerable#include?. Returns +true+ if the # collection does not include the object. sig { params(object: T.untyped).returns(T::Boolean) } diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index d99a518595fd9..292e91fc8cd6e 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -565,8 +565,8 @@ def runtime_requirements(formula) def expand_requirements unsatisfied_reqs = Hash.new { |h, k| h[k] = [] } formulae = [formula] - formula_deps_map = formula.recursive_dependencies - .index_by(&:name) + formula_deps_map = {} + formula.recursive_dependencies.each { |dep| formula_deps_map[dep.name] = dep } while (f = formulae.pop) runtime_requirements = runtime_requirements(f) @@ -1206,10 +1206,11 @@ def previously_fetched_formula def fetch_bottle_tab @fetch_bottle_tab ||= begin formula.fetch_bottle_tab - @bottle_tab_runtime_dependencies = formula.bottle_tab_attributes - .fetch("runtime_dependencies", []) - .index_by { |dep| dep["full_name"] } - .freeze + @bottle_tab_runtime_dependencies = {} + formula.bottle_tab_attributes + .fetch("runtime_dependencies", []) + .each { |dep| @bottle_tab_runtime_dependencies[dep["full_name"]] = dep } + @bottle_tab_runtime_dependencies.freeze true rescue DownloadError, ArgumentError @fetch_bottle_tab = true From 1a40468ce4d8650038fba21ddec295eb29e18514 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Mon, 22 Jan 2024 10:12:22 -0800 Subject: [PATCH 23/24] Fix compact_blank style --- Library/Homebrew/extend/enumerable.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/extend/enumerable.rb b/Library/Homebrew/extend/enumerable.rb index 419b1cd20b5ad..77b499b2ddc79 100644 --- a/Library/Homebrew/extend/enumerable.rb +++ b/Library/Homebrew/extend/enumerable.rb @@ -26,5 +26,5 @@ def compact_blank = T.unsafe(self).reject(&:blank?) class Hash # Hash#reject has its own definition, so this needs one too. - def compact_blank = reject { T.unsafe(_2).blank? } + def compact_blank = reject { |_k, v| T.unsafe(v).blank? } end From e574904cb72805e773707e928442528d316e43a9 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Mon, 22 Jan 2024 10:41:48 -0800 Subject: [PATCH 24/24] Use each_with_object --- Library/Homebrew/extend/enumerable.rbi | 11 ----------- Library/Homebrew/formula_installer.rb | 13 ++++++------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Library/Homebrew/extend/enumerable.rbi b/Library/Homebrew/extend/enumerable.rbi index a95b0bf4bb4fa..207de60eb603d 100644 --- a/Library/Homebrew/extend/enumerable.rbi +++ b/Library/Homebrew/extend/enumerable.rbi @@ -1,16 +1,5 @@ # typed: strict -module Enumerable - requires_ancestor { Object } - - sig { - type_parameters(:key).params( - block: T.nilable(T.proc.params(o: Enumerable::Elem).returns(T.type_parameter(:key))), - ).returns(T::Hash[T.type_parameter(:key), Enumerable::Elem]) - } - def index_by(&block); end -end - class Hash sig { returns(T::Hash[Hash::K, Hash::V]) } def compact_blank; end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 292e91fc8cd6e..4d7a21cf960bd 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -565,8 +565,8 @@ def runtime_requirements(formula) def expand_requirements unsatisfied_reqs = Hash.new { |h, k| h[k] = [] } formulae = [formula] - formula_deps_map = {} - formula.recursive_dependencies.each { |dep| formula_deps_map[dep.name] = dep } + formula_deps_map = formula.recursive_dependencies + .each_with_object({}) { |dep, h| h[dep.name] = dep } while (f = formulae.pop) runtime_requirements = runtime_requirements(f) @@ -1206,11 +1206,10 @@ def previously_fetched_formula def fetch_bottle_tab @fetch_bottle_tab ||= begin formula.fetch_bottle_tab - @bottle_tab_runtime_dependencies = {} - formula.bottle_tab_attributes - .fetch("runtime_dependencies", []) - .each { |dep| @bottle_tab_runtime_dependencies[dep["full_name"]] = dep } - @bottle_tab_runtime_dependencies.freeze + @bottle_tab_runtime_dependencies = formula.bottle_tab_attributes + .fetch("runtime_dependencies", []) + .each_with_object({}) { |dep, h| h[dep["full_name"]] = dep } + .freeze true rescue DownloadError, ArgumentError @fetch_bottle_tab = true