Merge pull request #15176 from reitermarkus/cask-renames
Implement cask renames.
This commit is contained in:
		
						commit
						3dabf504bd
					
				@ -46,8 +46,15 @@ module Homebrew
 | 
			
		||||
          json_casks, updated = Homebrew::API.fetch_json_api_file "cask.jws.json",
 | 
			
		||||
                                                                  target: HOMEBREW_CACHE_API/"cask.jws.json"
 | 
			
		||||
 | 
			
		||||
          cache["renames"] = {}
 | 
			
		||||
          cache["casks"] = json_casks.to_h do |json_cask|
 | 
			
		||||
            [json_cask["token"], json_cask.except("token")]
 | 
			
		||||
            token = json_cask.delete("token")
 | 
			
		||||
 | 
			
		||||
            json_cask.fetch("old_tokens", []).each do |old_token|
 | 
			
		||||
              cache["renames"][old_token] = token
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
            [token, json_cask]
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          updated
 | 
			
		||||
@ -61,7 +68,17 @@ module Homebrew
 | 
			
		||||
            write_names(regenerate: json_updated)
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          cache["casks"]
 | 
			
		||||
          cache.fetch("casks")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        sig { returns(T::Hash[String, String]) }
 | 
			
		||||
        def all_renames
 | 
			
		||||
          unless cache.key?("renames")
 | 
			
		||||
            json_updated = download_and_cache_data!
 | 
			
		||||
            write_names(regenerate: json_updated)
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          cache.fetch("renames")
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        sig { params(regenerate: T::Boolean).void }
 | 
			
		||||
 | 
			
		||||
@ -80,7 +80,7 @@ module Homebrew
 | 
			
		||||
          cache["aliases"]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        sig { returns(Hash) }
 | 
			
		||||
        sig { returns(T::Hash[String, String]) }
 | 
			
		||||
        def all_renames
 | 
			
		||||
          unless cache.key?("renames")
 | 
			
		||||
            json_updated = download_and_cache_data!
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ require "cask/dsl"
 | 
			
		||||
require "cask/installer"
 | 
			
		||||
require "cask/macos"
 | 
			
		||||
require "cask/metadata"
 | 
			
		||||
require "cask/migrator"
 | 
			
		||||
require "cask/pkg"
 | 
			
		||||
require "cask/quarantine"
 | 
			
		||||
require "cask/staged"
 | 
			
		||||
 | 
			
		||||
@ -78,6 +78,17 @@ module Cask
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # An old name for the cask.
 | 
			
		||||
    sig { returns(T::Array[String]) }
 | 
			
		||||
    def old_tokens
 | 
			
		||||
      @old_tokens ||= if tap
 | 
			
		||||
        tap.cask_renames
 | 
			
		||||
           .flat_map { |old_token, new_token| (new_token == token) ? old_token : [] }
 | 
			
		||||
      else
 | 
			
		||||
        []
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def config=(config)
 | 
			
		||||
      @config = config
 | 
			
		||||
 | 
			
		||||
@ -96,22 +107,18 @@ module Cask
 | 
			
		||||
      define_method(method_name) { |&block| @dsl.send(method_name, &block) }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { returns(T::Array[[String, String]]) }
 | 
			
		||||
    def timestamped_versions
 | 
			
		||||
      relative_paths = Pathname.glob(metadata_timestamped_path(version: "*", timestamp: "*"))
 | 
			
		||||
    sig { params(caskroom_path: Pathname).returns(T::Array[[String, String]]) }
 | 
			
		||||
    def timestamped_versions(caskroom_path: self.caskroom_path)
 | 
			
		||||
      relative_paths = Pathname.glob(metadata_timestamped_path(
 | 
			
		||||
                                       version: "*", timestamp: "*",
 | 
			
		||||
                                       caskroom_path: caskroom_path
 | 
			
		||||
                                     ))
 | 
			
		||||
                               .map { |p| p.relative_path_from(p.parent.parent) }
 | 
			
		||||
      # Sorbet is unaware that Pathname is sortable: https://github.com/sorbet/sorbet/issues/6844
 | 
			
		||||
      T.unsafe(relative_paths).sort_by(&:basename) # sort by timestamp
 | 
			
		||||
       .map { |p| p.split.map(&:to_s) }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def versions
 | 
			
		||||
      timestamped_versions.map(&:first)
 | 
			
		||||
                          .reverse
 | 
			
		||||
                          .uniq
 | 
			
		||||
                          .reverse
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def full_name
 | 
			
		||||
      return token if tap.nil?
 | 
			
		||||
      return token if tap.user == "Homebrew"
 | 
			
		||||
@ -119,8 +126,9 @@ module Cask
 | 
			
		||||
      "#{tap.name}/#{token}"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { returns(T::Boolean) }
 | 
			
		||||
    def installed?
 | 
			
		||||
      !versions.empty?
 | 
			
		||||
      installed_caskfile&.exist? || false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # The caskfile is needed during installation when there are
 | 
			
		||||
@ -131,18 +139,41 @@ module Cask
 | 
			
		||||
 | 
			
		||||
    sig { returns(T.nilable(Time)) }
 | 
			
		||||
    def install_time
 | 
			
		||||
      _, time = timestamped_versions.last
 | 
			
		||||
      return unless time
 | 
			
		||||
 | 
			
		||||
      Time.strptime(time, Metadata::TIMESTAMP_FORMAT)
 | 
			
		||||
      # <caskroom_path>/.metadata/<version>/<timestamp>/Casks/<token>.{rb,json} -> <timestamp>
 | 
			
		||||
      time = installed_caskfile&.dirname&.dirname&.basename&.to_s
 | 
			
		||||
      Time.strptime(time, Metadata::TIMESTAMP_FORMAT) if time
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { returns(T.nilable(Pathname)) }
 | 
			
		||||
    def installed_caskfile
 | 
			
		||||
      installed_version = timestamped_versions.last
 | 
			
		||||
      caskfile_dir = metadata_main_container_path.join(*installed_version, "Casks")
 | 
			
		||||
      return caskfile_dir.join("#{token}.json") if caskfile_dir.join("#{token}.json").exist?
 | 
			
		||||
      installed_caskroom_path = caskroom_path
 | 
			
		||||
      installed_token = token
 | 
			
		||||
 | 
			
		||||
      caskfile_dir.join("#{token}.rb")
 | 
			
		||||
      # Check if the cask is installed with an old name.
 | 
			
		||||
      old_tokens.each do |old_token|
 | 
			
		||||
        old_caskroom_path = Caskroom.path/old_token
 | 
			
		||||
        next if !old_caskroom_path.directory? || old_caskroom_path.symlink?
 | 
			
		||||
 | 
			
		||||
        installed_caskroom_path = old_caskroom_path
 | 
			
		||||
        installed_token = old_token
 | 
			
		||||
        break
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      installed_version = timestamped_versions(caskroom_path: installed_caskroom_path).last
 | 
			
		||||
      return unless installed_version
 | 
			
		||||
 | 
			
		||||
      caskfile_dir = metadata_main_container_path(caskroom_path: installed_caskroom_path)
 | 
			
		||||
                     .join(*installed_version, "Casks")
 | 
			
		||||
 | 
			
		||||
      ["json", "rb"]
 | 
			
		||||
        .map { |ext| caskfile_dir.join("#{installed_token}.#{ext}") }
 | 
			
		||||
        .find(&:exist?)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { returns(T.nilable(String)) }
 | 
			
		||||
    def installed_version
 | 
			
		||||
      # <caskroom_path>/.metadata/<version>/<timestamp>/Casks/<token>.{rb,json} -> <version>
 | 
			
		||||
      installed_caskfile&.dirname&.dirname&.dirname&.basename&.to_s
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def config_path
 | 
			
		||||
@ -173,6 +204,7 @@ module Cask
 | 
			
		||||
      current_download_sha.blank? || current_download_sha != new_download_sha
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { returns(Pathname) }
 | 
			
		||||
    def caskroom_path
 | 
			
		||||
      @caskroom_path ||= Caskroom.path.join(token)
 | 
			
		||||
    end
 | 
			
		||||
@ -182,26 +214,23 @@ module Cask
 | 
			
		||||
                         greedy_auto_updates: greedy_auto_updates).empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # TODO: Rename to `outdated_version` and only return one version.
 | 
			
		||||
    def outdated_versions(greedy: false, greedy_latest: false, greedy_auto_updates: false)
 | 
			
		||||
      # special case: tap version is not available
 | 
			
		||||
      return [] if version.nil?
 | 
			
		||||
 | 
			
		||||
      if version.latest?
 | 
			
		||||
        return versions if (greedy || greedy_latest) && outdated_download_sha?
 | 
			
		||||
        return [installed_version] if (greedy || greedy_latest) && outdated_download_sha?
 | 
			
		||||
 | 
			
		||||
        return []
 | 
			
		||||
      elsif auto_updates && !greedy && !greedy_auto_updates
 | 
			
		||||
        return []
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      installed = versions
 | 
			
		||||
      current   = installed.last
 | 
			
		||||
 | 
			
		||||
      # not outdated unless there is a different version on tap
 | 
			
		||||
      return [] if current == version
 | 
			
		||||
      return [] if installed_version == version
 | 
			
		||||
 | 
			
		||||
      # collect all installed versions that are different than tap version and return them
 | 
			
		||||
      installed.reject { |v| v == version }
 | 
			
		||||
      [installed_version]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def outdated_info(greedy, verbose, json, greedy_latest, greedy_auto_updates)
 | 
			
		||||
