From 155b57eb9ee2f8e81c694bbd4fa6a552b06d49ef Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Wed, 27 Dec 2023 12:40:35 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Add=20incorrect=20PHP=20symlink?= =?UTF-8?q?=20purge=20(#270)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces a new diagnostics feature which is executed when the app boots. When the app boots, the integrity of the PHP symlinks are checked to ensure that all symlinks correctly link to a valid PHP version. If any links to an incorrect PHP version, then those outdated or incorrect symlinks will be removed. For example, if `php@8.2` links to `../Cellar/php/8.3.0` then that is an obvious reason for that symlink to be purged because it links to the incorrect version. (This example behaviour has been noted in #270.) This occurs prior to the rest of the startup process, so this way no incorrect PHP versions can pop up in the version switcher, and no incorrect PHP version is reported as being installed when managing installed PHP versions. --- PHP Monitor.xcodeproj/project.pbxproj | 12 ++-- .../PHP/Switcher/InternalSwitcher+Valet.swift | 66 ++++++++++--------- .../Homebrew/BrewDiagnostics.swift | 36 ++++++++++ phpmon/Domain/Menu/MainMenu+Startup.swift | 3 + 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 7b2faec..3355369 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -3647,7 +3647,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1400; + CURRENT_PROJECT_VERSION = 1405; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -3678,7 +3678,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1400; + CURRENT_PROJECT_VERSION = 1405; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; @@ -3918,7 +3918,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1400; + CURRENT_PROJECT_VERSION = 1405; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4034,7 +4034,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1400; + CURRENT_PROJECT_VERSION = 1405; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4150,7 +4150,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1400; + CURRENT_PROJECT_VERSION = 1405; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4331,7 +4331,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1400; + CURRENT_PROJECT_VERSION = 1405; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; diff --git a/phpmon/Common/PHP/Switcher/InternalSwitcher+Valet.swift b/phpmon/Common/PHP/Switcher/InternalSwitcher+Valet.swift index 83de877..1f57091 100644 --- a/phpmon/Common/PHP/Switcher/InternalSwitcher+Valet.swift +++ b/phpmon/Common/PHP/Switcher/InternalSwitcher+Valet.swift @@ -27,7 +27,7 @@ extension InternalSwitcher { return corrections.contains(true) } - // MARK: - PHP FPM pool + // MARK: - Corrections public func disableDefaultPhpFpmPool(_ version: String) async -> FixApplied { let pool = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf" @@ -54,37 +54,7 @@ extension InternalSwitcher { return false } - func getExpectedConfigurationFiles(for version: String) -> [ExpectedConfigurationFile] { - return [ - ExpectedConfigurationFile( - destination: "/php-fpm.d/valet-fpm.conf", - source: "/cli/stubs/etc-phpfpm-valet.conf", - replacements: [ - "VALET_USER": Paths.whoami, - "VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory, - "valet.sock": "valet\(version.replacingOccurrences(of: ".", with: "")).sock" - ], - applies: { Valet.shared.version!.major > 2 } - ), - ExpectedConfigurationFile( - destination: "/conf.d/error_log.ini", - source: "/cli/stubs/etc-phpfpm-error_log.ini", - replacements: [ - "VALET_USER": Paths.whoami, - "VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory - ], - applies: { return true } - ), - ExpectedConfigurationFile( - destination: "/conf.d/php-memory-limits.ini", - source: "/cli/stubs/php-memory-limits.ini", - replacements: [:], - applies: { return true } - ) - ] - } - - func ensureConfigurationFilesExist(_ version: String) async -> FixApplied { + public func ensureConfigurationFilesExist(_ version: String) async -> FixApplied { let files = self.getExpectedConfigurationFiles(for: version) // For each of the files, attempt to fix anything that is wrong @@ -124,6 +94,38 @@ extension InternalSwitcher { return outcomes.contains(true) } + // MARK: - Internals + + private func getExpectedConfigurationFiles(for version: String) -> [ExpectedConfigurationFile] { + return [ + ExpectedConfigurationFile( + destination: "/php-fpm.d/valet-fpm.conf", + source: "/cli/stubs/etc-phpfpm-valet.conf", + replacements: [ + "VALET_USER": Paths.whoami, + "VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory, + "valet.sock": "valet\(version.replacingOccurrences(of: ".", with: "")).sock" + ], + applies: { Valet.shared.version!.major > 2 } + ), + ExpectedConfigurationFile( + destination: "/conf.d/error_log.ini", + source: "/cli/stubs/etc-phpfpm-error_log.ini", + replacements: [ + "VALET_USER": Paths.whoami, + "VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory + ], + applies: { return true } + ), + ExpectedConfigurationFile( + destination: "/conf.d/php-memory-limits.ini", + source: "/cli/stubs/php-memory-limits.ini", + replacements: [:], + applies: { return true } + ) + ] + } + } public struct ExpectedConfigurationFile { diff --git a/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift b/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift index 1141a62..8a6eb68 100644 --- a/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift +++ b/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift @@ -46,6 +46,42 @@ class BrewDiagnostics { return destination.contains("/nginx-full/") }() + /** + It is possible to have outdated symlinks for PHP installations. This can mean that certain PHP installations + are going to be reported incorrectly (e.g. `php@8.2` links to an installation in a `8.3` folder after an upgrade). + + To ensure this does not cause issues, PHP Monitor will automatically remove all incorrect PHP symlinks. + */ + public static func checkForOutdatedPhpInstallationSymlinks() async { + // Set up a regular expression + let regex = try! NSRegularExpression(pattern: "^php@[0-9]+\\.[0-9]+$", options: .caseInsensitive) + + // Check for incorrect versions + if let contents = try? FileSystem.getShallowContentsOfDirectory("\(Paths.optPath)") + .filter({ + let range = NSRange($0.startIndex..., in: $0) + return regex.firstMatch(in: $0, options: [], range: range) != nil + }) { + + for symlink in contents { + let version = symlink.replacingOccurrences(of: "php@", with: "") + if let destination = try? FileSystem.getDestinationOfSymlink("\(Paths.optPath)/\(symlink)") { + if !destination.contains("Cellar/php/\(version)") + && !destination.contains("Cellar/php@\(version)") { + Log.err("Symlink for \(symlink) is incorrect and was likely not purged correctly after upgrading. Removing...") + do { + try FileSystem.remove("\(Paths.optPath)/\(symlink)") + } catch { + Log.err("Symlink for \(symlink) was incorrect but could not be removed!") + } + } + } else { + Log.warn("Could not read symlink at: \(Paths.optPath)/\(symlink)! Symlink check skipped.") + } + } + } + } + /** It is possible to have the `shivammathur/php` tap installed, and for the core homebrew information to be outdated. This will then result in two different aliases claiming to point to the same formula (`php`). diff --git a/phpmon/Domain/Menu/MainMenu+Startup.swift b/phpmon/Domain/Menu/MainMenu+Startup.swift index 1da66fe..34ce7f5 100644 --- a/phpmon/Domain/Menu/MainMenu+Startup.swift +++ b/phpmon/Domain/Menu/MainMenu+Startup.swift @@ -32,6 +32,9 @@ extension MainMenu { // Determine what the `php` formula is aliased to await PhpEnvironments.shared.determinePhpAlias() + // Make sure that broken symlinks are removed ASAP + await BrewDiagnostics.checkForOutdatedPhpInstallationSymlinks() + // Initialize preferences _ = Preferences.shared