From d9f472340dbcd3e7ba0aa91cb4ed18bbfad26965 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 14 Dec 2020 18:43:31 +0100 Subject: [PATCH] Add `top_level_info_plists` helper method. --- Library/Homebrew/unversioned_cask_checker.rb | 48 ++++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/unversioned_cask_checker.rb b/Library/Homebrew/unversioned_cask_checker.rb index 679782d6a7..1fef545e0c 100644 --- a/Library/Homebrew/unversioned_cask_checker.rb +++ b/Library/Homebrew/unversioned_cask_checker.rb @@ -46,6 +46,20 @@ module Homebrew pkgs.count == 1 end + # Filter paths to `Info.plist` files so that ones belonging + # to e.g. nested `.app`s are ignored. + sig { params(paths: T::Array[Pathname]).returns(T::Array[Pathname]) } + def top_level_info_plists(paths) + # Go from `./Contents/Info.plist` to `./`. + top_level_paths = paths.map { |path| path.parent.parent } + + paths.reject do |path| + top_level_paths.any? do |_other_top_level_path| + path.ascend.drop(3).any? { |parent_path| top_level_paths.include?(parent_path) } + end + end + end + sig { returns(T.nilable(String)) } def guess_cask_version if apps.empty? && pkgs.empty? @@ -64,15 +78,12 @@ module Homebrew end info_plist_paths = apps.flat_map do |app| - Pathname.glob(dir/"**"/app.source.basename/"Contents"/"Info.plist").reject do |info_plist_path| - # Ignore nested apps. - info_plist_path.parent.parent.parent.ascend.any? { |p| p.extname == ".app" } - end.sort + top_level_info_plists(Pathname.glob(dir/"**"/app.source.basename/"Contents"/"Info.plist")).sort end info_plist_paths.each do |info_plist_path| - if (version = BundleVersion.from_info_plist(info_plist_path)&.nice_version) - return version + if (version = BundleVersion.from_info_plist(info_plist_path)) + return version.nice_version end end @@ -85,7 +96,6 @@ module Homebrew system_command!("installer", args: ["-plist", "-pkginfo", "-pkg", pkg_path]) .plist .map { |package| package.fetch("Package") } - .uniq Dir.mktmpdir do |extract_dir| extract_dir = Pathname(extract_dir) @@ -98,16 +108,34 @@ module Homebrew next end + top_level_info_plist_paths = top_level_info_plists(Pathname.glob(extract_dir/"**/Contents/Info.plist")) + + unique_info_plist_versions = + top_level_info_plist_paths.map { |i| BundleVersion.from_info_plist(i)&.nice_version } + .compact.uniq + return unique_info_plist_versions.first if unique_info_plist_versions.count == 1 + package_info_path = extract_dir/"PackageInfo" if package_info_path.exist? - if (version = BundleVersion.from_package_info(package_info_path)&.nice_version) - return version + if (version = BundleVersion.from_package_info(package_info_path)) + return version.nice_version end elsif packages.count == 1 onoe "#{pkg_path.basename} does not contain a `PackageInfo` file." end - opoo "#{pkg_path.basename} contains multiple packages: (#{packages.join(", ")})" if packages.count != 1 + distribution_path = extract_dir/"Distribution" + if distribution_path.exist? + Homebrew.install_bundler_gems! + require "nokogiri" + + xml = Nokogiri::XML(distribution_path.read) + + product_version = xml.xpath("//installer-gui-script//product").first&.attr("version") + return product_version if product_version + end + + opoo "#{pkg_path.basename} contains multiple packages: #{packages}" if packages.count != 1 $stderr.puts Pathname.glob(extract_dir/"**/*") .map { |path|