diff --git a/Library/Homebrew/cask/artifact/moved.rb b/Library/Homebrew/cask/artifact/moved.rb index 9a25a4c689713..3709c84615fea 100644 --- a/Library/Homebrew/cask/artifact/moved.rb +++ b/Library/Homebrew/cask/artifact/moved.rb @@ -52,12 +52,34 @@ def move(adopt: false, force: false, verbose: false, predecessor: nil, reinstall else if adopt ohai "Adopting existing #{self.class.english_name} at '#{target}'" - same = command.run( - "/usr/bin/diff", - args: ["--recursive", "--brief", source, target], - verbose:, - print_stdout: verbose, - ).success? + + source_plist = Pathname("#{source}/Contents/Info.plist") + target_plist = Pathname("#{target}/Contents/Info.plist") + same = if source_plist.size? && + (source_bundle_version = Homebrew::BundleVersion.from_info_plist(source_plist)) && + target_plist.size? && + (target_bundle_version = Homebrew::BundleVersion.from_info_plist(target_plist)) + if source_bundle_version.short_version == target_bundle_version.short_version + if source_bundle_version.version == target_bundle_version.version + true + else + onoe "The bundle version of #{source} is #{source_bundle_version.version} but " \ + "is #{target_bundle_version.version} for #{target}!" + false + end + else + onoe "The bundle short version of #{source} is #{source_bundle_version.short_version} but " \ + "is #{target_bundle_version.short_version} for #{target}!" + false + end + else + command.run( + "/usr/bin/diff", + args: ["--recursive", "--brief", source, target], + verbose:, + print_stdout: verbose, + ).success? + end unless same raise CaskError, @@ -73,7 +95,7 @@ def move(adopt: false, force: false, verbose: false, predecessor: nil, reinstall message = "It seems there is already #{self.class.english_article} " \ "#{self.class.english_name} at '#{target}'" - raise CaskError, "#{message}." unless force + raise CaskError, "#{message}." if !force && !adopt opoo "#{message}; overwriting." delete(target, force:, command:, **options) @@ -120,13 +142,13 @@ def matching_artifact?(cask) end end - def move_back(skip: false, force: false, command: nil, **options) + def move_back(skip: false, force: false, adopt: false, command: nil, **options) FileUtils.rm source if source.symlink? && source.dirname.join(source.readlink) == target if Utils.path_occupied?(source) message = "It seems there is already #{self.class.english_article} " \ "#{self.class.english_name} at '#{source}'" - raise CaskError, "#{message}." unless force + raise CaskError, "#{message}." if !force && !adopt opoo "#{message}; overwriting." delete(source, force:, command:, **options) diff --git a/Library/Homebrew/cask/artifact/symlinked.rb b/Library/Homebrew/cask/artifact/symlinked.rb index 7cb41bd84160a..1f5199d887622 100644 --- a/Library/Homebrew/cask/artifact/symlinked.rb +++ b/Library/Homebrew/cask/artifact/symlinked.rb @@ -43,7 +43,7 @@ def summarize_installed private - def link(force: false, command: nil, **_options) + def link(force: false, adopt: false, command: nil, **_options) unless source.exist? raise CaskError, "It seems the #{self.class.link_type_english_name.downcase} " \ @@ -54,7 +54,7 @@ def link(force: false, command: nil, **_options) message = "It seems there is already #{self.class.english_article} " \ "#{self.class.english_name} at '#{target}'" - if force && target.symlink? && + if (force || adopt) && target.symlink? && (target.realpath == source.realpath || target.realpath.to_s.start_with?("#{cask.caskroom_path}/")) opoo "#{message}; overwriting." Utils.gain_permissions_remove(target, command:)