@ -279,6 +308,7 @@ module Cask
 | 
			
		||||
      {
 | 
			
		||||
        "token"                => token,
 | 
			
		||||
        "full_token"           => full_name,
 | 
			
		||||
        "old_tokens"           => old_tokens,
 | 
			
		||||
        "tap"                  => tap&.name,
 | 
			
		||||
        "name"                 => name,
 | 
			
		||||
        "desc"                 => desc,
 | 
			
		||||
@ -287,7 +317,7 @@ module Cask
 | 
			
		||||
        "url_specs"            => url_specs,
 | 
			
		||||
        "appcast"              => appcast,
 | 
			
		||||
        "version"              => version,
 | 
			
		||||
        "installed"            => versions.last,
 | 
			
		||||
        "installed"            => installed_version,
 | 
			
		||||
        "outdated"             => outdated?,
 | 
			
		||||
        "sha256"               => sha256,
 | 
			
		||||
        "artifacts"            => artifacts_list,
 | 
			
		||||
@ -349,7 +379,7 @@ module Cask
 | 
			
		||||
 | 
			
		||||
    def api_to_local_hash(hash)
 | 
			
		||||
      hash["token"] = token
 | 
			
		||||
      hash["installed"] = versions.last
 | 
			
		||||
      hash["installed"] = installed_version
 | 
			
		||||
      hash["outdated"] = outdated?
 | 
			
		||||
      hash
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -401,11 +401,11 @@ module Cask
 | 
			
		||||
      self.for(ref, need_path: true).path
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.load(ref, config: nil)
 | 
			
		||||
      self.for(ref).load(config: config)
 | 
			
		||||
    def self.load(ref, config: nil, warn: true)
 | 
			
		||||
      self.for(ref, warn: warn).load(config: config)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.for(ref, need_path: false)
 | 
			
		||||
    def self.for(ref, need_path: false, warn: true)
 | 
			
		||||
      [
 | 
			
		||||
        FromInstanceLoader,
 | 
			
		||||
        FromContentLoader,
 | 
			
		||||
@ -422,7 +422,7 @@ module Cask
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      case (possible_tap_casks = tap_paths(ref)).count
 | 
			
		||||
      case (possible_tap_casks = tap_paths(ref, warn: warn)).count
 | 
			
		||||
      when 1
 | 
			
		||||
        return FromTapPathLoader.new(possible_tap_casks.first)
 | 
			
		||||
      when 2..Float::INFINITY
 | 
			
		||||
@ -441,9 +441,13 @@ module Cask
 | 
			
		||||
      Tap.default_cask_tap.cask_dir/"#{token.to_s.downcase}.rb"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.tap_paths(token)
 | 
			
		||||
    def self.tap_paths(token, warn: true)
 | 
			
		||||
      token = token.to_s.downcase
 | 
			
		||||
 | 
			
		||||
      Tap.map do |tap|
 | 
			
		||||
        find_cask_in_tap(token.to_s.downcase, tap)
 | 
			
		||||
        new_token = tap.cask_renames[token]
 | 
			
		||||
        opoo "Cask #{token} was renamed to #{new_token}." if new_token && warn
 | 
			
		||||
        find_cask_in_tap(new_token || token, tap)
 | 
			
		||||
      end.select(&:exist?)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,11 +13,18 @@ module Cask
 | 
			
		||||
      @path ||= HOMEBREW_PREFIX/"Caskroom"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Return all paths for installed casks.
 | 
			
		||||
    sig { returns(T::Array[Pathname]) }
 | 
			
		||||
    def self.paths
 | 
			
		||||
      return [] unless path.exist?
 | 
			
		||||
 | 
			
		||||
      path.children.select { |p| p.directory? && !p.symlink? }
 | 
			
		||||
    end
 | 
			
		||||
    private_class_method :paths
 | 
			
		||||
 | 
			
		||||
    sig { returns(T::Boolean) }
 | 
			
		||||
    def self.any_casks_installed?
 | 
			
		||||
      return false unless path.exist?
 | 
			
		||||
 | 
			
		||||
      path.children.select(&:directory?).any?
 | 
			
		||||
      paths.any?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { void }
 | 
			
		||||
@ -39,9 +46,7 @@ module Cask
 | 
			
		||||
 | 
			
		||||
    sig { params(config: T.nilable(Config)).returns(T::Array[Cask]) }
 | 
			
		||||
    def self.casks(config: nil)
 | 
			
		||||
      return [] unless path.exist?
 | 
			
		||||
 | 
			
		||||
      path.children.select(&:directory?).sort.map do |path|
 | 
			
		||||
      paths.sort.map do |path|
 | 
			
		||||
        token = path.basename.to_s
 | 
			
		||||
 | 
			
		||||
        begin
 | 
			
		||||
 | 
			
		||||
@ -39,17 +39,14 @@ module Cask
 | 
			
		||||
    def self.installation_info(cask)
 | 
			
		||||
      return "Not installed\n" unless cask.installed?
 | 
			
		||||
 | 
			
		||||
      install_info = +""
 | 
			
		||||
      cask.versions.each do |version|
 | 
			
		||||
        versioned_staged_path = cask.caskroom_path.join(version)
 | 
			
		||||
      versioned_staged_path = cask.caskroom_path.join(cask.installed_version)
 | 
			
		||||
      path_details = if versioned_staged_path.exist?
 | 
			
		||||
        versioned_staged_path.abv
 | 
			
		||||
      else
 | 
			
		||||
        Formatter.error("does not exist")
 | 
			
		||||
      end
 | 
			
		||||
        install_info << "#{versioned_staged_path} (#{path_details})\n"
 | 
			
		||||
      end
 | 
			
		||||
      install_info.freeze
 | 
			
		||||
 | 
			
		||||
      "#{versioned_staged_path} (#{path_details})\n"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.name_info(cask)
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ require "utils/topological_hash"
 | 
			
		||||
 | 
			
		||||
require "cask/config"
 | 
			
		||||
require "cask/download"
 | 
			
		||||
require "cask/migrator"
 | 
			
		||||
require "cask/quarantine"
 | 
			
		||||
 | 
			
		||||
require "cgi"
 | 
			
		||||
@ -87,6 +88,8 @@ module Cask
 | 
			
		||||
      start_time = Time.now
 | 
			
		||||
      odebug "Cask::Installer#install"
 | 
			
		||||
 | 
			
		||||
      Migrator.migrate_if_needed(@cask)
 | 
			
		||||
 | 
			
		||||
      old_config = @cask.config
 | 
			
		||||
      if @cask.installed? && !force? && !reinstall? && !upgrade?
 | 
			
		||||
        return if quiet?
 | 
			
		||||
@ -228,8 +231,9 @@ on_request: true)
 | 
			
		||||
 | 
			
		||||
        next if artifact.is_a?(Artifact::Binary) && !binaries?
 | 
			
		||||
 | 
			
		||||
        artifact.install_phase(command: @command, verbose: verbose?, adopt: adopt?, force: force?,
 | 
			
		||||
                               predecessor: predecessor)
 | 
			
		||||
        artifact.install_phase(
 | 
			
		||||
          command: @command, verbose: verbose?, adopt: adopt?, force: force?, predecessor: predecessor,
 | 
			
		||||
        )
 | 
			
		||||
        already_installed_artifacts.unshift(artifact)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
@ -383,7 +387,6 @@ on_request: true)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def save_config_file
 | 
			
		||||
      metadata_subdir
 | 
			
		||||
      @cask.config_path.atomic_write(@cask.config.to_json)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -410,7 +413,8 @@ on_request: true)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def remove_download_sha
 | 
			
		||||
      FileUtils.rm_f @cask.download_sha_path if @cask.download_sha_path.exist?
 | 
			
		||||
      FileUtils.rm_f @cask.download_sha_path
 | 
			
		||||
      @cask.download_sha_path.parent.rmdir_if_possible
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(successor: T.nilable(Cask)).void }
 | 
			
		||||
@ -427,8 +431,8 @@ on_request: true)
 | 
			
		||||
    def restore_backup
 | 
			
		||||
      return if !backup_path.directory? || !backup_metadata_path.directory?
 | 
			
		||||
 | 
			
		||||
      Pathname.new(@cask.staged_path).rmtree if @cask.staged_path.exist?
 | 
			
		||||
      Pathname.new(@cask.metadata_versioned_path).rmtree if @cask.metadata_versioned_path.exist?
 | 
			
		||||
      @cask.staged_path.rmtree if @cask.staged_path.exist?
 | 
			
		||||
      @cask.metadata_versioned_path.rmtree if @cask.metadata_versioned_path.exist?
 | 
			
		||||
 | 
			
		||||
      backup_path.rename @cask.staged_path
 | 
			
		||||
      backup_metadata_path.rename @cask.metadata_versioned_path
 | 
			
		||||
