1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 20:10:08 +02:00

🏗 Improved version comparison

This commit is contained in:
2023-02-05 17:18:09 +01:00
parent 208a430066
commit 78e682688b
9 changed files with 109 additions and 44 deletions

View File

@ -91,7 +91,7 @@
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "--cli" argument = "--cli"
isEnabled = "YES"> isEnabled = "NO">
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_working.json" argument = "--configuration:~/.phpmon_fconf_working.json"
@ -99,7 +99,7 @@
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_working_no_valet.json" argument = "--configuration:~/.phpmon_fconf_working_no_valet.json"
isEnabled = "YES"> isEnabled = "NO">
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_broken.json" argument = "--configuration:~/.phpmon_fconf_broken.json"

View File

@ -116,7 +116,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
setupNotifications() setupNotifications()
// Make sure the watchers are set up // Make sure the watchers are set up
// TODO: Move to after startup // TODO: Move to after startup
self.watchHomebrewBinFolder() // self.watchHomebrewBinFolder()
Task { // Make sure the menu performs its initial checks Task { // Make sure the menu performs its initial checks
await paths.loadUser() await paths.loadUser()

View File

@ -108,12 +108,12 @@ class AppUpdateChecker {
_ onlineVersion: AppVersion, _ onlineVersion: AppVersion,
_ background: Bool _ background: Bool
) -> Bool { ) -> Bool {
if Int(onlineVersion.build!)! > Int(currentVersion.build!)! { if onlineVersion.build! > currentVersion.build! {
Log.info("There is a newer build of PHP Monitor available! " Log.info("There is a newer build of PHP Monitor available! "
+ "(\(onlineVersion.computerReadable) > \(currentVersion.computerReadable))") + "(\(onlineVersion.computerReadable) > \(currentVersion.computerReadable))")
notifyAboutNewerVersion(version: onlineVersion) notifyAboutNewerVersion(version: onlineVersion)
return true return true
} else if Int(onlineVersion.build!)! < Int(currentVersion.build!)! { } else if onlineVersion.build! < currentVersion.build! {
Log.info("You are running a newer build of PHP Monitor " Log.info("You are running a newer build of PHP Monitor "
+ "(\(currentVersion.computerReadable) > \(onlineVersion.computerReadable)).") + "(\(currentVersion.computerReadable) > \(onlineVersion.computerReadable)).")
if !background { notifyVersionDoesNotNeedUpgrade() } if !background { notifyVersionDoesNotNeedUpgrade() }

View File

@ -10,15 +10,26 @@ import Foundation
class AppUpdater { class AppUpdater {
var caskFile: CaskFile? public func checkForUpdates(background: Bool) async {
if background && !Preferences.isEnabled(.automaticBackgroundUpdateCheck) {
Log.info("Skipping automatic update check due to user preference.")
return
}
public func checkForUpdates(background: Bool) { Log.info("The app will search for updates...")
guard let caskFile = CaskFile.from(
url: App.version.contains("-dev") let caskUrl = App.version.contains("-dev")
? Constants.Urls.DevBuildCaskFile ? Constants.Urls.DevBuildCaskFile
: Constants.Urls.StableBuildCaskFile : Constants.Urls.StableBuildCaskFile
) else {
return presentCouldNotRetrieveUpdate() 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
}
} }
self.caskFile = caskFile self.caskFile = caskFile
@ -32,24 +43,49 @@ class AppUpdater {
} }
} }
var caskFile: CaskFile!
public func newerVersionExists() -> Bool { 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
}
Log.info("You are running \(currentVersion.computerReadable). The latest version is: \(onlineVersion.computerReadable).")
// Do the comparison w/ current version // Do the comparison w/ current version
return true return true
} }
public func presentNewerVersionAvailableAlert() { public func presentNewerVersionAvailableAlert() {
print("A newer version is available")
} }
public func presentNoNewerVersionAvailableAlert() { public func presentNoNewerVersionAvailableAlert() {
print("No newer version is available")
} }
public func presentCouldNotRetrieveUpdate() { public func presentCouldNotRetrieveUpdate() {
print("Could not retrieve update")
} }
private func prepareForDownload() { private func prepareForDownload() {
} }
public static func checkIfUpgradeWasPerformed() {
if FileSystem.fileExists("~/.config/phpmon/updater/upgrade.success") {
// Send a notification about the update
Task { @MainActor in
LocalNotification.send(
title: "notification.phpmon_updated.title".localized,
subtitle: "notification.phpmon_updated.desc".localized(App.shortVersion),
preference: nil
)
try! FileSystem.remove("~/.config/phpmon/updater/upgrade.success")
}
}
}
} }

View File

@ -8,14 +8,14 @@
import Foundation import Foundation
class AppVersion { class AppVersion: Comparable {
var version: String var version: String
var build: String? var build: Int?
var suffix: String? var suffix: String?
init(version: String, build: String?, suffix: String? = nil) { init(version: String, build: String?, suffix: String? = nil) {
self.version = version self.version = version
self.build = build self.build = Int(build ?? "0")
self.suffix = suffix self.suffix = suffix
} }
@ -75,11 +75,27 @@ class AppVersion {
} }
var computerReadable: String { var computerReadable: String {
return "\(version)_\(build ?? "0")" return "\(version)_\(build ?? 0)"
} }
var humanReadable: String { var humanReadable: String {
return "\(version) (\(build ?? "???"))" return "\(version) (\(build ?? 0))"
} }
// MARK: - Comparable Protocol
static func < (lhs: AppVersion, rhs: AppVersion) -> Bool {
let comparisonResult = lhs.version.versionCompare(rhs.version)
if comparisonResult == .orderedDescending {
return true
}
return lhs.build ?? 0 < rhs.build ?? 0
}
static func == (lhs: AppVersion, rhs: AppVersion) -> Bool {
lhs.version.versionCompare(rhs.version) == .orderedSame
&& lhs.build == rhs.build
}
} }

