From 7159ca8612dbda50cd55cacc76e37e6207c3fa5a Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Fri, 24 Nov 2023 20:23:12 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Correctly=20handle=20mismatches?= =?UTF-8?q?=20when=20upgrading=20PHP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PHP/PHP Version/PhpEnvironments.swift | 36 +++++++++++++++++-- phpmon/Common/PHP/PhpInstallation.swift | 6 ++++ .../Integrations/Homebrew/BrewFormula.swift | 10 ++++-- .../Homebrew/BrewFormulaeHandler.swift | 7 ++-- .../UI/PhpVersionManagerView.swift | 8 +++-- phpmon/de.lproj/Localizable.strings | 1 + phpmon/en.lproj/Localizable.strings | 1 + phpmon/fr.lproj/Localizable.strings | 1 + phpmon/nl.lproj/Localizable.strings | 1 + phpmon/pt-PT.lproj/Localizable.strings | 1 + phpmon/vi.lproj/Localizable.strings | 1 + 11 files changed, 64 insertions(+), 9 deletions(-) diff --git a/phpmon/Common/PHP/PHP Version/PhpEnvironments.swift b/phpmon/Common/PHP/PHP Version/PhpEnvironments.swift index f33562a..5ac9069 100644 --- a/phpmon/Common/PHP/PHP Version/PhpEnvironments.swift +++ b/phpmon/Common/PHP/PHP Version/PhpEnvironments.swift @@ -37,7 +37,27 @@ class PhpEnvironments { from: brewPhpAlias.data(using: .utf8)! ).first! - Log.info("[BREW] On your system, the `php` formula means version \(homebrewPackage.version)!") + Log.info("[BREW] On your system, the `php` formula means version \(homebrewPackage.version).") + + // Check if that version actually corresponds to an older version + let phpConfigExecutablePath = "\(Paths.optPath)/php/bin/php-config" + if FileSystem.fileExists(phpConfigExecutablePath) { + let longVersionString = Command.execute( + path: phpConfigExecutablePath, + arguments: ["--version"], + trimNewlines: false + ).trimmingCharacters(in: .whitespacesAndNewlines) + + if let version = try? VersionNumber.parse(longVersionString) { + PhpEnvironments.brewPhpAlias = version.short + if version.short != homebrewPackage.version { + Log.info("[BREW] An older version of `php` is actually installed (\(version.short)).") + } + } else { + Log.warn("Could not determine the actual version of the php binary; assuming Homebrew is correct.") + PhpEnvironments.brewPhpAlias = homebrewPackage.version + } + } } // MARK: - Properties @@ -77,7 +97,12 @@ class PhpEnvironments { As such, we take that information from Homebrew. */ - static var brewPhpAlias: String { + static var brewPhpAlias: String = "" + + /** + It's possible for the alias to be newer than the actual installed version of PHP. + */ + static var homebrewBrewPhpAlias: String { if PhpEnvironments.shared.homebrewPackage == nil { return "8.2" } return PhpEnvironments.shared.homebrewPackage.version @@ -144,7 +169,12 @@ class PhpEnvironments { // Avoid inserting a duplicate if !supportedVersions.contains(phpAlias) && FileSystem.fileExists("\(Paths.optPath)/php/bin/php") { - supportedVersions.insert(phpAlias) + let phpAliasInstall = PhpInstallation(phpAlias) + // Before inserting, ensure that the actual output matches the alias + // if that isn't the case, our formula remains out-of-date + if !phpAliasInstall.missingBinary { + supportedVersions.insert(phpAlias) + } } availablePhpVersions = Array(supportedVersions) diff --git a/phpmon/Common/PHP/PhpInstallation.swift b/phpmon/Common/PHP/PhpInstallation.swift index 5658747..4c9c5de 100644 --- a/phpmon/Common/PHP/PhpInstallation.swift +++ b/phpmon/Common/PHP/PhpInstallation.swift @@ -12,6 +12,8 @@ class PhpInstallation { var versionNumber: VersionNumber + var missingBinary: Bool = false + var isHealthy: Bool = true /** @@ -35,6 +37,10 @@ class PhpInstallation { // The parser should always work, or the string has to be very unusual. // If so, the app SHOULD crash, so that the users report what's up. self.versionNumber = try! VersionNumber.parse(longVersionString) + } else { + // Keep track that the `php-config` binary is missing; this often means there's a mismatch between + // the `php` version alias and the actual installed version (e.g. you haven't upgraded `php`) + missingBinary = true } if FileSystem.fileExists(phpExecutablePath) { diff --git a/phpmon/Domain/Integrations/Homebrew/BrewFormula.swift b/phpmon/Domain/Integrations/Homebrew/BrewFormula.swift index 3291212..c663717 100644 --- a/phpmon/Domain/Integrations/Homebrew/BrewFormula.swift +++ b/phpmon/Domain/Integrations/Homebrew/BrewFormula.swift @@ -8,7 +8,7 @@ import Foundation -struct BrewFormula { +struct BrewFormula: Equatable { /// Name of the formula. let name: String @@ -48,6 +48,12 @@ struct BrewFormula { return upgradeVersion != nil } + /// Whether this formula alias is different. + var hasUpgradedFormulaAlias: Bool { + return self.shortVersion == PhpEnvironments.homebrewBrewPhpAlias + && PhpEnvironments.homebrewBrewPhpAlias != PhpEnvironments.brewPhpAlias + } + /// The associated Homebrew folder with this PHP formula. var homebrewFolder: String { let resolved = name @@ -60,7 +66,7 @@ struct BrewFormula { /// The short version associated with this formula, if installed. var shortVersion: String? { guard let version = self.installedVersion else { - return nil + return self.displayName.replacingOccurrences(of: "PHP ", with: "") } return VersionNumber.make(from: version)?.short ?? nil diff --git a/phpmon/Domain/Integrations/Homebrew/BrewFormulaeHandler.swift b/phpmon/Domain/Integrations/Homebrew/BrewFormulaeHandler.swift index 39d5b22..8ded2e7 100644 --- a/phpmon/Domain/Integrations/Homebrew/BrewFormulaeHandler.swift +++ b/phpmon/Domain/Integrations/Homebrew/BrewFormulaeHandler.swift @@ -44,7 +44,8 @@ class BrewFormulaeHandler: HandlesBrewFormulae { } return Brew.phpVersionFormulae.map { (version, formula) in - let fullVersion = PhpEnvironments.shared.cachedPhpInstallations[version]?.versionNumber.text + let fullVersion = PhpEnvironments.shared.cachedPhpInstallations[version]? + .versionNumber.text var upgradeVersion: String? @@ -54,13 +55,15 @@ class BrewFormulaeHandler: HandlesBrewFormulae { })?.current_version } - return BrewFormula( + let formula = BrewFormula( name: formula, displayName: "PHP \(version)", installedVersion: fullVersion, upgradeVersion: upgradeVersion, prerelease: Constants.ExperimentalPhpVersions.contains(version) ) + + return formula }.sorted { $0.displayName > $1.displayName } } } diff --git a/phpmon/Modules/PHP Version Manager/UI/PhpVersionManagerView.swift b/phpmon/Modules/PHP Version Manager/UI/PhpVersionManagerView.swift index ebe4a0a..00e9491 100644 --- a/phpmon/Modules/PHP Version Manager/UI/PhpVersionManagerView.swift +++ b/phpmon/Modules/PHP Version Manager/UI/PhpVersionManagerView.swift @@ -157,7 +157,11 @@ struct PhpVersionManagerView: View { } } - if formula.isInstalled && formula.hasUpgrade { + if formula.hasUpgradedFormulaAlias { + Text("phpman.version.automatic_upgrade".localized(formula.shortVersion!)) + .font(.system(size: 11)) + .foregroundColor(.gray) + } else if formula.isInstalled && formula.hasUpgrade { Text("phpman.version.has_update".localized( formula.installedVersion!, formula.upgradeVersion! @@ -195,7 +199,7 @@ struct PhpVersionManagerView: View { } else { Button("phpman.buttons.install".localizedForSwiftUI) { Task { await self.install(formula) } - } + }.disabled(formula.hasUpgradedFormulaAlias) } } .listRowBackground(index % 2 == 0 ? Color.gray.opacity(0): Color.gray.opacity(0.08)) diff --git a/phpmon/de.lproj/Localizable.strings b/phpmon/de.lproj/Localizable.strings index de087a7..245815b 100644 --- a/phpmon/de.lproj/Localizable.strings +++ b/phpmon/de.lproj/Localizable.strings @@ -90,6 +90,7 @@ "phpman.version.has_update" = "Version %@ installiert, %@ verfügbar."; "phpman.version.installed" = "Version %@ ist derzeit installiert."; "phpman.version.available_for_installation" = "Diese Version kann installiert werden."; +"phpman.version.automatic_upgrade" = "Diese Version wird automatisch installiert, indem eine ältere Version aktualisiert wird."; "phpman.buttons.uninstall" = "Deinstallieren"; "phpman.buttons.install" = "Installieren"; "phpman.buttons.update" = "Aktualisieren"; diff --git a/phpmon/en.lproj/Localizable.strings b/phpmon/en.lproj/Localizable.strings index bd5c8dd..126dde4 100644 --- a/phpmon/en.lproj/Localizable.strings +++ b/phpmon/en.lproj/Localizable.strings @@ -107,6 +107,7 @@ "phpman.version.has_update" = "Version %@ installed, %@ available."; "phpman.version.installed" = "Version %@ is currently installed."; "phpman.version.available_for_installation" = "This version can be installed."; +"phpman.version.automatic_upgrade" = "This version will be automatically installed by upgrading an older version."; "phpman.buttons.uninstall" = "Uninstall"; "phpman.buttons.install" = "Install"; "phpman.buttons.update" = "Update"; diff --git a/phpmon/fr.lproj/Localizable.strings b/phpmon/fr.lproj/Localizable.strings index 5e8fb13..ca0f010 100644 --- a/phpmon/fr.lproj/Localizable.strings +++ b/phpmon/fr.lproj/Localizable.strings @@ -107,6 +107,7 @@ "phpman.version.has_update" = "Version %@ installée, %@ disponible."; "phpman.version.installed" = "La version %@ est actuellement installée."; "phpman.version.available_for_installation" = "Cette version peut être installée."; +"phpman.version.automatic_upgrade" = "Cette version sera installée automatiquement en mettant à jour une version plus ancienne."; "phpman.buttons.uninstall" = "Désinstaller"; "phpman.buttons.install" = "Installer"; "phpman.buttons.update" = "Mettre à jour"; diff --git a/phpmon/nl.lproj/Localizable.strings b/phpmon/nl.lproj/Localizable.strings index c118a6e..23f1db4 100644 --- a/phpmon/nl.lproj/Localizable.strings +++ b/phpmon/nl.lproj/Localizable.strings @@ -91,6 +91,7 @@ "phpman.version.has_update" = "Versie %@ geïnstalleerd, %@ beschikbaar."; "phpman.version.installed" = "Versie %@ is momenteel geïnstalleerd."; "phpman.version.available_for_installation" = "Deze versie kan worden geïnstalleerd."; +"phpman.version.automatic_upgrade" = "Deze versie zal automatisch geïnstalleerd worden door een upgrade."; "phpman.buttons.uninstall" = "Verwijderen"; "phpman.buttons.install" = "Installeren"; "phpman.buttons.update" = "Bijwerken"; diff --git a/phpmon/pt-PT.lproj/Localizable.strings b/phpmon/pt-PT.lproj/Localizable.strings index 71cccf5..c3a73ce 100644 --- a/phpmon/pt-PT.lproj/Localizable.strings +++ b/phpmon/pt-PT.lproj/Localizable.strings @@ -90,6 +90,7 @@ "phpman.version.has_update" = "Versão %@ instalada, %@ disponível."; "phpman.version.installed" = "Versão %@ atualmente instalada."; "phpman.version.available_for_installation" = "Esta versão pode ser instalada."; +"phpman.version.automatic_upgrade" = "Esta versão será instalada automaticamente ao atualizar uma versão mais antiga."; "phpman.buttons.uninstall" = "Desinstalar"; "phpman.buttons.install" = "Instalar"; "phpman.buttons.update" = "Atualizar"; diff --git a/phpmon/vi.lproj/Localizable.strings b/phpmon/vi.lproj/Localizable.strings index e97c28e..2f54cfe 100644 --- a/phpmon/vi.lproj/Localizable.strings +++ b/phpmon/vi.lproj/Localizable.strings @@ -90,6 +90,7 @@ "phpman.version.has_update" = "Phiên bản %@ được cài đặt, Phiên bản %@ có sẵn."; "phpman.version.installed" = "Phiên bản %@ hiện đã được cài đặt."; "phpman.version.available_for_installation" = "Phiên bản này có thể được cài đặt."; +"phpman.version.automatic_upgrade" = "Phiên bản này sẽ được cài đặt tự động bằng cách nâng cấp từ một phiên bản cũ hơn."; "phpman.buttons.uninstall" = "Gỡ cài đặt"; "phpman.buttons.install" = "Cài đặt"; "phpman.buttons.update" = "Cập nhật";