From 3064a07d69b4ceff89a7a13747b848298e502c8d Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Tue, 16 Jul 2024 18:29:11 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=A6=20Use=20NVAppUpdater=20and=20NVAle?= =?UTF-8?q?rt=20packages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEVELOPER.md | 11 ++ PHP Monitor.xcodeproj/project.pbxproj | 130 +++++++------- phpmon-updater/LaunchControl.swift | 46 ----- phpmon-updater/Updater.swift | 162 ------------------ phpmon-updater/Utility.swift | 34 ---- phpmon-updater/main.swift | 15 +- phpmon/Common/Errors/AlertableError.swift | 2 +- phpmon/Domain/App/AppUpdater.swift | 7 +- phpmon/Domain/App/Base.lproj/Main.storyboard | 7 +- .../App/Services/ValetServicesManager.swift | 5 +- phpmon/Domain/App/Startup.swift | 5 +- .../Composer/ComposerWindow.swift | 3 +- .../Homebrew/BrewDiagnostics.swift | 3 +- .../Integrations/Valet/Valet+Alerts.swift | 7 +- phpmon/Domain/Menu/MainMenu+Actions.swift | 15 +- phpmon/Domain/Menu/MainMenu+FixMyValet.swift | 9 +- phpmon/Domain/Menu/MainMenu+Startup.swift | 3 +- phpmon/Domain/Menu/MainMenu+Switcher.swift | 5 +- phpmon/Domain/Menu/MainMenu.swift | 5 +- phpmon/Domain/Notice/BetterAlert.swift | 122 ------------- phpmon/Domain/Notice/BetterAlertVC.swift | 77 --------- phpmon/Domain/Notice/NVAlertExtension.swift | 23 +++ phpmon/Domain/PHP/PhpGuard.swift | 3 +- phpmon/Domain/Preferences/Stats.swift | 3 +- phpmon/Domain/Presets/Preset.swift | 3 +- phpmon/Domain/SwiftUI/Menu/ServicesView.swift | 5 +- .../Domain List/UI/DomainListVC+Actions.swift | 9 +- 27 files changed, 175 insertions(+), 544 deletions(-) delete mode 100644 phpmon-updater/LaunchControl.swift delete mode 100644 phpmon-updater/Updater.swift delete mode 100644 phpmon-updater/Utility.swift delete mode 100644 phpmon/Domain/Notice/BetterAlert.swift delete mode 100644 phpmon/Domain/Notice/BetterAlertVC.swift create mode 100644 phpmon/Domain/Notice/NVAlertExtension.swift diff --git a/DEVELOPER.md b/DEVELOPER.md index 068b449..4e4b6e4 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -14,6 +14,17 @@ It also automatically runs when you try to build the project. You'll get a warni swiftlint --fix ``` +## 📦 Swift Packages + +Starting from PHP Monitor 7.1, the app now uses various first-party package dependencies. + +The following package dependencies are in use: + +* [`NVAppUpdater`](https://github.com/nicoverbruggen/NVAppUpdater) +* [`NVAlert`](https://github.com/nicoverbruggen/NVAlert) + +You may need an internet connection to download these dependencies, or you can also clone the dependencies and include them manually. + ## ⚙️ Preferences You can find the persisted configuration file in `~/Library/Preferences/com.nicoverbruggen.phpmon.plist` diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index add3dae..1eb22de 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -64,11 +64,6 @@ C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */; }; C406A5F3298AD2CE00B5B85A /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = C406A5F2298AD2CE00B5B85A /* main.swift */; }; C406A5F7298AD2CF00B5B85A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C406A5F6298AD2CF00B5B85A /* Assets.xcassets */; }; - C406A602298AD50D00B5B85A /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C406A601298AD50D00B5B85A /* Updater.swift */; }; - C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; }; - C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; }; - C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; }; - C4080FFB27BD956700BF2C6B /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; }; C409349D298EE8E900D25014 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C409349C298EE8E900D25014 /* AppUpdater.swift */; }; C409349E298EE8E900D25014 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C409349C298EE8E900D25014 /* AppUpdater.swift */; }; C409349F298EE8E900D25014 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C409349C298EE8E900D25014 /* AppUpdater.swift */; }; @@ -305,6 +300,9 @@ C46FA9882822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; }; C46FA9892822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; }; C46FA98C2822F08F00D78807 /* PhpConfigurationFileTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA98A2822F08F00D78807 /* PhpConfigurationFileTest.swift */; }; + C47014FC2C46D31B0069AAE7 /* NVAppUpdater in Frameworks */ = {isa = PBXBuildFile; productRef = C47014FB2C46D31B0069AAE7 /* NVAppUpdater */; }; + C47014FF2C46D57C0069AAE7 /* NVAlert in Frameworks */ = {isa = PBXBuildFile; productRef = C47014FE2C46D57C0069AAE7 /* NVAlert */; }; + C47015022C46D6910069AAE7 /* NVAlertExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47015012C46D6910069AAE7 /* NVAlertExtension.swift */; }; C4709CA228524B3400088BB8 /* StatsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4709CA128524B3400088BB8 /* StatsView.swift */; }; C471E79328F9B21F0021E251 /* ActiveFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */; }; C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */; }; @@ -392,10 +390,6 @@ C471E81828F9BAE80021E251 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA23E246C358E00944F05 /* StringExtension.swift */; }; C471E81928F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40508B028ADAB44008FAC1F /* NSMenuItemExtension.swift */; }; C471E81A28F9BAE80021E251 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */; }; - C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; }; - C471E81C28F9BB250021E251 /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; }; - C471E81D28F9BB260021E251 /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; }; - C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; }; C471E81F28F9BB290021E251 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; }; C471E82028F9BB290021E251 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; }; C471E82128F9BB2E0021E251 /* ProjectTypeDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */; }; @@ -720,8 +714,6 @@ C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */; }; C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */; }; C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */; }; - C4C75F5A298C2D5700DFD82E /* LaunchControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C75F59298C2D5700DFD82E /* LaunchControl.swift */; }; - C4C75F5C298C31C000DFD82E /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C75F5B298C31C000DFD82E /* Utility.swift */; }; C4C8900328F0E28800CE5E97 /* FileSystemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */; }; C4C8900528F0E3D100CE5E97 /* RealFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */; }; C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */; }; @@ -946,9 +938,6 @@ C406A5F2298AD2CE00B5B85A /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; C406A5F6298AD2CF00B5B85A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; C406A5FB298AD2CF00B5B85A /* phpmon-updater.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "phpmon-updater.entitlements"; sourceTree = ""; }; - C406A601298AD50D00B5B85A /* Updater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = ""; }; - C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetterAlert.swift; sourceTree = ""; }; - C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetterAlertVC.swift; sourceTree = ""; }; C409349C298EE8E900D25014 /* AppUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdater.swift; sourceTree = ""; }; C40934A1298EEB2C00D25014 /* CaskFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaskFile.swift; sourceTree = ""; }; C40934A6298EEB8700D25014 /* phpmon-dev.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = "phpmon-dev.rb"; sourceTree = ""; }; @@ -1060,6 +1049,7 @@ C46FA23E246C358E00944F05 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = ""; }; C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFile.swift; sourceTree = ""; }; C46FA98A2822F08F00D78807 /* PhpConfigurationFileTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFileTest.swift; sourceTree = ""; }; + C47015012C46D6910069AAE7 /* NVAlertExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NVAlertExtension.swift; sourceTree = ""; }; C4709CA128524B3400088BB8 /* StatsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsView.swift; sourceTree = ""; }; C471E79228F9B1D30021E251 /* PHP Monitor.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "PHP Monitor.xctestplan"; sourceTree = ""; }; C471E7AD28F9B4940021E251 /* Feature Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Feature Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1120,8 +1110,6 @@ C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusMenu+Items.swift"; sourceTree = ""; }; C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Startup.swift"; sourceTree = ""; }; C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPrefs.swift; sourceTree = ""; }; - C4C75F59298C2D5700DFD82E /* LaunchControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchControl.swift; sourceTree = ""; }; - C4C75F5B298C31C000DFD82E /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = ""; }; C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemProtocol.swift; sourceTree = ""; }; C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealFileSystem.swift; sourceTree = ""; }; C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveFileSystem.swift; sourceTree = ""; }; @@ -1198,6 +1186,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C47014FC2C46D31B0069AAE7 /* NVAppUpdater in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1205,6 +1194,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C47014FF2C46D57C0069AAE7 /* NVAlert in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1348,24 +1338,12 @@ isa = PBXGroup; children = ( C406A5F2298AD2CE00B5B85A /* main.swift */, - C406A601298AD50D00B5B85A /* Updater.swift */, - C4C75F5B298C31C000DFD82E /* Utility.swift */, - C4C75F59298C2D5700DFD82E /* LaunchControl.swift */, C406A5F6298AD2CF00B5B85A /* Assets.xcassets */, C406A5FB298AD2CF00B5B85A /* phpmon-updater.entitlements */, ); path = "phpmon-updater"; sourceTree = ""; }; - C4080FF827BD955900BF2C6B /* Notice */ = { - isa = PBXGroup; - children = ( - C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */, - C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */, - ); - path = Notice; - sourceTree = ""; - }; C40C5C9E2846A42D00E28255 /* Presets */ = { isa = PBXGroup; children = ( @@ -1468,7 +1446,7 @@ C41E181722CB61EB0072CF09 /* Domain */ = { isa = PBXGroup; children = ( - C4080FF827BD955900BF2C6B /* Notice */, + C47015002C46D6860069AAE7 /* Notice */, C4AF9F6B275445D300D44ED0 /* Integrations */, C4B13B1D25C4915000548C3A /* App */, C4D9ADBD27761084007277F4 /* PHP */, @@ -1793,6 +1771,14 @@ path = "Domain List"; sourceTree = ""; }; + C47015002C46D6860069AAE7 /* Notice */ = { + isa = PBXGroup; + children = ( + C47015012C46D6910069AAE7 /* NVAlertExtension.swift */, + ); + path = Notice; + sourceTree = ""; + }; C471E6D928F9AFC20021E251 /* Testables */ = { isa = PBXGroup; children = ( @@ -2255,6 +2241,9 @@ dependencies = ( ); name = "PHP Monitor Self-Updater"; + packageProductDependencies = ( + C47014FB2C46D31B0069AAE7 /* NVAppUpdater */, + ); productName = "PHP Monitor Updater"; productReference = C406A5F0298AD2CE00B5B85A /* PHP Monitor Self-Updater.app */; productType = "com.apple.product-type.application"; @@ -2275,6 +2264,7 @@ ); name = "PHP Monitor"; packageProductDependencies = ( + C47014FE2C46D57C0069AAE7 /* NVAlert */, ); productName = phpmon; productReference = C41C1B3322B0097F00E7CF16 /* PHP Monitor.app */; @@ -2381,6 +2371,8 @@ ); mainGroup = C41C1B2A22B0097F00E7CF16; packageReferences = ( + C47014FA2C46D31B0069AAE7 /* XCRemoteSwiftPackageReference "NVAppUpdater" */, + C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */, ); productRefGroup = C41C1B3422B0097F00E7CF16 /* Products */; projectDirPath = ""; @@ -2508,10 +2500,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C4C75F5C298C31C000DFD82E /* Utility.swift in Sources */, C490E3BC29BCA375006D2DE6 /* Measurements.swift in Sources */, - C406A602298AD50D00B5B85A /* Updater.swift in Sources */, - C4C75F5A298C2D5700DFD82E /* LaunchControl.swift in Sources */, C41F3D08298AED0D0042ACBF /* System.swift in Sources */, C406A5F3298AD2CE00B5B85A /* main.swift in Sources */, ); @@ -2552,7 +2541,6 @@ C48DDD0D29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */, C45B91532956123A00F4EC78 /* FakeServicesManager.swift in Sources */, C41C708D28AA7F7900E8D498 /* NoWarningsView.swift in Sources */, - C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */, 0309E6672B0D4B2F002AC007 /* BrewExtensionsObservable.swift in Sources */, C4E0F7ED27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */, C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */, @@ -2686,7 +2674,6 @@ C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */, C4FACE83288F1F9700FC478F /* OnboardingWindowController.swift in Sources */, C4415E8D2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */, - C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */, C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */, C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */, C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */, @@ -2715,6 +2702,7 @@ C4EE188422D3386B00E126E5 /* Constants.swift in Sources */, C493084A279F331F009C240B /* AddSiteVC.swift in Sources */, C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */, + C47015022C46D6910069AAE7 /* NVAlertExtension.swift in Sources */, C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2879,7 +2867,6 @@ C471E82A28F9BB330021E251 /* ValetListable.swift in Sources */, 031E2B6B2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */, C471E82728F9BB310021E251 /* BrewDiagnostics.swift in Sources */, - C471E81C28F9BB250021E251 /* BetterAlert.swift in Sources */, C471E7DB28F9BA8F0021E251 /* RealShell.swift in Sources */, C490E3B929BCA368006D2DE6 /* App+BrewWatch.swift in Sources */, C471E7FF28F9BAD10021E251 /* Xdebug.swift in Sources */, @@ -2896,7 +2883,6 @@ C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */, C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */, C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */, - C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */, C471E82928F9BB330021E251 /* Valet.swift in Sources */, C471E80728F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */, C471E7D528F9BA8F0021E251 /* TestableConfigurations.swift in Sources */, @@ -3092,7 +3078,6 @@ C4463FCF29804BCB007B93D5 /* RCFile.swift in Sources */, C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */, C471E82828F9BB310021E251 /* BrewDiagnostics.swift in Sources */, - C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */, C43BCD4729FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */, C44E985F29B23EBF0059F773 /* UpdateCheckTest.swift in Sources */, C4513F8E2B13E2E5001AD760 /* PhpExtensionManagerWindowController.swift in Sources */, @@ -3108,7 +3093,6 @@ C471E7DD28F9BAA30021E251 /* CommandProtocol.swift in Sources */, C471E7D128F9BA630021E251 /* RealFileSystem.swift in Sources */, 033D459B2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */, - C471E81D28F9BB260021E251 /* BetterAlertVC.swift in Sources */, C471E82B28F9BB340021E251 /* Valet.swift in Sources */, C471E80328F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */, C471E7C928F9BA2F0021E251 /* TestableConfigurations.swift in Sources */, @@ -3165,7 +3149,6 @@ C44A874928905BB000498BC4 /* ProgressVC.swift in Sources */, C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */, C485707528BF454F00539B36 /* StatsView.swift in Sources */, - C4080FFB27BD956700BF2C6B /* BetterAlertVC.swift in Sources */, C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */, 54D9E0BB27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */, C485707328BF454300539B36 /* OnboardingView.swift in Sources */, @@ -3258,7 +3241,6 @@ C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */, C417DC75277614690015E6EE /* Helpers.swift in Sources */, C469E6FF294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */, - C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */, C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */, 5489625928313231004F647A /* CreatedFromFile.swift in Sources */, C4513F932B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */, @@ -3439,7 +3421,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -3474,7 +3456,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -3509,7 +3491,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -3544,7 +3526,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -3685,7 +3667,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1490; + CURRENT_PROJECT_VERSION = 1500; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -3698,7 +3680,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.0.4; + MARKETING_VERSION = 7.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_MODULE_NAME = PHP_Monitor; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -3716,7 +3698,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1490; + CURRENT_PROJECT_VERSION = 1500; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; @@ -3729,7 +3711,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.0.4; + MARKETING_VERSION = 7.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_MODULE_NAME = PHP_Monitor; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -3957,7 +3939,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1490; + CURRENT_PROJECT_VERSION = 1500; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; @@ -3970,7 +3952,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.0.4; + MARKETING_VERSION = 7.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev; PRODUCT_MODULE_NAME = PHP_Monitor; PRODUCT_NAME = "$(TARGET_NAME) DEV"; @@ -4074,7 +4056,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1490; + CURRENT_PROJECT_VERSION = 1500; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4087,7 +4069,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.0.4; + MARKETING_VERSION = 7.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev; PRODUCT_MODULE_NAME = PHP_Monitor; PRODUCT_NAME = "$(TARGET_NAME) DEV"; @@ -4191,7 +4173,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1490; + CURRENT_PROJECT_VERSION = 1500; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4204,7 +4186,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.0.4; + MARKETING_VERSION = 7.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap; PRODUCT_MODULE_NAME = PHP_Monitor; PRODUCT_NAME = "$(TARGET_NAME) EAP"; @@ -4239,7 +4221,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -4374,7 +4356,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1490; + CURRENT_PROJECT_VERSION = 1500; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4387,7 +4369,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 7.0.4; + MARKETING_VERSION = 7.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap; PRODUCT_MODULE_NAME = PHP_Monitor; PRODUCT_NAME = "$(TARGET_NAME) EAP"; @@ -4422,7 +4404,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 12.4; - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -4614,6 +4596,38 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + C47014FA2C46D31B0069AAE7 /* XCRemoteSwiftPackageReference "NVAppUpdater" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/nicoverbruggen/NVAppUpdater"; + requirement = { + branch = main; + kind = branch; + }; + }; + C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/nicoverbruggen/NVAlert"; + requirement = { + branch = main; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + C47014FB2C46D31B0069AAE7 /* NVAppUpdater */ = { + isa = XCSwiftPackageProductDependency; + package = C47014FA2C46D31B0069AAE7 /* XCRemoteSwiftPackageReference "NVAppUpdater" */; + productName = NVAppUpdater; + }; + C47014FE2C46D57C0069AAE7 /* NVAlert */ = { + isa = XCSwiftPackageProductDependency; + package = C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */; + productName = NVAlert; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = C41C1B2B22B0097F00E7CF16 /* Project object */; } diff --git a/phpmon-updater/LaunchControl.swift b/phpmon-updater/LaunchControl.swift deleted file mode 100644 index deef6ac..0000000 --- a/phpmon-updater/LaunchControl.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// LaunchControl.swift -// PHP Monitor Self-Updater -// -// Created by Nico Verbruggen on 02/02/2023. -// Copyright © 2023 Nico Verbruggen. All rights reserved. -// - -import Foundation -import Cocoa - -class LaunchControl { - public static func smartRestart(priority: [String]) async { - for appPath in priority { - if FileManager.default.fileExists(atPath: appPath) { - let app = await LaunchControl.startApplication(at: appPath) - if app != nil { - return - } - } - } - } - - public static func terminateApplications(bundleIds: [String]) async { - let runningApplications = NSWorkspace.shared.runningApplications - - // Terminate all instances found - for id in bundleIds { - if let phpmon = runningApplications.first(where: { - (application) in return application.bundleIdentifier == id - }) { - phpmon.terminate() - } - } - } - - public static func startApplication(at path: String) async -> NSRunningApplication? { - await withCheckedContinuation { continuation in - let url = NSURL(fileURLWithPath: path, isDirectory: true) as URL - let configuration = NSWorkspace.OpenConfiguration() - NSWorkspace.shared.openApplication(at: url, configuration: configuration) { phpmon, error in - continuation.resume(returning: phpmon) - } - } - } -} diff --git a/phpmon-updater/Updater.swift b/phpmon-updater/Updater.swift deleted file mode 100644 index d67924e..0000000 --- a/phpmon-updater/Updater.swift +++ /dev/null @@ -1,162 +0,0 @@ -// -// Updater.swift -// PHP Monitor Updater -// -// Created by Nico Verbruggen on 01/02/2023. -// Copyright © 2023 Nico Verbruggen. All rights reserved. -// - -import Cocoa - -class Updater: NSObject, NSApplicationDelegate { - - var updaterDirectory: String = "" - var manifestPath: String = "" - var manifest: ReleaseManifest! = nil - - func applicationDidFinishLaunching(_ aNotification: Notification) { - Task { await self.installUpdate() } - } - - func installUpdate() async { - print("PHP MONITOR SELF-UPDATER by Nico Verbruggen") - print("===========================================") - - self.updaterDirectory = "~/.config/phpmon/updater" - .replacingOccurrences(of: "~", with: NSHomeDirectory()) - - print("Updater directory set to: \(self.updaterDirectory)") - - self.manifestPath = "\(updaterDirectory)/update.json" - - // Fetch the manifest on the local filesystem - let manifest = await parseManifest()! - - // Download the latest file - let zipPath = await download(manifest) - - // Terminate all instances of PHP Monitor first - await LaunchControl.terminateApplications(bundleIds: [ - "com.nicoverbruggen.phpmon.eap", - "com.nicoverbruggen.phpmon.dev", - "com.nicoverbruggen.phpmon" - ]) - - // Install the app based on the zip - let appPath = await extractAndInstall(zipPath: zipPath) - - // Restart PHP Monitor, this will also close the updater - _ = await LaunchControl.startApplication(at: appPath) - - exit(1) - } - - func applicationWillTerminate(_ aNotification: Notification) { - exit(1) - } - - func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { - return false - } - - private func parseManifest() async -> ReleaseManifest? { - // Read out the correct information from the manifest JSON - print("Checking manifest file at \(manifestPath)...") - - do { - let manifestText = try String(contentsOfFile: manifestPath) - manifest = try JSONDecoder().decode(ReleaseManifest.self, from: manifestText.data(using: .utf8)!) - return manifest - } catch { - print("Parsing the manifest failed (or the manifest file doesn't exist)!") - await Alert.show(description: "The manifest file for a potential update was not found. Please try searching for updates again in PHP Monitor.") - } - - return nil - } - - private func download(_ manifest: ReleaseManifest) async -> String { - // Remove all zips - system_quiet("rm -rf \(updaterDirectory)/*.zip") - - // Download the file (and follow redirects + no output on failure) - system_quiet("cd \"\(updaterDirectory)\" && curl \(manifest.url) -fLO --max-time 20") - - // Identify the downloaded file - let filename = system("cd \"\(updaterDirectory)\" && ls | grep .zip") - .trimmingCharacters(in: .whitespacesAndNewlines) - - // Ensure the zip exists - if filename.isEmpty { - print("The update has not been downloaded. Sadly, that means that PHP Monitor cannot not updated!") - await Alert.show(description: "The update could not be downloaded, or the file was not correctly written to disk. \n\nPlease try again. \n\n(Note that the download will time-out after 20 seconds, so for slow connections it is recommended to manually download the update.)") - } - - // Calculate the checksum for the downloaded file - let checksum = system("openssl dgst -sha256 \"\(updaterDirectory)/\(filename)\" | awk '{print $NF}'") - .trimmingCharacters(in: .whitespacesAndNewlines) - - // Compare the checksums - print(""" - Comparing checksums... - Expected SHA256: \(manifest.sha256) - Actual SHA256: \(checksum) - """) - - // Make sure the checksum matches before we do anything with the file - if checksum != manifest.sha256 { - print("The checksums failed to match. Cancelling!") - await Alert.show(description: "The downloaded update failed checksum validation. Please try again. If this issue persists, there may be an issue with the server and I do not recommend upgrading.") - } - - // Return the path to the zip - return "\(updaterDirectory)/\(filename)" - } - - private func extractAndInstall(zipPath: String) async -> String { - // Remove the directory that will contain the extracted update - system_quiet("rm -rf \"\(updaterDirectory)/extracted\"") - - // Recreate the directory where we will unzip the .app file - system_quiet("mkdir -p \"\(updaterDirectory)/extracted\"") - - // Make sure the updater directory exists - var isDirectory: ObjCBool = true - if !FileManager.default.fileExists(atPath: "\(updaterDirectory)/extracted", isDirectory: &isDirectory) { - await Alert.show(description: "The updater directory is missing. The automatic updater will quit. Make sure that ` ~/.config/phpmon/updater` is writeable.") - } - - // Unzip the file - system_quiet("unzip \"\(zipPath)\" -d \"\(updaterDirectory)/extracted\"") - - // Find the .app file - let app = system("ls \"\(updaterDirectory)/extracted\" | grep .app") - .trimmingCharacters(in: .whitespacesAndNewlines) - - print("Finished extracting: \(updaterDirectory)/extracted/\(app)") - - // Make sure the file was extracted - if app.isEmpty { - await Alert.show(description: "The downloaded file could not be extracted. The automatic updater will quit. Make sure that ` ~/.config/phpmon/updater` is writeable.") - } - - // Remove the original app - print("Removing \(app) before replacing...") - system_quiet("rm -rf \"/Applications/\(app)\"") - - // Move the new app in place - system_quiet("mv \"\(updaterDirectory)/extracted/\(app)\" \"/Applications/\(app)\"") - - // Remove the zip - system_quiet("rm \"\(zipPath)\"") - - // Remove the manifest - system_quiet("rm \"\(manifestPath)\"") - - // Write a file that is only written when we upgraded successfully - system_quiet("touch \"\(updaterDirectory)/upgrade.success\"") - - // Return the new location of the app - return "/Applications/\(app)" - } -} diff --git a/phpmon-updater/Utility.swift b/phpmon-updater/Utility.swift deleted file mode 100644 index e980ba6..0000000 --- a/phpmon-updater/Utility.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// Utility.swift -// PHP Monitor Self-Updater -// -// Created by Nico Verbruggen on 02/02/2023. -// Copyright © 2023 Nico Verbruggen. All rights reserved. -// - -import Foundation -import Cocoa - -class Alert { - public static func show(description: String, shouldExit: Bool = true) async { - await withUnsafeContinuation { continuation in - DispatchQueue.main.async { - let alert = NSAlert() - alert.messageText = "The app could not be updated." - alert.informativeText = description - alert.addButton(withTitle: "OK") - alert.alertStyle = .critical - alert.runModal() - if shouldExit { - exit(0) - } - continuation.resume() - } - } - } -} - -public struct ReleaseManifest: Codable { - let url: String - let sha256: String -} diff --git a/phpmon-updater/main.swift b/phpmon-updater/main.swift index 6008aa0..b60b77e 100644 --- a/phpmon-updater/main.swift +++ b/phpmon-updater/main.swift @@ -7,8 +7,17 @@ // import Cocoa +import NVAppUpdater -let app = NSApplication.shared -let delegate = Updater() -app.delegate = delegate +let delegate = SelfUpdater( + appName: "PHP Monitor", + bundleIdentifiers: [ + "com.nicoverbruggen.phpmon.eap", + "com.nicoverbruggen.phpmon.dev", + "com.nicoverbruggen.phpmon" + ], + selfUpdaterPath: "~/.config/phpmon/updater" +) + +NSApplication.shared.delegate = delegate _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) diff --git a/phpmon/Common/Errors/AlertableError.swift b/phpmon/Common/Errors/AlertableError.swift index d05e8a8..a76f730 100644 --- a/phpmon/Common/Errors/AlertableError.swift +++ b/phpmon/Common/Errors/AlertableError.swift @@ -8,6 +8,6 @@ import Foundation -protocol AlertableError { +public protocol AlertableError { func getErrorMessageKey() -> String } diff --git a/phpmon/Domain/App/AppUpdater.swift b/phpmon/Domain/App/AppUpdater.swift index a2a985c..7ca668a 100644 --- a/phpmon/Domain/App/AppUpdater.swift +++ b/phpmon/Domain/App/AppUpdater.swift @@ -8,6 +8,7 @@ import Foundation import Cocoa +import NVAlert class AppUpdater { var caskFile: CaskFile! @@ -72,7 +73,7 @@ class AppUpdater { : "brew upgrade phpmon" Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "updater.alerts.newer_version_available.title" .localized(latestVersionOnline.humanReadable), subtitle: "updater.alerts.newer_version_available.subtitle" @@ -112,7 +113,7 @@ class AppUpdater { public func presentNoNewerVersionAvailableAlert() { Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "updater.alerts.is_latest_version.title".localized, subtitle: "updater.alerts.is_latest_version.subtitle".localized(App.shortVersion), description: "" @@ -124,7 +125,7 @@ class AppUpdater { public func presentCouldNotRetrieveUpdate() { Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "updater.alerts.cannot_check_for_update.title".localized, subtitle: "updater.alerts.cannot_check_for_update.subtitle".localized, description: "updater.alerts.cannot_check_for_update.description".localized( diff --git a/phpmon/Domain/App/Base.lproj/Main.storyboard b/phpmon/Domain/App/Base.lproj/Main.storyboard index dbc156f..ebdbf76 100644 --- a/phpmon/Domain/App/Base.lproj/Main.storyboard +++ b/phpmon/Domain/App/Base.lproj/Main.storyboard @@ -1,7 +1,6 @@ - @@ -515,10 +514,10 @@ - + - + @@ -830,7 +829,7 @@ Gw - + diff --git a/phpmon/Domain/App/Services/ValetServicesManager.swift b/phpmon/Domain/App/Services/ValetServicesManager.swift index 8192210..081940d 100644 --- a/phpmon/Domain/App/Services/ValetServicesManager.swift +++ b/phpmon/Domain/App/Services/ValetServicesManager.swift @@ -8,6 +8,7 @@ import Foundation import Cocoa +import NVAlert class ValetServicesManager: ServicesManager { override init() { @@ -131,7 +132,7 @@ class ValetServicesManager: ServicesManager { Log.err("The service '\(named)' is now reporting an error.") guard let errorLogPath = after.error_log_path else { - return BetterAlert().withInformation( + return NVAlert().withInformation( title: "alert.service_error.title".localized(named), subtitle: "alert.service_error.subtitle.no_error_log".localized(named), description: "alert.service_error.extra".localized @@ -140,7 +141,7 @@ class ValetServicesManager: ServicesManager { .show() } - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.service_error.title".localized(named), subtitle: "alert.service_error.subtitle.error_log".localized(named), description: "alert.service_error.extra".localized diff --git a/phpmon/Domain/App/Startup.swift b/phpmon/Domain/App/Startup.swift index 06583a5..d388cf2 100644 --- a/phpmon/Domain/App/Startup.swift +++ b/phpmon/Domain/App/Startup.swift @@ -7,6 +7,7 @@ import Foundation import AppKit +import NVAlert class Startup { @@ -55,7 +56,7 @@ class Startup { */ @MainActor private func showAlert(for check: EnvironmentCheck) { if check.requiresAppRestart { - BetterAlert() + NVAlert() .withInformation( title: check.titleText, subtitle: check.subtitleText, @@ -66,7 +67,7 @@ class Startup { }).show() } - BetterAlert() + NVAlert() .withInformation( title: check.titleText, subtitle: check.subtitleText, diff --git a/phpmon/Domain/Integrations/Composer/ComposerWindow.swift b/phpmon/Domain/Integrations/Composer/ComposerWindow.swift index b441522..b5a31b9 100644 --- a/phpmon/Domain/Integrations/Composer/ComposerWindow.swift +++ b/phpmon/Domain/Integrations/Composer/ComposerWindow.swift @@ -7,6 +7,7 @@ // import Foundation +import NVAlert @MainActor class ComposerWindow { private var shouldNotify: Bool! = nil @@ -109,7 +110,7 @@ import Foundation // MARK: Alert private func presentMissingAlert() { - BetterAlert() + NVAlert() .withInformation( title: "alert.composer_missing.title".localized, subtitle: "alert.composer_missing.subtitle".localized, diff --git a/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift b/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift index f16ed14..3e67f9a 100644 --- a/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift +++ b/phpmon/Domain/Integrations/Homebrew/BrewDiagnostics.swift @@ -7,6 +7,7 @@ // import Foundation +import NVAlert class BrewDiagnostics { /** @@ -183,7 +184,7 @@ class BrewDiagnostics { */ private static func presentAlertAboutConflict() { Task { @MainActor in - BetterAlert() + NVAlert() .withInformation( title: "alert.php_alias_conflict.title".localized, subtitle: "alert.php_alias_conflict.info".localized diff --git a/phpmon/Domain/Integrations/Valet/Valet+Alerts.swift b/phpmon/Domain/Integrations/Valet/Valet+Alerts.swift index 3f722bc..e790d1f 100644 --- a/phpmon/Domain/Integrations/Valet/Valet+Alerts.swift +++ b/phpmon/Domain/Integrations/Valet/Valet+Alerts.swift @@ -7,6 +7,7 @@ // import Foundation +import NVAlert extension Valet { @@ -16,7 +17,7 @@ extension Valet { public func notifyAboutUnsupportedTLD() { if Valet.shared.config.tld != "test" && Preferences.isEnabled(.warnAboutNonStandardTLD) { Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.warnings.tld_issue.title".localized, subtitle: "alert.warnings.tld_issue.subtitle".localized, description: "alert.warnings.tld_issue.description".localized @@ -33,7 +34,7 @@ extension Valet { public func notifyAboutOutdatedValetVersion(_ version: VersionNumber) { Task { @MainActor in - BetterAlert() + NVAlert() .withInformation( title: "alert.min_valet_version.title".localized, subtitle: "alert.min_valet_version.info".localized( @@ -60,7 +61,7 @@ extension Valet { } Task { @MainActor in - BetterAlert() + NVAlert() .withInformation( title: "alert.php_fpm_broken.title".localized, subtitle: "alert.php_fpm_broken.info".localized, diff --git a/phpmon/Domain/Menu/MainMenu+Actions.swift b/phpmon/Domain/Menu/MainMenu+Actions.swift index 644cf65..4c99a73 100644 --- a/phpmon/Domain/Menu/MainMenu+Actions.swift +++ b/phpmon/Domain/Menu/MainMenu+Actions.swift @@ -7,6 +7,7 @@ // import Cocoa +import NVAlert extension MainMenu { @@ -20,7 +21,7 @@ extension MainMenu { @MainActor @objc func displayUnlinkedInfo() { Task { @MainActor in - BetterAlert() + NVAlert() .withInformation( title: "phpman.unlinked.title".localized, subtitle: "phpman.unlinked.desc".localized, @@ -32,7 +33,7 @@ extension MainMenu { } @MainActor @objc func fixHomebrewPermissions() { - if !BetterAlert() + if !NVAlert() .withInformation( title: "alert.fix_homebrew_permissions.title".localized, subtitle: "alert.fix_homebrew_permissions.subtitle".localized, @@ -47,7 +48,7 @@ extension MainMenu { asyncExecution { try Actions.fixHomebrewPermissions() } success: { - BetterAlert() + NVAlert() .withInformation( title: "alert.fix_homebrew_permissions_done.title".localized, subtitle: "alert.fix_homebrew_permissions_done.subtitle".localized, @@ -56,7 +57,7 @@ extension MainMenu { .withPrimary(text: "generic.ok".localized) .show() } failure: { error in - BetterAlert.show(for: error as! HomebrewPermissionError) + NVAlert.show(for: error as! HomebrewPermissionError) } } @@ -175,7 +176,7 @@ extension MainMenu { return } - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.revert_description.title".localized, subtitle: "alert.revert_description.subtitle".localized( preset.textDescription @@ -196,7 +197,7 @@ extension MainMenu { } @MainActor @objc func showPresetHelp() { - BetterAlert().withInformation( + NVAlert().withInformation( title: "preset_help_title".localized, subtitle: "preset_help_info".localized, description: "preset_help_desc".localized @@ -263,7 +264,7 @@ extension MainMenu { Task { MainMenu.shared.switchToPhpVersion(version) } } else { Task { - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.php_switch_unavailable.title".localized, subtitle: "alert.php_switch_unavailable.subtitle".localized(version) ).withPrimary( diff --git a/phpmon/Domain/Menu/MainMenu+FixMyValet.swift b/phpmon/Domain/Menu/MainMenu+FixMyValet.swift index d685c9a..230130f 100644 --- a/phpmon/Domain/Menu/MainMenu+FixMyValet.swift +++ b/phpmon/Domain/Menu/MainMenu+FixMyValet.swift @@ -8,6 +8,7 @@ import Foundation import AppKit +import NVAlert extension MainMenu { @@ -19,7 +20,7 @@ extension MainMenu { return } - if !BetterAlert() + if !NVAlert() .withInformation( title: "alert.fix_my_valet.title".localized, subtitle: "alert.fix_my_valet.info".localized(PhpEnvironments.brewPhpAlias) @@ -43,7 +44,7 @@ extension MainMenu { } @MainActor private func presentAlertForMissingFormula() { - BetterAlert() + NVAlert() .withInformation( title: "alert.php_formula_missing.title".localized, subtitle: "alert.php_formula_missing.info".localized @@ -53,7 +54,7 @@ extension MainMenu { } @MainActor private func presentAlertForSameVersion() { - BetterAlert() + NVAlert() .withInformation( title: "alert.fix_my_valet_done.title".localized, subtitle: "alert.fix_my_valet_done.subtitle".localized, @@ -64,7 +65,7 @@ extension MainMenu { } @MainActor private func presentAlertForDifferentVersion(version: String) { - BetterAlert() + NVAlert() .withInformation( title: "alert.fix_my_valet_done.title".localized, subtitle: "alert.fix_my_valet_done.subtitle".localized, diff --git a/phpmon/Domain/Menu/MainMenu+Startup.swift b/phpmon/Domain/Menu/MainMenu+Startup.swift index 597b43f..8e2c2b0 100644 --- a/phpmon/Domain/Menu/MainMenu+Startup.swift +++ b/phpmon/Domain/Menu/MainMenu+Startup.swift @@ -7,6 +7,7 @@ // import Cocoa +import NVAlert extension MainMenu { /** @@ -143,7 +144,7 @@ extension MainMenu { */ private func onEnvironmentFail() async { Task { @MainActor [self] in - BetterAlert() + NVAlert() .withInformation( title: "alert.cannot_start.title".localized, subtitle: "alert.cannot_start.subtitle".localized, diff --git a/phpmon/Domain/Menu/MainMenu+Switcher.swift b/phpmon/Domain/Menu/MainMenu+Switcher.swift index 5ed8573..aa3fc86 100644 --- a/phpmon/Domain/Menu/MainMenu+Switcher.swift +++ b/phpmon/Domain/Menu/MainMenu+Switcher.swift @@ -7,6 +7,7 @@ // import Foundation +import NVAlert extension MainMenu { @@ -75,7 +76,7 @@ extension MainMenu { } @MainActor private func suggestFixMyValet(failed version: String) { - let outcome = BetterAlert() + let outcome = NVAlert() .withInformation( title: "alert.php_switch_failed.title".localized(version), subtitle: "alert.php_switch_failed.info".localized(version), @@ -90,7 +91,7 @@ extension MainMenu { } @MainActor private func suggestFixMyComposer() { - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.global_composer_platform_issues.title".localized, subtitle: "alert.global_composer_platform_issues.subtitle".localized, description: "alert.global_composer_platform_issues.desc".localized diff --git a/phpmon/Domain/Menu/MainMenu.swift b/phpmon/Domain/Menu/MainMenu.swift index 32d4a3b..f309d11 100644 --- a/phpmon/Domain/Menu/MainMenu.swift +++ b/phpmon/Domain/Menu/MainMenu.swift @@ -6,6 +6,7 @@ // import Cocoa +import NVAlert @MainActor class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate { @@ -120,7 +121,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate @objc func showIncompatiblePhpVersionsAlert() { Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "startup.unsupported_versions_explanation.title".localized, subtitle: "startup.unsupported_versions_explanation.subtitle".localized( PhpEnvironments.shared.incompatiblePhpVersions @@ -185,7 +186,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate @objc func openLiteModeInfo() { Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "lite_mode_explanation.title".localized, subtitle: "lite_mode_explanation.subtitle".localized, description: "lite_mode_explanation.description".localized diff --git a/phpmon/Domain/Notice/BetterAlert.swift b/phpmon/Domain/Notice/BetterAlert.swift deleted file mode 100644 index 798c795..0000000 --- a/phpmon/Domain/Notice/BetterAlert.swift +++ /dev/null @@ -1,122 +0,0 @@ -// -// Notice.swift -// PHP Monitor -// -// Created by Nico Verbruggen on 16/02/2022. -// Copyright © 2023 Nico Verbruggen. All rights reserved. -// - -import Foundation -import Cocoa - -@MainActor -class BetterAlert { - - var windowController: NSWindowController! - - var noticeVC: BetterAlertVC { - return self.windowController.contentViewController as! BetterAlertVC - } - - init() { - let storyboard = NSStoryboard(name: "Main", bundle: nil) - - self.windowController = storyboard.instantiateController( - withIdentifier: "noticeWindow" - ) as? NSWindowController - } - - public static func make() -> BetterAlert { - return BetterAlert() - } - - public func withPrimary( - text: String, - action: @MainActor @escaping (BetterAlertVC) -> Void = { vc in - vc.close(with: .alertFirstButtonReturn) - } - ) -> Self { - self.noticeVC.buttonPrimary.title = text - self.noticeVC.actionPrimary = action - return self - } - - public func withSecondary( - text: String, - action: (@MainActor (BetterAlertVC) -> Void)? = { vc in - vc.close(with: .alertSecondButtonReturn) - } - ) -> Self { - self.noticeVC.buttonSecondary.title = text - self.noticeVC.actionSecondary = action - return self - } - - public func withTertiary( - text: String = "", - action: (@MainActor (BetterAlertVC) -> Void)? = nil - ) -> Self { - if text == "" { - self.noticeVC.buttonTertiary.bezelStyle = .helpButton - } - self.noticeVC.buttonTertiary.title = text - self.noticeVC.actionTertiary = action - return self - } - - public func withInformation( - title: String, - subtitle: String, - description: String = "" - ) -> Self { - self.noticeVC.labelTitle.stringValue = title - self.noticeVC.labelSubtitle.stringValue = subtitle - self.noticeVC.labelDescription.stringValue = description - - // If the description is missing, handle the excess space and change the top margin - if description == "" { - self.noticeVC.labelDescription.isHidden = true - self.noticeVC.primaryButtonTopMargin.constant = 0 - } - return self - } - - /** - Shows the modal and returns a ModalResponse. - If you wish to simply show the alert and disregard the outcome, use `show`. - */ - @MainActor public func runModal() -> NSApplication.ModalResponse { - if !Thread.isMainThread { - fatalError("You should always present alerts on the main thread!") - } - - NSApp.activate(ignoringOtherApps: true) - - windowController.window?.makeKeyAndOrderFront(nil) - windowController.window?.setCenterPosition(offsetY: 70) - return NSApplication.shared.runModal(for: windowController.window!) - } - - /** Shows the modal and returns true if the user pressed the primary button. */ - @MainActor public func didSelectPrimary() -> Bool { - return self.runModal() == .alertFirstButtonReturn - } - - /** - Shows the modal and does not return anything. - */ - @MainActor public func show() { - _ = self.runModal() - } - - /** - Shows the modal for a particular error. - */ - @MainActor public static func show(for error: Error & AlertableError) { - let key = error.getErrorMessageKey() - return BetterAlert().withInformation( - title: "\(key).title".localized, - subtitle: "\(key).description".localized - ).withPrimary(text: "generic.ok".localized).show() - } -} diff --git a/phpmon/Domain/Notice/BetterAlertVC.swift b/phpmon/Domain/Notice/BetterAlertVC.swift deleted file mode 100644 index d3b2206..0000000 --- a/phpmon/Domain/Notice/BetterAlertVC.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// NoticeVC.swift -// PHP Monitor -// -// Created by Nico Verbruggen on 16/02/2022. -// Copyright © 2023 Nico Verbruggen. All rights reserved. -// - -import Foundation -import Cocoa - -class BetterAlertVC: NSViewController { - - // MARK: - Outlets - - @IBOutlet weak var labelTitle: NSTextField! - @IBOutlet weak var labelSubtitle: NSTextField! - @IBOutlet weak var labelDescription: NSTextField! - - @IBOutlet weak var buttonPrimary: NSButton! - @IBOutlet weak var buttonSecondary: NSButton! - @IBOutlet weak var buttonTertiary: NSButton! - - var actionPrimary: (@MainActor (BetterAlertVC) -> Void) = { _ in } - var actionSecondary: (@MainActor (BetterAlertVC) -> Void)? - var actionTertiary: (@MainActor (BetterAlertVC) -> Void)? - - @IBOutlet weak var imageView: NSImageView! - - @IBOutlet weak var primaryButtonTopMargin: NSLayoutConstraint! - - // MARK: - Lifecycle - - override func viewWillAppear() { - imageView.image = NSApp.applicationIconImage - - if actionSecondary == nil { - buttonSecondary.isHidden = true - } - if actionTertiary == nil { - buttonTertiary.isHidden = true - } - } - - override func viewDidAppear() { - view.window?.makeFirstResponder(buttonPrimary) - } - - deinit { - // Log.perf("deinit: \(String(describing: self)).\(#function)") - } - - // MARK: Outlet Actions - - @IBAction func primaryButtonAction(_ sender: Any) { - self.actionPrimary(self) - } - - @IBAction func secondaryButtonAction(_ sender: Any) { - if self.actionSecondary != nil { - self.actionSecondary!(self) - } else { - self.close(with: .alertSecondButtonReturn) - } - } - - @IBAction func tertiaryButtonAction(_ sender: Any) { - if self.actionTertiary != nil { - self.actionTertiary!(self) - } - } - - @MainActor public func close(with code: NSApplication.ModalResponse) { - self.view.window?.close() - NSApplication.shared.stopModal(withCode: code) - } -} diff --git a/phpmon/Domain/Notice/NVAlertExtension.swift b/phpmon/Domain/Notice/NVAlertExtension.swift new file mode 100644 index 0000000..061b925 --- /dev/null +++ b/phpmon/Domain/Notice/NVAlertExtension.swift @@ -0,0 +1,23 @@ +// +// NVAlertExtension.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 16/07/2024. +// Copyright © 2024 Nico Verbruggen. All rights reserved. +// + +import Foundation +import NVAlert + +extension NVAlert { + /** + Shows the modal for a particular error. + */ + @MainActor public static func show(for error: Error & AlertableError) { + let key = error.getErrorMessageKey() + return NVAlert().withInformation( + title: "\(key).title".localized, + subtitle: "\(key).description".localized + ).withPrimary(text: "generic.ok".localized).show() + } +} diff --git a/phpmon/Domain/PHP/PhpGuard.swift b/phpmon/Domain/PHP/PhpGuard.swift index 7c2cc71..55af936 100644 --- a/phpmon/Domain/PHP/PhpGuard.swift +++ b/phpmon/Domain/PHP/PhpGuard.swift @@ -7,6 +7,7 @@ // import Foundation +import NVAlert class PhpGuard { @@ -43,7 +44,7 @@ class PhpGuard { Log.info("PHP Guard noticed a different PHP version. An alert will be displayed!") Task { @MainActor in - BetterAlert() + NVAlert() .withInformation( title: "startup.version_mismatch.title".localized, subtitle: "startup.version_mismatch.subtitle".localized( diff --git a/phpmon/Domain/Preferences/Stats.swift b/phpmon/Domain/Preferences/Stats.swift index 1b912a2..fb2d3a5 100644 --- a/phpmon/Domain/Preferences/Stats.swift +++ b/phpmon/Domain/Preferences/Stats.swift @@ -8,6 +8,7 @@ import Foundation import Cocoa +import NVAlert class Stats { @@ -123,7 +124,7 @@ class Stats { } Task { @MainActor in - let donate = BetterAlert() + let donate = NVAlert() .withInformation( title: "startup.sponsor_encouragement.title".localized, subtitle: "startup.sponsor_encouragement.subtitle".localized, diff --git a/phpmon/Domain/Presets/Preset.swift b/phpmon/Domain/Presets/Preset.swift index 3233267..1c9bcfd 100644 --- a/phpmon/Domain/Presets/Preset.swift +++ b/phpmon/Domain/Presets/Preset.swift @@ -7,6 +7,7 @@ // import Foundation +import NVAlert struct Preset: Codable, Equatable { let name: String @@ -139,7 +140,7 @@ struct Preset: Codable, Equatable { return true } else { Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.php_switch_unavailable.title".localized, subtitle: "alert.php_switch_unavailable.subtitle".localized(version!), description: "alert.php_switch_unavailable.info".localized( diff --git a/phpmon/Domain/SwiftUI/Menu/ServicesView.swift b/phpmon/Domain/SwiftUI/Menu/ServicesView.swift index 96ccab0..e098062 100644 --- a/phpmon/Domain/SwiftUI/Menu/ServicesView.swift +++ b/phpmon/Domain/SwiftUI/Menu/ServicesView.swift @@ -8,6 +8,7 @@ import Foundation import SwiftUI +import NVAlert struct ServicesView: View { @@ -81,7 +82,7 @@ struct ServicesView: View { : "key_service_not_running" // Show an alert with more information - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.\(type).title".localized, subtitle: "alert.\(type).subtitle".localized, description: "alert.\(type).desc".localized @@ -116,7 +117,7 @@ struct ServiceView: View { if service.status == .missing { Button { Task { @MainActor in - BetterAlert().withInformation( + NVAlert().withInformation( title: "alert.warnings.service_missing.title".localized, subtitle: "alert.warnings.service_missing.subtitle".localized, description: "alert.warnings.service_missing.description".localized diff --git a/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift b/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift index 29807c1..817bac4 100644 --- a/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift +++ b/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift @@ -8,6 +8,7 @@ import Foundation import Cocoa +import NVAlert extension DomainListVC { @@ -17,7 +18,7 @@ extension DomainListVC { } guard let url = selected.getListableUrl() else { - BetterAlert() + NVAlert() .withInformation( title: "domain_list.alert.invalid_folder_name".localized, subtitle: "domain_list.alert.invalid_folder_name_desc".localized @@ -249,7 +250,7 @@ extension DomainListVC { } private func notifyAboutUsingIsolatedPhpVersionInTerminal(version: VersionNumber) { - BetterAlert() + NVAlert() .withInformation( title: "domain_list.alerts_isolated_php_terminal.title".localized(version.short), subtitle: "domain_list.alerts_isolated_php_terminal.subtitle".localized( @@ -263,7 +264,7 @@ extension DomainListVC { } private func notifyAboutFailedSecureStatus(command: String) { - BetterAlert() + NVAlert() .withInformation( title: "domain_list.alerts_status_not_changed.title".localized, subtitle: "domain_list.alerts_status_not_changed.desc".localized(command) @@ -273,7 +274,7 @@ extension DomainListVC { } private func notifyAboutFailedSiteIsolation(command: String) { - BetterAlert() + NVAlert() .withInformation( title: "domain_list.alerts_isolation_failed.title".localized, subtitle: "domain_list.alerts_isolation_failed.subtitle".localized,