@ -544,6 +548,12 @@ on_request: true)
 | 
			
		||||
 | 
			
		||||
      # toplevel staged distribution
 | 
			
		||||
      @cask.caskroom_path.rmdir_if_possible unless upgrade?
 | 
			
		||||
 | 
			
		||||
      # Remove symlinks for renamed casks if they are now broken.
 | 
			
		||||
      @cask.old_tokens.each do |old_token|
 | 
			
		||||
        old_caskroom_path = Caskroom.path/old_token
 | 
			
		||||
        FileUtils.rm old_caskroom_path if old_caskroom_path.symlink? && !old_caskroom_path.exist?
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def purge_caskroom_path
 | 
			
		||||
@ -555,9 +565,11 @@ on_request: true)
 | 
			
		||||
 | 
			
		||||
    # load the same cask file that was used for installation, if possible
 | 
			
		||||
    def load_installed_caskfile!
 | 
			
		||||
      Migrator.migrate_if_needed(@cask)
 | 
			
		||||
 | 
			
		||||
      installed_caskfile = @cask.installed_caskfile
 | 
			
		||||
 | 
			
		||||
      if installed_caskfile.exist?
 | 
			
		||||
      if installed_caskfile&.exist?
 | 
			
		||||
        begin
 | 
			
		||||
          @cask = CaskLoader.load(installed_caskfile)
 | 
			
		||||
          return
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ module Cask
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def self.format_versioned(cask)
 | 
			
		||||
      cask.to_s.concat(cask.versions.map(&:to_s).join(" ").prepend(" "))
 | 
			
		||||
      "#{cask}#{cask.installed_version&.prepend(" ")}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -9,26 +9,27 @@ module Cask
 | 
			
		||||
    METADATA_SUBDIR = ".metadata"
 | 
			
		||||
    TIMESTAMP_FORMAT = "%Y%m%d%H%M%S.%L"
 | 
			
		||||
 | 
			
		||||
    def metadata_main_container_path
 | 
			
		||||
      @metadata_main_container_path ||= caskroom_path.join(METADATA_SUBDIR)
 | 
			
		||||
    def metadata_main_container_path(caskroom_path: self.caskroom_path)
 | 
			
		||||
      caskroom_path.join(METADATA_SUBDIR)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def metadata_versioned_path(version: self.version)
 | 
			
		||||
    def metadata_versioned_path(version: self.version, caskroom_path: self.caskroom_path)
 | 
			
		||||
      cask_version = (version || :unknown).to_s
 | 
			
		||||
 | 
			
		||||
      raise CaskError, "Cannot create metadata path with empty version." if cask_version.empty?
 | 
			
		||||
 | 
			
		||||
      metadata_main_container_path.join(cask_version)
 | 
			
		||||
      metadata_main_container_path(caskroom_path: caskroom_path).join(cask_version)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def metadata_timestamped_path(version: self.version, timestamp: :latest, create: false)
 | 
			
		||||
    def metadata_timestamped_path(version: self.version, timestamp: :latest, create: false,
 | 
			
		||||
                                  caskroom_path: self.caskroom_path)
 | 
			
		||||
      raise CaskError, "Cannot create metadata path when timestamp is :latest." if create && timestamp == :latest
 | 
			
		||||
 | 
			
		||||
      path = if timestamp == :latest
 | 
			
		||||
        Pathname.glob(metadata_versioned_path(version: version).join("*")).max
 | 
			
		||||
        Pathname.glob(metadata_versioned_path(version: version, caskroom_path: caskroom_path).join("*")).max
 | 
			
		||||
      else
 | 
			
		||||
        timestamp = new_timestamp if timestamp == :now
 | 
			
		||||
        metadata_versioned_path(version: version).join(timestamp)
 | 
			
		||||
        metadata_versioned_path(version: version, caskroom_path: caskroom_path).join(timestamp)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if create && !path.directory?
 | 
			
		||||
@ -39,11 +40,13 @@ module Cask
 | 
			
		||||
      path
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def metadata_subdir(leaf, version: self.version, timestamp: :latest, create: false)
 | 
			
		||||
    def metadata_subdir(leaf, version: self.version, timestamp: :latest, create: false,
 | 
			
		||||
                        caskroom_path: self.caskroom_path)
 | 
			
		||||
      raise CaskError, "Cannot create metadata subdir when timestamp is :latest." if create && timestamp == :latest
 | 
			
		||||
      raise CaskError, "Cannot create metadata subdir for empty leaf." if !leaf.respond_to?(:empty?) || leaf.empty?
 | 
			
		||||
 | 
			
		||||
      parent = metadata_timestamped_path(version: version, timestamp: timestamp, create: create)
 | 
			
		||||
      parent = metadata_timestamped_path(version: version, timestamp: timestamp, create: create,
 | 
			
		||||
                                         caskroom_path: caskroom_path)
 | 
			
		||||
 | 
			
		||||
      return if parent.nil?
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										86
									
								
								Library/Homebrew/cask/migrator.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Library/Homebrew/cask/migrator.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,86 @@
 | 
			
		||||
# typed: true
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
require "cask/cask_loader"
 | 
			
		||||
require "utils/inreplace"
 | 
			
		||||
 | 
			
		||||
module Cask
 | 
			
		||||
  class Migrator
 | 
			
		||||
    extend ::Utils::Inreplace
 | 
			
		||||
 | 
			
		||||
    attr_reader :old_cask, :new_cask
 | 
			
		||||
 | 
			
		||||
    sig { params(old_cask: Cask, new_cask: Cask).void }
 | 
			
		||||
    def initialize(old_cask, new_cask)
 | 
			
		||||
      raise CaskNotInstalledError, new_cask unless new_cask.installed?
 | 
			
		||||
 | 
			
		||||
      @old_cask = old_cask
 | 
			
		||||
      @new_cask = new_cask
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(new_cask: Cask, dry_run: T::Boolean).void }
 | 
			
		||||
    def self.migrate_if_needed(new_cask, dry_run: false)
 | 
			
		||||
      old_tokens = new_cask.old_tokens
 | 
			
		||||
      return if old_tokens.empty?
 | 
			
		||||
 | 
			
		||||
      return unless (installed_caskfile = new_cask.installed_caskfile)
 | 
			
		||||
 | 
			
		||||
      installed_token = installed_caskfile.relative_path_from(Caskroom.path).basename.to_s
 | 
			
		||||
      return if new_cask.token == installed_token
 | 
			
		||||
 | 
			
		||||
      old_cask = CaskLoader.load(installed_caskfile)
 | 
			
		||||
      migrator = new(old_cask, new_cask)
 | 
			
		||||
      migrator.migrate(dry_run: dry_run)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(dry_run: T::Boolean).void }
 | 
			
		||||
    def migrate(dry_run: false)
 | 
			
		||||
      old_token = old_cask.token
 | 
			
		||||
      new_token = new_cask.token
 | 
			
		||||
 | 
			
		||||
      old_caskroom_path = old_cask.caskroom_path
 | 
			
		||||
      new_caskroom_path = new_cask.caskroom_path
 | 
			
		||||
 | 
			
		||||
      old_installed_caskfile = old_cask.installed_caskfile.relative_path_from(old_caskroom_path)
 | 
			
		||||
      new_installed_caskfile = old_installed_caskfile.dirname/old_installed_caskfile.basename.sub(
 | 
			
		||||
        old_token,
 | 
			
		||||
        new_token,
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      if dry_run
 | 
			
		||||
        oh1 "Would migrate cask #{Formatter.identifier(old_token)} to #{Formatter.identifier(new_token)}"
 | 
			
		||||
 | 
			
		||||
        puts "cp -r #{old_caskroom_path} #{new_caskroom_path}"
 | 
			
		||||
        puts "mv #{new_caskroom_path}/#{old_installed_caskfile} #{new_caskroom_path}/#{new_installed_caskfile}"
 | 
			
		||||
        puts "rm -r #{old_caskroom_path}"
 | 
			
		||||
        puts "ln -s #{new_caskroom_path.basename} #{old_caskroom_path}"
 | 
			
		||||
      else
 | 
			
		||||
        oh1 "Migrating cask #{Formatter.identifier(old_token)} to #{Formatter.identifier(new_token)}"
 | 
			
		||||
 | 
			
		||||
        begin
 | 
			
		||||
          FileUtils.cp_r old_caskroom_path, new_caskroom_path
 | 
			
		||||
          FileUtils.mv new_caskroom_path/old_installed_caskfile, new_caskroom_path/new_installed_caskfile
 | 
			
		||||
          self.class.replace_caskfile_token(new_caskroom_path/new_installed_caskfile, old_token, new_token)
 | 
			
		||||
        rescue => e
 | 
			
		||||
          FileUtils.rm_rf new_caskroom_path
 | 
			
		||||
          raise e
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        FileUtils.rm_r old_caskroom_path
 | 
			
		||||
        FileUtils.ln_s new_caskroom_path.basename, old_caskroom_path
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sig { params(path: Pathname, old_token: String, new_token: String).void }
 | 
			
		||||
    def self.replace_caskfile_token(path, old_token, new_token)
 | 
			
		||||
      case path.extname
 | 
			
		||||
      when ".rb"
 | 
			
		||||
        inreplace path, /\A\s*cask\s+"#{Regexp.escape(old_token)}"/, "cask #{new_token.inspect}"
 | 
			
		||||
      when ".json"
 | 
			
		||||
        json = JSON.parse(path.read)
 | 
			
		||||
        json["token"] = new_token
 | 
			
		||||
        path.atomic_write json.to_json
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -13,13 +13,6 @@ module Cask
 | 
			
		||||
        raise CaskNotInstalledError, cask if !cask.installed? && !force
 | 
			
		||||
 | 
			
		||||
        Installer.new(cask, binaries: binaries, force: force, verbose: verbose).uninstall
 | 
			
		||||
 | 
			
		||||
        next if (versions = cask.versions).empty?
 | 
			
		||||
 | 
			
		||||
        puts <<~EOS
 | 
			
		||||
          #{cask} #{versions.to_sentence} #{(versions.count == 1) ? "is" : "are"} still installed.
 | 
			
		||||
          Remove #{(versions.count == 1) ? "it" : "them all"} with `brew uninstall --cask --force #{cask}`.
 | 
			
		||||
        EOS
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -95,8 +95,7 @@ module Cask
 | 
			
		||||
      caught_exceptions = []
 | 
			
		||||
 | 
			
		||||
      upgradable_casks = outdated_casks.map do |c|
 | 
			
		||||
        if !c.installed_caskfile.exist? && c.tap.to_s == "homebrew/cask" &&
 | 
			
		||||
           Homebrew::API::Cask.all_casks.key?(c.token)
 | 
			
		||||
        if !c.installed? && c.tap.to_s == "homebrew/cask" && Homebrew::API::Cask.all_casks.key?(c.token)
 | 
			
		||||
          odie <<~EOS
 | 
			
		||||
            The cask '#{c.token}' was affected by a bug and cannot be upgraded as-is. To fix this, run:
 | 
			
		||||
              brew reinstall --cask --force #{c.token}
 | 
			
		||||
@ -204,7 +203,7 @@ module Cask
 | 
			
		||||
        new_cask_installer.install_artifacts(predecessor: old_cask)
 | 
			
		||||
        new_artifacts_installed = true
 | 
			
		||||
 | 
			
		||||
        # If successful, wipe the old cask from staging
 | 
			
		||||
        # If successful, wipe the old cask from staging.
 | 
			
		||||
        old_cask_installer.finalize_upgrade
 | 
			
		||||
      rescue => e
 | 
			
		||||
        new_cask_installer.uninstall_artifacts(successor: old_cask) if new_artifacts_installed
 | 
			
		||||
 | 
			
		||||
@ -155,7 +155,7 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
        return false if cask.blank?
 | 
			
		||||
        return true unless basename.to_s.match?(/\A#{Regexp.escape(name)}--#{Regexp.escape(cask.version)}\b/)
 | 
			
		||||
        return true if scrub && cask.versions.exclude?(cask.version)
 | 
			
		||||
        return true if scrub && cask.installed_version != cask.version
 | 
			
		||||
 | 
			
		||||
        if cask.version.latest?
 | 
			
		||||
          cleanup_threshold = (DateTime.now - CLEANUP_DEFAULT_DAYS).to_time
 | 
			
		||||
 | 
			
		||||
@ -47,12 +47,14 @@ module Homebrew
 | 
			
		||||
          ignore_unavailable: T.nilable(T::Boolean),
 | 
			
		||||
          method:             T.nilable(Symbol),
 | 
			
		||||
          uniq:               T::Boolean,
 | 
			
		||||
          warn:               T::Boolean,
 | 
			
		||||
        ).returns(T::Array[T.any(Formula, Keg, Cask::Cask)])
 | 
			
		||||
      }
 | 
			
		||||
      def to_formulae_and_casks(only: parent&.only_formula_or_cask, ignore_unavailable: nil, method: nil, uniq: true)
 | 
			
		||||
      def to_formulae_and_casks(only: parent&.only_formula_or_cask, ignore_unavailable: nil, method: nil, uniq: true,
 | 
			
		||||
                                warn: true)
 | 
			
		||||
        @to_formulae_and_casks ||= {}
 | 
			
		||||
        @to_formulae_and_casks[only] ||= downcased_unique_named.flat_map do |name|
 | 
			
		||||
          load_formula_or_cask(name, only: only, method: method)
 | 
			
		||||
          load_formula_or_cask(name, only: only, method: method, warn: warn)
 | 
			
		||||
        rescue FormulaUnreadableError, FormulaClassUnavailableError,
 | 
			
		||||
               TapFormulaUnreadableError, TapFormulaClassUnavailableError,
 | 
			
		||||
               Cask::CaskUnreadableError
 | 
			
		||||
