From 300880f3e5fc5162b9f1af9c872247b4a8c24caf Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Sun, 5 Feb 2023 17:58:44 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Reworked=20updater?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PHP Monitor.xcodeproj/project.pbxproj | 10 - phpmon/Domain/App/AppUpdateChecker.swift | 228 ------------------ phpmon/Domain/App/AppUpdater.swift | 143 ++++++++--- phpmon/Domain/App/AppVersion.swift | 2 +- .../Integrations/Homebrew/CaskFile.swift | 1 - phpmon/Domain/Menu/MainMenu+Startup.swift | 7 +- phpmon/Domain/Menu/MainMenu.swift | 2 +- phpmon/Localizable.strings | 5 +- tests/unit/Parsers/CaskFileParserTest.swift | 1 + tests/unit/Versions/AppVersionTest.swift | 20 +- 10 files changed, 130 insertions(+), 289 deletions(-) delete mode 100644 phpmon/Domain/App/AppUpdateChecker.swift diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 8aab78f..d12de6e 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -205,8 +205,6 @@ C46B2648298B324100084651 /* ReleaseManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46B2647298B324100084651 /* ReleaseManifest.swift */; }; C46B2649298B324100084651 /* ReleaseManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46B2647298B324100084651 /* ReleaseManifest.swift */; }; C46B2650298B3C2100084651 /* PHP Monitor Self-Updater.app in Resources */ = {isa = PBXBuildFile; fileRef = C46B264F298B3C2100084651 /* PHP Monitor Self-Updater.app */; }; - C46E206D28299B3800D909D6 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; }; - C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; }; C46E20702829D27F00D909D6 /* AppUpdaterCheckTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */; }; C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; }; C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; }; @@ -347,7 +345,6 @@ C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; }; C471E84728F9BB650021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; }; C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; }; - C471E84928F9BB650021E251 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; }; C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; }; C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; }; C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; }; @@ -437,7 +434,6 @@ C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; }; C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; }; C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; }; - C471E8AC28F9BB8F0021E251 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; }; C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; }; C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; }; C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; }; @@ -870,7 +866,6 @@ C469E702294CFDF700A82AB2 /* DomainsListTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainsListTest.swift; sourceTree = ""; }; C46B2647298B324100084651 /* ReleaseManifest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReleaseManifest.swift; sourceTree = ""; }; C46B264F298B3C2100084651 /* PHP Monitor Self-Updater.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = "PHP Monitor Self-Updater.app"; sourceTree = ""; }; - C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdateChecker.swift; sourceTree = ""; }; C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppUpdaterCheckTest.swift; sourceTree = ""; }; C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = ""; }; C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = ""; }; @@ -1557,7 +1552,6 @@ C4EED88827A48778006D7272 /* InterAppHandler.swift */, C4D8016522B1584700C6DA1B /* Startup.swift */, C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */, - C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */, C40FE736282ABA4F00A302C2 /* AppVersion.swift */, C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */, C409349C298EE8E900D25014 /* AppUpdater.swift */, @@ -2198,7 +2192,6 @@ C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */, C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */, C41CA5ED2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */, - C46E206D28299B3800D909D6 /* AppUpdateChecker.swift in Sources */, C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */, 03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */, C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */, @@ -2302,7 +2295,6 @@ C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */, C471E84728F9BB650021E251 /* Startup.swift in Sources */, C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */, - C471E84928F9BB650021E251 /* AppUpdateChecker.swift in Sources */, C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */, C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */, C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */, @@ -2472,7 +2464,6 @@ C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */, C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */, C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */, - C471E8AC28F9BB8F0021E251 /* AppUpdateChecker.swift in Sources */, C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */, C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */, C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */, @@ -2795,7 +2786,6 @@ C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */, C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */, C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */, - C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/phpmon/Domain/App/AppUpdateChecker.swift b/phpmon/Domain/App/AppUpdateChecker.swift deleted file mode 100644 index 6eabd73..0000000 --- a/phpmon/Domain/App/AppUpdateChecker.swift +++ /dev/null @@ -1,228 +0,0 @@ -// -// Updater.swift -// PHP Monitor -// -// Created by Nico Verbruggen on 09/05/2022. -// Copyright © 2023 Nico Verbruggen. All rights reserved. -// - -import Foundation -import AppKit - -class AppUpdateChecker { - - public static var latestCaskFileContents: String = "" - - public static var enabled: Bool = { - return Preferences.isEnabled(.automaticBackgroundUpdateCheck) - }() - - public static var isDev: Bool = { - return App.version.contains("-dev") - }() - - public static func retrieveVersionFromCask( - _ initiatedFromBackground: Bool = true - ) async -> String { - let caskFile = App.version.contains("-dev") - ? Constants.Urls.DevBuildCaskFile.absoluteString - : Constants.Urls.StableBuildCaskFile.absoluteString - - var command = "curl -s" - - if initiatedFromBackground { - command = "curl -s --max-time 5" - } - - AppUpdateChecker.latestCaskFileContents = await Shell.pipe("\(command) '\(caskFile)'").out - return await Shell.pipe("echo \"\(Self.latestCaskFileContents)\" | grep version").out - } - - public static func checkIfNewerVersionIsAvailable( - initiatedFromBackground: Bool = true - ) async { - if initiatedFromBackground { - if !Preferences.isEnabled(.automaticBackgroundUpdateCheck) { - Log.info("Automatic updates are disabled. No check will be performed.") - return - } - - Log.info("Automatic updates are enabled, a check will be performed.") - } - - let versionString = await retrieveVersionFromCask(initiatedFromBackground) - - guard let onlineVersion = AppVersion.from(versionString) else { - Log.err("We couldn't check for updates!") - - // Only notify about connection issues if the request to check for updates was explicit - if !initiatedFromBackground { - notifyAboutConnectionIssue() - } - - return - } - - let currentVersion = AppVersion.fromCurrentVersion() - - handleVersionComparison( - currentVersion, - onlineVersion, - initiatedFromBackground - ) - } - - private static func handleVersionComparison( - _ currentVersion: AppVersion, - _ onlineVersion: AppVersion, - _ background: Bool - ) { - // TODO: Restore original behaviour - notifyAboutNewerVersion(version: onlineVersion) - return - - switch onlineVersion.version.versionCompare(currentVersion.version) { - case .orderedAscending: - Log.info("You are running a newer version of PHP Monitor " - + "(\(currentVersion.computerReadable) > \(onlineVersion.computerReadable)).") - if !background { notifyVersionDoesNotNeedUpgrade() } - case .orderedDescending: - Log.info("There is a newer version (\(onlineVersion)) available! " - + "(\(onlineVersion.computerReadable) > \(currentVersion.computerReadable))") - notifyAboutNewerVersion(version: onlineVersion) - case .orderedSame: - if currentVersion.build != nil - && onlineVersion.build != nil - && buildDiffers(currentVersion, onlineVersion, background) { - return - } - - Log.info("The installed version (\(currentVersion.computerReadable)) matches the latest release " - + "(\(onlineVersion.computerReadable)).") - if !background { notifyVersionDoesNotNeedUpgrade() } - } - } - - private static func buildDiffers( - _ currentVersion: AppVersion, - _ onlineVersion: AppVersion, - _ background: Bool - ) -> Bool { - if onlineVersion.build! > currentVersion.build! { - Log.info("There is a newer build of PHP Monitor available! " - + "(\(onlineVersion.computerReadable) > \(currentVersion.computerReadable))") - notifyAboutNewerVersion(version: onlineVersion) - return true - } else if onlineVersion.build! < currentVersion.build! { - Log.info("You are running a newer build of PHP Monitor " - + "(\(currentVersion.computerReadable) > \(onlineVersion.computerReadable)).") - if !background { notifyVersionDoesNotNeedUpgrade() } - return true - } - - return false - } - - private static func notifyVersionDoesNotNeedUpgrade() { - Task { @MainActor in - BetterAlert().withInformation( - title: "updater.alerts.is_latest_version.title".localized, - subtitle: "updater.alerts.is_latest_version.subtitle".localized(App.shortVersion), - description: "" - ) - .withPrimary(text: "generic.ok".localized) - .show() - } - } - - private static func notifyAboutNewerVersion(version: AppVersion) { - let devSuffix = isDev ? "-dev" : "" - let command = isDev ? "brew upgrade phpmon-dev" : "brew upgrade phpmon" - - Task { @MainActor in - BetterAlert().withInformation( - title: "updater.alerts.newer_version_available.title".localized(version.humanReadable), - subtitle: "updater.alerts.newer_version_available.subtitle".localized, - description: HomebrewDiagnostics.customCaskInstalled - ? "updater.installation_source.brew".localized(command) - : "updater.installation_source.direct".localized - ) - .withPrimary( - text: "updater.alerts.buttons.install".localized, - action: { vc in - Self.installUpdate() - vc.close(with: .OK) - } - ) - .withSecondary( - text: "updater.alerts.buttons.release_notes".localized, - action: { vc in - vc.close(with: .OK) - - NSWorkspace.shared.open( - Constants.Urls.GitHubReleases.appendingPathComponent("/tag/v\(version.tagged)\(devSuffix)") - ) - } - ) - .withTertiary(text: "Dismiss", action: { vc in - vc.close(with: .OK) - }) - .show() - } - } - - private static func installUpdate() { - let updater = Bundle.main.resourceURL!.path + "/PHP Monitor Self-Updater.app" - - system_quiet("mkdir -p ~/.config/phpmon/updater 2> /dev/null") - - let updaterDirectory = "~/.config/phpmon/updater" - .replacingOccurrences(of: "~", with: NSHomeDirectory()) - - system_quiet("cp -R \"\(updater)\" \"\(updaterDirectory)/PHP Monitor Self-Updater.app\"") - - let sha256 = system("echo \"\(Self.latestCaskFileContents)\" | grep sha256") - .trimmingCharacters(in: .whitespacesAndNewlines) - .replacingOccurrences(of: "'", with: "") - .split(separator: " ").last ?? "" - - let url = system("echo \"\(Self.latestCaskFileContents)\" | grep url") - .trimmingCharacters(in: .whitespacesAndNewlines) - .replacingOccurrences(of: "'", with: "") - .split(separator: " ").last ?? "" - - try! FileSystem.writeAtomicallyToFile( - "\(updaterDirectory)/update.json", - content: """ - { "url": "\(url)", "sha256": "\(sha256)" } - """ - ) - - let updaterUrl = NSURL(fileURLWithPath: updater, isDirectory: true) as URL - let configuration = NSWorkspace.OpenConfiguration() - NSWorkspace.shared.openApplication(at: updaterUrl, configuration: configuration) { _, _ in - print("The updater has been launched successfully!") - } - } - - private static func notifyAboutConnectionIssue() { - Task { @MainActor in - BetterAlert().withInformation( - title: "updater.alerts.cannot_check_for_update.title".localized, - subtitle: "updater.alerts.cannot_check_for_update.subtitle".localized, - description: "updater.alerts.cannot_check_for_update.description".localized( - App.version - ) - ) - .withTertiary( - text: "updater.alerts.buttons.releases_on_github".localized, - action: { _ in - NSWorkspace.shared.open(Constants.Urls.GitHubReleases) - } - ) - .withPrimary(text: "generic.ok".localized) - .show() - } - } - -} diff --git a/phpmon/Domain/App/AppUpdater.swift b/phpmon/Domain/App/AppUpdater.swift index 4517e5e..9e867d9 100644 --- a/phpmon/Domain/App/AppUpdater.swift +++ b/phpmon/Domain/App/AppUpdater.swift @@ -7,75 +7,160 @@ // import Foundation +import Cocoa class AppUpdater { + var caskFile: CaskFile! + var latestVersionOnline: AppVersion! + var interactive: Bool = false - public func checkForUpdates(background: Bool) async { - if background && !Preferences.isEnabled(.automaticBackgroundUpdateCheck) { + public func checkForUpdates(interactive: Bool) async { + self.interactive = interactive + + if interactive && !Preferences.isEnabled(.automaticBackgroundUpdateCheck) { Log.info("Skipping automatic update check due to user preference.") return } Log.info("The app will search for updates...") - let caskUrl = App.version.contains("-dev") + let caskUrl = App.identifier.contains(".dev") ? Constants.Urls.DevBuildCaskFile : Constants.Urls.StableBuildCaskFile guard let caskFile = await CaskFile.from(url: caskUrl) else { Log.err("The contents of the CaskFile at '\(caskUrl.absoluteString)' could not be retrieved.") - - if !background { - return presentCouldNotRetrieveUpdate() - } else { - return - } + return presentCouldNotRetrieveUpdateIfInteractive() } self.caskFile = caskFile - if newerVersionExists() { - presentNewerVersionAvailableAlert() - } else { - if !background { - presentNoNewerVersionAvailableAlert() - } - } - } - - var caskFile: CaskFile! - - public func newerVersionExists() -> Bool { let currentVersion = AppVersion.fromCurrentVersion() guard let onlineVersion = AppVersion.from(caskFile.version) else { Log.err("The version string from the CaskFile could not be read.") - return false + return presentCouldNotRetrieveUpdateIfInteractive() } - Log.info("You are running \(currentVersion.computerReadable). The latest version is: \(onlineVersion.computerReadable).") + latestVersionOnline = onlineVersion + Log.info("The latest version read from '\(caskUrl.lastPathComponent)' is: v\(onlineVersion.computerReadable).") - // Do the comparison w/ current version - return true + if latestVersionOnline > currentVersion { + presentNewerVersionAvailableAlert() + } else if interactive { + presentNoNewerVersionAvailableAlert() + } } + private func presentCouldNotRetrieveUpdateIfInteractive() { + if interactive { + return presentCouldNotRetrieveUpdate() + } else { + return + } + } + + // MARK: - Alerts + public func presentNewerVersionAvailableAlert() { - print("A newer version is available") + let command = App.identifier.contains(".dev") + ? "brew upgrade phpmon-dev" + : "brew upgrade phpmon" + + Task { @MainActor in + BetterAlert().withInformation( + title: "updater.alerts.newer_version_available.title" + .localized(latestVersionOnline.humanReadable), + subtitle: "updater.alerts.newer_version_available.subtitle" + .localized, + description: HomebrewDiagnostics.customCaskInstalled + ? "updater.installation_source.brew".localized(command) + : "updater.installation_source.direct".localized + ) + .withPrimary( + text: "updater.alerts.buttons.install".localized, + action: { vc in + self.prepareForDownload() + vc.close(with: .OK) + } + ) + .withSecondary( + text: "updater.alerts.buttons.release_notes".localized, + action: { _ in + let urlSegments = self.caskFile.url.split(separator: "/") + let tag = urlSegments[urlSegments.count - 2] // ../download/{tag}/{file.zip} + NSWorkspace.shared.open( + Constants.Urls.GitHubReleases.appendingPathComponent("/tag/\(tag)") + ) + } + ) + .withTertiary(text: "updater.alerts.buttons.dismiss".localized, action: { vc in + vc.close(with: .OK) + }) + .show() + } } public func presentNoNewerVersionAvailableAlert() { - print("No newer version is available") + Task { @MainActor in + BetterAlert().withInformation( + title: "updater.alerts.is_latest_version.title".localized, + subtitle: "updater.alerts.is_latest_version.subtitle".localized(App.shortVersion), + description: "" + ) + .withPrimary(text: "generic.ok".localized) + .show() + } } public func presentCouldNotRetrieveUpdate() { - print("Could not retrieve update") + Task { @MainActor in + BetterAlert().withInformation( + title: "updater.alerts.cannot_check_for_update.title".localized, + subtitle: "updater.alerts.cannot_check_for_update.subtitle".localized, + description: "updater.alerts.cannot_check_for_update.description".localized( + App.version + ) + ) + .withTertiary( + text: "updater.alerts.buttons.releases_on_github".localized, + action: { _ in + NSWorkspace.shared.open(Constants.Urls.GitHubReleases) + } + ) + .withPrimary(text: "generic.ok".localized) + .show() + } } + // MARK: - Preparing for Self-Updater + private func prepareForDownload() { + let updater = Bundle.main.resourceURL!.path + "/PHP Monitor Self-Updater.app" + system_quiet("mkdir -p ~/.config/phpmon/updater 2> /dev/null") + + let updaterDirectory = "~/.config/phpmon/updater" + .replacingOccurrences(of: "~", with: NSHomeDirectory()) + + system_quiet("cp -R \"\(updater)\" \"\(updaterDirectory)/PHP Monitor Self-Updater.app\"") + + try! FileSystem.writeAtomicallyToFile( + "\(updaterDirectory)/update.json", + content: "{ \"url\": \"\(caskFile.url)\", \"sha256\": \"\(caskFile.sha256)\" }" + ) + + let updaterUrl = NSURL(fileURLWithPath: updater, isDirectory: true) as URL + let configuration = NSWorkspace.OpenConfiguration() + + NSWorkspace.shared.openApplication(at: updaterUrl, configuration: configuration) { _, _ in + Log.info("The updater has been launched successfully!") + } } - public static func checkIfUpgradeWasPerformed() { + // MARK: - Checking if Self-Updater Worked + + public static func checkIfUpdateWasPerformed() { if FileSystem.fileExists("~/.config/phpmon/updater/upgrade.success") { // Send a notification about the update Task { @MainActor in diff --git a/phpmon/Domain/App/AppVersion.swift b/phpmon/Domain/App/AppVersion.swift index 04d0f69..5d020af 100644 --- a/phpmon/Domain/App/AppVersion.swift +++ b/phpmon/Domain/App/AppVersion.swift @@ -87,7 +87,7 @@ class AppVersion: Comparable { static func < (lhs: AppVersion, rhs: AppVersion) -> Bool { let comparisonResult = lhs.version.versionCompare(rhs.version) - if comparisonResult == .orderedDescending { + if comparisonResult == .orderedAscending { return true } diff --git a/phpmon/Domain/Integrations/Homebrew/CaskFile.swift b/phpmon/Domain/Integrations/Homebrew/CaskFile.swift index c1ebea1..c2ddf0b 100644 --- a/phpmon/Domain/Integrations/Homebrew/CaskFile.swift +++ b/phpmon/Domain/Integrations/Homebrew/CaskFile.swift @@ -75,5 +75,4 @@ struct CaskFile { return CaskFile(properties: props) } - } diff --git a/phpmon/Domain/Menu/MainMenu+Startup.swift b/phpmon/Domain/Menu/MainMenu+Startup.swift index c25bebe..dc5d183 100644 --- a/phpmon/Domain/Menu/MainMenu+Startup.swift +++ b/phpmon/Domain/Menu/MainMenu+Startup.swift @@ -112,10 +112,7 @@ extension MainMenu { } } - // await AppUpdateChecker.checkIfNewerVersionIsAvailable() - await AppUpdater().checkForUpdates(background: true) - - exit(0) + await AppUpdater().checkForUpdates(interactive: false) } // Check if the linked version has changed between launches of phpmon @@ -125,7 +122,7 @@ extension MainMenu { Log.info("PHP Monitor is ready to serve!") // Check if we upgraded just now - AppUpdater.checkIfUpgradeWasPerformed() + AppUpdater.checkIfUpdateWasPerformed() } /** diff --git a/phpmon/Domain/Menu/MainMenu.swift b/phpmon/Domain/Menu/MainMenu.swift index f8fd480..1675fe7 100644 --- a/phpmon/Domain/Menu/MainMenu.swift +++ b/phpmon/Domain/Menu/MainMenu.swift @@ -199,7 +199,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate } @objc func checkForUpdates() { - Task { await AppUpdateChecker.checkIfNewerVersionIsAvailable(initiatedFromBackground: false) } + Task { await AppUpdater().checkForUpdates(interactive: true) } } // MARK: - Menu Delegate diff --git a/phpmon/Localizable.strings b/phpmon/Localizable.strings index 6c052e4..eaa0e4d 100644 --- a/phpmon/Localizable.strings +++ b/phpmon/Localizable.strings @@ -623,8 +623,8 @@ COMMON TROUBLESHOOTING TIPS "updater.alerts.newer_version_available.title" = "PHP Monitor v%@ is now available!"; "updater.alerts.newer_version_available.subtitle" = "Keeping PHP Monitor up-to-date is highly recommended, since newer versions usually fix bugs and include fixes to support the latest versions of Valet and PHP."; -"updater.installation_source.brew" = "The recommended method of installing updates to PHP Monitor is to simply press 'Install Update'. This will launch the separate PHP Monitor Self-Updater, which will update the app. You may also upgrade via the terminal by running `%@`."; -"updater.installation_source.direct" = "The recommended method of installing updates to PHP Monitor is to simply press 'Install Update'. This will launch the separate PHP Monitor Self-Updater, which will update the app."; +"updater.installation_source.brew" = "The recommended method of installing updates to PHP Monitor is to simply press 'Install Update'.\n\n(You may also upgrade via the terminal by running `%@`, but this is not recommended.)"; +"updater.installation_source.direct" = "The recommended method of installing updates to PHP Monitor is to simply press 'Install Update'."; "updater.alerts.buttons.release_notes" = "View Release Notes"; "updater.alerts.is_latest_version.title" = "PHP Monitor is up-to-date!"; @@ -635,6 +635,7 @@ COMMON TROUBLESHOOTING TIPS "updater.alerts.cannot_check_for_update.description" = "The currently installed version is: %@. You can go to the list of the latest releases (on GitHub) by clicking on the button on the left."; "updater.alerts.buttons.releases_on_github" = "View Releases"; "updater.alerts.buttons.install" = "Install Update"; +"updater.alerts.buttons.dismiss" = "Dismiss"; // WARNINGS ABOUT NON-DEFAULT TLD diff --git a/tests/unit/Parsers/CaskFileParserTest.swift b/tests/unit/Parsers/CaskFileParserTest.swift index df065d3..5e1c18b 100644 --- a/tests/unit/Parsers/CaskFileParserTest.swift +++ b/tests/unit/Parsers/CaskFileParserTest.swift @@ -49,4 +49,5 @@ class CaskFileParserTest: XCTestCase { XCTAssertTrue(caskFile.properties.keys.contains("url")) XCTAssertTrue(caskFile.properties.keys.contains("appcast")) } + } diff --git a/tests/unit/Versions/AppVersionTest.swift b/tests/unit/Versions/AppVersionTest.swift index 1ff9836..6886bae 100644 --- a/tests/unit/Versions/AppVersionTest.swift +++ b/tests/unit/Versions/AppVersionTest.swift @@ -60,21 +60,17 @@ class AppVersionTest: XCTestCase { } func test_can_compare_version_numbers() { - var first = AppVersion.from("5.0_100")! - var second = AppVersion.from("5.0_101")! - XCTAssertTrue(second > first) + // Build is newer + XCTAssertTrue(AppVersion.from("5.0_101")! > AppVersion.from("5.0_100")!) - first = AppVersion.from("5.0_100")! - second = AppVersion.from("5.0_100")! - XCTAssertFalse(second > first) + // Version and build is the same + XCTAssertFalse(AppVersion.from("5.0.0_100")! > AppVersion.from("5.0_100")!) - first = AppVersion.from("5.0_100")! - second = AppVersion.from("5.0.1_100")! - XCTAssertFalse(second > first) + // Version is newer + XCTAssertTrue(AppVersion.from("5.1_100")! > AppVersion.from("5.0_100")!) - first = AppVersion.from("5.0_102")! - second = AppVersion.from("5.0_101")! - XCTAssertFalse(second > first) + // Build is older + XCTAssertFalse(AppVersion.from("5.0_101")! > AppVersion.from("5.0_102")!) } }