Only upgrade :latest casks when --greedy and the cask has been updated
A sha256 hash of the previous download is stored and compared with new downloads before updating :latest casks. This prevents unnecessary reinstalls when the cask hasn't been updated. Move download path to cask from installer to prevent unnecessary redownloads of casks.
This commit is contained in:
parent
34dd8e3057
commit
b85f407e95
@ -21,6 +21,8 @@ module Cask
|
||||
|
||||
attr_reader :token, :sourcefile_path, :source, :config, :default_config
|
||||
|
||||
attr_accessor :download
|
||||
|
||||
def self.all
|
||||
Tap.flat_map(&:cask_files).map do |f|
|
||||
CaskLoader::FromTapPathLoader.new(f).load(config: nil)
|
||||
@ -127,6 +129,23 @@ module Cask
|
||||
metadata_main_container_path/"config.json"
|
||||
end
|
||||
|
||||
def download_sha_path
|
||||
metadata_main_container_path/"LATEST_DOWNLOAD_SHA256"
|
||||
end
|
||||
|
||||
def new_download_sha
|
||||
require "cask/installer"
|
||||
|
||||
@new_download_sha ||= Installer.new(self, verify_download_integrity: false)
|
||||
.download(quiet: true)
|
||||
.instance_eval { |x| Digest::SHA256.file(x).hexdigest }
|
||||
end
|
||||
|
||||
def outdated_download_sha?
|
||||
current_download_sha = download_sha_path.read if download_sha_path.exist?
|
||||
current_download_sha.blank? || current_download_sha != new_download_sha
|
||||
end
|
||||
|
||||
def caskroom_path
|
||||
@caskroom_path ||= Caskroom.path.join(token)
|
||||
end
|
||||
@ -140,14 +159,6 @@ module Cask
|
||||
# special case: tap version is not available
|
||||
return [] if version.nil?
|
||||
|
||||
if greedy || (greedy_latest && greedy_auto_updates) || (greedy_auto_updates && auto_updates)
|
||||
return versions if version.latest?
|
||||
elsif greedy_latest && version.latest?
|
||||
return versions
|
||||
elsif auto_updates
|
||||
return []
|
||||
end
|
||||
|
||||
latest_version = if Homebrew::EnvConfig.install_from_api? &&
|
||||
(latest_cask_version = Homebrew::API::Versions.latest_cask_version(token))
|
||||
DSL::Version.new latest_cask_version.to_s
|
||||
@ -155,6 +166,16 @@ module Cask
|
||||
version
|
||||
end
|
||||
|
||||
if greedy || greedy_latest || (greedy_auto_updates && auto_updates)
|
||||
if latest_version.latest?
|
||||
return versions if outdated_download_sha?
|
||||
|
||||
return []
|
||||
end
|
||||
elsif auto_updates
|
||||
return []
|
||||
end
|
||||
|
||||
installed = versions
|
||||
current = installed.last
|
||||
|
||||
|
||||
@ -181,8 +181,9 @@ module Cask
|
||||
|
||||
sig { params(quiet: T.nilable(T::Boolean), timeout: T.nilable(T.any(Integer, Float))).returns(Pathname) }
|
||||
def download(quiet: nil, timeout: nil)
|
||||
@download ||= downloader.fetch(quiet: quiet, verify_download_integrity: @verify_download_integrity,
|
||||
timeout: timeout)
|
||||
# Store cask download path in cask to prevent multiple downloads in a row when checking if it's outdated
|
||||
@cask.download ||= downloader.fetch(quiet: quiet, verify_download_integrity: @verify_download_integrity,
|
||||
timeout: timeout)
|
||||
end
|
||||
|
||||
def verify_has_sha
|
||||
@ -248,6 +249,7 @@ module Cask
|
||||
end
|
||||
|
||||
save_config_file
|
||||
save_download_sha if @cask.version.latest?
|
||||
rescue => e
|
||||
begin
|
||||
already_installed_artifacts.each do |artifact|
|
||||
@ -394,6 +396,10 @@ module Cask
|
||||
@cask.config_path.atomic_write(@cask.config.to_json)
|
||||
end
|
||||
|
||||
def save_download_sha
|
||||
@cask.download_sha_path.atomic_write(@cask.new_download_sha)
|
||||
end
|
||||
|
||||
def uninstall
|
||||
oh1 "Uninstalling Cask #{Formatter.identifier(@cask)}"
|
||||
uninstall_artifacts(clear: true)
|
||||
|
||||
@ -131,15 +131,17 @@ describe Cask::Cask, :cask do
|
||||
describe ":latest casks" do
|
||||
let(:cask) { described_class.new("basic-cask") }
|
||||
|
||||
shared_examples ":latest cask" do |greedy, tap_version, expectations|
|
||||
shared_examples ":latest cask" do |greedy, outdated_sha, tap_version, expectations|
|
||||
expectations.each do |installed_version, expected_output|
|
||||
context "when versions #{installed_version} are installed and the " \
|
||||
"tap version is #{tap_version}, #{"not" unless greedy} greedy" do
|
||||
"tap version is #{tap_version}, #{"not " unless greedy}greedy" \
|
||||
"and sha is #{"not " unless outdated_sha}outdated" do
|
||||
subject { cask.outdated_versions(greedy: greedy) }
|
||||
|
||||
it {
|
||||
allow(cask).to receive(:versions).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
|
||||
expect(subject).to eq expected_output
|
||||
}
|
||||
@ -148,23 +150,29 @@ describe Cask::Cask, :cask do
|
||||
end
|
||||
|
||||
describe ":latest version installed, :latest version in tap" do
|
||||
include_examples ":latest cask", false, "latest",
|
||||
include_examples ":latest cask", false, false, "latest",
|
||||
["latest"] => []
|
||||
include_examples ":latest cask", true, "latest",
|
||||
include_examples ":latest cask", true, false, "latest",
|
||||
["latest"] => []
|
||||
include_examples ":latest cask", true, true, "latest",
|
||||
["latest"] => ["latest"]
|
||||
end
|
||||
|
||||
describe "numbered version installed, :latest version in tap" do
|
||||
include_examples ":latest cask", false, "latest",
|
||||
include_examples ":latest cask", false, false, "latest",
|
||||
["1.2.3"] => ["1.2.3"]
|
||||
include_examples ":latest cask", true, "latest",
|
||||
include_examples ":latest cask", true, false, "latest",
|
||||
["1.2.3"] => []
|
||||
include_examples ":latest cask", true, true, "latest",
|
||||
["1.2.3"] => ["1.2.3"]
|
||||
end
|
||||
|
||||
describe "latest version installed, numbered version in tap" do
|
||||
include_examples ":latest cask", false, "1.2.3",
|
||||
include_examples ":latest cask", false, false, "1.2.3",
|
||||
["latest"] => ["latest"]
|
||||
include_examples ":latest cask", true, "1.2.3",
|
||||
include_examples ":latest cask", true, false, "1.2.3",
|
||||
["latest"] => ["latest"]
|
||||
include_examples ":latest cask", true, true, "1.2.3",
|
||||
["latest"] => ["latest"]
|
||||
end
|
||||
end
|
||||
|
||||
@ -106,8 +106,10 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.versions).to include("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)
|
||||
|
||||
described_class.run("--greedy")
|
||||
|
||||
@ -124,12 +126,12 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(local_transmission.versions).to include("2.61")
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.versions).to include("latest")
|
||||
expect(version_latest.outdated_download_sha?).to be(false)
|
||||
end
|
||||
|
||||
it 'does not include the Casks with "auto_updates true" when the version did not change' do
|
||||
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")
|
||||
@ -146,6 +148,32 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
expect(auto_updates.versions).to include("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_1).to be_a_directory
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.versions).to include("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)
|
||||
|
||||
described_class.run("version-latest", "--greedy")
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.versions).to include("latest")
|
||||
expect(version_latest.outdated_download_sha?).to be(false)
|
||||
|
||||
described_class.run("version-latest", "--greedy")
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.versions).to include("latest")
|
||||
expect(version_latest.outdated_download_sha?).to be(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -167,6 +195,8 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
|
||||
describe 'without --greedy it ignores the Casks with "version latest" or "auto_updates true"' do
|
||||
it "would update all the installed Casks when no token is provided" do
|
||||
expect(described_class).not_to receive(:upgrade_cask)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
expect(local_caffeine.versions).to include("1.2.2")
|
||||
@ -189,6 +219,8 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
end
|
||||
|
||||
it "would update only the Casks specified in the command line" do
|
||||
expect(described_class).not_to receive(:upgrade_cask)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
expect(local_caffeine.versions).to include("1.2.2")
|
||||
@ -211,6 +243,8 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
end
|
||||
|
||||
it 'would update "auto_updates" and "latest" Casks when their tokens are provided in the command line' do
|
||||
expect(described_class).not_to receive(:upgrade_cask)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
expect(local_caffeine.versions).to include("1.2.2")
|
||||
@ -235,6 +269,8 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
|
||||
describe "with --greedy it checks additional Casks" do
|
||||
it 'would include the Casks with "auto_updates true" or "version latest"' do
|
||||
expect(described_class).not_to receive(:upgrade_cask)
|
||||
|
||||
expect(local_caffeine).to be_installed
|
||||
expect(local_caffeine_path).to be_a_directory
|
||||
expect(local_caffeine.versions).to include("1.2.2")
|
||||
@ -248,8 +284,9 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(local_transmission.versions).to include("2.60")
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
expect(version_latest.versions).to include("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)
|
||||
|
||||
described_class.run("--greedy", "--dry-run")
|
||||
|
||||
@ -269,10 +306,12 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
expect(local_transmission.versions).not_to include("2.61")
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.outdated_download_sha?).to be(true)
|
||||
end
|
||||
|
||||
it 'does not include the Casks with "auto_updates true" when the version did not change' do
|
||||
it 'would update outdated Casks with "auto_updates true"' do
|
||||
expect(described_class).not_to receive(:upgrade_cask)
|
||||
|
||||
expect(auto_updates).to be_installed
|
||||
expect(auto_updates_path).to be_a_directory
|
||||
expect(auto_updates.versions).to include("2.57")
|
||||
@ -283,13 +322,26 @@ describe Cask::Cmd::Upgrade, :cask do
|
||||
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")
|
||||
end
|
||||
|
||||
described_class.run("--dry-run", "auto-updates", "--greedy")
|
||||
it 'would update outdated Casks with "version latest"' do
|
||||
expect(described_class).not_to receive(:upgrade_cask)
|
||||
|
||||
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(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.versions).to include("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)
|
||||
|
||||
described_class.run("--dry-run", "version-latest", "--greedy")
|
||||
|
||||
expect(version_latest).to be_installed
|
||||
expect(version_latest_path_1).to be_a_directory
|
||||
expect(version_latest_path_2).to be_a_directory
|
||||
expect(version_latest.versions).to include("latest")
|
||||
expect(version_latest.outdated_download_sha?).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -223,6 +223,22 @@ describe Cask::Installer, :cask do
|
||||
described_class.new(caffeine, quiet: true).install
|
||||
}.to output(nil).to_stdout
|
||||
end
|
||||
|
||||
it "does NOT generate LATEST_DOWNLOAD_SHA256 file for installed Cask without version :latest" do
|
||||
caffeine = Cask::CaskLoader.load(cask_path("local-caffeine"))
|
||||
|
||||
described_class.new(caffeine).install
|
||||
|
||||
expect(caffeine.download_sha_path).not_to be_a_file
|
||||
end
|
||||
|
||||
it "generates and finds LATEST_DOWNLOAD_SHA256 file for installed Cask with version :latest" do
|
||||
latest_cask = Cask::CaskLoader.load(cask_path("version-latest"))
|
||||
|
||||
described_class.new(latest_cask).install
|
||||
|
||||
expect(latest_cask.download_sha_path).to be_a_file
|
||||
end
|
||||
end
|
||||
|
||||
describe "uninstall" do
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user