From 4a0c72b89c4859465289b81129bf93564682c99e Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sat, 20 Jul 2024 11:14:53 -0700 Subject: [PATCH] Use cask tab to better identify installed casks Previously we would identify installed casks by token derived from directories present in the caskroom directory. That was error prone when the token was ambiguous. In that case, the `Cask::Caskroom.cask` method would default to the first cask which was not always correct. Now that we have the cask tab we can use the installed receipt to get the tap a cask came from. With both the tap and the token, we can be sure that we're loading the cask that is actually installed and not another cask from a different tap that just happens to have the same name. --- Library/Homebrew/cask/caskroom.rb | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/caskroom.rb b/Library/Homebrew/cask/caskroom.rb index 1c2d4dd0914c0..0b3bc136b75f1 100644 --- a/Library/Homebrew/cask/caskroom.rb +++ b/Library/Homebrew/cask/caskroom.rb @@ -28,6 +28,23 @@ def self.tokens paths.map { |path| path.basename.to_s } end + sig { returns(T::Array[String]) } + def self.full_tokens + require "cask/tab" + + paths.map do |path| + token = path.basename.to_s + # Cask tabs were only added on July 13, 2024 in + # https://github.com/Homebrew/brew/pull/17554 so + # they might not exist for older installs. + if (tab_path = path/".metadata"/AbstractTab::FILENAME).exist? + tap = Tab.from_file(tab_path).tap + token = "#{tap}/#{token}" if tap + end + token + end + end + sig { returns(T::Boolean) } def self.any_casks_installed? paths.any? @@ -55,7 +72,7 @@ def self.ensure_caskroom_exists # @api internal sig { params(config: T.nilable(Config)).returns(T::Array[Cask]) } def self.casks(config: nil) - tokens.sort.filter_map do |token| + full_tokens.sort.filter_map do |token| CaskLoader.load(token, config:, warn: false) rescue TapCaskAmbiguityError => e T.must(e.loaders.first).load(config:)