-
-
Notifications
You must be signed in to change notification settings - Fork 9.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement brew cask upgrade
#3396
Merged
reitermarkus
merged 15 commits into
Homebrew:master
from
amyspark:hacktoberfest-upgrade
Nov 27, 2017
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
55727b7
Hack a first working version of upgrade
amyspark 7f2e4f5
Finalize metadata handling and uninstall logic
amyspark 84c1284
Fix style issues
amyspark 94d266e
Rework uninstallation step
amyspark 522a229
Fix upgrade tests and some upgrade? leftovers
amyspark 72e673a
Fix reinstall/uninstall tests
amyspark 8cc1aea
Implement @reitermarkus's upgrade flow
amyspark 36fe355
Add tests for upgrade recovery
amyspark 8ee6ac2
Implement @reitermarkus's comments
amyspark c9b5de4
Output message if no Casks are outdated
amyspark 7ce4319
Upgrade an outdated Cask just by name, no need for --greedy
amyspark 7ee98eb
Implement more of @reitermarkus's comments
amyspark e0be066
Load Casks only once (and fix style issues)
amyspark a2730c8
Implement more of @reitermarkus's comments
amyspark 8abe60d
Remove redundant --greedy
amyspark File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ class Installer | |
|
||
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 @@ def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false | |
@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 @@ def stage | |
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 @@ def uninstall_existing_cask | |
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 @@ def save_caskfile | |
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 @@ def uninstall_artifacts | |
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 @@ def gain_permissions_remove(path) | |
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 [email protected]_path.nil? && @cask.staged_path.exist? | ||
|
@@ -420,10 +440,10 @@ def purge_versioned_files | |
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this check here necessary, since this is not
rm_rf
but onlyrmdir
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Line 445 clears the Cask's versioned metadata (which is what we need for
finalize_upgrade
), but the lines below delete the whole metadata folder (which we need foruninstall
), and then purges the whole Cask's folder (which will break everything).(edited for clarity and completeness)