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