@ -86,14 +88,14 @@ module Homebrew
 | 
			
		||||
        end.uniq.freeze
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def load_formula_or_cask(name, only: nil, method: nil)
 | 
			
		||||
      def load_formula_or_cask(name, only: nil, method: nil, warn: true)
 | 
			
		||||
        unreadable_error = nil
 | 
			
		||||
 | 
			
		||||
        if only != :cask
 | 
			
		||||
          begin
 | 
			
		||||
            formula = case method
 | 
			
		||||
            when nil, :factory
 | 
			
		||||
              Formulary.factory(name, *spec, force_bottle: @force_bottle, flags: @flags)
 | 
			
		||||
              Formulary.factory(name, *spec, force_bottle: @force_bottle, flags: @flags, warn: warn)
 | 
			
		||||
            when :resolve
 | 
			
		||||
              resolve_formula(name)
 | 
			
		||||
            when :latest_kegs
 | 
			
		||||
@ -124,7 +126,7 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
          begin
 | 
			
		||||
            config = Cask::Config.from_args(@parent) if @cask_options
 | 
			
		||||
            cask = Cask::CaskLoader.load(name, config: config)
 | 
			
		||||
            cask = Cask::CaskLoader.load(name, config: config, warn: warn)
 | 
			
		||||
 | 
			
		||||
            if unreadable_error.present?
 | 
			
		||||
              onoe <<~EOS
 | 
			
		||||
@ -145,7 +147,7 @@ module Homebrew
 | 
			
		||||
            # If we're trying to get a keg-like Cask, do our best to handle it
 | 
			
		||||
            # not being readable and return something that can be used.
 | 
			
		||||
            if want_keg_like_cask
 | 
			
		||||
              cask_version = Cask::Cask.new(name, config: config).versions.first
 | 
			
		||||
              cask_version = Cask::Cask.new(name, config: config).installed_version
 | 
			
		||||
              cask = Cask::Cask.new(name, config: config) do
 | 
			
		||||
                version cask_version if cask_version
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
@ -3,12 +3,11 @@
 | 
			
		||||
 | 
			
		||||
require "migrator"
 | 
			
		||||
require "cli/parser"
 | 
			
		||||
require "cask/migrator"
 | 
			
		||||
 | 
			
		||||
module Homebrew
 | 
			
		||||
  module_function
 | 
			
		||||
 | 
			
		||||
  sig { returns(CLI::Parser) }
 | 
			
		||||
  def migrate_args
 | 
			
		||||
  def self.migrate_args
 | 
			
		||||
    Homebrew::CLI::Parser.new do
 | 
			
		||||
      description <<~EOS
 | 
			
		||||
        Migrate renamed packages to new names, where <formula> are old names of
 | 
			
		||||
@ -19,17 +18,27 @@ module Homebrew
 | 
			
		||||
                          "the same taps and migrate them anyway."
 | 
			
		||||
      switch "-n", "--dry-run",
 | 
			
		||||
             description: "Show what would be migrated, but do not actually migrate anything."
 | 
			
		||||
      switch "--formula", "--formulae",
 | 
			
		||||
             description: "Only migrate formulae."
 | 
			
		||||
      switch "--cask", "--casks",
 | 
			
		||||
             description: "Only migrate casks."
 | 
			
		||||
 | 
			
		||||
      named_args :installed_formula, min: 1
 | 
			
		||||
      conflicts "--formula", "--cask"
 | 
			
		||||
 | 
			
		||||
      named_args [:installed_formula, :installed_cask], min: 1
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def migrate
 | 
			
		||||
  def self.migrate
 | 
			
		||||
    args = migrate_args.parse
 | 
			
		||||
 | 
			
		||||
    args.named.to_kegs.each do |keg|
 | 
			
		||||
      f = Formulary.from_keg(keg)
 | 
			
		||||
      Migrator.migrate_if_needed(f, force: args.force?, dry_run: args.dry_run?)
 | 
			
		||||
    args.named.to_formulae_and_casks(warn: false).each do |formula_or_cask|
 | 
			
		||||
      case formula_or_cask
 | 
			
		||||
      when Formula
 | 
			
		||||
        Migrator.migrate_if_needed(formula_or_cask, force: args.force?, dry_run: args.dry_run?)
 | 
			
		||||
      when Cask::Cask
 | 
			
		||||
        Cask::Migrator.migrate_if_needed(formula_or_cask, dry_run: args.dry_run?)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@
 | 
			
		||||
 | 
			
		||||
require "migrator"
 | 
			
		||||
require "formulary"
 | 
			
		||||
require "cask/cask_loader"
 | 
			
		||||
require "descriptions"
 | 
			
		||||
require "cleanup"
 | 
			
		||||
require "description_cache_store"
 | 
			
		||||
@ -246,6 +247,7 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
        hub.dump(auto_update: args.auto_update?) unless args.quiet?
 | 
			
		||||
        hub.reporters.each(&:migrate_tap_migration)
 | 
			
		||||
        hub.reporters.each(&:migrate_cask_rename)
 | 
			
		||||
        hub.reporters.each { |r| r.migrate_formula_rename(force: args.force?, verbose: args.verbose?) }
 | 
			
		||||
 | 
			
		||||
        CacheStoreDatabase.use(:descriptions) do |db|
 | 
			
		||||
