From 6397229f68532ef4b4ecab8510eb2697a0ed6bf0 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Sat, 1 Apr 2023 18:56:42 -0700 Subject: [PATCH 1/4] Enable types in extensions, etc. --- .../cmd/postgresql-upgrade-database.rb | 12 ++++----- Library/Homebrew/dependencies.rb | 20 +++++++------- Library/Homebrew/dependencies.rbi | 4 +++ Library/Homebrew/extend/object.rbi | 6 +++++ .../Homebrew/extend/os/mac/hardware/cpu.rb | 4 +-- Library/Homebrew/extend/os/mac/keg.rb | 4 +-- Library/Homebrew/extend/predicable.rb | 2 +- Library/Homebrew/extend/predicable.rbi | 5 ++++ Library/Homebrew/extend/time.rb | 5 ++-- Library/Homebrew/livecheck/strategy.rb | 8 +++--- Library/Homebrew/utils/pypi.rb | 26 ++++++++++--------- 11 files changed, 57 insertions(+), 39 deletions(-) create mode 100644 Library/Homebrew/extend/object.rbi create mode 100644 Library/Homebrew/extend/predicable.rbi diff --git a/Library/Homebrew/cmd/postgresql-upgrade-database.rb b/Library/Homebrew/cmd/postgresql-upgrade-database.rb index 50421460d9..e0c2907c97 100755 --- a/Library/Homebrew/cmd/postgresql-upgrade-database.rb +++ b/Library/Homebrew/cmd/postgresql-upgrade-database.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "cli/parser" @@ -60,10 +60,10 @@ module Homebrew odie "No #{name} #{pg_version_data}.* version installed!" unless old_bin - server_stopped = false - moved_data = false - initdb_run = false - upgraded = false + server_stopped = T.let(false, T::Boolean) + moved_data = T.let(false, T::Boolean) + initdb_run = T.let(false, T::Boolean) + upgraded = T.let(false, T::Boolean) begin # Following instructions from: @@ -88,7 +88,7 @@ module Homebrew system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "start" end - initdb_args = [] + initdb_args = T.let([], T::Array[String]) locale_settings = %w[ lc_collate lc_ctype diff --git a/Library/Homebrew/dependencies.rb b/Library/Homebrew/dependencies.rb index 3b107e9999..fedb68cb72 100644 --- a/Library/Homebrew/dependencies.rb +++ b/Library/Homebrew/dependencies.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "delegate" @@ -16,19 +16,19 @@ class Dependencies < SimpleDelegator alias eql? == def optional - select(&:optional?) + __getobj__.select(&:optional?) end def recommended - select(&:recommended?) + __getobj__.select(&:recommended?) end def build - select(&:build?) + __getobj__.select(&:build?) end def required - select(&:required?) + __getobj__.select(&:required?) end def default @@ -37,7 +37,7 @@ class Dependencies < SimpleDelegator sig { returns(String) } def inspect - "#<#{self.class.name}: #{to_a}>" + "#<#{self.class.name}: #{__getobj__}>" end end @@ -52,11 +52,11 @@ class Requirements < SimpleDelegator end def <<(other) - if other.is_a?(Comparable) - grep(other.class) do |req| + if other.is_a?(Object) && other.is_a?(Comparable) + __getobj__.grep(other.class) do |req| return self if req > other - delete(req) + __getobj__.delete(req) end end super @@ -65,6 +65,6 @@ class Requirements < SimpleDelegator sig { returns(String) } def inspect - "#<#{self.class.name}: {#{to_a.join(", ")}}>" + "#<#{self.class.name}: {#{__getobj__.to_a.join(", ")}}>" end end diff --git a/Library/Homebrew/dependencies.rbi b/Library/Homebrew/dependencies.rbi index 94819cec58..652ce4f99d 100644 --- a/Library/Homebrew/dependencies.rbi +++ b/Library/Homebrew/dependencies.rbi @@ -2,6 +2,10 @@ class Dependencies < SimpleDelegator include Kernel + # This is a workaround to enable `alias eql? ==` + # @see https://github.com/sorbet/sorbet/issues/2378#issuecomment-569474238 + sig { params(arg0: BasicObject).returns(T::Boolean) } + def ==(arg0); end end class Requirements < SimpleDelegator diff --git a/Library/Homebrew/extend/object.rbi b/Library/Homebrew/extend/object.rbi new file mode 100644 index 0000000000..cc39405568 --- /dev/null +++ b/Library/Homebrew/extend/object.rbi @@ -0,0 +1,6 @@ +# typed: strict + +class Object + sig { returns(T::Boolean) } + def present?; end +end diff --git a/Library/Homebrew/extend/os/mac/hardware/cpu.rb b/Library/Homebrew/extend/os/mac/hardware/cpu.rb index 280525c4e7..9e79aa6677 100644 --- a/Library/Homebrew/extend/os/mac/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/mac/hardware/cpu.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "macho" @@ -114,7 +114,7 @@ module Hardware end end - def intel_family + def intel_family(_family = nil, _cpu_model = nil) case sysctl_int("hw.cpufamily") when 0x73d67300 # Yonah: Core Solo/Duo :core diff --git a/Library/Homebrew/extend/os/mac/keg.rb b/Library/Homebrew/extend/os/mac/keg.rb index 6a47832a5c..6647028c96 100644 --- a/Library/Homebrew/extend/os/mac/keg.rb +++ b/Library/Homebrew/extend/os/mac/keg.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true class Keg @@ -108,7 +108,7 @@ class Keg # Needed to make symlink permissions consistent on macOS and Linux for # reproducible bottles. def consistent_reproducible_symlink_permissions! - find do |file| + path.find do |file| File.lchmod 0777, file if file.symlink? end end diff --git a/Library/Homebrew/extend/predicable.rb b/Library/Homebrew/extend/predicable.rb index 914244d5d3..6aa79ad949 100644 --- a/Library/Homebrew/extend/predicable.rb +++ b/Library/Homebrew/extend/predicable.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Predicable diff --git a/Library/Homebrew/extend/predicable.rbi b/Library/Homebrew/extend/predicable.rbi new file mode 100644 index 0000000000..cd5e165e4c --- /dev/null +++ b/Library/Homebrew/extend/predicable.rbi @@ -0,0 +1,5 @@ +# typed: strict + +module Predicable + requires_ancestor { Class } +end diff --git a/Library/Homebrew/extend/time.rb b/Library/Homebrew/extend/time.rb index 1fee2d4bd3..d62de2c8ea 100644 --- a/Library/Homebrew/extend/time.rb +++ b/Library/Homebrew/extend/time.rb @@ -1,16 +1,17 @@ -# typed: false +# typed: true # frozen_string_literal: true module TimeRemaining refine Time do def remaining + T.bind(self, Time) [0, self - Time.now].max end def remaining! r = remaining - raise Timeout::Error if r <= 0 + Kernel.raise Timeout::Error if r <= 0 r end diff --git a/Library/Homebrew/livecheck/strategy.rb b/Library/Homebrew/livecheck/strategy.rb index 45b671defd..dc5446d160 100644 --- a/Library/Homebrew/livecheck/strategy.rb +++ b/Library/Homebrew/livecheck/strategy.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Homebrew @@ -161,7 +161,7 @@ module Homebrew # specifies the strategy and contains a `strategy` block next if (livecheck_strategy != strategy_symbol) || !block_provided elsif strategy.const_defined?(:PRIORITY) && - !strategy::PRIORITY.positive? && + !strategy.const_get(:PRIORITY).positive? && livecheck_strategy != strategy_symbol # Ignore strategies with a priority of 0 or lower, unless the # strategy is specified in the `livecheck` block @@ -174,7 +174,7 @@ module Homebrew # Sort usable strategies in descending order by priority, using the # DEFAULT_PRIORITY when a strategy doesn't contain a PRIORITY constant usable_strategies.sort_by do |strategy| - (strategy.const_defined?(:PRIORITY) ? -strategy::PRIORITY : -DEFAULT_PRIORITY) + (strategy.const_defined?(:PRIORITY) ? -strategy.const_get(:PRIORITY) : -DEFAULT_PRIORITY) end end @@ -216,7 +216,7 @@ module Homebrew # @return [Hash] sig { params(url: String, homebrew_curl: T::Boolean).returns(T::Hash[Symbol, T.untyped]) } def self.page_content(url, homebrew_curl: false) - stderr = nil + stderr = T.let(nil, T.nilable(String)) [:default, :browser].each do |user_agent| stdout, stderr, status = curl_with_workarounds( *PAGE_CONTENT_CURL_ARGS, url, diff --git a/Library/Homebrew/utils/pypi.rb b/Library/Homebrew/utils/pypi.rb index 3fa0277588..c65576a186 100644 --- a/Library/Homebrew/utils/pypi.rb +++ b/Library/Homebrew/utils/pypi.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true # Helper functions for updating PyPI resources. @@ -7,8 +7,6 @@ module PyPI extend T::Sig - module_function - PYTHONHOSTED_URL_PREFIX = "https://files.pythonhosted.org/packages/" private_constant :PYTHONHOSTED_URL_PREFIX @@ -35,13 +33,16 @@ module PyPI return end - @name = package_string - @name, @version = @name.split("==") if @name.include? "==" + if package_string.include? "==" + @name, @version = package_string.split("==") + else + @name = package_string + end - return unless (match = @name.match(/^(.*?)\[(.+)\]$/)) + return unless (match = T.must(@name).match(/^(.*?)\[(.+)\]$/)) @name = match[1] - @extras = match[2].split "," + @extras = T.must(match[2]).split "," end # Get name, URL, SHA-256 checksum, and latest version for a given PyPI package. @@ -87,7 +88,7 @@ module PyPI sig { params(other: Package).returns(T::Boolean) } def same_package?(other) - @name.tr("_", "-").casecmp(other.name.tr("_", "-")).zero? + T.must(@name.tr("_", "-").casecmp(other.name.tr("_", "-"))).zero? end # Compare only names so we can use .include? and .uniq on a Package array @@ -109,7 +110,7 @@ module PyPI end sig { params(url: String, version: T.any(String, Version)).returns(T.nilable(String)) } - def update_pypi_url(url, version) + def self.update_pypi_url(url, version) package = Package.new url, is_url: true return unless package.valid_pypi_package? @@ -133,8 +134,9 @@ module PyPI ignore_non_pypi_packages: T.nilable(T::Boolean), ).returns(T.nilable(T::Boolean)) } - def update_python_resources!(formula, version: nil, package_name: nil, extra_packages: nil, exclude_packages: nil, - print_only: false, silent: false, ignore_non_pypi_packages: false) + def self.update_python_resources!(formula, version: nil, package_name: nil, extra_packages: nil, + exclude_packages: nil, print_only: false, silent: false, + ignore_non_pypi_packages: false) auto_update_list = formula.tap&.pypi_formula_mappings if auto_update_list.present? && auto_update_list.key?(formula.full_name) && @@ -282,7 +284,7 @@ module PyPI true end - def json_to_packages(json_tree, main_package, exclude_packages) + def self.json_to_packages(json_tree, main_package, exclude_packages) return [] if json_tree.blank? json_tree.flat_map do |package_json| From 0079cefc954013ede355e4786a4f8b27e54332bf Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Sun, 2 Apr 2023 12:20:53 -0700 Subject: [PATCH 2/4] Enable types in remaining untyped extensions --- .../extend/os/linux/dev-cmd/update-test.rb | 14 ++++++-------- Library/Homebrew/extend/os/linux/diagnostic.rb | 10 +++++----- Library/Homebrew/extend/os/linux/hardware/cpu.rb | 3 ++- Library/Homebrew/extend/os/mac/diagnostic.rb | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/extend/os/linux/dev-cmd/update-test.rb b/Library/Homebrew/extend/os/linux/dev-cmd/update-test.rb index ebdbbd8f88..0f711eeafd 100644 --- a/Library/Homebrew/extend/os/linux/dev-cmd/update-test.rb +++ b/Library/Homebrew/extend/os/linux/dev-cmd/update-test.rb @@ -1,18 +1,16 @@ -# typed: false +# typed: true # frozen_string_literal: true module Homebrew extend T::Sig - module_function - class << self alias generic_git_tags git_tags - end - def git_tags - tags = generic_git_tags - tags = Utils.popen_read("git tag --list | sort -rV") if tags.blank? - tags + def git_tags + tags = generic_git_tags + tags = Utils.popen_read("git tag --list | sort -rV") if tags.blank? + tags + end end end diff --git a/Library/Homebrew/extend/os/linux/diagnostic.rb b/Library/Homebrew/extend/os/linux/diagnostic.rb index a4d69332d2..c68dbcc802 100644 --- a/Library/Homebrew/extend/os/linux/diagnostic.rb +++ b/Library/Homebrew/extend/os/linux/diagnostic.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "tempfile" @@ -46,7 +46,7 @@ module Homebrew f.write "#!/bin/sh\n" f.chmod 0700 f.close - return if system f.path + return if system T.must(f.path) <<~EOS The directory #{HOMEBREW_TEMP} does not permit executing @@ -56,12 +56,12 @@ module Homebrew echo 'export HOMEBREW_TEMP=~/tmp' >> #{shell_profile} EOS ensure - f.unlink + f&.unlink end def check_xdg_data_dirs - return if ENV["XDG_DATA_DIRS"].blank? - return if ENV["XDG_DATA_DIRS"].split("/").include?(HOMEBREW_PREFIX/"share") + xdg_data_dirs = ENV["XDG_DATA_DIRS"] + return if xdg_data_dirs.blank? || xdg_data_dirs.split("/").include?(HOMEBREW_PREFIX/"share") <<~EOS Homebrew's share was not found in your XDG_DATA_DIRS but you have diff --git a/Library/Homebrew/extend/os/linux/hardware/cpu.rb b/Library/Homebrew/extend/os/linux/hardware/cpu.rb index 0e6805a6e0..253b7571ec 100644 --- a/Library/Homebrew/extend/os/linux/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/linux/hardware/cpu.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Hardware @@ -111,6 +111,7 @@ module Hardware end %w[aes altivec avx avx2 lm ssse3 sse4_2].each do |flag| + T.bind(self, T.class_of(Hardware::CPU)) define_method("#{flag}?") { flags.include? flag } end diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index 97350b4a89..1cbc907f33 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Homebrew @@ -379,7 +379,7 @@ module Homebrew real_tmp = tmp.realpath.parent where_tmp = volumes.which real_tmp ensure - Dir.delete tmp + Dir.delete tmp.to_s end rescue return From 4df5a80c7344fe84670acf97e16625ff18597988 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Sun, 2 Apr 2023 12:25:55 -0700 Subject: [PATCH 3/4] brew style --fix --- Library/Homebrew/extend/os/linux/diagnostic.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/extend/os/linux/diagnostic.rb b/Library/Homebrew/extend/os/linux/diagnostic.rb index c68dbcc802..f583b965ae 100644 --- a/Library/Homebrew/extend/os/linux/diagnostic.rb +++ b/Library/Homebrew/extend/os/linux/diagnostic.rb @@ -60,7 +60,7 @@ module Homebrew end def check_xdg_data_dirs - xdg_data_dirs = ENV["XDG_DATA_DIRS"] + xdg_data_dirs = ENV.fetch("XDG_DATA_DIRS", nil) return if xdg_data_dirs.blank? || xdg_data_dirs.split("/").include?(HOMEBREW_PREFIX/"share") <<~EOS From bc588cc04f9003c6f4384cef3bf596990d5b2195 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Sun, 2 Apr 2023 16:38:30 -0700 Subject: [PATCH 4/4] Fix tests --- Library/Homebrew/extend/os/linux/hardware/cpu.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/extend/os/linux/hardware/cpu.rb b/Library/Homebrew/extend/os/linux/hardware/cpu.rb index 253b7571ec..12762704bc 100644 --- a/Library/Homebrew/extend/os/linux/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/linux/hardware/cpu.rb @@ -111,8 +111,10 @@ module Hardware end %w[aes altivec avx avx2 lm ssse3 sse4_2].each do |flag| - T.bind(self, T.class_of(Hardware::CPU)) - define_method("#{flag}?") { flags.include? flag } + define_method("#{flag}?") do + T.bind(self, T.class_of(Hardware::CPU)) + flags.include? flag + end end def sse3?