mkevenaar / chocolatey-packages

My chocolatey packages
https://mkevenaar.github.io/chocolatey-packages/
Apache License 2.0
42 stars 70 forks source link

(googledrive) Improve handling of reinstalls, uninstalls, and package upgrades/downgrades #182

Closed brogers5 closed 1 year ago

brogers5 commented 1 year ago

Description

This changeset adds support for silent uninstallations, as well as version detection support to improve googledrive's handling of a few situations, including:

Motivation and Context

Fixes #138, fixes #154, fixes #165.

By default, Google Drive is configured to silently update itself. As Google Drive's installer currently does not support reinstallations, this could cause the installer to return exit code 1638 with either an initial package install (when the machine already has Google Drive installed), or a package upgrade (since a package upgrade may occur after the software was updated).

When run non-silently, if the installer has the same version packaged, Google Drive will inform the user it is already installed :

Google Drive Already Installed Dialog

The package will now detect the currently installed version of Google Drive (if any) and compare it to the packaged software version. If the software is not installed, or the packaged version is newer, the package will continue to install/upgrade as it historically has. However, if the packaged version is already installed, download and installation of Google Drive will now be skipped by default, which enables the package install/upgrade to gracefully succeed. This can be optionally overridden with the --force switch if desired.

Google Drive's installer also does not support downgrades. If the installer has an earlier version packaged, the installer will inform the user a newer version is already installed:

Google Drive Old Version Dialog

The software will need to be uninstalled first if we're doing a forced reinstallation or a downgrade. To get this process started, I've implemented support for a silent uninstall as documented here.

The uninstaller is quirky in that it will shell an executable out to TEMP (regardless of where it starts from), spawn a child process from said executable, then terminate itself. Unfortunately, both Uninstall-ChocolateyPackage and Start-ChocolateyProcessAsAdmin will only track the parent process, and terminates with exit code 0 well before the child process actually finishes, which necessitated the use of Start-Process with both -PassThru and -Wait to correctly handle this situation.

The uninstaller will also queue some files to be cleaned up upon the next reboot, and prevents another installation of Google Drive before the reboot completes:

Google Drive Install after Uninstall Dialog

To work around this, a warning is printed after uninstallation completes, which states that a reboot is required to complete the uninstallation. In the case of a mandatory uninstall, the install script will deliberately throw an error in an attempt to guide users toward the correct path. An install that is attempted before this happens will fail with exit code 1610.

How Has this Been Tested?

Environments

Dev

Chocolatey Test Environment

Steps

Create Test Packages

  1. Created a test package of the current version that consumes the modified scripts (i.e. choco pack).
  2. Create an internalized test package for a past version with a similar patch applied (reference commit reverting to v70.0.2.0 available at https://github.com/brogers5/chocolatey-packages-mkevenaar/commit/a91ba6a75763cadf1c0f6e302dfecdc438f63f13).

    Note An internalized package was necessary since the software uses an unversioned download URL. Unfortunately, I'm a FOSS user and thus do not have access to Chocolatey's CDN.

  3. Repeat step 1 with the forked past package version.

Prepare Testing Environment

  1. Download the current distributed installer binary for Google Drive (in my case, v72.0.2.0), and copy to the testing environment.
  2. Copy test packages to testing environment.
  3. Open an elevated instance of Windows PowerShell, and Set-Location to my packages' parent directory.
  4. Create a pre-install VM checkpoint for the testing environment.

Clean Install Regression Test

  1. Install the past version test package (i.e. choco install googledrive --source="'.'" --version=70.0.2.0).
  2. Confirm the package proceeds with installing the packaged version of Google Drive.
  3. Confirm the package installation succeeds without errors.

Upgrade Regression Test

  1. Upgrade to the current version test package (i.e. choco upgrade googledrive --source="'.'").
  2. Confirm the package proceeds with installing the packaged version of Google Drive.
  3. Confirm the package upgrade succeeds without errors.

Package-Only Install Test

  1. Revert testing environment VM to pre-install checkpoint.
  2. Manually install Google Drive using the copied installer binary.
  3. Install the current version test package (i.e. choco install googledrive --source="'.'").
  4. Confirm the package installation skips installation of Google Drive.
  5. Confirm the package installation succeeds without errors.

Package-Only Upgrade Test

  1. Revert testing environment VM to pre-install checkpoint.
  2. Install the past version test package (i.e. choco install googledrive --source="'.'" --version=70.0.2.0).
  3. Manually install Google Drive using the copied installer binary.
  4. Upgrade to the current version test package (i.e. choco upgrade googledrive --source="'.'").
  5. Confirm the package upgrade skips installation of Google Drive.
  6. Confirm the package upgrade succeeds without errors.

Forced Reinstallation Test

  1. Start the forced reinstallation process by forcibly installing the current version test package (i.e. choco install googledrive --source="'.'" --force).
  2. Confirm the package uninstalls Google Drive successfully.
  3. Confirm the package throws an error after uninstallation, prompting the user to complete a reboot.
  4. Reboot Windows.
  5. Reattempt a forced installation of the current version test package (i.e. choco install googledrive --source="'.'" --force).
  6. Confirm the forced package installation succeeds without errors.

Downgrade Test

  1. Start the software downgrade process by installing the past version test package (i.e. choco install googledrive --source="'.'" --version=70.0.2.0 --allow-downgrade).
  2. Confirm the package uninstalls Google Drive successfully.
  3. Confirm the package installation throws an error after uninstallation, prompting the user to complete a reboot.
  4. Reboot Windows.
  5. Reattempt installation of the past version test package (i.e. choco install googledrive --source="'.'" --version=70.0.2.0 --allow-downgrade).
  6. Confirm the package downgrade succeeds without errors.

Uninstall Test

  1. Uninstall the test package (i.e. choco uninstall googledrive).
  2. Confirm the software uninstallation is silent and completes successfully.
  3. Confirm the package uninstallation completes without errors.

Screenshot (if appropriate, usually isn't needed):

N/A

Types of changes

Checklist:

AppVeyorBot commented 1 year ago

:x: Package verification failed, please review the Appveyor Logs and the provided Artifacts before requesting a human reviewer to take a look.

AppVeyorBot commented 1 year ago

:white_check_mark: Package verification completed without issues. PR is now pending human review

AppVeyorBot commented 1 year ago

:white_check_mark: Package verification completed without issues. PR is now pending human review

mkevenaar commented 1 year ago

@brogers5 your changes have been merged, thanks for your contribution!