1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-12-21 19:20:06 +01:00

♻️ Refactor startup sequence

Most of the logic from the MainMenu+Startup extension has now been
completely removed. It has now been moved to the Startup+Launch
extension, which is a better place for this logic. Where necessary,
functions have been annotated with MainActor.

Additionally, checking which third-party apps have been installed
has been moved to `App+DetectApps.swift`, a separate extension.
This commit is contained in:
2025-11-26 14:02:16 +01:00
parent 42e7edc01c
commit 7af61a80f5
5 changed files with 82 additions and 50 deletions

View File

@@ -63,6 +63,14 @@
036C39122E5C8D42008DAEDF /* PackagistError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036C390E2E5C8D3B008DAEDF /* PackagistError.swift */; }; 036C39122E5C8D42008DAEDF /* PackagistError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036C390E2E5C8D3B008DAEDF /* PackagistError.swift */; };
036C39142E5CB822008DAEDF /* TestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036C39132E5CB820008DAEDF /* TestBundle.swift */; }; 036C39142E5CB822008DAEDF /* TestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036C39132E5CB820008DAEDF /* TestBundle.swift */; };
036C3A212E5CBBAA008DAEDF /* ValetConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */; }; 036C3A212E5CBBAA008DAEDF /* ValetConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */; };
0379C49F2ED71D050035D7EA /* Startup+Launch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C49E2ED71CFC0035D7EA /* Startup+Launch.swift */; };
0379C4A02ED71D050035D7EA /* Startup+Launch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C49E2ED71CFC0035D7EA /* Startup+Launch.swift */; };
0379C4A12ED71D050035D7EA /* Startup+Launch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C49E2ED71CFC0035D7EA /* Startup+Launch.swift */; };
0379C4A22ED71D050035D7EA /* Startup+Launch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C49E2ED71CFC0035D7EA /* Startup+Launch.swift */; };
0379C4A42ED720220035D7EA /* App+DetectApps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C4A32ED7201D0035D7EA /* App+DetectApps.swift */; };
0379C4A52ED720220035D7EA /* App+DetectApps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C4A32ED7201D0035D7EA /* App+DetectApps.swift */; };
0379C4A62ED720220035D7EA /* App+DetectApps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C4A32ED7201D0035D7EA /* App+DetectApps.swift */; };
0379C4A72ED720220035D7EA /* App+DetectApps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379C4A32ED7201D0035D7EA /* App+DetectApps.swift */; };
0386B0B42ED36C3D00CA6795 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0386B0B32ED36C3D00CA6795 /* Locked.swift */; }; 0386B0B42ED36C3D00CA6795 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0386B0B32ED36C3D00CA6795 /* Locked.swift */; };
0386B0B52ED36C3D00CA6795 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0386B0B32ED36C3D00CA6795 /* Locked.swift */; }; 0386B0B52ED36C3D00CA6795 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0386B0B32ED36C3D00CA6795 /* Locked.swift */; };
0386B0B62ED36C3D00CA6795 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0386B0B32ED36C3D00CA6795 /* Locked.swift */; }; 0386B0B62ED36C3D00CA6795 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0386B0B32ED36C3D00CA6795 /* Locked.swift */; };
@@ -550,7 +558,6 @@
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; }; C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
C471E84D28F9BB650021E251 /* Valet+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */; }; C471E84D28F9BB650021E251 /* Valet+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */; };
C471E84E28F9BB650021E251 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; }; C471E84E28F9BB650021E251 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
C471E84F28F9BB650021E251 /* MainMenu+Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */; };
C471E85028F9BB650021E251 /* MainMenu+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */; }; C471E85028F9BB650021E251 /* MainMenu+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */; };
C471E85128F9BB650021E251 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; }; C471E85128F9BB650021E251 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
C471E85228F9BB650021E251 /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; }; C471E85228F9BB650021E251 /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; };
@@ -637,7 +644,6 @@
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; }; C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
C471E8B028F9BB8F0021E251 /* Valet+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */; }; C471E8B028F9BB8F0021E251 /* Valet+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */; };
C471E8B128F9BB8F0021E251 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; }; C471E8B128F9BB8F0021E251 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
C471E8B228F9BB8F0021E251 /* MainMenu+Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */; };
C471E8B328F9BB8F0021E251 /* MainMenu+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */; }; C471E8B328F9BB8F0021E251 /* MainMenu+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */; };
C471E8B428F9BB8F0021E251 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; }; C471E8B428F9BB8F0021E251 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
C471E8B528F9BB8F0021E251 /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; }; C471E8B528F9BB8F0021E251 /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; };
@@ -829,7 +835,6 @@
C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C1019A27C65C6F001FACC2 /* Process.swift */; }; C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C1019A27C65C6F001FACC2 /* Process.swift */; };
C4C3643928AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */; }; C4C3643928AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */; };
C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */; }; 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 */; }; C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */; };
C4C8900328F0E28800CE5E97 /* FileSystemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */; }; C4C8900328F0E28800CE5E97 /* FileSystemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */; };
C4C8900528F0E3D100CE5E97 /* RealFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */; }; C4C8900528F0E3D100CE5E97 /* RealFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */; };
@@ -947,7 +952,6 @@
C4F30B08278E195800755FCE /* brew-services.json in Resources */ = {isa = PBXBuildFile; fileRef = C4F30B06278E195800755FCE /* brew-services.json */; }; C4F30B08278E195800755FCE /* brew-services.json in Resources */ = {isa = PBXBuildFile; fileRef = C4F30B06278E195800755FCE /* brew-services.json */; };
C4F30B09278E1A0E00755FCE /* CustomPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */; }; C4F30B09278E1A0E00755FCE /* CustomPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */; };
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D89BC52783C99400A02B68 /* ComposerJson.swift */; }; C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D89BC52783C99400A02B68 /* ComposerJson.swift */; };
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */; };
C4F319C927B034A500AFF46F /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DEB7D327A5D60B00834718 /* Stats.swift */; }; C4F319C927B034A500AFF46F /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DEB7D327A5D60B00834718 /* Stats.swift */; };
C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F361602836BFD9003598CC /* MainMenu+Actions.swift */; }; C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F361602836BFD9003598CC /* MainMenu+Actions.swift */; };
C4F520672AF03791006787F2 /* ExtensionEnumeratorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F520662AF03791006787F2 /* ExtensionEnumeratorTest.swift */; }; C4F520672AF03791006787F2 /* ExtensionEnumeratorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F520662AF03791006787F2 /* ExtensionEnumeratorTest.swift */; };
@@ -1042,6 +1046,8 @@
036C39092E5C8CBD008DAEDF /* PackagistP2Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackagistP2Response.swift; sourceTree = "<group>"; }; 036C39092E5C8CBD008DAEDF /* PackagistP2Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackagistP2Response.swift; sourceTree = "<group>"; };
036C390E2E5C8D3B008DAEDF /* PackagistError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackagistError.swift; sourceTree = "<group>"; }; 036C390E2E5C8D3B008DAEDF /* PackagistError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackagistError.swift; sourceTree = "<group>"; };
036C39132E5CB820008DAEDF /* TestBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestBundle.swift; sourceTree = "<group>"; }; 036C39132E5CB820008DAEDF /* TestBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestBundle.swift; sourceTree = "<group>"; };
0379C49E2ED71CFC0035D7EA /* Startup+Launch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Startup+Launch.swift"; sourceTree = "<group>"; };
0379C4A32ED7201D0035D7EA /* App+DetectApps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "App+DetectApps.swift"; sourceTree = "<group>"; };
0386B0B32ED36C3D00CA6795 /* Locked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Locked.swift; sourceTree = "<group>"; }; 0386B0B32ED36C3D00CA6795 /* Locked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Locked.swift; sourceTree = "<group>"; };
0386B0B82ED36DF800CA6795 /* LockedTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockedTests.swift; sourceTree = "<group>"; }; 0386B0B82ED36DF800CA6795 /* LockedTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockedTests.swift; sourceTree = "<group>"; };
0392CDE52EB23B8F009176DA /* CertificateValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertificateValidator.swift; sourceTree = "<group>"; }; 0392CDE52EB23B8F009176DA /* CertificateValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertificateValidator.swift; sourceTree = "<group>"; };
@@ -1264,7 +1270,6 @@
C4C0E8E627F88B41002D32A9 /* DomainScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainScanner.swift; sourceTree = "<group>"; }; C4C0E8E627F88B41002D32A9 /* DomainScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainScanner.swift; sourceTree = "<group>"; };
C4C1019A27C65C6F001FACC2 /* Process.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Process.swift; sourceTree = "<group>"; }; C4C1019A27C65C6F001FACC2 /* Process.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Process.swift; sourceTree = "<group>"; };
C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusMenu+Items.swift"; sourceTree = "<group>"; }; C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusMenu+Items.swift"; sourceTree = "<group>"; };
C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Startup.swift"; sourceTree = "<group>"; };
C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPrefs.swift; sourceTree = "<group>"; }; C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPrefs.swift; sourceTree = "<group>"; };
C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemProtocol.swift; sourceTree = "<group>"; }; C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemProtocol.swift; sourceTree = "<group>"; };
C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealFileSystem.swift; sourceTree = "<group>"; }; C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealFileSystem.swift; sourceTree = "<group>"; };
@@ -2091,7 +2096,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */, C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */,
C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */,
C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */, C44CCD4827AFF3B700CE40E5 /* MainMenu+Async.swift */,
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */, C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */,
C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */, C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */,
@@ -2188,10 +2192,12 @@
C415D3E72770F692005EF286 /* AppDelegate+InterApp.swift */, C415D3E72770F692005EF286 /* AppDelegate+InterApp.swift */,
03D846312EB64E35006EFE3C /* CrashReporter.swift */, 03D846312EB64E35006EFE3C /* CrashReporter.swift */,
C4811D2322D70A4700B5F6B3 /* App.swift */, C4811D2322D70A4700B5F6B3 /* App.swift */,
0379C4A32ED7201D0035D7EA /* App+DetectApps.swift */,
C4B97B77275CF1B5003F3378 /* App+ActivationPolicy.swift */, C4B97B77275CF1B5003F3378 /* App+ActivationPolicy.swift */,
C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */, C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */,
C4EED88827A48778006D7272 /* InterAppHandler.swift */, C4EED88827A48778006D7272 /* InterAppHandler.swift */,
C4D8016522B1584700C6DA1B /* Startup.swift */, C4D8016522B1584700C6DA1B /* Startup.swift */,
0379C49E2ED71CFC0035D7EA /* Startup+Launch.swift */,
03BFF5262E312C39007F96FA /* Startup+Timers.swift */, 03BFF5262E312C39007F96FA /* Startup+Timers.swift */,
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */, C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */,
C40FE736282ABA4F00A302C2 /* AppVersion.swift */, C40FE736282ABA4F00A302C2 /* AppVersion.swift */,
@@ -2850,6 +2856,7 @@
C40C5C9C2846A40600E28255 /* Preset.swift in Sources */, C40C5C9C2846A40600E28255 /* Preset.swift in Sources */,
C4B79EBC29CA38DB00A483EE /* BrewCommand.swift in Sources */, C4B79EBC29CA38DB00A483EE /* BrewCommand.swift in Sources */,
C41CD0292628D8EE0065BBED /* GlobalKeybindPreference.swift in Sources */, C41CD0292628D8EE0065BBED /* GlobalKeybindPreference.swift in Sources */,
0379C4A42ED720220035D7EA /* App+DetectApps.swift in Sources */,
C4B6091A2853AAD300C95265 /* SectionHeaderView.swift in Sources */, C4B6091A2853AAD300C95265 /* SectionHeaderView.swift in Sources */,
C436B39D29F3C42500B6A64E /* PreferencesTabs.swift in Sources */, C436B39D29F3C42500B6A64E /* PreferencesTabs.swift in Sources */,
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */, C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */,
@@ -2866,6 +2873,7 @@
C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */, C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */,
C46EBC4A28DB966A007ACC74 /* TestableShell.swift in Sources */, C46EBC4A28DB966A007ACC74 /* TestableShell.swift in Sources */,
C44C198D276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */, C44C198D276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */,
0379C49F2ED71D050035D7EA /* Startup+Launch.swift in Sources */,
54D9E0B827E4F51E003B9AD9 /* KeyCombo.swift in Sources */, 54D9E0B827E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
C4C0E8E727F88B41002D32A9 /* DomainScanner.swift in Sources */, C4C0E8E727F88B41002D32A9 /* DomainScanner.swift in Sources */,
C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */, C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */,
@@ -2969,7 +2977,6 @@
C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */, C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */,
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */, C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */,
54D9E0BA27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */, 54D9E0BA27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */,
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */,
C4821C5A2C2DEDE200357A68 /* AppMenu.swift in Sources */, C4821C5A2C2DEDE200357A68 /* AppMenu.swift in Sources */,
C42106662AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */, C42106662AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
C4B79ECB29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */, C4B79ECB29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
@@ -3039,6 +3046,7 @@
035983A22E97FA9100218DC7 /* Container.swift in Sources */, 035983A22E97FA9100218DC7 /* Container.swift in Sources */,
C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */, C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */,
C4513F922B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */, C4513F922B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */,
0379C4A22ED71D050035D7EA /* Startup+Launch.swift in Sources */,
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */, C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */,
032DAC2B2E8BEB5B0018E01C /* RealWebApi.swift in Sources */, 032DAC2B2E8BEB5B0018E01C /* RealWebApi.swift in Sources */,
C471E84728F9BB650021E251 /* Startup.swift in Sources */, C471E84728F9BB650021E251 /* Startup.swift in Sources */,
@@ -3049,7 +3057,6 @@
C471E84D28F9BB650021E251 /* Valet+Alerts.swift in Sources */, C471E84D28F9BB650021E251 /* Valet+Alerts.swift in Sources */,
C471E84E28F9BB650021E251 /* MainMenu.swift in Sources */, C471E84E28F9BB650021E251 /* MainMenu.swift in Sources */,
C40934A4298EEB2C00D25014 /* CaskFile.swift in Sources */, C40934A4298EEB2C00D25014 /* CaskFile.swift in Sources */,
C471E84F28F9BB650021E251 /* MainMenu+Startup.swift in Sources */,
C471E85028F9BB650021E251 /* MainMenu+Async.swift in Sources */, C471E85028F9BB650021E251 /* MainMenu+Async.swift in Sources */,
C471E85128F9BB650021E251 /* MainMenu+Switcher.swift in Sources */, C471E85128F9BB650021E251 /* MainMenu+Switcher.swift in Sources */,
C471E85228F9BB650021E251 /* MainMenu+FixMyValet.swift in Sources */, C471E85228F9BB650021E251 /* MainMenu+FixMyValet.swift in Sources */,
@@ -3084,6 +3091,7 @@
03C29A772EC88E3100FBA25E /* ValetServicesDataManager.swift in Sources */, 03C29A772EC88E3100FBA25E /* ValetServicesDataManager.swift in Sources */,
C40175BA2903108900763A68 /* ValetInteractor.swift in Sources */, C40175BA2903108900763A68 /* ValetInteractor.swift in Sources */,
C43931C729C4BD610069165B /* PhpVersionManagerView.swift in Sources */, C43931C729C4BD610069165B /* PhpVersionManagerView.swift in Sources */,
0379C4A52ED720220035D7EA /* App+DetectApps.swift in Sources */,
036C390A2E5C8CC5008DAEDF /* PackagistP2Response.swift in Sources */, 036C390A2E5C8CC5008DAEDF /* PackagistP2Response.swift in Sources */,
C4463FCE29804BCB007B93D5 /* RCFile.swift in Sources */, C4463FCE29804BCB007B93D5 /* RCFile.swift in Sources */,
C45B9150295608E300F4EC78 /* ValetServicesManager.swift in Sources */, C45B9150295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
@@ -3237,6 +3245,7 @@
033D45A12B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */, 033D45A12B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */,
C471E89328F9BB8F0021E251 /* Application.swift in Sources */, C471E89328F9BB8F0021E251 /* Application.swift in Sources */,
036C39022E5C883B008DAEDF /* Packagist.swift in Sources */, 036C39022E5C883B008DAEDF /* Packagist.swift in Sources */,
0379C4A72ED720220035D7EA /* App+DetectApps.swift in Sources */,
C471E89428F9BB8F0021E251 /* LocalNotification.swift in Sources */, C471E89428F9BB8F0021E251 /* LocalNotification.swift in Sources */,
C441CC592AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */, C441CC592AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
C40934A5298EEB2C00D25014 /* CaskFile.swift in Sources */, C40934A5298EEB2C00D25014 /* CaskFile.swift in Sources */,
@@ -3271,13 +3280,13 @@
03DAD3A82EB3B08F003417BD /* DomainListVC+Certs.swift in Sources */, 03DAD3A82EB3B08F003417BD /* DomainListVC+Certs.swift in Sources */,
C471E8A828F9BB8F0021E251 /* App+GlobalHotkey.swift in Sources */, C471E8A828F9BB8F0021E251 /* App+GlobalHotkey.swift in Sources */,
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */, C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */,
0379C4A02ED71D050035D7EA /* Startup+Launch.swift in Sources */,
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */, C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */,
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */, C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */,
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */, C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */,
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */, C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */,
C471E8B028F9BB8F0021E251 /* Valet+Alerts.swift in Sources */, C471E8B028F9BB8F0021E251 /* Valet+Alerts.swift in Sources */,
C471E8B128F9BB8F0021E251 /* MainMenu.swift in Sources */, C471E8B128F9BB8F0021E251 /* MainMenu.swift in Sources */,
C471E8B228F9BB8F0021E251 /* MainMenu+Startup.swift in Sources */,
C471E8B328F9BB8F0021E251 /* MainMenu+Async.swift in Sources */, C471E8B328F9BB8F0021E251 /* MainMenu+Async.swift in Sources */,
C471E8B428F9BB8F0021E251 /* MainMenu+Switcher.swift in Sources */, C471E8B428F9BB8F0021E251 /* MainMenu+Switcher.swift in Sources */,
C471E8B528F9BB8F0021E251 /* MainMenu+FixMyValet.swift in Sources */, C471E8B528F9BB8F0021E251 /* MainMenu+FixMyValet.swift in Sources */,
@@ -3488,6 +3497,7 @@
C4F780C825D80B75000DBC97 /* DateExtension.swift in Sources */, C4F780C825D80B75000DBC97 /* DateExtension.swift in Sources */,
C493084B279F331F009C240B /* AddSiteVC.swift in Sources */, C493084B279F331F009C240B /* AddSiteVC.swift in Sources */,
C44A874928905BB000498BC4 /* ProgressVC.swift in Sources */, C44A874928905BB000498BC4 /* ProgressVC.swift in Sources */,
0379C4A62ED720220035D7EA /* App+DetectApps.swift in Sources */,
C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */, C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */,
C485707528BF454F00539B36 /* StatsView.swift in Sources */, C485707528BF454F00539B36 /* StatsView.swift in Sources */,
C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */, C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */,
@@ -3518,6 +3528,7 @@
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */, C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */,
C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */, C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */,
03263A3A2E86D5EC00BD0415 /* UpdateScheduler.swift in Sources */, 03263A3A2E86D5EC00BD0415 /* UpdateScheduler.swift in Sources */,
0379C4A12ED71D050035D7EA /* Startup+Launch.swift in Sources */,
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */, C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */,
C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */, C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */,
C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */, C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */,
@@ -3649,7 +3660,6 @@
C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */, C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */,
C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */, C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */,
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */, C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */,
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */,
C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */, C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */,
03D846252EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */, 03D846252EB6344E006EFE3C /* DomainListVC+Window.swift in Sources */,
0329A9A42E92A69000A62A12 /* WarningManager+Evaluations.swift in Sources */, 0329A9A42E92A69000A62A12 /* WarningManager+Evaluations.swift in Sources */,

