From aaa814ac9c46f720399e47d30e099a4f8f1fb129 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Thu, 2 Mar 2023 20:27:30 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=20WIP:=20Respond=20directly=20to?= =?UTF-8?q?=20PHP=20binary=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PHP Monitor.xcodeproj/project.pbxproj | 10 ++++++++++ phpmon/Common/Helpers/FSNotifier.swift | 23 +--------------------- phpmon/Common/Helpers/Measurements.swift | 17 ++++++++++++++++ phpmon/Common/PHP/PHP Version/PhpEnv.swift | 4 ++++ phpmon/Domain/App/App.swift | 3 +++ phpmon/Domain/App/AppDelegate.swift | 20 ------------------- phpmon/Domain/App/Startup.swift | 7 ++++--- phpmon/Domain/Menu/MainMenu+Startup.swift | 17 +++++++++++++++- 8 files changed, 55 insertions(+), 46 deletions(-) create mode 100644 phpmon/Common/Helpers/Measurements.swift diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index b955110..3ba8f76 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -540,6 +540,10 @@ C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; }; C4998F0A2617633900B2526E /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4998F092617633900B2526E /* PreferencesWindowController.swift */; }; C4998F0B2617633900B2526E /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4998F092617633900B2526E /* PreferencesWindowController.swift */; }; + C49EAA5229B12A5A00AB28FC /* Measurements.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5129B12A5A00AB28FC /* Measurements.swift */; }; + C49EAA5329B12A5A00AB28FC /* Measurements.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5129B12A5A00AB28FC /* Measurements.swift */; }; + C49EAA5429B12A5A00AB28FC /* Measurements.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5129B12A5A00AB28FC /* Measurements.swift */; }; + C49EAA5529B12A5A00AB28FC /* Measurements.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5129B12A5A00AB28FC /* Measurements.swift */; }; C4A6957628D23EE300A14CF8 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; }; C4A6957728D23EE300A14CF8 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; }; C4A81CA428C67101008DD9D1 /* PMTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A81CA328C67101008DD9D1 /* PMTableView.swift */; }; @@ -899,6 +903,7 @@ C4930849279F331F009C240B /* AddSiteVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSiteVC.swift; sourceTree = ""; }; C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentCheck.swift; sourceTree = ""; }; C4998F092617633900B2526E /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; + C49EAA5129B12A5A00AB28FC /* Measurements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Measurements.swift; sourceTree = ""; }; C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentManager.swift; sourceTree = ""; }; C4A81CA328C67101008DD9D1 /* PMTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMTableView.swift; sourceTree = ""; }; C4AC51FB27E27F47008528CA /* DomainListKindCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListKindCell.swift; sourceTree = ""; }; @@ -1503,6 +1508,7 @@ C4D36614291160A1006BD146 /* WIP.swift */, C41ADCE72970CCC700120423 /* FSNotifier.swift */, C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */, + C49EAA5129B12A5A00AB28FC /* Measurements.swift */, ); path = Helpers; sourceTree = ""; @@ -2225,6 +2231,7 @@ C4EC1E73279DFCF40010F296 /* Events.swift in Sources */, C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */, C4C8900528F0E3D100CE5E97 /* RealFileSystem.swift in Sources */, + C49EAA5229B12A5A00AB28FC /* Measurements.swift in Sources */, C4A81CA428C67101008DD9D1 /* PMTableView.swift in Sources */, C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */, C4CE7F9629683B43000102CF /* PhpVersionNumberCollection.swift in Sources */, @@ -2337,6 +2344,7 @@ C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */, C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */, C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */, + C49EAA5429B12A5A00AB28FC /* Measurements.swift in Sources */, C471E86128F9BB650021E251 /* AddSiteVC.swift in Sources */, C471E86228F9BB650021E251 /* AddProxyVC.swift in Sources */, C471E86328F9BB650021E251 /* PMTableView.swift in Sources */, @@ -2486,6 +2494,7 @@ C471E8B028F9BB8F0021E251 /* ActivePhpInstallation+Checks.swift in Sources */, C471E8B128F9BB8F0021E251 /* MainMenu.swift in Sources */, C471E8B228F9BB8F0021E251 /* MainMenu+Startup.swift in Sources */, + C49EAA5529B12A5A00AB28FC /* Measurements.swift in Sources */, C471E8B328F9BB8F0021E251 /* MainMenu+Async.swift in Sources */, C471E8B428F9BB8F0021E251 /* MainMenu+Switcher.swift in Sources */, C471E8B528F9BB8F0021E251 /* MainMenu+FixMyValet.swift in Sources */, @@ -2716,6 +2725,7 @@ C4CE7F9729683B43000102CF /* PhpVersionNumberCollection.swift in Sources */, C4F30B09278E1A0E00755FCE /* CustomPrefs.swift in Sources */, C40FE738282ABA4F00A302C2 /* AppVersion.swift in Sources */, + C49EAA5329B12A5A00AB28FC /* Measurements.swift in Sources */, C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */, C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */, C4AF9F78275447F100D44ED0 /* ValetConfigurationTest.swift in Sources */, diff --git a/phpmon/Common/Helpers/FSNotifier.swift b/phpmon/Common/Helpers/FSNotifier.swift index ca4a678..349d78e 100644 --- a/phpmon/Common/Helpers/FSNotifier.swift +++ b/phpmon/Common/Helpers/FSNotifier.swift @@ -16,9 +16,7 @@ class FSNotifier { public static var shared: FSNotifier! = nil let queue = DispatchQueue(label: "FSWatch2Queue", attributes: .concurrent) - var lastUpdate: TimeInterval? - var linked: Bool private var fileDescriptor: CInt = -1 private var dispatchSource: DispatchSourceFileSystemObject? @@ -28,9 +26,6 @@ class FSNotifier { init(for url: URL, eventMask: DispatchSource.FileSystemEvent, onChange: @escaping () -> Void) { self.url = url - self.linked = FileSystem.fileExists(Paths.php) - Log.info("[FSN] Initial PHP linked state: \(linked ? "linked" : "unlinked")") - fileDescriptor = open(url.path, O_EVTONLY) dispatchSource = DispatchSource.makeFileSystemObjectSource( @@ -43,27 +38,11 @@ class FSNotifier { let distance = self.lastUpdate?.distance(to: Date().timeIntervalSince1970) if distance == nil || distance != nil && distance! > 1.00 { - print("FS event fired, checking in 1s, no duplicate FS events will be acted upon") - + // FS event fired, checking in 1s, no duplicate FS events will be acted upon self.lastUpdate = Date().timeIntervalSince1970 Task { await delay(seconds: 1) - - let newLinked = FileSystem.fileExists(Paths.php) - - if newLinked != self.linked { - self.linked = newLinked - - Log.info("The status of the PHP binary has changed!") - - if newLinked { - Log.info("php is linked") - } else { - Log.info("php is not linked") - } - } - onChange() } } diff --git a/phpmon/Common/Helpers/Measurements.swift b/phpmon/Common/Helpers/Measurements.swift new file mode 100644 index 0000000..d0ff231 --- /dev/null +++ b/phpmon/Common/Helpers/Measurements.swift @@ -0,0 +1,17 @@ +// +// Measurements.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 02/03/2023. +// Copyright © 2023 Nico Verbruggen. All rights reserved. +// + +import Foundation + +public struct Measurement { + let started = Date() + + var milliseconds: Double { + return round(Date().timeIntervalSince(started) * 1000 * 1000) / 1000 + } +} diff --git a/phpmon/Common/PHP/PHP Version/PhpEnv.swift b/phpmon/Common/PHP/PHP Version/PhpEnv.swift index 198687e..d5cb0bb 100644 --- a/phpmon/Common/PHP/PHP Version/PhpEnv.swift +++ b/phpmon/Common/PHP/PHP Version/PhpEnv.swift @@ -16,6 +16,10 @@ class PhpEnv { self.currentInstall = ActivePhpInstallation.load() } + static func prepare() { + _ = Self.shared + } + func determinePhpAlias() async { let brewPhpAlias = await Shell.pipe("\(Paths.brew) info php --json").out diff --git a/phpmon/Domain/App/App.swift b/phpmon/Domain/App/App.swift index bfb5659..8adc4c0 100644 --- a/phpmon/Domain/App/App.swift +++ b/phpmon/Domain/App/App.swift @@ -86,6 +86,9 @@ class App { /** The warning manager, responsible for keeping track of warnings. */ var warnings = WarningManager.shared + /** The filesystem watchers, responsible for keeping track of changes to the PHP installation. */ + var watchers: [FSNotifier.Kind: FSNotifier] = [:] + /** Timer that will periodically reload info about the user's PHP installation. */ var timer: Timer? diff --git a/phpmon/Domain/App/AppDelegate.swift b/phpmon/Domain/App/AppDelegate.swift index 6012996..f0cf1d3 100644 --- a/phpmon/Domain/App/AppDelegate.swift +++ b/phpmon/Domain/App/AppDelegate.swift @@ -50,11 +50,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele */ var logger = Log.shared - /** - - */ - var watchers: [FSNotifier.Kind: FSNotifier] = [:] - // MARK: - Initializer /** @@ -114,24 +109,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele func applicationDidFinishLaunching(_ aNotification: Notification) { // Make sure notifications will work setupNotifications() - // Make sure the watchers are set up - // TODO: Move to after startup - // self.watchHomebrewBinFolder() Task { // Make sure the menu performs its initial checks await menu.startup() } } - - func watchHomebrewBinFolder() { - self.watchers[.homebrewLocks] = FSNotifier( - for: URL(fileURLWithPath: Paths.binPath), - eventMask: .all, - onChange: { - // Removing requires termination and then removing reference - // self.watchers[.homebrewLocks]?.terminate() - // self.watchers[.homebrewLocks] = nil - } - ) - } } diff --git a/phpmon/Domain/App/Startup.swift b/phpmon/Domain/App/Startup.swift index c53b54b..448209c 100644 --- a/phpmon/Domain/App/Startup.swift +++ b/phpmon/Domain/App/Startup.swift @@ -25,13 +25,14 @@ class Startup { if group.condition() { Log.info("Now running \(group.checks.count) \(group.name) checks!") for check in group.checks { + let start = Measurement() if await check.succeeds() { - Log.info("[PASS] \(check.name)") + Log.info("[PASS] \(check.name) (\(start.milliseconds) ms)") continue } // If we get here, something's gone wrong and the check has failed... - Log.info("[FAIL] \(check.name)") + Log.info("[FAIL] \(check.name) (\(start.milliseconds) ms)") await showAlert(for: check) return false } @@ -232,7 +233,7 @@ class Startup { return await Shell.pipe("valet --version").out .contains("Composer detected issues in your platform") }, - name: "`no global composer issues", + name: "no global composer issues", titleText: "startup.errors.global_composer_platform_issues.title".localized, subtitleText: "startup.errors.global_composer_platform_issues.subtitle".localized, descriptionText: "startup.errors.global_composer_platform_issues.desc".localized diff --git a/phpmon/Domain/Menu/MainMenu+Startup.swift b/phpmon/Domain/Menu/MainMenu+Startup.swift index 8ed3b95..afbd036 100644 --- a/phpmon/Domain/Menu/MainMenu+Startup.swift +++ b/phpmon/Domain/Menu/MainMenu+Startup.swift @@ -66,7 +66,22 @@ extension MainMenu { updatePhpVersionInStatusBar() // Attempt to find out if PHP-FPM is broken - let installation = PhpEnv.phpInstall + PhpEnv.prepare() + + // Set up the filesystem watcher for the Homebrew binaries + App.shared.watchers[.homebrewBinaries] = FSNotifier( + for: URL(fileURLWithPath: Paths.binPath), + eventMask: .all, + onChange: { + Task { + await PhpEnv.detectPhpVersions() + MainMenu.shared.refreshActiveInstallation() + } + // Removing requires termination and then removing reference + // self.watchers[.homebrewBinaries]?.terminate() + // self.watchers[.homebrewBinaries] = nil + } + ) // Check for other problems WarningManager.shared.evaluateWarnings()