From 03e583e746da4340b67078a6f0078f1768abd25e Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Tue, 5 Mar 2024 17:11:55 +0000 Subject: [PATCH] cask: read bundle version from `Info.plist` when sensible. If you're trying to use `brew info --json=v2` to get an installed version and figure out if it is outdated: you're going to have a bad time with `auto_updates` casks because `installed_version` alone is not enough to get the actually currently installed version of the app. Instead, in these cases, try to read from `Info.plist` if there is one and use that version. While we're here, add a `blank?` method to `Version` so we can use it for `present?` checks (making a `null?` `Version` object `blank?`). Co-authored-by: Markus Reiter --- Library/Homebrew/cask/cask.rb | 25 ++++++++++++++++++- .../support/fixtures/cask/everything.json | 2 ++ Library/Homebrew/version.rb | 6 +++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cask/cask.rb b/Library/Homebrew/cask/cask.rb index fc76d85389b86..e82def925e727 100644 --- a/Library/Homebrew/cask/cask.rb +++ b/Library/Homebrew/cask/cask.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "attrable" +require "bundle_version" require "cask/cask_loader" require "cask/config" require "cask/dsl" @@ -176,8 +177,20 @@ def installed_caskfile sig { returns(T.nilable(String)) } def installed_version + return unless (installed_caskfile = self.installed_caskfile) + # /.metadata///Casks/.{rb,json} -> - installed_caskfile&.dirname&.dirname&.dirname&.basename&.to_s + installed_caskfile.dirname.dirname.dirname.basename.to_s + end + + sig { returns(T.nilable(String)) } + def bundle_short_version + bundle_version&.short_version + end + + sig { returns(T.nilable(String)) } + def bundle_long_version + bundle_version&.version end def config_path @@ -326,6 +339,8 @@ def to_h "version" => version, "installed" => installed_version, "installed_time" => install_time&.to_i, + "bundle_version" => bundle_long_version, + "bundle_short_version" => bundle_short_version, "outdated" => outdated?, "sha256" => sha256, "artifacts" => artifacts_list, @@ -386,6 +401,14 @@ def to_hash_with_variations private + sig { returns(T.nilable(Homebrew::BundleVersion)) } + def bundle_version + @bundle_version ||= if (bundle = artifacts.find { |a| a.is_a?(Artifact::App) }&.target) && + (plist = Pathname("#{bundle}/Contents/Info.plist")) && plist.exist? + Homebrew::BundleVersion.from_info_plist(plist) + end + end + def api_to_local_hash(hash) hash["token"] = token hash["installed"] = installed_version diff --git a/Library/Homebrew/test/support/fixtures/cask/everything.json b/Library/Homebrew/test/support/fixtures/cask/everything.json index 6efdcaa095993..59bebe0635c47 100644 --- a/Library/Homebrew/test/support/fixtures/cask/everything.json +++ b/Library/Homebrew/test/support/fixtures/cask/everything.json @@ -21,6 +21,8 @@ "version": "1.2.3", "installed": null, "installed_time": null, + "bundle_version": null, + "bundle_short_version": null, "outdated": false, "sha256": "c64c05bdc0be845505d6e55e69e696a7f50d40846e76155f0c85d5ff5e7bbb84", "artifacts": [ diff --git a/Library/Homebrew/version.rb b/Library/Homebrew/version.rb index 80862aca98a6b..493780eec731d 100644 --- a/Library/Homebrew/version.rb +++ b/Library/Homebrew/version.rb @@ -94,6 +94,9 @@ def numeric? def null? false end + + sig { returns(T::Boolean) } + def blank? = null? end # A pseudo-token representing the absence of a token. @@ -127,6 +130,9 @@ def null? true end + sig { returns(T::Boolean) } + def blank? = true + sig { override.returns(String) } def inspect "#<#{self.class.name}>"