aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cask/lib
diff options
context:
space:
mode:
authorMarkus Reiter2017-11-27 23:41:03 +0100
committerGitHub2017-11-27 23:41:03 +0100
commitf50ae449800c85b53910bf294b9271c45c25da01 (patch)
treee07111b8e02a4e2005faae4195af6743a5a9f88c /Library/Homebrew/cask/lib
parentf7baa3b380c1ed38d78da054c99b1b5f3678a645 (diff)
parent8abe60d2dc3f010112aa671a82e4dceb22c11e5b (diff)
downloadbrew-f50ae449800c85b53910bf294b9271c45c25da01.tar.bz2
Merge pull request #3396 from amyspark/hacktoberfest-upgrade
Implement `brew cask upgrade`
Diffstat (limited to 'Library/Homebrew/cask/lib')
-rw-r--r--Library/Homebrew/cask/lib/hbc/artifact/moved.rb31
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli.rb1
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/upgrade.rb87
-rw-r--r--Library/Homebrew/cask/lib/hbc/installer.rb42
4 files changed, 147 insertions, 14 deletions
diff --git a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb
index ba1c8e907..11e019af2 100644
--- a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb
+++ b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb
@@ -12,7 +12,7 @@ module Hbc
end
def uninstall_phase(**options)
- delete(**options)
+ move_back(**options)
end
def summarize_installed
@@ -30,7 +30,7 @@ module Hbc
message = "It seems there is already #{self.class.english_article} #{self.class.english_name} at '#{target}'"
raise CaskError, "#{message}." unless force
opoo "#{message}; overwriting."
- delete(force: force, command: command, **options)
+ delete(target, force: force, command: command, **options)
end
unless source.exist?
@@ -49,7 +49,32 @@ module Hbc
add_altname_metadata(target, source.basename, command: command)
end
- def delete(force: false, command: nil, **_)
+ def move_back(skip: false, force: false, command: nil, **options)
+ if Utils.path_occupied?(source)
+ message = "It seems there is already #{self.class.english_article} #{self.class.english_name} at '#{source}'"
+ raise CaskError, "#{message}." unless force
+ opoo "#{message}; overwriting."
+ delete(source, force: force, command: command, **options)
+ end
+
+ unless target.exist?
+ return if skip
+ raise CaskError, "It seems the #{self.class.english_name} source '#{target}' is not there."
+ end
+
+ ohai "Moving #{self.class.english_name} '#{target.basename}' back to '#{source}'."
+ source.dirname.mkpath
+
+ if source.parent.writable?
+ FileUtils.move(target, source)
+ else
+ command.run("/bin/mv", args: [target, source], sudo: true)
+ end
+
+ add_altname_metadata(target, source.basename, command: command)
+ end
+
+ def delete(target, force: false, command: nil, **_)
ohai "Removing #{self.class.english_name} '#{target}'."
raise CaskError, "Cannot remove undeletable #{self.class.english_name}." if MacOS.undeletable?(target)
diff --git a/Library/Homebrew/cask/lib/hbc/cli.rb b/Library/Homebrew/cask/lib/hbc/cli.rb
index e147c8280..215b59843 100644
--- a/Library/Homebrew/cask/lib/hbc/cli.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli.rb
@@ -21,6 +21,7 @@ require "hbc/cli/reinstall"
require "hbc/cli/search"
require "hbc/cli/style"
require "hbc/cli/uninstall"
+require "hbc/cli/upgrade"
require "hbc/cli/--version"
require "hbc/cli/zap"
diff --git a/Library/Homebrew/cask/lib/hbc/cli/upgrade.rb b/Library/Homebrew/cask/lib/hbc/cli/upgrade.rb
new file mode 100644
index 000000000..bd80ad690
--- /dev/null
+++ b/Library/Homebrew/cask/lib/hbc/cli/upgrade.rb
@@ -0,0 +1,87 @@
+module Hbc
+ class CLI
+ class Upgrade < AbstractCommand
+ option "--greedy", :greedy, false
+ option "--quiet", :quiet, false
+ option "--force", :force, false
+ option "--skip-cask-deps", :skip_cask_deps, false
+
+ def initialize(*)
+ super
+ self.verbose = ($stdout.tty? || verbose?) && !quiet?
+ end
+
+ def run
+ outdated_casks = casks(alternative: lambda {
+ Hbc.installed.select do |cask|
+ cask.outdated?(greedy?)
+ end
+ }).select { |cask| cask.outdated?(true) }
+
+ if outdated_casks.empty?
+ oh1 "No Casks to upgrade"
+ return
+ end
+
+ oh1 "Upgrading #{Formatter.pluralize(outdated_casks.length, "outdated package")}, with result:"
+ puts outdated_casks.map { |f| "#{f.full_name} #{f.version}" } * ", "
+
+ outdated_casks.each do |old_cask|
+ odebug "Started upgrade process for Cask #{old_cask}"
+ raise CaskNotInstalledError, old_cask unless old_cask.installed? || force?
+
+ raise CaskUnavailableError.new(old_cask, "The Caskfile is missing!") if old_cask.installed_caskfile.nil?
+
+ old_cask = CaskLoader.load(old_cask.installed_caskfile)
+
+ old_cask_installer = Installer.new(old_cask, binaries: binaries?, verbose: verbose?, force: force?, upgrade: true)
+
+ new_cask = CaskLoader.load(old_cask.to_s)
+
+ new_cask_installer =
+ Installer.new(new_cask, binaries: binaries?,
+ verbose: verbose?,
+ force: force?,
+ skip_cask_deps: skip_cask_deps?,
+ require_sha: require_sha?,
+ upgrade: true)
+
+ started_upgrade = false
+ new_artifacts_installed = false
+
+ begin
+ # Start new Cask's installation steps
+ new_cask_installer.check_conflicts
+
+ new_cask_installer.fetch
+
+ new_cask_installer.stage
+
+ # Move the old Cask's artifacts back to staging
+ old_cask_installer.start_upgrade
+ # And flag it so in case of error
+ started_upgrade = true
+
+ # Install the new Cask
+ new_cask_installer.install_artifacts
+ new_artifacts_installed = true
+
+ new_cask_installer.enable_accessibility_access
+
+ # If successful, wipe the old Cask from staging
+ old_cask_installer.finalize_upgrade
+ rescue CaskError => e
+ new_cask_installer.uninstall_artifacts if new_artifacts_installed
+ new_cask_installer.purge_versioned_files
+ old_cask_installer.revert_upgrade if started_upgrade
+ raise e
+ end
+ end
+ end
+
+ def self.help
+ "upgrades all outdated casks"
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb
index 1063f488b..6056250fc 100644
--- a/Library/Homebrew/cask/lib/hbc/installer.rb
+++ b/Library/Homebrew/cask/lib/hbc/installer.rb
@@ -19,7 +19,7 @@ module Hbc
PERSISTENT_METADATA_SUBDIRS = ["gpg"].freeze
- def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false, binaries: true, verbose: false, require_sha: false)
+ def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false, binaries: true, verbose: false, require_sha: false, upgrade: false)
@cask = cask
@command = command
@force = force
@@ -28,9 +28,10 @@ module Hbc
@verbose = verbose
@require_sha = require_sha
@reinstall = false
+ @upgrade = upgrade
end
- attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :verbose?
+ attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :upgrade?, :verbose?
def self.print_caveats(cask)
odebug "Printing caveats"
@@ -82,7 +83,7 @@ module Hbc
def install
odebug "Hbc::Installer#install"
- if @cask.installed? && !force? && !@reinstall
+ if @cask.installed? && !force? && !@reinstall && !upgrade?
raise CaskAlreadyInstalledError, @cask
end
@@ -129,13 +130,13 @@ module Hbc
installed_cask = installed_caskfile.exist? ? CaskLoader.load(installed_caskfile) : @cask
# Always force uninstallation, ignore method parameter
- Installer.new(installed_cask, binaries: binaries?, verbose: verbose?, force: true).uninstall
+ Installer.new(installed_cask, binaries: binaries?, verbose: verbose?, force: true, upgrade: upgrade?).uninstall
end
def summary
s = ""
s << "#{Emoji.install_badge} " if Emoji.enabled?
- s << "#{@cask} was successfully installed!"
+ s << "#{@cask} was successfully #{upgrade? ? "upgraded" : "installed"}!"
end
def download
@@ -367,12 +368,31 @@ module Hbc
def uninstall
oh1 "Uninstalling Cask #{@cask}"
disable_accessibility_access
- uninstall_artifacts
+ uninstall_artifacts(clear: true)
purge_versioned_files
purge_caskroom_path if force?
end
- def uninstall_artifacts
+ def start_upgrade
+ oh1 "Starting upgrade for Cask #{@cask}"
+
+ disable_accessibility_access
+ uninstall_artifacts
+ end
+
+ def revert_upgrade
+ opoo "Reverting upgrade for Cask #{@cask}"
+ install_artifacts
+ enable_accessibility_access
+ end
+
+ def finalize_upgrade
+ purge_versioned_files
+
+ puts summary
+ end
+
+ def uninstall_artifacts(clear: false)
odebug "Un-installing artifacts"
artifacts = @cask.artifacts
@@ -381,7 +401,7 @@ module Hbc
artifacts.each do |artifact|
next unless artifact.respond_to?(:uninstall_phase)
odebug "Un-installing artifact of class #{artifact.class}"
- artifact.uninstall_phase(command: @command, verbose: verbose?, force: force?)
+ artifact.uninstall_phase(command: @command, verbose: verbose?, skip: clear, force: force?)
end
end
@@ -405,7 +425,7 @@ module Hbc
end
def purge_versioned_files
- odebug "Purging files for version #{@cask.version} of Cask #{@cask}"
+ ohai "Purging files for version #{@cask.version} of Cask #{@cask}"
# versioned staged distribution
gain_permissions_remove(@cask.staged_path) if !@cask.staged_path.nil? && @cask.staged_path.exist?
@@ -420,10 +440,10 @@ module Hbc
end
end
@cask.metadata_versioned_path.rmdir_if_possible
- @cask.metadata_master_container_path.rmdir_if_possible
+ @cask.metadata_master_container_path.rmdir_if_possible unless upgrade?
# toplevel staged distribution
- @cask.caskroom_path.rmdir_if_possible
+ @cask.caskroom_path.rmdir_if_possible unless upgrade?
end
def purge_caskroom_path