@ -390,6 +392,14 @@ class Reporter
 | 
			
		||||
        when "M"
 | 
			
		||||
          # Report updated casks
 | 
			
		||||
          @report[:MC] << tap.formula_file_to_name(src)
 | 
			
		||||
        when /^R\d{0,3}/
 | 
			
		||||
          src_full_name = tap.formula_file_to_name(src)
 | 
			
		||||
          dst_full_name = tap.formula_file_to_name(dst)
 | 
			
		||||
          # Don't report formulae that are moved within a tap but not renamed
 | 
			
		||||
          next if src_full_name == dst_full_name
 | 
			
		||||
 | 
			
		||||
          @report[:DC] << src_full_name
 | 
			
		||||
          @report[:AC] << dst_full_name
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
@ -416,6 +426,41 @@ class Reporter
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    renamed_casks = Set.new
 | 
			
		||||
    @report[:DC].each do |old_full_name|
 | 
			
		||||
      old_name = old_full_name.split("/").last
 | 
			
		||||
      new_name = tap.cask_renames[old_name]
 | 
			
		||||
      next unless new_name
 | 
			
		||||
 | 
			
		||||
      new_full_name = if tap.name == "homebrew/cask"
 | 
			
		||||
        new_name
 | 
			
		||||
      else
 | 
			
		||||
        "#{tap}/#{new_name}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      renamed_casks << [old_full_name, new_full_name] if @report[:AC].include?(new_full_name)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @report[:AC].each do |new_full_name|
 | 
			
		||||
      new_name = new_full_name.split("/").last
 | 
			
		||||
      old_name = tap.cask_renames.key(new_name)
 | 
			
		||||
      next unless old_name
 | 
			
		||||
 | 
			
		||||
      old_full_name = if tap.name == "homebrew/cask"
 | 
			
		||||
        old_name
 | 
			
		||||
      else
 | 
			
		||||
        "#{tap}/#{old_name}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      renamed_casks << [old_full_name, new_full_name]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if renamed_casks.any?
 | 
			
		||||
      @report[:AC] -= renamed_casks.map(&:last)
 | 
			
		||||
      @report[:DC] -= renamed_casks.map(&:first)
 | 
			
		||||
      @report[:RC] = renamed_casks.to_a
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    renamed_formulae = Set.new
 | 
			
		||||
    @report[:D].each do |old_full_name|
 | 
			
		||||
      old_name = old_full_name.split("/").last
 | 
			
		||||
@ -445,7 +490,7 @@ class Reporter
 | 
			
		||||
      renamed_formulae << [old_full_name, new_full_name]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if renamed_formulae.present?
 | 
			
		||||
    if renamed_formulae.any?
 | 
			
		||||
      @report[:A] -= renamed_formulae.map(&:last)
 | 
			
		||||
      @report[:D] -= renamed_formulae.map(&:first)
 | 
			
		||||
      @report[:R] = renamed_formulae.to_a
 | 
			
		||||
@ -541,6 +586,12 @@ class Reporter
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def migrate_cask_rename
 | 
			
		||||
    Cask::Caskroom.casks.each do |cask|
 | 
			
		||||
      Cask::Migrator.migrate_if_needed(cask)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def migrate_formula_rename(force:, verbose:)
 | 
			
		||||
    Formula.installed.each do |formula|
 | 
			
		||||
      next unless Migrator.needs_migration?(formula)
 | 
			
		||||
@ -631,6 +682,7 @@ class ReporterHub
 | 
			
		||||
    dump_new_formula_report
 | 
			
		||||
    dump_new_cask_report
 | 
			
		||||
    dump_renamed_formula_report if report_all
 | 
			
		||||
    dump_renamed_cask_report if report_all
 | 
			
		||||
    dump_deleted_formula_report(report_all)
 | 
			
		||||
    dump_deleted_cask_report(report_all)
 | 
			
		||||
 | 
			
		||||
@ -723,6 +775,16 @@ class ReporterHub
 | 
			
		||||
    output_dump_formula_or_cask_report "Renamed Formulae", formulae
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def dump_renamed_cask_report
 | 
			
		||||
    casks = select_formula_or_cask(:RC).sort.map do |name, new_name|
 | 
			
		||||
      name = pretty_installed(name) if installed?(name)
 | 
			
		||||
      new_name = pretty_installed(new_name) if installed?(new_name)
 | 
			
		||||
      "#{name} -> #{new_name}"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    output_dump_formula_or_cask_report "Renamed Casks", casks
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def dump_deleted_formula_report(report_all)
 | 
			
		||||
    formulae = select_formula_or_cask(:D).sort.map do |name|
 | 
			
		||||
      if installed?(name)
 | 
			
		||||
 | 
			
		||||
@ -502,7 +502,8 @@ class Formula
 | 
			
		||||
  # Old names for the formula.
 | 
			
		||||
  def oldnames
 | 
			
		||||
    @oldnames ||= if tap
 | 
			
		||||
      tap.formula_renames.select { |_, oldname| oldname == name }.keys
 | 
			
		||||
      tap.formula_renames
 | 
			
		||||
         .flat_map { |old_name, new_name| (new_name == name) ? old_name : [] }
 | 
			
		||||
    else
 | 
			
		||||
      []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -523,8 +523,7 @@ module Formulary
 | 
			
		||||
 | 
			
		||||
  # Loads tapped formulae.
 | 
			
		||||
  class TapLoader < FormulaLoader
 | 
			
		||||
    def initialize(tapped_name, from: nil)
 | 
			
		||||
      warn = [:keg, :rack].exclude?(from)
 | 
			
		||||
    def initialize(tapped_name, from: nil, warn: true)
 | 
			
		||||
      name, path, tap = formula_name_path(tapped_name, warn: warn)
 | 
			
		||||
      super name, path, tap: tap
 | 
			
		||||
    end
 | 
			
		||||
@ -555,7 +554,7 @@ module Formulary
 | 
			
		||||
          new_name = new_tap.core_tap? ? name : new_tapped_name
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        opoo "Use #{new_name} instead of deprecated #{old_name}" if warn && old_name && new_name
 | 
			
		||||
        opoo "Formula #{old_name} was renamed to #{new_name}." if warn && old_name && new_name
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      [name, path, tap]
 | 
			
		||||
@ -649,7 +648,7 @@ module Formulary
 | 
			
		||||
  # * a formula URL
 | 
			
		||||
  # * a local bottle reference
 | 
			
		||||
  def self.factory(
 | 
			
		||||
    ref, spec = :stable, alias_path: nil, from: nil,
 | 
			
		||||
    ref, spec = :stable, alias_path: nil, from: nil, warn: true,
 | 
			
		||||
    force_bottle: false, flags: [], ignore_errors: false
 | 
			
		||||
  )
 | 
			
		||||
    raise ArgumentError, "Formulae must have a ref!" unless ref
 | 
			
		||||
