'brew cask upgrade' will continue upgrading casks after a failure

'cask upgrade' command collects all exceptions thrown
from individual casks during the upgrade process. If
there were more than one cask that raised exceptions
during the upgrade process, a MultipleCaskErrors
exception will be thrown.

Issue #5203
This commit is contained in:
Zach Auten 2019-04-03 19:17:12 -04:00
parent cf4511f72a
commit 41b5b788d5
5 changed files with 141 additions and 51 deletions

View File

@ -31,21 +31,24 @@ module Cask
ohai "Casks with `auto_updates` or `version :latest` will not be upgraded" if args.empty? && !greedy? ohai "Casks with `auto_updates` or `version :latest` will not be upgraded" if args.empty? && !greedy?
oh1 "Upgrading #{outdated_casks.count} #{"outdated package".pluralize(outdated_casks.count)}:" oh1 "Upgrading #{outdated_casks.count} #{"outdated package".pluralize(outdated_casks.count)}:"
cask_upgrades = outdated_casks.map do |cask| caught_exceptions = []
if cask.installed_caskfile.nil? outdated_casks.each do |cask|
"#{cask.full_name} #{cask.version}" begin
else old_cask = CaskLoader.load(cask.installed_caskfile)
"#{cask.full_name} #{CaskLoader.load(cask.installed_caskfile).version} -> #{cask.version}" puts "#{cask.full_name} #{old_cask.version} -> #{cask.version}"
upgrade_cask(old_cask)
rescue CaskError => e
caught_exceptions << e
next
end end
end end
puts cask_upgrades.join(", ") return if caught_exceptions.empty?
raise MultipleCaskErrors, caught_exceptions if caught_exceptions.count > 1
raise caught_exceptions.first if caught_exceptions.count == 1
end
outdated_casks.each do |old_cask| def upgrade_cask(old_cask)
odebug "Started upgrade process for Cask #{old_cask}" odebug "Started upgrade process for Cask #{old_cask}"
raise CaskUnavailableError.new(old_cask, "The Caskfile is missing!") if old_cask.installed_caskfile.nil?
old_cask = CaskLoader.load(old_cask.installed_caskfile)
old_config = old_cask.config old_config = old_cask.config
old_cask_installer = old_cask_installer =
@ -98,7 +101,6 @@ module Cask
raise e raise e
end end
end end
end
def self.help def self.help
"upgrades all outdated casks" "upgrades all outdated casks"

View File

@ -1,6 +1,19 @@
module Cask module Cask
class CaskError < RuntimeError; end class CaskError < RuntimeError; end
class MultipleCaskErrors < CaskError
def initialize(errors)
@errors = errors
end
def to_s
<<~EOS
Problems with multiple casks:
#{@errors.map(&:to_s).join("\n")}
EOS
end
end
class AbstractCaskErrorWithToken < CaskError class AbstractCaskErrorWithToken < CaskError
attr_reader :token attr_reader :token
attr_reader :reason attr_reader :reason

View File

@ -222,4 +222,61 @@ describe Cask::Cmd::Upgrade, :cask do
expect(bad_checksum.staged_path).not_to exist expect(bad_checksum.staged_path).not_to exist
end end
end end
context "multiple failures" do
let(:installed) {
[
"outdated/bad-checksum",
"outdated/local-transmission",
"outdated/bad-checksum2",
]
}
before do
installed.each { |cask| Cask::Cmd::Install.run(cask) }
allow_any_instance_of(described_class).to receive(:verbose?).and_return(true)
end
it "will not end the upgrade process" do
bad_checksum = Cask::CaskLoader.load("bad-checksum")
bad_checksum_path = bad_checksum.config.appdir.join("Caffeine.app")
local_transmission = Cask::CaskLoader.load("local-transmission")
local_transmission_path = Cask::Config.global.appdir.join("Transmission.app")
bad_checksum_2 = Cask::CaskLoader.load("bad-checksum2")
bad_checksum_2_path = bad_checksum_2.config.appdir.join("container")
expect(bad_checksum).to be_installed
expect(bad_checksum_path).to be_a_directory
expect(bad_checksum.versions).to include("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(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 {
described_class.run
}.to raise_error(Cask::MultipleCaskErrors)
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.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(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.staged_path).not_to exist
end
end
end end

View File

@ -0,0 +1,9 @@
cask 'bad-checksum2' do
version '1.2.3'
sha256 'badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadb'
url "file://#{TEST_FIXTURE_DIR}/cask/container.tar.gz"
homepage 'https://brew.sh/container-tar-gz'
app 'container'
end

View File

@ -0,0 +1,9 @@
cask 'bad-checksum2' do
version '1.2.2'
sha256 'fab685fabf73d5a9382581ce8698fce9408f5feaa49fa10d9bc6c510493300f5'
url "file://#{TEST_FIXTURE_DIR}/cask/container.tar.gz"
homepage 'https://brew.sh/container-tar-gz'
app 'container'
end