View File

@@ -0,0 +1,32 @@
//
// App+DetectApps.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 26/11/2025.
// Copyright © 2025 Nico Verbruggen. All rights reserved.
//
extension App {
/**
Detect which applications are installed that can be used to open a domain's source directory.
*/
public func detectApplications() async {
Log.info("Detecting applications...")
// Start by detecting the default applications
var detected = await Application.detectPresetApplications(container)
// Next up, scan for additional apps
let customApps = Preferences.custom.scanApps?.map { appName in
return Application(container, appName, .user_supplied)
} ?? []
// Append any detected apps
for app in customApps where await app.isInstalled() {
detected.append(app)
}
App.shared.detectedApplications = detected
Log.info("Detected applications: \(detected.map { $0.name })")
}
}

View File

@@ -113,8 +113,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
// Make sure notifications will work // Make sure notifications will work
setupNotifications() setupNotifications()
// Start with the regular busy icon
MainMenu.shared.setStatusBar(image: NSImage.statusBarIcon)
Task { // Make sure the menu performs its initial checks Task { // Make sure the menu performs its initial checks
await MainMenu.shared.startup() await Startup.check(App.shared.container)
} }
} }

View File

@@ -1,25 +1,32 @@
// //
// MainMenu+Startup.swift // Startup+Launch.swift
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 03/01/2022. // Created by Nico Verbruggen on 26/11/2025.
// Copyright © 2025 Nico Verbruggen. All rights reserved. // Copyright © 2025 Nico Verbruggen. All rights reserved.
// //
import Foundation
import Cocoa import Cocoa
import NVAlert import NVAlert
extension MainMenu { extension Startup {
/** /**
Kick off the startup of the rendering of the main menu. Kick off the startup of the rendering of the main menu.
*/ */
func startup() async { static func check(_ container: Container) async {
// Start with the icon // Create a new instance of Startup w/ the container
await MainActor.run { let startup = Startup(container)
self.setStatusBar(image: NSImage.statusBarIcon)
}
if await Startup().checkEnvironment() { // Perform the startup checks
await startup.check()
}
/**
Perform all checks and execute pass or fail results.
*/
private func check() async {
if await self.checkEnvironment() {
await self.onEnvironmentPass() await self.onEnvironmentPass()
} else { } else {
await self.onEnvironmentFail() await self.onEnvironmentFail()
@@ -29,6 +36,7 @@ extension MainMenu {
/** /**
When the environment is all clear and the app can run, let's go. When the environment is all clear and the app can run, let's go.
*/ */
@MainActor
private func onEnvironmentPass() async { private func onEnvironmentPass() async {
// Load additional preferences // Load additional preferences
await container.preferences.loadCustomPreferences() await container.preferences.loadCustomPreferences()
@@ -69,7 +77,7 @@ extension MainMenu {
App.shared.handlePhpConfigWatcher() App.shared.handlePhpConfigWatcher()
// Detect built-in and custom applications // Detect built-in and custom applications
await detectApplications() await App.shared.detectApplications()
// Load the rollback preset // Load the rollback preset
PresetHelper.loadRollbackPresetFromFile() PresetHelper.loadRollbackPresetFromFile()
@@ -150,6 +158,7 @@ extension MainMenu {
/** /**
When the environment is not OK, present an alert to inform the user. When the environment is not OK, present an alert to inform the user.
*/ */
@MainActor
private func onEnvironmentFail() async { private func onEnvironmentFail() async {
NVAlert() NVAlert()
.withInformation( .withInformation(
@@ -164,34 +173,6 @@ extension MainMenu {
}) })
.show() .show()
await startup() await self.check()
}
/**
Detect which applications are installed that can be used to open a domain's source directory.
*/
private func detectApplications() async {
Log.info("Detecting applications...")
App.shared.detectedApplications = await Application.detectPresetApplications(container)
let customApps = Preferences.custom.scanApps?.map { appName in
return Application(container, appName, .user_supplied)
} ?? []
var detectedCustomApps: [Application] = []
for app in customApps where await app.isInstalled() {
detectedCustomApps.append(app)
}
App.shared.detectedApplications
.append(contentsOf: detectedCustomApps)
let appNames = App.shared.detectedApplications.map { app in
return app.name
}
Log.info("Detected applications: \(appNames)")
} }
} }

View File

@@ -10,6 +10,12 @@ import AppKit
import NVAlert import NVAlert
class Startup { class Startup {
var container: Container
init(_ container: Container) {
self.container = container
}
/** /**
Checks the user's environment and checks if PHP Monitor can be used properly. Checks the user's environment and checks if PHP Monitor can be used properly.
This checks if PHP is installed, Valet is running, the appropriate permissions are set, and more. This checks if PHP is installed, Valet is running, the appropriate permissions are set, and more.