-
-
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
Properly upgrade Casks with version :latest #3492
Conversation
No worries, there had to be something. 😜
I'd suggest to just move |
@@ -420,6 +436,14 @@ def zap | |||
purge_caskroom_path | |||
end | |||
|
|||
def backup_path(path) | |||
Pathname.new "#{path}.upgrading" unless path.nil? |
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.
When would path
be nil
?
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.
Also, since this is only used for staged_path
, you could make this take no arguments and just return Pathname("#{@cask.staged_path}.upgrading")
.
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.
path
should never be nil
, but I wanted to preserve the semantics of gain_permissions_remove(staged_path) if !staged_path.nil? && staged_path.exist?
.
@@ -378,10 +378,26 @@ def start_upgrade | |||
|
|||
disable_accessibility_access | |||
uninstall_artifacts | |||
backup if version_is_latest? |
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.
Let's always create a backup, not just when version_is_latest?
.
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.
If we always create a backup, we'll need a way to know if this is the new or old cask when purge_versioned_files
. Otherwise, it will leave a dangling, empty folder if the upgrade fails (see the test "restores the old Cask if the upgrade failed"
in upgrade_spec.rb
).
Would another variable e.g. old_cask
, new_cask
instead of upgrade
work for you?
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.
Isn't start_upgrade
only called on the old cask?
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, I took advantage of that; see next commit.
(and if doing so, correctly set the staged_path when purging it)
if backed_up? | ||
Pathname.new "#{@cask.staged_path}.upgrading" | ||
else | ||
@cask.staged_path |
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.
I think this is really hard to follow. The only reason for this is purge_versioned_files
using it. I'd suggest making two specialised versions of purge_versioned_files
, one normal one, and one for the upgrade?
case.
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.
I'll do it that way, and then factor out the whole metadata handling (to avoid code duplication).
Avoid using variables altogether; fork out the purge into two specialized + one common function
if @cask.metadata_versioned_path.respond_to?(:children) && | ||
@cask.metadata_versioned_path.exist? | ||
@cask.metadata_versioned_path.exist? && | ||
!(upgrade? && version_is_latest?) |
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.
Do we still need version_is_latest?
now?
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, the backup mechanism doesn't involve the Cask's metadata; if the version is latest
, deleting this line will make purge_metadata
"uninstall" the Cask while leaving all artifacts in place.
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.
On second thoughts, I'll just go ahead with two fully separate methods and get rid of that line.
def gain_permissions_remove(path) | ||
Utils.gain_permissions_remove(path, command: @command) | ||
end | ||
|
||
def purge_backed_versioned_files |
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.
purge_backed_up_versioned_files
Pathname.new "#{@cask.metadata_versioned_path}.upgrading" | ||
end | ||
|
||
def version_is_latest? |
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.
This can now be removed.
end | ||
end | ||
backup_metadata_path.rmdir_if_possible | ||
@cask.metadata_master_container_path.rmdir_if_possible unless upgrade? |
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.
The unless upgrade?
here doesn't make sense, because this method is only called when upgrading.
@@ -31,7 +31,7 @@ def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false | |||
@upgrade = upgrade | |||
end | |||
|
|||
attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :upgrade?, :verbose? | |||
attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?, :upgrade?, :verbose?, :backed_up? |
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.
This is not needed anymore.
@@ -71,7 +71,7 @@ def move_back(skip: false, force: false, command: nil, **options) | |||
command.run("/bin/mv", args: [target, source], sudo: true) | |||
end | |||
|
|||
add_altname_metadata(target, source.basename, command: command) | |||
add_altname_metadata(source, target.basename, command: command) |
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.
Remove this completely. We don‘t need to add this when moving it back, actually.
|
||
# Homebrew-Cask metadata | ||
if backup_metadata_path.respond_to?(:children) && | ||
backup_metadata_path.exist? && |
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.
The &&
shouldn‘t be here.
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.
The whole condition here could probably just be backup_metadata_path.directory?
.
Leftover && and remove xattr "copy"
I think you missed this comment by a minute: #3492 (comment) |
Yep, I wasn't using my inbox to keep up with comments. Thanks for the heads up @reitermarkus. |
Simplify a condition
Thanks again, @amyspark! 👍 |
brew tests
with your changes locally?When I proposed #3396, I forgot to test if the upgrade process worked for
version :latest
Casks.Obviously, this came back to bite me 😢
In this initial state, I've submitted a test to summarize the issue. The missing part would be to tamper with
staged_path
ifversion :latest
and use a randomized? path, but I'd like to request your comments on the best way to do it.This pull request, once finished, fixes Homebrew/homebrew-cask#41373.
Thanks for your comments!
/cc @MikeMcQuaid @vitorgalvao @reitermarkus