From 6db5cdec25017f70de23562346971923b72f4215 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Fri, 7 Oct 2022 22:55:48 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Introduce=20SLOW=20SHELL=20and?= =?UTF-8?q?=20fix=20a=20few=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcschemes/PHP Monitor.xcscheme | 5 ++++ phpmon/Common/Helpers/Filesystem.swift | 23 ++++++++++++++++--- phpmon/Common/PHP/PHP Version/PhpHelper.swift | 8 +++++-- phpmon/Common/PHP/PhpExtension.swift | 4 ++++ phpmon/Common/Shell/SystemShell.swift | 8 +++++++ .../Testables/TestableConfigurations.swift | 1 - phpmon/Common/Testables/TestableShell.swift | 11 +++++++-- phpmon/Domain/Menu/MainMenu+Switcher.swift | 2 +- phpmon/Domain/Menu/MainMenu.swift | 4 +++- 9 files changed, 56 insertions(+), 10 deletions(-) diff --git a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor.xcscheme b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor.xcscheme index 1a553ad..0ed1bb3 100644 --- a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor.xcscheme +++ b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor.xcscheme @@ -73,6 +73,11 @@ value = "" isEnabled = "NO"> + + Bool { + return FileManager.default.isExecutableFile( + atPath: path.replacingTildeWithHomeDirectory + ) + } + /** Checks if a file or directory exists at the provided path. */ public static func exists(_ path: String) -> Bool { return FileManager.default.fileExists( - atPath: path.replacingOccurrences(of: "~", with: Paths.homePath) + atPath: path.replacingTildeWithHomeDirectory ) } @@ -26,7 +35,7 @@ class Filesystem { public static func fileExists(_ path: String) -> Bool { var isDirectory: ObjCBool = true let exists = FileManager.default.fileExists( - atPath: path.replacingOccurrences(of: "~", with: Paths.homePath), + atPath: path.replacingTildeWithHomeDirectory, isDirectory: &isDirectory ) @@ -39,7 +48,7 @@ class Filesystem { public static func directoryExists(_ path: String) -> Bool { var isDirectory: ObjCBool = true let exists = FileManager.default.fileExists( - atPath: path.replacingOccurrences(of: "~", with: Paths.homePath), + atPath: path.replacingTildeWithHomeDirectory, isDirectory: &isDirectory ) @@ -59,3 +68,11 @@ class Filesystem { } } + +extension String { + + var replacingTildeWithHomeDirectory: String { + return self.replacingOccurrences(of: "~", with: Paths.homePath) + } + +} diff --git a/phpmon/Common/PHP/PHP Version/PhpHelper.swift b/phpmon/Common/PHP/PHP Version/PhpHelper.swift index b0a8064..50fe730 100644 --- a/phpmon/Common/PHP/PHP Version/PhpHelper.swift +++ b/phpmon/Common/PHP/PHP Version/PhpHelper.swift @@ -27,7 +27,9 @@ class PhpHelper { Task { // Create the appropriate folders and check if the files exist do { - await Shell.quiet("mkdir -p ~/.config/phpmon/bin") + if !Filesystem.directoryExists("~/.config/phpmon/bin") { + await Shell.quiet("mkdir -p ~/.config/phpmon/bin") + } if Filesystem.fileExists(destination) { let contents = try String(contentsOfFile: destination) @@ -62,7 +64,9 @@ class PhpHelper { ) // Make sure the file is executable - await Shell.quiet("chmod +x \(destination)") + if !Filesystem.isExecutableFile(destination) { + await Shell.quiet("chmod +x \(destination)") + } // Create a symlink if the folder is not in the PATH if !inPath { diff --git a/phpmon/Common/PHP/PhpExtension.swift b/phpmon/Common/PHP/PhpExtension.swift index b6e7d7e..df20d07 100644 --- a/phpmon/Common/PHP/PhpExtension.swift +++ b/phpmon/Common/PHP/PhpExtension.swift @@ -85,6 +85,10 @@ class PhpExtension { await sed(file: file, original: line, replacement: newLine) enabled.toggle() + + DispatchQueue.main.async { + MainMenu.shared.rebuild(async: false) + } } // MARK: - Static Methods diff --git a/phpmon/Common/Shell/SystemShell.swift b/phpmon/Common/Shell/SystemShell.swift index 17a214a..e5a4ed2 100644 --- a/phpmon/Common/Shell/SystemShell.swift +++ b/phpmon/Common/Shell/SystemShell.swift @@ -88,6 +88,14 @@ class SystemShell: Shellable { let outputPipe = Pipe() let errorPipe = Pipe() + // Seriously slow down how long it takes for the shell to return output + // (in order to debug or identify async issues) + if ProcessInfo.processInfo.environment["SLOW_SHELL_MODE"] != nil { + print("[SLOW SHELL] \(command)") + let delayInSeconds = 3 + try! await Task.sleep(nanoseconds: UInt64(delayInSeconds * 1_000_000_000)) + } + task.standardOutput = outputPipe task.standardError = errorPipe task.launch() diff --git a/phpmon/Common/Testables/TestableConfigurations.swift b/phpmon/Common/Testables/TestableConfigurations.swift index 44b7d97..6d490e7 100644 --- a/phpmon/Common/Testables/TestableConfigurations.swift +++ b/phpmon/Common/Testables/TestableConfigurations.swift @@ -99,7 +99,6 @@ class TestableConfigurations { : .instant("Unable to find application named 'Sublime Merge'", .stdErr), "/usr/bin/open -Ra \"iTerm\"" : .instant("Unable to find application named 'iTerm'", .stdErr), - ] ) } diff --git a/phpmon/Common/Testables/TestableShell.swift b/phpmon/Common/Testables/TestableShell.swift index aae56b3..05a4ee3 100644 --- a/phpmon/Common/Testables/TestableShell.swift +++ b/phpmon/Common/Testables/TestableShell.swift @@ -33,8 +33,15 @@ public class TestableShell: Shellable { didReceiveOutput: @escaping (String, ShellStream) -> Void, withTimeout timeout: TimeInterval ) async throws -> (Process, ShellOutput) { - // TODO: Add delay to track down issues - // TODO: Remove assertion + + // Seriously slow down the shell's return rate in order to debug or identify async issues + if ProcessInfo.processInfo.environment["SLOW_SHELL_MODE"] != nil { + print("[SLOW SHELL] \(command)") + let delayInSeconds = 3 + try! await Task.sleep(nanoseconds: UInt64(delayInSeconds * 1_000_000_000)) + } + + // This assertion will only fire during test builds assert(expectations.keys.contains(command), "No response declared for command: \(command)") guard let expectation = expectations[command] else { diff --git a/phpmon/Domain/Menu/MainMenu+Switcher.swift b/phpmon/Domain/Menu/MainMenu+Switcher.swift index bc14115..58a3df2 100644 --- a/phpmon/Domain/Menu/MainMenu+Switcher.swift +++ b/phpmon/Domain/Menu/MainMenu+Switcher.swift @@ -118,6 +118,6 @@ extension MainMenu { preference: .notifyAboutVersionChange ) - Task { await PhpEnv.phpInstall.notifyAboutBrokenPhpFpm() } + Task { PhpEnv.phpInstall.notifyAboutBrokenPhpFpm() } } } diff --git a/phpmon/Domain/Menu/MainMenu.swift b/phpmon/Domain/Menu/MainMenu.swift index aaa87ca..4744b99 100644 --- a/phpmon/Domain/Menu/MainMenu.swift +++ b/phpmon/Domain/Menu/MainMenu.swift @@ -106,7 +106,9 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate @MainActor @objc func reloadPhpMonitorMenuInForeground() async { refreshActiveInstallation() refreshIcon() - rebuild(async: false) + DispatchQueue.main.async { + self.rebuild(async: false) + } await ServicesManager.loadHomebrewServices() }