View File

@ -24,8 +24,14 @@ struct CaskFile {
return self.properties["version"]! return self.properties["version"]!
} }
public static func from(url: URL) -> CaskFile? { public static func from(url: URL) async -> CaskFile? {
let string = try? String(contentsOf: url) var string: String?
if url.scheme == "file" {
string = try? String(contentsOf: url)
} else {
string = await Shell.pipe("curl -s --max-time 10 '\(url.absoluteString)'").out
}
guard let string else { guard let string else {
Log.err("The content of the URL for the CaskFile could not be retrieved") Log.err("The content of the URL for the CaskFile could not be retrieved")

View File

@ -112,7 +112,10 @@ extension MainMenu {
} }
} }
await AppUpdateChecker.checkIfNewerVersionIsAvailable() // await AppUpdateChecker.checkIfNewerVersionIsAvailable()
await AppUpdater().checkForUpdates(background: true)
exit(0)
} }
// Check if the linked version has changed between launches of phpmon // Check if the linked version has changed between launches of phpmon
@ -122,7 +125,7 @@ extension MainMenu {
Log.info("PHP Monitor is ready to serve!") Log.info("PHP Monitor is ready to serve!")
// Check if we upgraded just now // Check if we upgraded just now
// self.checkIfUpgradeWasPerformed() AppUpdater.checkIfUpgradeWasPerformed()
} }
/** /**
@ -191,18 +194,4 @@ extension MainMenu {
Log.info("Detected applications: \(appNames)") Log.info("Detected applications: \(appNames)")
} }
private func checkIfUpgradeWasPerformed() {
if FileSystem.fileExists("~/.config/phpmon/updater/upgrade.success") {
// Send a notification about the update
Task { @MainActor in
LocalNotification.send(
title: "notification.phpmon_updated.title".localized,
subtitle: "notification.phpmon_updated.desc".localized(App.shortVersion),
preference: nil
)
try! FileSystem.remove("~/.config/phpmon/updater/upgrade.success")
}
}
}
} }

View File

@ -16,8 +16,8 @@ class CaskFileParserTest: XCTestCase {
.url(forResource: "phpmon-dev", withExtension: "rb")! .url(forResource: "phpmon-dev", withExtension: "rb")!
} }
func test_can_extract_fields_from_cask_file() throws { func test_can_extract_fields_from_cask_file() async throws {
guard let caskFile = CaskFile.from(url: CaskFileParserTest.exampleFilePath) else { guard let caskFile = await CaskFile.from(url: CaskFileParserTest.exampleFilePath) else {
return XCTFail("The CaskFile could not be parsed, check the log for more info") return XCTFail("The CaskFile could not be parsed, check the log for more info")
} }
@ -39,8 +39,8 @@ class CaskFileParserTest: XCTestCase {
) )
} }
func test_can_extract_fields_from_remote_cask_file() throws { func test_can_extract_fields_from_remote_cask_file() async throws {
guard let caskFile = CaskFile.from(url: Constants.Urls.StableBuildCaskFile) else { guard let caskFile = await CaskFile.from(url: Constants.Urls.StableBuildCaskFile) else {
return XCTFail("The remote CaskFile could not be parsed, check the log for more info") return XCTFail("The remote CaskFile could not be parsed, check the log for more info")
} }

View File

@ -28,7 +28,7 @@ class AppVersionTest: XCTestCase {
XCTAssertNotNil(version) XCTAssertNotNil(version)
XCTAssertEqual("1.0.0", version?.version) XCTAssertEqual("1.0.0", version?.version)
XCTAssertEqual("600", version?.build) XCTAssertEqual(600, version?.build)
XCTAssertEqual(nil, version?.suffix) XCTAssertEqual(nil, version?.suffix)
} }
@ -46,7 +46,7 @@ class AppVersionTest: XCTestCase {
XCTAssertNotNil(version) XCTAssertNotNil(version)
XCTAssertEqual("1.0.0", version?.version) XCTAssertEqual("1.0.0", version?.version)
XCTAssertEqual("870", version?.build) XCTAssertEqual(870, version?.build)
XCTAssertEqual("dev", version?.suffix) XCTAssertEqual("dev", version?.suffix)
} }
@ -55,8 +55,26 @@ class AppVersionTest: XCTestCase {
XCTAssertNotNil(version) XCTAssertNotNil(version)
XCTAssertEqual("1.0.0", version?.version) XCTAssertEqual("1.0.0", version?.version)
XCTAssertEqual("870", version?.build) XCTAssertEqual(870, version?.build)
XCTAssertEqual("dev", version?.suffix) XCTAssertEqual("dev", version?.suffix)
} }
func test_can_compare_version_numbers() {
var first = AppVersion.from("5.0_100")!
var second = AppVersion.from("5.0_101")!
XCTAssertTrue(second > first)
first = AppVersion.from("5.0_100")!
second = AppVersion.from("5.0_100")!
XCTAssertFalse(second > first)
first = AppVersion.from("5.0_100")!
second = AppVersion.from("5.0.1_100")!
XCTAssertFalse(second > first)
first = AppVersion.from("5.0_102")!
second = AppVersion.from("5.0_101")!
XCTAssertFalse(second > first)
}
} }