From 927e1c02fa8e5ed16d2feae151501bc69bc51bb0 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Sun, 6 Feb 2022 13:15:03 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20`waitAndExecute?= =?UTF-8?q?`=20=E2=86=92=20`asyncExecution`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change allows for errors to be thrown during the `asyncExecution` initial callback, and if one is thrown, allows a `failure` callback to be used. Existing instances of `waitAndExecute` have been replaced. I also added the ability to tweak the behaviours of the actions that are always performed when the asyncExecution method is called: you can now specify limited behaviours (e.g. only set busy icon). For that use case I have already created a new method: `asyncWithBusyUI`. With this change, the handling of the Homebrew Permissions flow has also been modified: when the user does not get administrative permissions an error is now thrown which results in an alert being presented to the user once the error occurs. There is now an opportunity to further refactor other parts of the app to more gracefully handle failure states using the Error and AlertableError protocols. --- PHP Monitor.xcodeproj/project.pbxproj | 32 +++- README.md | 6 +- phpmon-common/Core/Actions.swift | 7 +- phpmon-common/Errors/AlertableError.swift | 13 ++ .../Errors/HomebrewPermissionError.swift | 21 +++ phpmon/Domain/Core/Base.lproj/Main.storyboard | 4 +- phpmon/Domain/Helpers/Alert.swift | 13 +- phpmon/Domain/Menu/MainMenu.swift | 153 +++++++++++++----- phpmon/Domain/Menu/StatusMenu.swift | 14 +- phpmon/Localizable.strings | 16 +- 10 files changed, 215 insertions(+), 64 deletions(-) create mode 100644 phpmon-common/Errors/AlertableError.swift create mode 100644 phpmon-common/Errors/HomebrewPermissionError.swift diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 1bae20a..48cfe50 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -79,6 +79,12 @@ C44C198E276E3A1C0072762D /* ProgressWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* ProgressWindow.swift */; }; C44C1991276E44CB0072762D /* ProgressWindow.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C44C1990276E44CB0072762D /* ProgressWindow.storyboard */; }; C44C1992276E44CB0072762D /* ProgressWindow.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C44C1990276E44CB0072762D /* ProgressWindow.storyboard */; }; + C44CCD4027AFE2FC00CE40E5 /* AlertableError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD3F27AFE2FC00CE40E5 /* AlertableError.swift */; }; + C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD3F27AFE2FC00CE40E5 /* AlertableError.swift */; }; + C44CCD4227AFE2FC00CE40E5 /* AlertableError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD3F27AFE2FC00CE40E5 /* AlertableError.swift */; }; + C44CCD4527AFE94900CE40E5 /* HomebrewPermissionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD4427AFE94900CE40E5 /* HomebrewPermissionError.swift */; }; + C44CCD4627AFE94900CE40E5 /* HomebrewPermissionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD4427AFE94900CE40E5 /* HomebrewPermissionError.swift */; }; + C44CCD4727AFE94900CE40E5 /* HomebrewPermissionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD4427AFE94900CE40E5 /* HomebrewPermissionError.swift */; }; C464ADAC275A7A3F003FCD53 /* SiteListWC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C464ADAB275A7A3F003FCD53 /* SiteListWC.swift */; }; C464ADAD275A7A3F003FCD53 /* SiteListWC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C464ADAB275A7A3F003FCD53 /* SiteListWC.swift */; }; C464ADAF275A7A69003FCD53 /* SiteListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C464ADAE275A7A69003FCD53 /* SiteListVC.swift */; }; @@ -264,6 +270,8 @@ C43A8A2325D9D20D00591B77 /* BrewJsonParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewJsonParserTest.swift; sourceTree = ""; }; C44C198C276E3A1C0072762D /* ProgressWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressWindow.swift; sourceTree = ""; }; C44C1990276E44CB0072762D /* ProgressWindow.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ProgressWindow.storyboard; sourceTree = ""; }; + C44CCD3F27AFE2FC00CE40E5 /* AlertableError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertableError.swift; sourceTree = ""; }; + C44CCD4427AFE94900CE40E5 /* HomebrewPermissionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewPermissionError.swift; sourceTree = ""; }; C464ADAB275A7A3F003FCD53 /* SiteListWC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteListWC.swift; sourceTree = ""; }; C464ADAE275A7A69003FCD53 /* SiteListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteListVC.swift; sourceTree = ""; }; C464ADB1275A87CA003FCD53 /* SiteListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteListCell.swift; sourceTree = ""; }; @@ -517,6 +525,15 @@ path = Progress; sourceTree = ""; }; + C44CCD4327AFE93300CE40E5 /* Errors */ = { + isa = PBXGroup; + children = ( + C44CCD3F27AFE2FC00CE40E5 /* AlertableError.swift */, + C44CCD4427AFE94900CE40E5 /* HomebrewPermissionError.swift */, + ); + path = Errors; + sourceTree = ""; + }; C464ADAA275A7A25003FCD53 /* SiteList */ = { isa = PBXGroup; children = ( @@ -617,6 +634,7 @@ C4B5853A2770FE2500DA4FBE /* phpmon-common */ = { isa = PBXGroup; children = ( + C44CCD4327AFE93300CE40E5 /* Errors */, C40C7F2127721F7300DDDCDC /* Core */, 54B20EDF263AA22C00D3250E /* PHP */, ); @@ -872,7 +890,9 @@ C4EC1E6E279DF87A0010F296 /* Async.swift in Sources */, C40C7F2327721F8200DDDCDC /* ActivePhpInstallation.swift in Sources */, C4B585462770FE3900DA4FBE /* Command.swift in Sources */, + C44CCD4727AFE94900CE40E5 /* HomebrewPermissionError.swift in Sources */, C4D9ADCA277611A0007277F4 /* InternalSwitcher.swift in Sources */, + C44CCD4227AFE2FC00CE40E5 /* AlertableError.swift in Sources */, C48D6C72279CD2AC00F26D7E /* PhpVersionNumber.swift in Sources */, C40C7F2527721F9800DDDCDC /* HomebrewPackage.swift in Sources */, C417DC76277614690015E6EE /* Helpers.swift in Sources */, @@ -919,6 +939,7 @@ C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */, C4811D2422D70A4700B5F6B3 /* App.swift in Sources */, C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */, + C44CCD4527AFE94900CE40E5 /* HomebrewPermissionError.swift in Sources */, C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */, 5420395F2613607600FB00FA /* Preferences.swift in Sources */, C48D0C9325CC804200CC7490 /* XibLoadable.swift in Sources */, @@ -939,6 +960,7 @@ C4EC1E73279DFCF40010F296 /* Events.swift in Sources */, C4B5853E2770FE3900DA4FBE /* Paths.swift in Sources */, C41C1B4B22B019FF00E7CF16 /* ActivePhpInstallation.swift in Sources */, + C44CCD4027AFE2FC00CE40E5 /* AlertableError.swift in Sources */, C4188989275FE8CB001EF227 /* Filesystem.swift in Sources */, C4B97B7B275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */, C4EED88927A48778006D7272 /* InterAppHandler.swift in Sources */, @@ -1010,7 +1032,9 @@ C417DC75277614690015E6EE /* Helpers.swift in Sources */, C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */, C4B97B79275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */, + C44CCD4627AFE94900CE40E5 /* HomebrewPermissionError.swift in Sources */, C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */, + C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */, C4F780BA25D80B62000DBC97 /* AppDelegate.swift in Sources */, 54FCFD31276C8DA4004CE748 /* HotkeyPreferenceView.swift in Sources */, C4998F0B2617633900B2526E /* PrefsWC.swift in Sources */, @@ -1215,7 +1239,7 @@ C41C1B4422B0098000E7CF16 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIconBeta; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = phpmon/phpmon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -1230,7 +1254,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = "5.1-dev"; - PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.beta; + PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -1240,7 +1264,7 @@ C41C1B4522B0098000E7CF16 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIconBeta; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = phpmon/phpmon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -1255,7 +1279,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = "5.1-dev"; - PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.beta; + PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; diff --git a/README.md b/README.md index 0b03a19..6a8e202 100644 --- a/README.md +++ b/README.md @@ -320,9 +320,9 @@ You can always still ask Valet using the command line, should it be necessary. I
After running PHP Monitor, Homebrew sometimes has issues with `brew upgrade` or `brew cleanup`! -This is a security feature of Homebrew. When you start a service as an administrator, the root user becomes the owner of relevant binaries. You will need to manually clean up those folders yourself using `rm -rf` (or by manually removing those folders via Finder). +You can now use **First Aid & Services > Restore Homebrew Permissions** to (temporarily) resolve this issue and allow for a clean and painless `brew upgrade` or `brew cleanup` process. -If you would like to know more, consult [this issue](https://github.com/nicoverbruggen/phpmon/issues/85) for more information. +If you would like to know more, consult [this issue](https://github.com/nicoverbruggen/phpmon/issues/85) for more information about why this is needed.
@@ -399,4 +399,4 @@ I have done my best to annotate as much as humanly possible, and have avoided us I also have a few tests for key parts of the application that I found needed to be tested. In the future, I would like to add even more tests for some of the UI stuff, but for now the tests are more unit tests than feature tests. -For more detailed information for developers, please see [the documentation file for developers](./DEVS.md). \ No newline at end of file +For more detailed information for developers, please see [the documentation file for developers](./DEVS.md). diff --git a/phpmon-common/Core/Actions.swift b/phpmon-common/Core/Actions.swift index fd6bd2f..23a677b 100644 --- a/phpmon-common/Core/Actions.swift +++ b/phpmon-common/Core/Actions.swift @@ -34,7 +34,7 @@ class Actions { brew("services stop dnsmasq", sudo: true) } - public static func fixHomebrewPermissions() + public static func fixHomebrewPermissions() throws { var servicesCommands = [ "\(Paths.brew) services stop nginx", @@ -65,10 +65,7 @@ class Actions { let eventResult: NSAppleEventDescriptor? = appleScript?.executeAndReturnError(nil) if (eventResult == nil) { - print("Oh no, that didn't work.") - } else { - NotificationCenter.default.post(name: Events.ServicesUpdated, object: nil) - print("Oh, that worked.") + throw HomebrewPermissionError(kind: .applescriptNilError) } } diff --git a/phpmon-common/Errors/AlertableError.swift b/phpmon-common/Errors/AlertableError.swift new file mode 100644 index 0000000..f32540b --- /dev/null +++ b/phpmon-common/Errors/AlertableError.swift @@ -0,0 +1,13 @@ +// +// Errors.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 06/02/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import Foundation + +protocol AlertableError { + func getErrorMessageKey() -> String +} diff --git a/phpmon-common/Errors/HomebrewPermissionError.swift b/phpmon-common/Errors/HomebrewPermissionError.swift new file mode 100644 index 0000000..ea05a77 --- /dev/null +++ b/phpmon-common/Errors/HomebrewPermissionError.swift @@ -0,0 +1,21 @@ +// +// HomebrewPermissionError.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 06/02/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import Foundation + +struct HomebrewPermissionError: Error, AlertableError { + enum Kind: String { + case applescriptNilError = "homebrew_permissions.applescript_returned_nil" + } + + let kind: Kind + + func getErrorMessageKey() -> String { + return "alert.errors.\(self.kind.rawValue)" + } +} diff --git a/phpmon/Domain/Core/Base.lproj/Main.storyboard b/phpmon/Domain/Core/Base.lproj/Main.storyboard index e65e6f7..bebb3da 100644 --- a/phpmon/Domain/Core/Base.lproj/Main.storyboard +++ b/phpmon/Domain/Core/Base.lproj/Main.storyboard @@ -771,7 +771,7 @@ Gw