@ -660,7 +659,7 @@ module Formulary
 | 
			
		||||
      return cache[:formulary_factory][cache_key]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    formula = loader_for(ref, from: from).get_formula(spec, alias_path: alias_path,
 | 
			
		||||
    formula = loader_for(ref, from: from, warn: warn).get_formula(spec, alias_path: alias_path,
 | 
			
		||||
                                                      force_bottle: force_bottle, flags: flags,
 | 
			
		||||
                                                      ignore_errors: ignore_errors)
 | 
			
		||||
    if factory_cached?
 | 
			
		||||
@ -683,7 +682,7 @@ module Formulary
 | 
			
		||||
    if keg
 | 
			
		||||
      from_keg(keg, spec, alias_path: alias_path, force_bottle: force_bottle, flags: flags)
 | 
			
		||||
    else
 | 
			
		||||
      factory(rack.basename.to_s, spec || :stable, alias_path: alias_path, from: :rack,
 | 
			
		||||
      factory(rack.basename.to_s, spec || :stable, alias_path: alias_path, from: :rack, warn: false,
 | 
			
		||||
              force_bottle: force_bottle, flags: flags)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
@ -704,15 +703,15 @@ module Formulary
 | 
			
		||||
    spec ||= tab.spec
 | 
			
		||||
 | 
			
		||||
    f = if tap.nil?
 | 
			
		||||
      factory(keg.rack.basename.to_s, spec, alias_path: alias_path, from: :keg,
 | 
			
		||||
      factory(keg.rack.basename.to_s, spec, alias_path: alias_path, from: :keg, warn: false,
 | 
			
		||||
              force_bottle: force_bottle, flags: flags)
 | 
			
		||||
    else
 | 
			
		||||
      begin
 | 
			
		||||
        factory("#{tap}/#{keg.rack.basename}", spec, alias_path: alias_path, from: :keg,
 | 
			
		||||
        factory("#{tap}/#{keg.rack.basename}", spec, alias_path: alias_path, from: :keg, warn: false,
 | 
			
		||||
                force_bottle: force_bottle, flags: flags)
 | 
			
		||||
      rescue FormulaUnavailableError
 | 
			
		||||
        # formula may be migrated to different tap. Try to search in core and all taps.
 | 
			
		||||
        factory(keg.rack.basename.to_s, spec, alias_path: alias_path, from: :keg,
 | 
			
		||||
        factory(keg.rack.basename.to_s, spec, alias_path: alias_path, from: :keg, warn: false,
 | 
			
		||||
                force_bottle: force_bottle, flags: flags)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
@ -757,7 +756,7 @@ module Formulary
 | 
			
		||||
    loader_for(ref).path
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.loader_for(ref, from: nil)
 | 
			
		||||
  def self.loader_for(ref, from: nil, warn: true)
 | 
			
		||||
    case ref
 | 
			
		||||
    when HOMEBREW_BOTTLES_EXTNAME_REGEX
 | 
			
		||||
      return BottleLoader.new(ref)
 | 
			
		||||
@ -770,7 +769,7 @@ module Formulary
 | 
			
		||||
        return AliasAPILoader.new(name) if Homebrew::API::Formula.all_aliases.key?(name)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      return TapLoader.new(ref, from: from)
 | 
			
		||||
      return TapLoader.new(ref, from: from, warn: warn)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    pathname_ref = Pathname.new(ref)
 | 
			
		||||
@ -800,7 +799,9 @@ module Formulary
 | 
			
		||||
      return FormulaLoader.new(name, path)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return TapLoader.new("#{CoreTap.instance}/#{ref}", from: from) if CoreTap.instance.formula_renames.key?(ref)
 | 
			
		||||
    if CoreTap.instance.formula_renames.key?(ref)
 | 
			
		||||
      return TapLoader.new("#{CoreTap.instance}/#{ref}", from: from, warn: warn)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    possible_taps = Tap.select { |tap| tap.formula_renames.key?(ref) }
 | 
			
		||||
 | 
			
		||||
@ -809,7 +810,7 @@ module Formulary
 | 
			
		||||
      raise TapFormulaWithOldnameAmbiguityError.new(ref, possible_tap_newname_formulae)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return TapLoader.new("#{possible_taps.first}/#{ref}", from: from) unless possible_taps.empty?
 | 
			
		||||
    return TapLoader.new("#{possible_taps.first}/#{ref}", from: from, warn: warn) unless possible_taps.empty?
 | 
			
		||||
 | 
			
		||||
    possible_keg_formula = Pathname.new("#{HOMEBREW_PREFIX}/opt/#{ref}/.brew/#{ref}.rb")
 | 
			
		||||
    return FormulaLoader.new(ref, possible_keg_formula) if possible_keg_formula.file?
 | 
			
		||||
 | 
			
		||||
@ -106,15 +106,14 @@ class Migrator
 | 
			
		||||
 | 
			
		||||
  def self.migrate_if_needed(formula, force:, dry_run: false)
 | 
			
		||||
    oldnames = Migrator.oldnames_needing_migration(formula)
 | 
			
		||||
    return if oldnames.empty?
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
      oldnames.each do |oldname|
 | 
			
		||||
        if dry_run
 | 
			
		||||
        ohai "Would migrate #{oldnames.to_sentence} to #{formula.name}"
 | 
			
		||||
        return
 | 
			
		||||
          oh1 "Would migrate formula #{Formatter.identifier(oldname)} to #{Formatter.identifier(formula.name)}"
 | 
			
		||||
          next
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
      oldnames.each do |oldname|
 | 
			
		||||
        migrator = Migrator.new(formula, oldname, force: force)
 | 
			
		||||
        migrator.migrate
 | 
			
		||||
      end
 | 
			
		||||
@ -205,7 +204,7 @@ class Migrator
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def migrate
 | 
			
		||||
    oh1 "Processing #{Formatter.identifier(oldname)} formula rename to #{Formatter.identifier(newname)}"
 | 
			
		||||
    oh1 "Migrating formula #{Formatter.identifier(oldname)} to #{Formatter.identifier(newname)}"
 | 
			
		||||
    lock
 | 
			
		||||
    unlink_oldname
 | 
			
		||||
    unlink_newname if new_cellar.exist?
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@ class Tap
 | 
			
		||||
 | 
			
		||||
  TAP_DIRECTORY = (HOMEBREW_LIBRARY/"Taps").freeze
 | 
			
		||||
 | 
			
		||||
  HOMEBREW_TAP_CASK_RENAMES_FILE = "cask_renames.json"
 | 
			
		||||
  HOMEBREW_TAP_FORMULA_RENAMES_FILE = "formula_renames.json"
 | 
			
		||||
  HOMEBREW_TAP_MIGRATIONS_FILE = "tap_migrations.json"
 | 
			
		||||
  HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR = "audit_exceptions"
 | 
			
		||||
@ -26,6 +27,7 @@ class Tap
 | 
			
		||||
 | 
			
		||||
  HOMEBREW_TAP_JSON_FILES = %W[
 | 
			
		||||
    #{HOMEBREW_TAP_FORMULA_RENAMES_FILE}
 | 
			
		||||
    #{HOMEBREW_TAP_CASK_RENAMES_FILE}
 | 
			
		||||
    #{HOMEBREW_TAP_MIGRATIONS_FILE}
 | 
			
		||||
    #{HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR}/*.json
 | 
			
		||||
    #{HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR}/*.json
 | 
			
		||||
@ -687,8 +689,20 @@ class Tap
 | 
			
		||||
    hash
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Hash with tap cask renames.
 | 
			
		||||
  sig { returns(T::Hash[String, String]) }
 | 
			
		||||
  def cask_renames
 | 
			
		||||
    @cask_renames ||= if name == "homebrew/cask" && !Homebrew::EnvConfig.no_install_from_api?
 | 
			
		||||
      Homebrew::API::Cask.all_renames
 | 
			
		||||
    elsif (rename_file = path/HOMEBREW_TAP_CASK_RENAMES_FILE).file?
 | 
			
		||||
      JSON.parse(rename_file.read)
 | 
			
		||||
    else
 | 
			
		||||
      {}
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Hash with tap formula renames.
 | 
			
		||||
  sig { returns(Hash) }
 | 
			
		||||
  sig { returns(T::Hash[String, String]) }
 | 
			
		||||
  def formula_renames
 | 
			
		||||
    @formula_renames ||= if (rename_file = path/HOMEBREW_TAP_FORMULA_RENAMES_FILE).file?
 | 
			
		||||
      JSON.parse(rename_file.read)
 | 
			
		||||
@ -931,7 +945,7 @@ class CoreTap < Tap
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # @private
 | 
			
		||||
  sig { returns(Hash) }
 | 
			
		||||
  sig { returns(T::Hash[String, String]) }
 | 
			
		||||
  def formula_renames
 | 
			
		||||
    @formula_renames ||= if Homebrew::EnvConfig.no_install_from_api?
 | 
			
		||||
      self.class.ensure_installed!
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ describe Cask::Cask, :cask do
 | 
			
		||||
  let(:cask) { described_class.new("versioned-cask") }
 | 
			
		||||
 | 
			
		||||
  context "when multiple versions are installed" do
 | 
			
		||||
    describe "#versions" do
 | 
			
		||||
    describe "#installed_version" do
 | 
			
		||||
      context "when there are duplicate versions" do
 | 
			
		||||
        it "uses the last unique version" do
 | 
			
		||||
          allow(cask).to receive(:timestamped_versions).and_return([
 | 
			
		||||
@ -13,11 +13,11 @@ describe Cask::Cask, :cask do
 | 
			
		||||
            ["1.2.2", "1001"],
 | 
			
		||||
          ])
 | 
			
		||||
 | 
			
		||||
          # Installed caskfile must exist to count as installed.
 | 
			
		||||
          allow_any_instance_of(Pathname).to receive(:exist?).and_return(true)
 | 
			
		||||
 | 
			
		||||
          expect(cask).to receive(:timestamped_versions)
 | 
			
		||||
          expect(cask.versions).to eq([
 | 
			
		||||
            "1.2.3",
 | 
			
		||||
            "1.2.2",
 | 
			
		||||
          ])
 | 
			
		||||
          expect(cask.installed_version).to eq("1.2.2")
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
@ -104,10 +104,10 @@ describe Cask::Cask, :cask do
 | 
			
		||||
      let(:cask) { described_class.new("basic-cask") }
 | 
			
		||||
 | 
			
		||||
      shared_examples "versioned casks" do |tap_version, expectations|
 | 
			
		||||
        expectations.each do |installed_versions, expected_output|
 | 
			
		||||
          context "when versions #{installed_versions.inspect} are installed and the tap version is #{tap_version}" do
 | 
			
		||||
        expectations.each do |installed_version, expected_output|
 | 
			
		||||
          context "when version #{installed_version.inspect} is installed and the tap version is #{tap_version}" do
 | 
			
		||||
            it {
 | 
			
		||||
              allow(cask).to receive(:versions).and_return(installed_versions)
 | 
			
		||||
              allow(cask).to receive(:installed_version).and_return(installed_version)
 | 
			
		||||
              allow(cask).to receive(:version).and_return(Cask::DSL::Version.new(tap_version))
 | 
			
		||||
              expect(cask).to receive(:outdated_versions).and_call_original
 | 
			
		||||
              expect(subject).to eq expected_output
 | 
			
		||||
@ -118,16 +118,13 @@ describe Cask::Cask, :cask do
 | 
			
		||||
 | 
			
		||||
      describe "installed version is equal to tap version => not outdated" do
 | 
			
		||||
        include_examples "versioned casks", "1.2.3",
 | 
			
		||||
                         ["1.2.3"]          => [],
 | 
			
		||||
                         ["1.2.4", "1.2.3"] => []
 | 
			
		||||
                         "1.2.3" => []
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      describe "installed version is different than tap version => outdated" do
 | 
			
		||||
        include_examples "versioned casks", "1.2.4",
 | 
			
		||||
                         ["1.2.3"]                   => ["1.2.3"],
 | 
			
		||||
                         ["1.2.4", "1.2.3"]          => ["1.2.3"],
 | 
			
		||||
                         ["1.2.2", "1.2.3"]          => ["1.2.2", "1.2.3"],
 | 
			
		||||
                         ["1.2.2", "1.2.4", "1.2.3"] => ["1.2.2", "1.2.3"]
 | 
			
		||||
                         "1.2.3" => ["1.2.3"],
 | 
			
		||||
                         "1.2.4" => []
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -142,7 +139,7 @@ describe Cask::Cask, :cask do
 | 
			
		||||
            subject { cask.outdated_versions(greedy: greedy) }
 | 
			
		||||
 | 
			
		||||
            it {
 | 
			
		||||
              allow(cask).to receive(:versions).and_return(installed_version)
 | 
			
		||||
              allow(cask).to receive(:installed_version).and_return(installed_version)
 | 
			
		||||
              allow(cask).to receive(:version).and_return(Cask::DSL::Version.new(tap_version))
 | 
			
		||||
              allow(cask).to receive(:outdated_download_sha?).and_return(outdated_sha)
 | 
			
		||||
              expect(cask).to receive(:outdated_versions).and_call_original
 | 
			
		||||
@ -154,29 +151,29 @@ describe Cask::Cask, :cask do
 | 
			
		||||
 | 
			
		||||
      describe ":latest version installed, :latest version in tap" do
 | 
			
		||||
        include_examples ":latest cask", false, false, "latest",
 | 
			
		||||
                         ["latest"] => []
 | 
			
		||||
                         "latest" => []
 | 
			
		||||
        include_examples ":latest cask", true, false, "latest",
 | 
			
		||||
                         ["latest"] => []
 | 
			
		||||
                         "latest" => []
 | 
			
		||||
        include_examples ":latest cask", true, true, "latest",
 | 
			
		||||
                         ["latest"] => ["latest"]
 | 
			
		||||
                         "latest" => ["latest"]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      describe "numbered version installed, :latest version in tap" do
 | 
			
		||||
        include_examples ":latest cask", false, false, "latest",
 | 
			
		||||
                         ["1.2.3"] => []
 | 
			
		||||
                         "1.2.3" => []
 | 
			
		||||
        include_examples ":latest cask", true, false, "latest",
 | 
			
		||||
                         ["1.2.3"] => []
 | 
			
		||||
                         "1.2.3" => []
 | 
			
		||||
        include_examples ":latest cask", true, true, "latest",
 | 
			
		||||
                         ["1.2.3"] => ["1.2.3"]
 | 
			
		||||
                         "1.2.3" => ["1.2.3"]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      describe "latest version installed, numbered version in tap" do
 | 
			
		||||
        include_examples ":latest cask", false, false, "1.2.3",
 | 
			
		||||
                         ["latest"] => ["latest"]
 | 
			
		||||
                         "latest" => ["latest"]
 | 
			
		||||
        include_examples ":latest cask", true, false, "1.2.3",
 | 
			
		||||
                         ["latest"] => ["latest"]
 | 
			
		||||
                         "latest" => ["latest"]
 | 
			
		||||
        include_examples ":latest cask", true, true, "1.2.3",
 | 
			
		||||
                         ["latest"] => ["latest"]
 | 
			
		||||
                         "latest" => ["latest"]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -313,7 +313,7 @@ describe Cask::Installer, :cask do
 | 
			
		||||
        caffeine = Cask::CaskLoader.load(path)
 | 
			
		||||
        expect(caffeine).to receive(:loaded_from_api?).twice.and_return(true)
 | 
			
		||||
        expect(caffeine).to receive(:caskfile_only?).twice.and_return(true)
 | 
			
		||||
        expect(caffeine).to receive(:installed_caskfile).once.and_return(invalid_path)
 | 
			
		||||
        expect(caffeine).to receive(:installed_caskfile).twice.and_return(invalid_path)
 | 
			
		||||
 | 
			
		||||
        described_class.new(caffeine).install
 | 
			
		||||
        expect(Cask::CaskLoader.load(path)).to be_installed
 | 
			
		||||
 | 
			
		||||
@ -112,14 +112,6 @@ describe Cask::Uninstall, :cask do
 | 
			
		||||
      expect(caskroom_path.join(first_installed_version)).not_to exist
 | 
			
		||||
      expect(caskroom_path).not_to exist
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "displays a message when versions remain installed" do
 | 
			
		||||
      expect do
 | 
			
		||||
        expect do
 | 
			
		||||
          described_class.uninstall_casks(Cask::Cask.new("versioned-cask"))
 | 
			
		||||
        end.not_to output.to_stderr
 | 
			
		||||
      end.to output(/#{token} #{first_installed_version} is still installed./).to_stdout
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "when Casks in Taps have been renamed or removed" do
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,12 @@
 | 
			
		||||
require "cask/upgrade"
 | 
			
		||||
 | 
			
		||||
describe Cask::Upgrade, :cask do
 | 
			
		||||
  let(:version_latest_path_second) { version_latest.config.appdir.join("Caffeine Pro.app") }
 | 
			
		||||
  let(:version_latest_path_first) { version_latest.config.appdir.join("Caffeine Mini.app") }
 | 
			
		||||
  let(:version_latest_paths) do
 | 
			
		||||
    [
 | 
			
		||||
      version_latest.config.appdir.join("Caffeine Mini.app"),
 | 
			
		||||
      version_latest.config.appdir.join("Caffeine Pro.app"),
 | 
			
		||||
    ]
 | 
			
		||||
  end
 | 
			
		||||
  let(:version_latest) { Cask::CaskLoader.load("version-latest") }
 | 
			
		||||
  let(:auto_updates_path) { auto_updates.config.appdir.join("MyFancyApp.app") }
 | 
			
		||||
  let(:auto_updates) { Cask::CaskLoader.load("auto-updates") }
 | 
			
		||||
@ -38,81 +42,81 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
      it "updates all the installed Casks when no token is provided" do
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(args: args)
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.3"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.61")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.61"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("2.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "2.0.0"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "updates only the Casks specified in the command line" do
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(local_caffeine, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.3"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'updates "auto_updates" and "latest" Casks when their tokens are provided in the command line' do
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(local_caffeine, auto_updates, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.3"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.61")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.61"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -120,24 +124,24 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
      it 'includes the Casks with "auto_updates true" or "version latest"' do
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_first).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
        expect(version_latest_paths).to all be_a_directory
 | 
			
		||||
        expect(version_latest.installed_version).to eq "latest"
 | 
			
		||||
        # Change download sha so that :latest cask decides to update itself
 | 
			
		||||
        version_latest.download_sha_path.write("fake download sha")
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(true)
 | 
			
		||||
@ -146,50 +150,49 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.3"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.61")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.61"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.61")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.61"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("2.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "2.0.0"
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_second).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
        expect(version_latest_paths).to all be_a_directory
 | 
			
		||||
        expect(version_latest.installed_version).to eq "latest"
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(false)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'does not include the Casks with "auto_updates true" or "version latest" when the version did not change' do
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(auto_updates, greedy: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.61")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.61"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(auto_updates, greedy: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.61")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.61"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'does not include the Casks with "version latest" when the version did not change' do
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_first).to be_a_directory
 | 
			
		||||
        expect(version_latest_path_second).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
        expect(version_latest_paths).to all be_a_directory
 | 
			
		||||
        expect(version_latest.installed_version).to eq "latest"
 | 
			
		||||
        # Change download sha so that :latest cask decides to update itself
 | 
			
		||||
        version_latest.download_sha_path.write("fake download sha")
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(true)
 | 
			
		||||
@ -197,17 +200,15 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
        described_class.upgrade_casks(version_latest, greedy: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_first).to be_a_directory
 | 
			
		||||
        expect(version_latest_path_second).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
        expect(version_latest_paths).to all be_a_directory
 | 
			
		||||
        expect(version_latest.installed_version).to eq "latest"
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(false)
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(version_latest, greedy: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_first).to be_a_directory
 | 
			
		||||
        expect(version_latest_path_second).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
        expect(version_latest_paths).to all be_a_directory
 | 
			
		||||
        expect(version_latest.installed_version).to eq "latest"
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(false)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
@ -236,34 +237,31 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(dry_run: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.versions).not_to include("2.61")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.versions).not_to include("2.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "would update only the Casks specified in the command line" do
 | 
			
		||||
@ -271,23 +269,21 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(local_caffeine, dry_run: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.versions).not_to include("2.61")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'would update "auto_updates" and "latest" Casks when their tokens are provided in the command line' do
 | 
			
		||||
@ -295,34 +291,31 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(local_caffeine, auto_updates, dry_run: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.versions).not_to include("2.61")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.versions).not_to include("2.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -332,20 +325,20 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        # Change download sha so that :latest cask decides to update itself
 | 
			
		||||
@ -356,24 +349,20 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
        expect(local_caffeine.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.versions).not_to include("2.61")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.versions).not_to include("2.61")
 | 
			
		||||
        expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
        expect(renamed_app).to be_installed
 | 
			
		||||
        expect(renamed_app_old_path).to be_a_directory
 | 
			
		||||
        expect(renamed_app_new_path).not_to be_a_directory
 | 
			
		||||
        expect(renamed_app.versions).to include("1.0.0")
 | 
			
		||||
        expect(renamed_app.versions).not_to include("2.0.0")
 | 
			
		||||
        expect(renamed_app.installed_version).to eq "1.0.0"
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(true)
 | 
			
		||||
@ -384,23 +373,21 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
 | 
			
		||||
        described_class.upgrade_casks(auto_updates, dry_run: true, greedy: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.versions).not_to include("2.61")
 | 
			
		||||
        expect(auto_updates.installed_version).to eq "2.57"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'would update outdated Casks with "version latest"' do
 | 
			
		||||
        expect(described_class).not_to receive(:upgrade_cask)
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_first).to be_a_directory
 | 
			
		||||
        expect(version_latest_path_second).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
        expect(version_latest_paths).to all be_a_directory
 | 
			
		||||
        expect(version_latest.installed_version).to eq "latest"
 | 
			
		||||
        # Change download sha so that :latest cask decides to update itself
 | 
			
		||||
        version_latest.download_sha_path.write("fake download sha")
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(true)
 | 
			
		||||
@ -408,9 +395,8 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
        described_class.upgrade_casks(version_latest, dry_run: true, greedy: true, args: args)
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_first).to be_a_directory
 | 
			
		||||
        expect(version_latest_path_second).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
        expect(version_latest_paths).to all be_a_directory
 | 
			
		||||
        expect(version_latest.installed_version).to eq "latest"
 | 
			
		||||
        expect(version_latest.outdated_download_sha?).to be(true)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
@ -440,7 +426,7 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
      expect(will_fail_if_upgraded).to be_installed
 | 
			
		||||
      expect(will_fail_if_upgraded_path).to be_a_file
 | 
			
		||||
      expect(will_fail_if_upgraded.versions).to include("1.2.2")
 | 
			
		||||
      expect(will_fail_if_upgraded.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
      expect do
 | 
			
		||||
        described_class.upgrade_casks(will_fail_if_upgraded, args: args)
 | 
			
		||||
@ -448,7 +434,7 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
      expect(will_fail_if_upgraded).to be_installed
 | 
			
		||||
      expect(will_fail_if_upgraded_path).to be_a_file
 | 
			
		||||
      expect(will_fail_if_upgraded.versions).to include("1.2.2")
 | 
			
		||||
      expect(will_fail_if_upgraded.installed_version).to eq "1.2.2"
 | 
			
		||||
      expect(will_fail_if_upgraded.staged_path).not_to exist
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -458,7 +444,7 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
      expect(bad_checksum).to be_installed
 | 
			
		||||
      expect(bad_checksum_path).to be_a_directory
 | 
			
		||||
      expect(bad_checksum.versions).to include("1.2.2")
 | 
			
		||||
      expect(bad_checksum.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
      expect do
 | 
			
		||||
        described_class.upgrade_casks(bad_checksum, args: args)
 | 
			
		||||
@ -466,7 +452,7 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
      expect(bad_checksum).to be_installed
 | 
			
		||||
      expect(bad_checksum_path).to be_a_directory
 | 
			
		||||
      expect(bad_checksum.versions).to include("1.2.2")
 | 
			
		||||
      expect(bad_checksum.installed_version).to eq "1.2.2"
 | 
			
		||||
      expect(bad_checksum.staged_path).not_to exist
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
@ -495,15 +481,15 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
      expect(bad_checksum).to be_installed
 | 
			
		||||
      expect(bad_checksum_path).to be_a_directory
 | 
			
		||||
      expect(bad_checksum.versions).to include("1.2.2")
 | 
			
		||||
      expect(bad_checksum.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
      expect(local_transmission).to be_installed
 | 
			
		||||
      expect(local_transmission_path).to be_a_directory
 | 
			
		||||
      expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
      expect(local_transmission.installed_version).to eq "2.60"
 | 
			
		||||
 | 
			
		||||
      expect(bad_checksum_2).to be_installed
 | 
			
		||||
      expect(bad_checksum_2_path).to be_a_file
 | 
			
		||||
      expect(bad_checksum_2.versions).to include("1.2.2")
 | 
			
		||||
      expect(bad_checksum_2.installed_version).to eq "1.2.2"
 | 
			
		||||
 | 
			
		||||
      expect do
 | 
			
		||||
        described_class.upgrade_casks(args: args)
 | 
			
		||||
@ -511,16 +497,16 @@ describe Cask::Upgrade, :cask do
 | 
			
		||||
 | 
			
		||||
      expect(bad_checksum).to be_installed
 | 
			
		||||
      expect(bad_checksum_path).to be_a_directory
 | 
			
		||||
      expect(bad_checksum.versions).to include("1.2.2")
 | 
			
		||||
      expect(bad_checksum.installed_version).to eq "1.2.2"
 | 
			
		||||
      expect(bad_checksum.staged_path).not_to exist
 | 
			
		||||
 | 
			
		||||
      expect(local_transmission).to be_installed
 | 
			
		||||
      expect(local_transmission_path).to be_a_directory
 | 
			
		||||
      expect(local_transmission.versions).to include("2.61")
 | 
			
		||||
      expect(local_transmission.installed_version).to eq "2.61"
 | 
			
		||||
 | 
			
		||||
      expect(bad_checksum_2).to be_installed
 | 
			
		||||
      expect(bad_checksum_2_path).to be_a_file
 | 
			
		||||
      expect(bad_checksum_2.versions).to include("1.2.2")
 | 
			
		||||
      expect(bad_checksum_2.installed_version).to eq "1.2.2"
 | 
			
		||||
      expect(bad_checksum_2.staged_path).not_to exist
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -4,17 +4,17 @@ require "cli/named_args"
 | 
			
		||||
 | 
			
		||||
def setup_unredable_formula(name)
 | 
			
		||||
  error = FormulaUnreadableError.new(name, RuntimeError.new("testing"))
 | 
			
		||||
  allow(Formulary).to receive(:factory).with(name, force_bottle: false, flags: []).and_raise(error)
 | 
			
		||||
  allow(Formulary).to receive(:factory).with(name, force_bottle: false, flags: [], warn: true).and_raise(error)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def setup_unredable_cask(name)
 | 
			
		||||
  error = Cask::CaskUnreadableError.new(name, "testing")
 | 
			
		||||
  allow(Cask::CaskLoader).to receive(:load).with(name).and_raise(error)
 | 
			
		||||
  allow(Cask::CaskLoader).to receive(:load).with(name, config: nil).and_raise(error)
 | 
			
		||||
  allow(Cask::CaskLoader).to receive(:load).with(name, config: nil, warn: true).and_raise(error)
 | 
			
		||||
 | 
			
		||||
  config = instance_double(Cask::Config)
 | 
			
		||||
  allow(Cask::Config).to receive(:from_args).and_return(config)
 | 
			
		||||
  allow(Cask::CaskLoader).to receive(:load).with(name, config: config).and_raise(error)
 | 
			
		||||
  allow(Cask::CaskLoader).to receive(:load).with(name, config: config, warn: true).and_raise(error)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe Homebrew::CLI::NamedArgs do
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ describe "brew migrate" do
 | 
			
		||||
    install_and_rename_coretap_formula "testball1", "testball2"
 | 
			
		||||
 | 
			
		||||
    expect { brew "migrate", "testball1" }
 | 
			
		||||
      .to output(/Processing testball1 formula rename to testball2/).to_stdout
 | 
			
		||||
      .to output(/Migrating formula testball1 to testball2/).to_stdout
 | 
			
		||||
      .and not_to_output.to_stderr
 | 
			
		||||
      .and be_a_success
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "token": "everything",
 | 
			
		||||
  "full_token": "everything",
 | 
			
		||||
  "old_tokens": [
 | 
			
		||||
 | 
			
		||||
  ],
 | 
			
		||||
  "tap": "homebrew/cask",
 | 
			
		||||
  "name": [
 | 
			
		||||
    "Everything"
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ module Test
 | 
			
		||||
        allow(::Cask::CaskLoader).to receive(:for).and_call_original if call_original
 | 
			
		||||
 | 
			
		||||
        loader = ::Cask::CaskLoader::FromInstanceLoader.new cask
 | 
			
		||||
        allow(::Cask::CaskLoader).to receive(:for).with(ref).and_return(loader)
 | 
			
		||||
        allow(::Cask::CaskLoader).to receive(:for).with(ref, warn: true).and_return(loader)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,8 @@ module Test
 | 
			
		||||
        allow(Formulary).to receive(:loader_for).and_call_original if call_original
 | 
			
		||||
 | 
			
		||||
        loader = double(get_formula: formula)
 | 
			
		||||
        allow(Formulary).to receive(:loader_for).with(ref, from: :keg).and_return(loader)
 | 
			
		||||
        allow(Formulary).to receive(:loader_for).with(ref, from: nil).and_return(loader)
 | 
			
		||||
        allow(Formulary).to receive(:loader_for).with(ref, from: :keg, warn: false).and_return(loader)
 | 
			
		||||
        allow(Formulary).to receive(:loader_for).with(ref, from: nil, warn: true).and_return(loader)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user