From 6e5b6b7cc9d7ac195a1c692de6c7192805d3ae46 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 8 Feb 2024 14:43:53 +0100 Subject: [PATCH 01/10] Remove unused parameter from `CaskLoader::tap_paths`. --- Library/Homebrew/cask/cask_loader.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 4d3cf740514a2..26d13fa6e39f5 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -482,7 +482,7 @@ def from_h_gsubs(value, appdir) # if the same token exists in multiple taps. class FromAmbiguousTapPathLoader < FromTapPathLoader def self.try_new(ref, warn: false) - case (possible_tap_casks = CaskLoader.tap_paths(ref, warn: warn)).count + case (possible_tap_casks = CaskLoader.tap_paths(ref)).count when 1 new(possible_tap_casks.first) when 2..Float::INFINITY @@ -587,7 +587,7 @@ def self.default_path(token) find_cask_in_tap(token.to_s.downcase, CoreCaskTap.instance) end - def self.tap_paths(token, warn: true) + def self.tap_paths(token) token = token.to_s.downcase Tap.map { |tap| find_cask_in_tap(token, tap) }.select(&:exist?) From 732e4438f4d9349e0893f71821bf1e7184ef7e42 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 8 Feb 2024 14:44:10 +0100 Subject: [PATCH 02/10] Use `token` instead of `name` for casks. --- Library/Homebrew/cask/cask_loader.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 26d13fa6e39f5..6c09a0a86d368 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -225,9 +225,9 @@ def self.try_new(ref, warn: false) new("#{tap}/#{token}") end - sig { params(tapped_name: String).void } - def initialize(tapped_name) - user, repo, token = tapped_name.split("/", 3) + sig { params(tapped_token: String).void } + def initialize(tapped_token) + user, repo, token = tapped_token.split("/", 3) tap = Tap.fetch(user, repo) cask = CaskLoader.find_cask_in_tap(token, tap) super cask From dc2109573143b3550365758ebcec46a85e3b3a2a Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 8 Feb 2024 14:44:41 +0100 Subject: [PATCH 03/10] Simplify multiple `if`s into single `case` statement. --- Library/Homebrew/cask/cask_loader.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 6c09a0a86d368..adfced06470b6 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -90,10 +90,14 @@ class FromPathLoader < AbstractContentLoader .returns(T.nilable(T.attached_class)) } def self.try_new(ref, warn: false) - ref = Pathname(ref) if ref.is_a?(String) - return unless ref.is_a?(Pathname) - - path = ref + path = case ref + when String + Pathname(ref) + when Pathname + ref + else + return + end return if %w[.rb .json].exclude?(path.extname) return unless path.expand_path.exist? From 889854b0b3a65a3c40b3ecb43a99b16d9e86ea7d Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 8 Feb 2024 14:53:55 +0100 Subject: [PATCH 04/10] Merge `FromTapPathLoader` into `FromPathLoader`. --- Library/Homebrew/cask/cask_loader.rb | 31 +++---------------- Library/Homebrew/cask/caskroom.rb | 2 +- .../Homebrew/test/cask/cask_loader_spec.rb | 4 +-- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index adfced06470b6..265028376277a 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -114,9 +114,8 @@ def initialize(path, token: T.unsafe(nil)) path = Pathname(path).expand_path @token = path.basename(path.extname).to_s - @path = path - @tap = Homebrew::API.tap_from_source_download(path) + @tap = Tap.from_path(path) || Homebrew::API.tap_from_source_download(path) end def load(config:) @@ -195,27 +194,8 @@ def load(config:) end end - # Loads a cask from a tap path. - class FromTapPathLoader < FromPathLoader - sig { - params(ref: T.any(String, Pathname, Cask, URI::Generic), warn: T::Boolean) - .returns(T.nilable(T.attached_class)) - } - def self.try_new(ref, warn: false) - return unless (loader = super) - - loader unless Tap.from_path(ref).nil? - end - - sig { params(path: T.any(Pathname, String)).void } - def initialize(path) - super(path) - @tap = Tap.from_path(path) - end - end - # Loads a cask from a specific tap. - class FromTapLoader < FromTapPathLoader + class FromTapLoader < FromPathLoader sig { params(ref: T.any(String, Pathname, Cask, URI::Generic), warn: T::Boolean) .returns(T.nilable(T.attached_class)) @@ -265,7 +245,7 @@ def self.try_new(ref, warn: false) end # Loads a cask from the default tap path. - class FromDefaultTapPathLoader < FromTapPathLoader + class FromDefaultTapPathLoader < FromPathLoader sig { params(ref: T.any(String, Pathname, Cask, URI::Generic), warn: T::Boolean) .returns(T.nilable(T.attached_class)) @@ -484,13 +464,13 @@ def from_h_gsubs(value, appdir) # Loader which tries loading casks from tap paths, failing # if the same token exists in multiple taps. - class FromAmbiguousTapPathLoader < FromTapPathLoader + class FromAmbiguousTapPathLoader < FromPathLoader def self.try_new(ref, warn: false) case (possible_tap_casks = CaskLoader.tap_paths(ref)).count when 1 new(possible_tap_casks.first) when 2..Float::INFINITY - loaders = possible_tap_casks.map(&FromTapPathLoader.method(:new)) + loaders = possible_tap_casks.map(&FromPathLoader.method(:new)) raise TapCaskAmbiguityError.new(ref, loaders) end end @@ -572,7 +552,6 @@ def self.for(ref, need_path: false, warn: true) FromURILoader, FromAPILoader, FromTapLoader, - FromTapPathLoader, FromPathLoader, FromDefaultTapPathLoader, FromAmbiguousTapPathLoader, diff --git a/Library/Homebrew/cask/caskroom.rb b/Library/Homebrew/cask/caskroom.rb index bc3f505df350f..272685dc59c23 100644 --- a/Library/Homebrew/cask/caskroom.rb +++ b/Library/Homebrew/cask/caskroom.rb @@ -56,7 +56,7 @@ def self.casks(config: nil) CaskLoader.load(token, config: config) rescue TapCaskAmbiguityError tap_path = CaskLoader.tap_paths(token).first - CaskLoader::FromTapPathLoader.new(tap_path).load(config: config) + CaskLoader::FromPathLoader.new(tap_path).load(config: config) rescue # Don't blow up because of a single unavailable cask. nil diff --git a/Library/Homebrew/test/cask/cask_loader_spec.rb b/Library/Homebrew/test/cask/cask_loader_spec.rb index b9c83cbb450b3..184343dd03b31 100644 --- a/Library/Homebrew/test/cask/cask_loader_spec.rb +++ b/Library/Homebrew/test/cask/cask_loader_spec.rb @@ -37,13 +37,13 @@ it "warns when using the short token" do expect do - expect(described_class.for("version-newest")).to be_a Cask::CaskLoader::FromTapPathLoader + expect(described_class.for("version-newest")).to be_a Cask::CaskLoader::FromPathLoader end.to output(/version-newest was renamed to version-latest/).to_stderr end it "warns when using the full token" do expect do - expect(described_class.for("homebrew/cask/version-newest")).to be_a Cask::CaskLoader::FromTapPathLoader + expect(described_class.for("homebrew/cask/version-newest")).to be_a Cask::CaskLoader::FromPathLoader end.to output(/version-newest was renamed to version-latest/).to_stderr end end From a37afcb777c6ae9bf0e667d13199cbcc75b48003 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 8 Feb 2024 15:11:02 +0100 Subject: [PATCH 05/10] Fix loading renamed casks from API. --- Library/Homebrew/cask/cask_loader.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 265028376277a..4aa25a9bf0d40 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -297,8 +297,7 @@ def self.try_new(ref, warn: false) return unless (match = ref.match(HOMEBREW_MAIN_TAP_CASK_REGEX)) token = match[:token] - - return unless Homebrew::API::Cask.all_casks.key?(token) + return if !Homebrew::API::Cask.all_casks.key?(token) && !Homebrew::API::Cask.all_renames.key?(token) ref = "#{CoreCaskTap.instance}/#{token}" From 76d8d6c840c17185f2ac8f6f6e12c768f3bc158b Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 8 Feb 2024 16:18:05 +0100 Subject: [PATCH 06/10] Add type signatures. --- Library/Homebrew/api/cask.rb | 2 +- Library/Homebrew/cask/cask_loader.rb | 10 +++++++--- Library/Homebrew/cli/named_args.rb | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/api/cask.rb b/Library/Homebrew/api/cask.rb index baaf2f0d8e3cb..17ca86b7169fd 100644 --- a/Library/Homebrew/api/cask.rb +++ b/Library/Homebrew/api/cask.rb @@ -60,7 +60,7 @@ def download_and_cache_data! end private :download_and_cache_data! - sig { returns(Hash) } + sig { returns(T::Hash[String, Hash]) } def all_casks unless cache.key?("casks") json_updated = download_and_cache_data! diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 4aa25a9bf0d40..3eb99e2dd9e93 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -281,7 +281,11 @@ def load(config:) class FromAPILoader include ILoader - attr_reader :token, :path + sig { returns(String) } + attr_reader :token + + sig { returns(Pathname) } + attr_reader :path sig { returns(T.nilable(Hash)) } attr_reader :from_json @@ -296,7 +300,7 @@ def self.try_new(ref, warn: false) return unless (match = ref.match(HOMEBREW_MAIN_TAP_CASK_REGEX)) - token = match[:token] + token = T.cast(match[:token], String) return if !Homebrew::API::Cask.all_casks.key?(token) && !Homebrew::API::Cask.all_renames.key?(token) ref = "#{CoreCaskTap.instance}/#{token}" @@ -313,7 +317,7 @@ def initialize(token, from_json: T.unsafe(nil)) end def load(config:) - json_cask = from_json || Homebrew::API::Cask.all_casks[token] + json_cask = from_json || Homebrew::API::Cask.all_casks.fetch(token) cask_options = { loaded_from_api: true, diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 04f81687ba970..9b470f4f2e870 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -256,11 +256,11 @@ def to_paths(only: parent&.only_formula_or_cask, recurse_tap: false) paths = [] if formula_path.exist? || - (!CoreTap.instance.installed? && Homebrew::API::Formula.all_formulae.key?(path.basename)) + (!CoreTap.instance.installed? && Homebrew::API::Formula.all_formulae.key?(path.basename.to_s)) paths << formula_path end if cask_path.exist? || - (!CoreCaskTap.instance.installed? && Homebrew::API::Cask.all_casks.key?(path.basename)) + (!CoreCaskTap.instance.installed? && Homebrew::API::Cask.all_casks.key?(path.basename.to_s)) paths << cask_path end From 13232626109c14bd2b10ccd943da26f588c22e86 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Thu, 8 Feb 2024 19:21:50 +0100 Subject: [PATCH 07/10] Rename constant. --- Library/Homebrew/cask/cask_loader.rb | 4 ++-- Library/Homebrew/tap_constants.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 3eb99e2dd9e93..1cfb08946e531 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -233,7 +233,7 @@ class FromDefaultTapLoader < FromTapLoader def self.try_new(ref, warn: false) ref = ref.to_s - return unless (match = ref.match(HOMEBREW_MAIN_TAP_CASK_REGEX)) + return unless (match = ref.match(HOMEBREW_DEFAULT_TAP_CASK_REGEX)) token = match[:token] @@ -298,7 +298,7 @@ def self.try_new(ref, warn: false) return if Homebrew::EnvConfig.no_install_from_api? return unless ref.is_a?(String) - return unless (match = ref.match(HOMEBREW_MAIN_TAP_CASK_REGEX)) + return unless (match = ref.match(HOMEBREW_DEFAULT_TAP_CASK_REGEX)) token = T.cast(match[:token], String) return if !Homebrew::API::Cask.all_casks.key?(token) && !Homebrew::API::Cask.all_renames.key?(token) diff --git a/Library/Homebrew/tap_constants.rb b/Library/Homebrew/tap_constants.rb index 670821f660d37..d692d5b0df335 100644 --- a/Library/Homebrew/tap_constants.rb +++ b/Library/Homebrew/tap_constants.rb @@ -5,8 +5,8 @@ HOMEBREW_TAP_FORMULA_REGEX = T.let(%r{^([\w-]+)/([\w-]+)/([\w+-.@]+)$}, Regexp) # Match taps' casks, e.g. `someuser/sometap/somecask` HOMEBREW_TAP_CASK_REGEX = T.let(%r{^([\w-]+)/([\w-]+)/([a-z0-9\-_]+)$}, Regexp) -# Match main cask taps' casks, e.g. `homebrew/cask/somecask` or `somecask` -HOMEBREW_MAIN_TAP_CASK_REGEX = T.let(%r{^(?:[Hh]omebrew/(?:homebrew-)?cask/)?(?[a-z0-9\-_]+)$}, Regexp) +# Match default cask taps' casks, e.g. `homebrew/cask/somecask` or `somecask` +HOMEBREW_DEFAULT_TAP_CASK_REGEX = T.let(%r{^(?:[Hh]omebrew/(?:homebrew-)?cask/)?(?[a-z0-9\-_]+)$}, Regexp) # Match taps' directory paths, e.g. `HOMEBREW_LIBRARY/Taps/someuser/sometap` HOMEBREW_TAP_DIR_REGEX = T.let( %r{#{Regexp.escape(HOMEBREW_LIBRARY.to_s)}/Taps/(?[\w-]+)/(?[\w-]+)}, Regexp From cb13f95928d92348a6c7a814ea0bc83d98a8d481 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Fri, 9 Feb 2024 16:59:27 +0100 Subject: [PATCH 08/10] Avoid `T.cast`. --- Library/Homebrew/cask/cask_loader.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 1cfb08946e531..cf2ac67abb024 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -297,10 +297,7 @@ class FromAPILoader def self.try_new(ref, warn: false) return if Homebrew::EnvConfig.no_install_from_api? return unless ref.is_a?(String) - - return unless (match = ref.match(HOMEBREW_DEFAULT_TAP_CASK_REGEX)) - - token = T.cast(match[:token], String) + return unless (token = ref[HOMEBREW_DEFAULT_TAP_CASK_REGEX, :token]) return if !Homebrew::API::Cask.all_casks.key?(token) && !Homebrew::API::Cask.all_renames.key?(token) ref = "#{CoreCaskTap.instance}/#{token}" From a8980a6abc03efccb3608e4bc4a9dc7d7a8742aa Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Fri, 9 Feb 2024 16:59:40 +0100 Subject: [PATCH 09/10] Fix code style. --- Library/Homebrew/tap_constants.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/tap_constants.rb b/Library/Homebrew/tap_constants.rb index d692d5b0df335..6f102bfcbf4bb 100644 --- a/Library/Homebrew/tap_constants.rb +++ b/Library/Homebrew/tap_constants.rb @@ -6,7 +6,9 @@ # Match taps' casks, e.g. `someuser/sometap/somecask` HOMEBREW_TAP_CASK_REGEX = T.let(%r{^([\w-]+)/([\w-]+)/([a-z0-9\-_]+)$}, Regexp) # Match default cask taps' casks, e.g. `homebrew/cask/somecask` or `somecask` -HOMEBREW_DEFAULT_TAP_CASK_REGEX = T.let(%r{^(?:[Hh]omebrew/(?:homebrew-)?cask/)?(?[a-z0-9\-_]+)$}, Regexp) +HOMEBREW_DEFAULT_TAP_CASK_REGEX = T.let( + %r{^(?:[Hh]omebrew/(?:homebrew-)?cask/)?(?[a-z0-9\-_]+)$}, Regexp +) # Match taps' directory paths, e.g. `HOMEBREW_LIBRARY/Taps/someuser/sometap` HOMEBREW_TAP_DIR_REGEX = T.let( %r{#{Regexp.escape(HOMEBREW_LIBRARY.to_s)}/Taps/(?[\w-]+)/(?[\w-]+)}, Regexp From 5cf4f2f0583fd063be892ccfbe763d2f42c3b1b3 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Fri, 9 Feb 2024 17:33:51 +0100 Subject: [PATCH 10/10] Fix type signature for `String#slice`. --- Library/Homebrew/sorbet/rbi/upstream.rbi | 108 +++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/Library/Homebrew/sorbet/rbi/upstream.rbi b/Library/Homebrew/sorbet/rbi/upstream.rbi index a00487f95aced..7653a8622eb49 100644 --- a/Library/Homebrew/sorbet/rbi/upstream.rbi +++ b/Library/Homebrew/sorbet/rbi/upstream.rbi @@ -2,3 +2,111 @@ # This file contains temporary definitions for fixes that have # been submitted upstream to https://github.com/sorbet/sorbet. + +# https://github.com/sorbet/sorbet/pull/7678 +class String + sig do + params( + arg0: Integer, + arg1: Integer, + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: T.any(T::Range[Integer], Regexp), + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: Regexp, + arg1: Integer, + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: Regexp, + arg1: T.any(String, Symbol), + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: String, + ) + .returns(T.nilable(String)) + end + def [](arg0, arg1=T.unsafe(nil)); end + + sig do + params( + arg0: Integer, + arg1: Integer, + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: T.any(T::Range[Integer], Regexp), + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: Regexp, + arg1: Integer, + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: Regexp, + arg1: T.any(String, Symbol), + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: String, + ) + .returns(T.nilable(String)) + end + def slice!(arg0, arg1=T.unsafe(nil)); end + + sig do + params( + arg0: Integer, + arg1: Integer, + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: T.any(T::Range[Integer], Regexp), + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: Regexp, + arg1: Integer, + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: Regexp, + arg1: T.any(String, Symbol), + ) + .returns(T.nilable(String)) + end + sig do + params( + arg0: String, + ) + .returns(T.nilable(String)) + end + def slice(arg0, arg1=T.unsafe(nil)); end +end