mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2026-04-03 01:50:09 +02:00
🚀 Version 7.0
This commit is contained in:
@@ -7,6 +7,20 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
0309E6672B0D4B2F002AC007 /* BrewExtensionsObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0309E6662B0D4B2F002AC007 /* BrewExtensionsObservable.swift */; };
|
||||||
|
031E2B692B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031E2B682B1525A7007C29E1 /* BrewPhpExtension.swift */; };
|
||||||
|
031E2B6A2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031E2B682B1525A7007C29E1 /* BrewPhpExtension.swift */; };
|
||||||
|
031E2B6B2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031E2B682B1525A7007C29E1 /* BrewPhpExtension.swift */; };
|
||||||
|
031E2B6C2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031E2B682B1525A7007C29E1 /* BrewPhpExtension.swift */; };
|
||||||
|
033D45982B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45972B0D4EC600070080 /* InstallPhpExtensionCommand.swift */; };
|
||||||
|
033D45992B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45972B0D4EC600070080 /* InstallPhpExtensionCommand.swift */; };
|
||||||
|
033D459A2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45972B0D4EC600070080 /* InstallPhpExtensionCommand.swift */; };
|
||||||
|
033D459B2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45972B0D4EC600070080 /* InstallPhpExtensionCommand.swift */; };
|
||||||
|
033D459E2B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D459D2B0D513900070080 /* RemovePhpExtensionCommand.swift */; };
|
||||||
|
033D459F2B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D459D2B0D513900070080 /* RemovePhpExtensionCommand.swift */; };
|
||||||
|
033D45A02B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D459D2B0D513900070080 /* RemovePhpExtensionCommand.swift */; };
|
||||||
|
033D45A12B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D459D2B0D513900070080 /* RemovePhpExtensionCommand.swift */; };
|
||||||
|
033D45A32B0D531D00070080 /* PhpExtensionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45A22B0D531D00070080 /* PhpExtensionManagerView+Actions.swift */; };
|
||||||
03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E36FE628D9219000636F7F /* ActiveShell.swift */; };
|
03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E36FE628D9219000636F7F /* ActiveShell.swift */; };
|
||||||
03E36FE828D9219000636F7F /* ActiveShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E36FE628D9219000636F7F /* ActiveShell.swift */; };
|
03E36FE828D9219000636F7F /* ActiveShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E36FE628D9219000636F7F /* ActiveShell.swift */; };
|
||||||
5420395926135DC100FB00FA /* PreferencesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* PreferencesVC.swift */; };
|
5420395926135DC100FB00FA /* PreferencesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* PreferencesVC.swift */; };
|
||||||
@@ -78,10 +92,10 @@
|
|||||||
C40C7F2927721FF600DDDCDC /* Valet+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */; };
|
C40C7F2927721FF600DDDCDC /* Valet+Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */; };
|
||||||
C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2F27722E8D00DDDCDC /* Logger.swift */; };
|
C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2F27722E8D00DDDCDC /* Logger.swift */; };
|
||||||
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2F27722E8D00DDDCDC /* Logger.swift */; };
|
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C7F2F27722E8D00DDDCDC /* Logger.swift */; };
|
||||||
C40D725A2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* PhpFormulaeStatus.swift */; };
|
C40D725A2A018ACC0054A067 /* BusyStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* BusyStatus.swift */; };
|
||||||
C40D725B2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* PhpFormulaeStatus.swift */; };
|
C40D725B2A018ACC0054A067 /* BusyStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* BusyStatus.swift */; };
|
||||||
C40D725C2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* PhpFormulaeStatus.swift */; };
|
C40D725C2A018ACC0054A067 /* BusyStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* BusyStatus.swift */; };
|
||||||
C40D725D2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* PhpFormulaeStatus.swift */; };
|
C40D725D2A018ACC0054A067 /* BusyStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D72592A018ACC0054A067 /* BusyStatus.swift */; };
|
||||||
C40D725F2A018AE30054A067 /* BrewFormula+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */; };
|
C40D725F2A018AE30054A067 /* BrewFormula+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */; };
|
||||||
C40D72602A018AE30054A067 /* BrewFormula+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */; };
|
C40D72602A018AE30054A067 /* BrewFormula+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */; };
|
||||||
C40D72612A018AE30054A067 /* BrewFormula+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */; };
|
C40D72612A018AE30054A067 /* BrewFormula+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */; };
|
||||||
@@ -122,11 +136,20 @@
|
|||||||
C41F3D08298AED0D0042ACBF /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
C41F3D08298AED0D0042ACBF /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
||||||
C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
||||||
C4205A7F27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
C4205A7F27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
||||||
|
C42106662AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
|
C42106672AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
|
C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
|
C42106692AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
C422DDAA28A2C49900CEAC97 /* PhpDoctorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */; };
|
C422DDAA28A2C49900CEAC97 /* PhpDoctorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */; };
|
||||||
C4232EE52612526500158FC6 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = C4232EE42612526500158FC6 /* Credits.html */; };
|
C4232EE52612526500158FC6 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = C4232EE42612526500158FC6 /* Credits.html */; };
|
||||||
C42337A3281F19F000459A48 /* Xdebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42337A2281F19F000459A48 /* Xdebug.swift */; };
|
C42337A3281F19F000459A48 /* Xdebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42337A2281F19F000459A48 /* Xdebug.swift */; };
|
||||||
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
|
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
|
||||||
C42759682627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
|
C42759682627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
|
||||||
|
C428311E2B52AD6F0009F9F1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3A22B0098000E7CF16 /* Assets.xcassets */; };
|
||||||
|
C428311F2B52AD6F0009F9F1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3A22B0098000E7CF16 /* Assets.xcassets */; };
|
||||||
|
C42831202B52AD700009F9F1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3A22B0098000E7CF16 /* Assets.xcassets */; };
|
||||||
|
C4292D542B023F61004F0D2A /* PhpExtensionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D532B023F61004F0D2A /* PhpExtensionManagerWindowController.swift */; };
|
||||||
|
C4292D562B024006004F0D2A /* PhpExtensionManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D552B024006004F0D2A /* PhpExtensionManagerView.swift */; };
|
||||||
C4297F7A28970D59004C4630 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
C4297F7A28970D59004C4630 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
||||||
C42C49DB27C2806F0074ABAC /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; };
|
C42C49DB27C2806F0074ABAC /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; };
|
||||||
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */ = {isa = PBXBuildFile; fileRef = C42CFB1527DFDE7900862737 /* nginx-site.test */; };
|
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */ = {isa = PBXBuildFile; fileRef = C42CFB1527DFDE7900862737 /* nginx-site.test */; };
|
||||||
@@ -153,15 +176,19 @@
|
|||||||
C43A8A1A25D9CD1000591B77 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A1925D9CD1000591B77 /* Utility.swift */; };
|
C43A8A1A25D9CD1000591B77 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A1925D9CD1000591B77 /* Utility.swift */; };
|
||||||
C43A8A2025D9D1D700591B77 /* brew-formula.json in Resources */ = {isa = PBXBuildFile; fileRef = C43A8A1F25D9D1D700591B77 /* brew-formula.json */; };
|
C43A8A2025D9D1D700591B77 /* brew-formula.json in Resources */ = {isa = PBXBuildFile; fileRef = C43A8A1F25D9D1D700591B77 /* brew-formula.json */; };
|
||||||
C43A8A2425D9D20D00591B77 /* HomebrewPackageTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */; };
|
C43A8A2425D9D20D00591B77 /* HomebrewPackageTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */; };
|
||||||
C43BCD4429FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* InstallAndUpgradeCommand.swift */; };
|
C43BCD4429FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* ModifyPhpVersionCommand.swift */; };
|
||||||
C43BCD4529FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* InstallAndUpgradeCommand.swift */; };
|
C43BCD4529FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* ModifyPhpVersionCommand.swift */; };
|
||||||
C43BCD4629FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* InstallAndUpgradeCommand.swift */; };
|
C43BCD4629FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* ModifyPhpVersionCommand.swift */; };
|
||||||
C43BCD4729FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* InstallAndUpgradeCommand.swift */; };
|
C43BCD4729FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43BCD4329FBEF40001547BC /* ModifyPhpVersionCommand.swift */; };
|
||||||
C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43FDBE829A932B0003D85EC /* PhpConfigChecker.swift */; };
|
C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43FDBE829A932B0003D85EC /* PhpConfigChecker.swift */; };
|
||||||
C44067F527E2582B0045BD4E /* DomainListNameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F427E2582B0045BD4E /* DomainListNameCell.swift */; };
|
C44067F527E2582B0045BD4E /* DomainListNameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F427E2582B0045BD4E /* DomainListNameCell.swift */; };
|
||||||
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
|
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
|
||||||
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */; };
|
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */; };
|
||||||
C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
|
C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
|
||||||
|
C4415E8D2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4415E8C2B0287E90035F520 /* BrewFormulaeObservable.swift */; };
|
||||||
|
C4415E8E2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4415E8C2B0287E90035F520 /* BrewFormulaeObservable.swift */; };
|
||||||
|
C4415E8F2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4415E8C2B0287E90035F520 /* BrewFormulaeObservable.swift */; };
|
||||||
|
C4415E902B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4415E8C2B0287E90035F520 /* BrewFormulaeObservable.swift */; };
|
||||||
C441CC562AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
C441CC562AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||||
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||||
C441CC582AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
C441CC582AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||||
@@ -195,6 +222,18 @@
|
|||||||
C44F868E2835BD8D005C353A /* phpmon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = C44F868D2835BD8D005C353A /* phpmon-config.json */; };
|
C44F868E2835BD8D005C353A /* phpmon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = C44F868D2835BD8D005C353A /* phpmon-config.json */; };
|
||||||
C450C8C628C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
C450C8C628C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
||||||
C450C8C728C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
C450C8C728C919EC002A2B4B /* PreferenceName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C450C8C528C919EC002A2B4B /* PreferenceName.swift */; };
|
||||||
|
C4513F8E2B13E2E5001AD760 /* PhpExtensionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D532B023F61004F0D2A /* PhpExtensionManagerWindowController.swift */; };
|
||||||
|
C4513F8F2B13E2E5001AD760 /* PhpExtensionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D532B023F61004F0D2A /* PhpExtensionManagerWindowController.swift */; };
|
||||||
|
C4513F902B13E2E6001AD760 /* PhpExtensionManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D532B023F61004F0D2A /* PhpExtensionManagerWindowController.swift */; };
|
||||||
|
C4513F912B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D552B024006004F0D2A /* PhpExtensionManagerView.swift */; };
|
||||||
|
C4513F922B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D552B024006004F0D2A /* PhpExtensionManagerView.swift */; };
|
||||||
|
C4513F932B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4292D552B024006004F0D2A /* PhpExtensionManagerView.swift */; };
|
||||||
|
C4513F942B13E30B001AD760 /* BrewExtensionsObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0309E6662B0D4B2F002AC007 /* BrewExtensionsObservable.swift */; };
|
||||||
|
C4513F952B13E30C001AD760 /* BrewExtensionsObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0309E6662B0D4B2F002AC007 /* BrewExtensionsObservable.swift */; };
|
||||||
|
C4513F962B13E30C001AD760 /* BrewExtensionsObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0309E6662B0D4B2F002AC007 /* BrewExtensionsObservable.swift */; };
|
||||||
|
C4513F972B13E338001AD760 /* PhpExtensionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45A22B0D531D00070080 /* PhpExtensionManagerView+Actions.swift */; };
|
||||||
|
C4513F982B13E338001AD760 /* PhpExtensionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45A22B0D531D00070080 /* PhpExtensionManagerView+Actions.swift */; };
|
||||||
|
C4513F992B13E338001AD760 /* PhpExtensionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033D45A22B0D531D00070080 /* PhpExtensionManagerView+Actions.swift */; };
|
||||||
C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
|
C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
|
||||||
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
|
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
|
||||||
C451AFF82969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
|
C451AFF82969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
|
||||||
@@ -586,14 +625,6 @@
|
|||||||
C48DDD0E29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; };
|
C48DDD0E29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; };
|
||||||
C48DDD0F29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; };
|
C48DDD0F29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; };
|
||||||
C48DDD1029C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; };
|
C48DDD1029C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; };
|
||||||
C490E3A729BC940D006D2DE6 /* ProgressWindowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */; };
|
|
||||||
C490E3AA29BC9B3E006D2DE6 /* ProgressViewSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */; };
|
|
||||||
C490E3B029BC9FE8006D2DE6 /* ProgressViewSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */; };
|
|
||||||
C490E3B129BC9FE8006D2DE6 /* ProgressViewSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */; };
|
|
||||||
C490E3B229BC9FE8006D2DE6 /* ProgressViewSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */; };
|
|
||||||
C490E3B329BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */; };
|
|
||||||
C490E3B429BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */; };
|
|
||||||
C490E3B529BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */; };
|
|
||||||
C490E3B629BCA367006D2DE6 /* App+BrewWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */; };
|
C490E3B629BCA367006D2DE6 /* App+BrewWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */; };
|
||||||
C490E3B829BCA367006D2DE6 /* App+BrewWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */; };
|
C490E3B829BCA367006D2DE6 /* App+BrewWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */; };
|
||||||
C490E3B929BCA368006D2DE6 /* App+BrewWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */; };
|
C490E3B929BCA368006D2DE6 /* App+BrewWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */; };
|
||||||
@@ -626,10 +657,10 @@
|
|||||||
C4AF9F7A2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; };
|
C4AF9F7A2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; };
|
||||||
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; };
|
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F792754499000D44ED0 /* Valet.swift */; };
|
||||||
C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */; };
|
C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */; };
|
||||||
C4AFC4AE29C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; };
|
C4AFC4AE29C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewPhpFormula.swift */; };
|
||||||
C4AFC4AF29C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; };
|
C4AFC4AF29C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewPhpFormula.swift */; };
|
||||||
C4AFC4B029C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; };
|
C4AFC4B029C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewPhpFormula.swift */; };
|
||||||
C4AFC4B129C4F32F00BF4E0D /* BrewFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */; };
|
C4AFC4B129C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4AD29C4F32F00BF4E0D /* BrewPhpFormula.swift */; };
|
||||||
C4AFC4B429C4F43300BF4E0D /* HomebrewUpgradableTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4B229C4F43300BF4E0D /* HomebrewUpgradableTest.swift */; };
|
C4AFC4B429C4F43300BF4E0D /* HomebrewUpgradableTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AFC4B229C4F43300BF4E0D /* HomebrewUpgradableTest.swift */; };
|
||||||
C4AFC4B829C4F6DC00BF4E0D /* brew-outdated.json in Resources */ = {isa = PBXBuildFile; fileRef = C4AFC4B729C4F57B00BF4E0D /* brew-outdated.json */; };
|
C4AFC4B829C4F6DC00BF4E0D /* brew-outdated.json in Resources */ = {isa = PBXBuildFile; fileRef = C4AFC4B729C4F57B00BF4E0D /* brew-outdated.json */; };
|
||||||
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5635D276AB09000F12CCB /* VersionExtractor.swift */; };
|
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5635D276AB09000F12CCB /* VersionExtractor.swift */; };
|
||||||
@@ -641,10 +672,10 @@
|
|||||||
C4B585452770FE3900DA4FBE /* RealCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5853D2770FE3900DA4FBE /* RealCommand.swift */; };
|
C4B585452770FE3900DA4FBE /* RealCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B5853D2770FE3900DA4FBE /* RealCommand.swift */; };
|
||||||
C4B6091A2853AAD300C95265 /* SectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B609192853AAD300C95265 /* SectionHeaderView.swift */; };
|
C4B6091A2853AAD300C95265 /* SectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B609192853AAD300C95265 /* SectionHeaderView.swift */; };
|
||||||
C4B6091D2853AB9700C95265 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B6091C2853AB9700C95265 /* ServicesView.swift */; };
|
C4B6091D2853AB9700C95265 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B6091C2853AB9700C95265 /* ServicesView.swift */; };
|
||||||
C4B79EB629CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewFormulaeHandler.swift */; };
|
C4B79EB629CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewPhpFormulaeHandler.swift */; };
|
||||||
C4B79EB729CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewFormulaeHandler.swift */; };
|
C4B79EB729CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewPhpFormulaeHandler.swift */; };
|
||||||
C4B79EB829CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewFormulaeHandler.swift */; };
|
C4B79EB829CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewPhpFormulaeHandler.swift */; };
|
||||||
C4B79EB929CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewFormulaeHandler.swift */; };
|
C4B79EB929CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EB529CA387F00A483EE /* BrewPhpFormulaeHandler.swift */; };
|
||||||
C4B79EBC29CA38DB00A483EE /* BrewCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */; };
|
C4B79EBC29CA38DB00A483EE /* BrewCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */; };
|
||||||
C4B79EBD29CA38DB00A483EE /* BrewCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */; };
|
C4B79EBD29CA38DB00A483EE /* BrewCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */; };
|
||||||
C4B79EBE29CA38DB00A483EE /* BrewCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */; };
|
C4B79EBE29CA38DB00A483EE /* BrewCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */; };
|
||||||
@@ -784,6 +815,10 @@
|
|||||||
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */; };
|
C4E49DEB28F7643D0026AC4E /* CommandProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */; };
|
||||||
C4E49DED28F764A00026AC4E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
C4E49DED28F764A00026AC4E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
||||||
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; };
|
||||||
|
C4E684092AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
||||||
|
C4E6840A2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
||||||
|
C4E6840B2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
||||||
|
C4E6840C2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */; };
|
||||||
C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E9D2BF2878B336008FFDAD /* OnboardingView.swift */; };
|
C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E9D2BF2878B336008FFDAD /* OnboardingView.swift */; };
|
||||||
C4E9D90129CBA09E00BD28D4 /* PHP Monitor Self-Updater.app in Resources */ = {isa = PBXBuildFile; fileRef = C4E9D90029CBA09E00BD28D4 /* PHP Monitor Self-Updater.app */; };
|
C4E9D90129CBA09E00BD28D4 /* PHP Monitor Self-Updater.app in Resources */ = {isa = PBXBuildFile; fileRef = C4E9D90029CBA09E00BD28D4 /* PHP Monitor Self-Updater.app */; };
|
||||||
C4EB53E528551F9B006F9937 /* HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EB53E428551F9B006F9937 /* HeaderView.swift */; };
|
C4EB53E528551F9B006F9937 /* HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EB53E428551F9B006F9937 /* HeaderView.swift */; };
|
||||||
@@ -804,6 +839,7 @@
|
|||||||
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED402783497000AB15D8 /* MainMenu+Startup.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 */; };
|
||||||
C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42337A2281F19F000459A48 /* Xdebug.swift */; };
|
C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42337A2281F19F000459A48 /* Xdebug.swift */; };
|
||||||
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F7809B25D80344000DBC97 /* CommandTest.swift */; };
|
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F7809B25D80344000DBC97 /* CommandTest.swift */; };
|
||||||
C4F780A825D80AE8000DBC97 /* php.ini in Resources */ = {isa = PBXBuildFile; fileRef = C4F780A725D80AE8000DBC97 /* php.ini */; };
|
C4F780A825D80AE8000DBC97 /* php.ini in Resources */ = {isa = PBXBuildFile; fileRef = C4F780A725D80AE8000DBC97 /* php.ini */; };
|
||||||
@@ -864,7 +900,12 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
0309E6662B0D4B2F002AC007 /* BrewExtensionsObservable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewExtensionsObservable.swift; sourceTree = "<group>"; };
|
||||||
|
031E2B682B1525A7007C29E1 /* BrewPhpExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewPhpExtension.swift; sourceTree = "<group>"; };
|
||||||
0336CAAF2B0D0CDA009A1034 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
0336CAAF2B0D0CDA009A1034 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
033D45972B0D4EC600070080 /* InstallPhpExtensionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallPhpExtensionCommand.swift; sourceTree = "<group>"; };
|
||||||
|
033D459D2B0D513900070080 /* RemovePhpExtensionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemovePhpExtensionCommand.swift; sourceTree = "<group>"; };
|
||||||
|
033D45A22B0D531D00070080 /* PhpExtensionManagerView+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PhpExtensionManagerView+Actions.swift"; sourceTree = "<group>"; };
|
||||||
03E36FE628D9219000636F7F /* ActiveShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveShell.swift; sourceTree = "<group>"; };
|
03E36FE628D9219000636F7F /* ActiveShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveShell.swift; sourceTree = "<group>"; };
|
||||||
5420395826135DC100FB00FA /* PreferencesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesVC.swift; sourceTree = "<group>"; };
|
5420395826135DC100FB00FA /* PreferencesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesVC.swift; sourceTree = "<group>"; };
|
||||||
5420395E2613607600FB00FA /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
5420395E2613607600FB00FA /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
||||||
@@ -905,7 +946,7 @@
|
|||||||
C40C7F1D2772136000DDDCDC /* PhpEnvironments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpEnvironments.swift; sourceTree = "<group>"; };
|
C40C7F1D2772136000DDDCDC /* PhpEnvironments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpEnvironments.swift; sourceTree = "<group>"; };
|
||||||
C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Valet+Alerts.swift"; sourceTree = "<group>"; };
|
C40C7F2727721FF600DDDCDC /* Valet+Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Valet+Alerts.swift"; sourceTree = "<group>"; };
|
||||||
C40C7F2F27722E8D00DDDCDC /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
C40C7F2F27722E8D00DDDCDC /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||||
C40D72592A018ACC0054A067 /* PhpFormulaeStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpFormulaeStatus.swift; sourceTree = "<group>"; };
|
C40D72592A018ACC0054A067 /* BusyStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BusyStatus.swift; sourceTree = "<group>"; };
|
||||||
C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrewFormula+UI.swift"; sourceTree = "<group>"; };
|
C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BrewFormula+UI.swift"; sourceTree = "<group>"; };
|
||||||
C40F505428ECA64E004AD45B /* TestableConfigurations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableConfigurations.swift; sourceTree = "<group>"; };
|
C40F505428ECA64E004AD45B /* TestableConfigurations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableConfigurations.swift; sourceTree = "<group>"; };
|
||||||
C40FE736282ABA4F00A302C2 /* AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersion.swift; sourceTree = "<group>"; };
|
C40FE736282ABA4F00A302C2 /* AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersion.swift; sourceTree = "<group>"; };
|
||||||
@@ -934,11 +975,14 @@
|
|||||||
C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalKeybindPreference.swift; sourceTree = "<group>"; };
|
C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalKeybindPreference.swift; sourceTree = "<group>"; };
|
||||||
C41E87192763D42300161EE0 /* DomainListVC+ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DomainListVC+ContextMenu.swift"; sourceTree = "<group>"; };
|
C41E87192763D42300161EE0 /* DomainListVC+ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DomainListVC+ContextMenu.swift"; sourceTree = "<group>"; };
|
||||||
C4205A7D27F4D21800191A39 /* ValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetProxy.swift; sourceTree = "<group>"; };
|
C4205A7D27F4D21800191A39 /* ValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetProxy.swift; sourceTree = "<group>"; };
|
||||||
|
C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PhpVersionManagerView+Actions.swift"; sourceTree = "<group>"; };
|
||||||
C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorView.swift; sourceTree = "<group>"; };
|
C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorView.swift; sourceTree = "<group>"; };
|
||||||
C422DDAC28A2DAC600CEAC97 /* PhpDoctorWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorWindowController.swift; sourceTree = "<group>"; };
|
C422DDAC28A2DAC600CEAC97 /* PhpDoctorWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorWindowController.swift; sourceTree = "<group>"; };
|
||||||
C4232EE42612526500158FC6 /* Credits.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = Credits.html; sourceTree = "<group>"; };
|
C4232EE42612526500158FC6 /* Credits.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = Credits.html; sourceTree = "<group>"; };
|
||||||
C42337A2281F19F000459A48 /* Xdebug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Xdebug.swift; sourceTree = "<group>"; };
|
C42337A2281F19F000459A48 /* Xdebug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Xdebug.swift; sourceTree = "<group>"; };
|
||||||
C42759662627662800093CAE /* NSMenuExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSMenuExtension.swift; sourceTree = "<group>"; };
|
C42759662627662800093CAE /* NSMenuExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSMenuExtension.swift; sourceTree = "<group>"; };
|
||||||
|
C4292D532B023F61004F0D2A /* PhpExtensionManagerWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpExtensionManagerWindowController.swift; sourceTree = "<group>"; };
|
||||||
|
C4292D552B024006004F0D2A /* PhpExtensionManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpExtensionManagerView.swift; sourceTree = "<group>"; };
|
||||||
C4297F7928970D59004C4630 /* WarningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarningView.swift; sourceTree = "<group>"; };
|
C4297F7928970D59004C4630 /* WarningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarningView.swift; sourceTree = "<group>"; };
|
||||||
C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+FixMyValet.swift"; sourceTree = "<group>"; };
|
C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+FixMyValet.swift"; sourceTree = "<group>"; };
|
||||||
C42CFB1527DFDE7900862737 /* nginx-site.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-site.test"; sourceTree = "<group>"; };
|
C42CFB1527DFDE7900862737 /* nginx-site.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-site.test"; sourceTree = "<group>"; };
|
||||||
@@ -954,12 +998,13 @@
|
|||||||
C43A8A1925D9CD1000591B77 /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = "<group>"; };
|
C43A8A1925D9CD1000591B77 /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = "<group>"; };
|
||||||
C43A8A1F25D9D1D700591B77 /* brew-formula.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-formula.json"; sourceTree = "<group>"; };
|
C43A8A1F25D9D1D700591B77 /* brew-formula.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-formula.json"; sourceTree = "<group>"; };
|
||||||
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewPackageTest.swift; sourceTree = "<group>"; };
|
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewPackageTest.swift; sourceTree = "<group>"; };
|
||||||
C43BCD4329FBEF40001547BC /* InstallAndUpgradeCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallAndUpgradeCommand.swift; sourceTree = "<group>"; };
|
C43BCD4329FBEF40001547BC /* ModifyPhpVersionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModifyPhpVersionCommand.swift; sourceTree = "<group>"; };
|
||||||
C43FDBE829A932B0003D85EC /* PhpConfigChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigChecker.swift; sourceTree = "<group>"; };
|
C43FDBE829A932B0003D85EC /* PhpConfigChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigChecker.swift; sourceTree = "<group>"; };
|
||||||
C44067F427E2582B0045BD4E /* DomainListNameCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListNameCell.swift; sourceTree = "<group>"; };
|
C44067F427E2582B0045BD4E /* DomainListNameCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListNameCell.swift; sourceTree = "<group>"; };
|
||||||
C44067F627E258410045BD4E /* DomainListPhpCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListPhpCell.swift; sourceTree = "<group>"; };
|
C44067F627E258410045BD4E /* DomainListPhpCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListPhpCell.swift; sourceTree = "<group>"; };
|
||||||
C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTypeCell.swift; sourceTree = "<group>"; };
|
C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTypeCell.swift; sourceTree = "<group>"; };
|
||||||
C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; };
|
C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; };
|
||||||
|
C4415E8C2B0287E90035F520 /* BrewFormulaeObservable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewFormulaeObservable.swift; sourceTree = "<group>"; };
|
||||||
C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigFSNotifier.swift; sourceTree = "<group>"; };
|
C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigFSNotifier.swift; sourceTree = "<group>"; };
|
||||||
C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; };
|
C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; };
|
||||||
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; };
|
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; };
|
||||||
@@ -1021,8 +1066,6 @@
|
|||||||
C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionNumber.swift; sourceTree = "<group>"; };
|
C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionNumber.swift; sourceTree = "<group>"; };
|
||||||
C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpVersionNumberTest.swift; sourceTree = "<group>"; };
|
C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpVersionNumberTest.swift; sourceTree = "<group>"; };
|
||||||
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockingOverlayView.swift; sourceTree = "<group>"; };
|
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockingOverlayView.swift; sourceTree = "<group>"; };
|
||||||
C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressWindowView.swift; sourceTree = "<group>"; };
|
|
||||||
C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressViewSubject.swift; sourceTree = "<group>"; };
|
|
||||||
C4927F0A27B2DFC200C55AFD /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
|
C4927F0A27B2DFC200C55AFD /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
|
||||||
C4930849279F331F009C240B /* AddSiteVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSiteVC.swift; sourceTree = "<group>"; };
|
C4930849279F331F009C240B /* AddSiteVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSiteVC.swift; sourceTree = "<group>"; };
|
||||||
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentCheck.swift; sourceTree = "<group>"; };
|
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentCheck.swift; sourceTree = "<group>"; };
|
||||||
@@ -1038,7 +1081,7 @@
|
|||||||
C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetConfigurationTest.swift; sourceTree = "<group>"; };
|
C4AF9F76275447F100D44ED0 /* ValetConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetConfigurationTest.swift; sourceTree = "<group>"; };
|
||||||
C4AF9F792754499000D44ED0 /* Valet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Valet.swift; sourceTree = "<group>"; };
|
C4AF9F792754499000D44ED0 /* Valet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Valet.swift; sourceTree = "<group>"; };
|
||||||
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetVersionExtractorTest.swift; sourceTree = "<group>"; };
|
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetVersionExtractorTest.swift; sourceTree = "<group>"; };
|
||||||
C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewFormula.swift; sourceTree = "<group>"; };
|
C4AFC4AD29C4F32F00BF4E0D /* BrewPhpFormula.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewPhpFormula.swift; sourceTree = "<group>"; };
|
||||||
C4AFC4B229C4F43300BF4E0D /* HomebrewUpgradableTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewUpgradableTest.swift; sourceTree = "<group>"; };
|
C4AFC4B229C4F43300BF4E0D /* HomebrewUpgradableTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewUpgradableTest.swift; sourceTree = "<group>"; };
|
||||||
C4AFC4B729C4F57B00BF4E0D /* brew-outdated.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-outdated.json"; sourceTree = "<group>"; };
|
C4AFC4B729C4F57B00BF4E0D /* brew-outdated.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-outdated.json"; sourceTree = "<group>"; };
|
||||||
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionExtractor.swift; sourceTree = "<group>"; };
|
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionExtractor.swift; sourceTree = "<group>"; };
|
||||||
@@ -1047,7 +1090,7 @@
|
|||||||
C4B5853D2770FE3900DA4FBE /* RealCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealCommand.swift; sourceTree = "<group>"; };
|
C4B5853D2770FE3900DA4FBE /* RealCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealCommand.swift; sourceTree = "<group>"; };
|
||||||
C4B609192853AAD300C95265 /* SectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderView.swift; sourceTree = "<group>"; };
|
C4B609192853AAD300C95265 /* SectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderView.swift; sourceTree = "<group>"; };
|
||||||
C4B6091C2853AB9700C95265 /* ServicesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServicesView.swift; sourceTree = "<group>"; };
|
C4B6091C2853AB9700C95265 /* ServicesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServicesView.swift; sourceTree = "<group>"; };
|
||||||
C4B79EB529CA387F00A483EE /* BrewFormulaeHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewFormulaeHandler.swift; sourceTree = "<group>"; };
|
C4B79EB529CA387F00A483EE /* BrewPhpFormulaeHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewPhpFormulaeHandler.swift; sourceTree = "<group>"; };
|
||||||
C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewCommand.swift; sourceTree = "<group>"; };
|
C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewCommand.swift; sourceTree = "<group>"; };
|
||||||
C4B79EC529CA474200A483EE /* FakeCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeCommand.swift; sourceTree = "<group>"; };
|
C4B79EC529CA474200A483EE /* FakeCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeCommand.swift; sourceTree = "<group>"; };
|
||||||
C4B79ECA29CA475900A483EE /* RemovePhpVersionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemovePhpVersionCommand.swift; sourceTree = "<group>"; };
|
C4B79ECA29CA475900A483EE /* RemovePhpVersionCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemovePhpVersionCommand.swift; sourceTree = "<group>"; };
|
||||||
@@ -1105,6 +1148,7 @@
|
|||||||
C4E49DE628F764050026AC4E /* ActiveCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveCommand.swift; sourceTree = "<group>"; };
|
C4E49DE628F764050026AC4E /* ActiveCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveCommand.swift; sourceTree = "<group>"; };
|
||||||
C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandProtocol.swift; sourceTree = "<group>"; };
|
C4E49DE928F7643D0026AC4E /* CommandProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandProtocol.swift; sourceTree = "<group>"; };
|
||||||
C4E49DEC28F764A00026AC4E /* TestableCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableCommand.swift; sourceTree = "<group>"; };
|
C4E49DEC28F764A00026AC4E /* TestableCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableCommand.swift; sourceTree = "<group>"; };
|
||||||
|
C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrewTapFormulae.swift; sourceTree = "<group>"; };
|
||||||
C4E713562570150F00007428 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; };
|
C4E713562570150F00007428 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; };
|
||||||
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
||||||
C4E9D2BF2878B336008FFDAD /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = "<group>"; };
|
C4E9D2BF2878B336008FFDAD /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = "<group>"; };
|
||||||
@@ -1119,6 +1163,7 @@
|
|||||||
C4F30B02278E16BA00755FCE /* HomebrewService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewService.swift; sourceTree = "<group>"; };
|
C4F30B02278E16BA00755FCE /* HomebrewService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewService.swift; sourceTree = "<group>"; };
|
||||||
C4F30B06278E195800755FCE /* brew-services.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "brew-services.json"; sourceTree = "<group>"; };
|
C4F30B06278E195800755FCE /* brew-services.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "brew-services.json"; sourceTree = "<group>"; };
|
||||||
C4F361602836BFD9003598CC /* MainMenu+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Actions.swift"; sourceTree = "<group>"; };
|
C4F361602836BFD9003598CC /* MainMenu+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Actions.swift"; sourceTree = "<group>"; };
|
||||||
|
C4F520662AF03791006787F2 /* ExtensionEnumeratorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionEnumeratorTest.swift; sourceTree = "<group>"; };
|
||||||
C4F5FBCC28218C93001065C5 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = "<group>"; };
|
C4F5FBCC28218C93001065C5 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = "<group>"; };
|
||||||
C4F7807925D7F84B000DBC97 /* Unit Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Unit Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
C4F7807925D7F84B000DBC97 /* Unit Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Unit Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
C4F7809B25D80344000DBC97 /* CommandTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandTest.swift; sourceTree = "<group>"; };
|
C4F7809B25D80344000DBC97 /* CommandTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandTest.swift; sourceTree = "<group>"; };
|
||||||
@@ -1174,6 +1219,23 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
0309E6652B0D4B1D002AC007 /* Data */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0309E6662B0D4B2F002AC007 /* BrewExtensionsObservable.swift */,
|
||||||
|
);
|
||||||
|
path = Data;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
033D459C2B0D506B00070080 /* PHP Versions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C43BCD4329FBEF40001547BC /* ModifyPhpVersionCommand.swift */,
|
||||||
|
C4B79ECA29CA475900A483EE /* RemovePhpVersionCommand.swift */,
|
||||||
|
);
|
||||||
|
path = "PHP Versions";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
5420395726135DB800FB00FA /* Preferences */ = {
|
5420395726135DB800FB00FA /* Preferences */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1416,6 +1478,25 @@
|
|||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C4292D512B023F37004F0D2A /* PHP Extension Manager */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0309E6652B0D4B1D002AC007 /* Data */,
|
||||||
|
C4292D522B023F52004F0D2A /* UI */,
|
||||||
|
);
|
||||||
|
path = "PHP Extension Manager";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
C4292D522B023F52004F0D2A /* UI */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C4292D532B023F61004F0D2A /* PhpExtensionManagerWindowController.swift */,
|
||||||
|
C4292D552B024006004F0D2A /* PhpExtensionManagerView.swift */,
|
||||||
|
033D45A22B0D531D00070080 /* PhpExtensionManagerView+Actions.swift */,
|
||||||
|
);
|
||||||
|
path = UI;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
C4297F7828970D4E004C4630 /* PHP Doctor */ = {
|
C4297F7828970D4E004C4630 /* PHP Doctor */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1447,6 +1528,14 @@
|
|||||||
path = Cells;
|
path = Cells;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C4415E8B2B02877A0035F520 /* State */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C40D72592A018ACC0054A067 /* BusyStatus.swift */,
|
||||||
|
);
|
||||||
|
path = State;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
C4463FD029804C13007B93D5 /* Common */ = {
|
C4463FD029804C13007B93D5 /* Common */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1488,6 +1577,7 @@
|
|||||||
children = (
|
children = (
|
||||||
C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */,
|
C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */,
|
||||||
C43931C429C4BD610069165B /* PhpVersionManagerView.swift */,
|
C43931C429C4BD610069165B /* PhpVersionManagerView.swift */,
|
||||||
|
C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */,
|
||||||
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */,
|
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */,
|
||||||
);
|
);
|
||||||
path = UI;
|
path = UI;
|
||||||
@@ -1504,7 +1594,7 @@
|
|||||||
C44DFA7F2A6705A100B98ED5 /* Data */ = {
|
C44DFA7F2A6705A100B98ED5 /* Data */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C40D72592A018ACC0054A067 /* PhpFormulaeStatus.swift */,
|
C4415E8C2B0287E90035F520 /* BrewFormulaeObservable.swift */,
|
||||||
C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */,
|
C40D725E2A018AE30054A067 /* BrewFormula+UI.swift */,
|
||||||
C44DFA7E2A67059700B98ED5 /* Fake */,
|
C44DFA7E2A67059700B98ED5 /* Fake */,
|
||||||
);
|
);
|
||||||
@@ -1550,6 +1640,7 @@
|
|||||||
C44DFA7A2A6703FD00B98ED5 /* PHP Config Editor */,
|
C44DFA7A2A6703FD00B98ED5 /* PHP Config Editor */,
|
||||||
C4297F7828970D4E004C4630 /* PHP Doctor */,
|
C4297F7828970D4E004C4630 /* PHP Doctor */,
|
||||||
C43931C329C4BD510069165B /* PHP Version Manager */,
|
C43931C329C4BD510069165B /* PHP Version Manager */,
|
||||||
|
C4292D512B023F37004F0D2A /* PHP Extension Manager */,
|
||||||
);
|
);
|
||||||
path = Modules;
|
path = Modules;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1595,6 +1686,15 @@
|
|||||||
path = phpmon;
|
path = phpmon;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C4513F8D2B13CD08001AD760 /* PHP Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
033D45972B0D4EC600070080 /* InstallPhpExtensionCommand.swift */,
|
||||||
|
033D459D2B0D513900070080 /* RemovePhpExtensionCommand.swift */,
|
||||||
|
);
|
||||||
|
path = "PHP Extensions";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
C456A0D02AA6175D0080144F /* Config */ = {
|
C456A0D02AA6175D0080144F /* Config */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1777,15 +1877,6 @@
|
|||||||
path = "PHP Version";
|
path = "PHP Version";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C490E3A329BC92E6006D2DE6 /* Progress */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */,
|
|
||||||
C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */,
|
|
||||||
);
|
|
||||||
path = Progress;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
C4AF9F6A275445C900D44ED0 /* Valet */ = {
|
C4AF9F6A275445C900D44ED0 /* Valet */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1818,10 +1909,12 @@
|
|||||||
C4B79EBA29CA38D100A483EE /* Commands */,
|
C4B79EBA29CA38D100A483EE /* Commands */,
|
||||||
C45B42C329C7C67400366A14 /* Fake */,
|
C45B42C329C7C67400366A14 /* Fake */,
|
||||||
C43931C929C4C03F0069165B /* Brew.swift */,
|
C43931C929C4C03F0069165B /* Brew.swift */,
|
||||||
C4AFC4AD29C4F32F00BF4E0D /* BrewFormula.swift */,
|
C4AFC4AD29C4F32F00BF4E0D /* BrewPhpFormula.swift */,
|
||||||
C4B79EB529CA387F00A483EE /* BrewFormulaeHandler.swift */,
|
C4B79EB529CA387F00A483EE /* BrewPhpFormulaeHandler.swift */,
|
||||||
C4F2E4362752F0870020E974 /* BrewDiagnostics.swift */,
|
C4F2E4362752F0870020E974 /* BrewDiagnostics.swift */,
|
||||||
C40934A1298EEB2C00D25014 /* CaskFile.swift */,
|
C40934A1298EEB2C00D25014 /* CaskFile.swift */,
|
||||||
|
C4E684082AF26B830023ED25 /* BrewTapFormulae.swift */,
|
||||||
|
031E2B682B1525A7007C29E1 /* BrewPhpExtension.swift */,
|
||||||
);
|
);
|
||||||
path = Homebrew;
|
path = Homebrew;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1859,6 +1952,7 @@
|
|||||||
C44CCD4327AFE93300CE40E5 /* Errors */,
|
C44CCD4327AFE93300CE40E5 /* Errors */,
|
||||||
C4F8C0A222D4F100002EFE61 /* Extensions */,
|
C4F8C0A222D4F100002EFE61 /* Extensions */,
|
||||||
C4811D2822D70D9C00B5F6B3 /* Helpers */,
|
C4811D2822D70D9C00B5F6B3 /* Helpers */,
|
||||||
|
C4415E8B2B02877A0035F520 /* State */,
|
||||||
5489625628312F95004F647A /* Protocols */,
|
5489625628312F95004F647A /* Protocols */,
|
||||||
);
|
);
|
||||||
path = Common;
|
path = Common;
|
||||||
@@ -1896,9 +1990,9 @@
|
|||||||
C4B79EBA29CA38D100A483EE /* Commands */ = {
|
C4B79EBA29CA38D100A483EE /* Commands */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C4513F8D2B13CD08001AD760 /* PHP Extensions */,
|
||||||
|
033D459C2B0D506B00070080 /* PHP Versions */,
|
||||||
C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */,
|
C4B79EBB29CA38DB00A483EE /* BrewCommand.swift */,
|
||||||
C43BCD4329FBEF40001547BC /* InstallAndUpgradeCommand.swift */,
|
|
||||||
C4B79ECA29CA475900A483EE /* RemovePhpVersionCommand.swift */,
|
|
||||||
);
|
);
|
||||||
path = Commands;
|
path = Commands;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1941,6 +2035,7 @@
|
|||||||
C4551656297AED18009B8466 /* ValetRcTest.swift */,
|
C4551656297AED18009B8466 /* ValetRcTest.swift */,
|
||||||
C40934AA298EEDA900D25014 /* CaskFileParserTest.swift */,
|
C40934AA298EEDA900D25014 /* CaskFileParserTest.swift */,
|
||||||
C4AFC4B229C4F43300BF4E0D /* HomebrewUpgradableTest.swift */,
|
C4AFC4B229C4F43300BF4E0D /* HomebrewUpgradableTest.swift */,
|
||||||
|
C4F520662AF03791006787F2 /* ExtensionEnumeratorTest.swift */,
|
||||||
);
|
);
|
||||||
path = Parsers;
|
path = Parsers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -2056,7 +2151,6 @@
|
|||||||
children = (
|
children = (
|
||||||
C4B609182853AAA700C95265 /* Domains */,
|
C4B609182853AAA700C95265 /* Domains */,
|
||||||
C4B609172853AA9E00C95265 /* Menu */,
|
C4B609172853AA9E00C95265 /* Menu */,
|
||||||
C490E3A329BC92E6006D2DE6 /* Progress */,
|
|
||||||
C4B609162853AA9A00C95265 /* Common */,
|
C4B609162853AA9A00C95265 /* Common */,
|
||||||
);
|
);
|
||||||
path = SwiftUI;
|
path = SwiftUI;
|
||||||
@@ -2236,7 +2330,7 @@
|
|||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
BuildIndependentTargetsInParallel = YES;
|
||||||
LastSwiftUpdateCheck = 1420;
|
LastSwiftUpdateCheck = 1420;
|
||||||
LastUpgradeCheck = 1430;
|
LastUpgradeCheck = 1500;
|
||||||
ORGANIZATIONNAME = "Nico Verbruggen";
|
ORGANIZATIONNAME = "Nico Verbruggen";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
C406A5EF298AD2CE00B5B85A = {
|
C406A5EF298AD2CE00B5B85A = {
|
||||||
@@ -2321,6 +2415,7 @@
|
|||||||
C4E2E85528FC256B003B070C /* brew-services-sudo.json in Resources */,
|
C4E2E85528FC256B003B070C /* brew-services-sudo.json in Resources */,
|
||||||
C4E2E85928FC256B003B070C /* brew-services-normal.json in Resources */,
|
C4E2E85928FC256B003B070C /* brew-services-normal.json in Resources */,
|
||||||
C40934A8298EEB8700D25014 /* phpmon-dev.rb in Resources */,
|
C40934A8298EEB8700D25014 /* phpmon-dev.rb in Resources */,
|
||||||
|
C428311F2B52AD6F0009F9F1 /* Assets.xcassets in Resources */,
|
||||||
C4E2E84F28FC22E4003B070C /* brew-formula.json in Resources */,
|
C4E2E84F28FC22E4003B070C /* brew-formula.json in Resources */,
|
||||||
C4E2E86228FC28A6003B070C /* brew-services.json in Resources */,
|
C4E2E86228FC28A6003B070C /* brew-services.json in Resources */,
|
||||||
);
|
);
|
||||||
@@ -2334,6 +2429,7 @@
|
|||||||
C4E2E85628FC256B003B070C /* brew-services-sudo.json in Resources */,
|
C4E2E85628FC256B003B070C /* brew-services-sudo.json in Resources */,
|
||||||
C4E2E85A28FC256B003B070C /* brew-services-normal.json in Resources */,
|
C4E2E85A28FC256B003B070C /* brew-services-normal.json in Resources */,
|
||||||
C40934A9298EEB8700D25014 /* phpmon-dev.rb in Resources */,
|
C40934A9298EEB8700D25014 /* phpmon-dev.rb in Resources */,
|
||||||
|
C42831202B52AD700009F9F1 /* Assets.xcassets in Resources */,
|
||||||
C4E2E85028FC22E4003B070C /* brew-formula.json in Resources */,
|
C4E2E85028FC22E4003B070C /* brew-formula.json in Resources */,
|
||||||
C4E2E86128FC28A6003B070C /* brew-services.json in Resources */,
|
C4E2E86128FC28A6003B070C /* brew-services.json in Resources */,
|
||||||
);
|
);
|
||||||
@@ -2345,6 +2441,7 @@
|
|||||||
files = (
|
files = (
|
||||||
C4551659297AED7D009B8466 /* valetrc.valid in Resources */,
|
C4551659297AED7D009B8466 /* valetrc.valid in Resources */,
|
||||||
C4FC8D3E2A49816300FBBD16 /* Localizable.strings in Resources */,
|
C4FC8D3E2A49816300FBBD16 /* Localizable.strings in Resources */,
|
||||||
|
C428311E2B52AD6F0009F9F1 /* Assets.xcassets in Resources */,
|
||||||
54FCFD27276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
|
54FCFD27276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
|
||||||
54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */,
|
54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */,
|
||||||
C42CFB1827DFDFDC00862737 /* nginx-site-isolated.test in Resources */,
|
C42CFB1827DFDFDC00862737 /* nginx-site-isolated.test in Resources */,
|
||||||
@@ -2413,16 +2510,18 @@
|
|||||||
C41ADCE82970CCC700120423 /* FSNotifier.swift in Sources */,
|
C41ADCE82970CCC700120423 /* FSNotifier.swift in Sources */,
|
||||||
C47699EF28A2F2A30060FEB8 /* WarningManager.swift in Sources */,
|
C47699EF28A2F2A30060FEB8 /* WarningManager.swift in Sources */,
|
||||||
C490E3BB29BCA375006D2DE6 /* Measurements.swift in Sources */,
|
C490E3BB29BCA375006D2DE6 /* Measurements.swift in Sources */,
|
||||||
|
C4E684092AF26B830023ED25 /* BrewTapFormulae.swift in Sources */,
|
||||||
C4B79EC629CA474200A483EE /* FakeCommand.swift in Sources */,
|
C4B79EC629CA474200A483EE /* FakeCommand.swift in Sources */,
|
||||||
C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */,
|
C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */,
|
||||||
C47DF1AF299D5A3B0007055D /* LoginItemManager.swift in Sources */,
|
C47DF1AF299D5A3B0007055D /* LoginItemManager.swift in Sources */,
|
||||||
C490E3AA29BC9B3E006D2DE6 /* ProgressViewSubject.swift in Sources */,
|
C4292D542B023F61004F0D2A /* PhpExtensionManagerWindowController.swift in Sources */,
|
||||||
C4D3661A291173EA006BD146 /* DictionaryExtension.swift in Sources */,
|
C4D3661A291173EA006BD146 /* DictionaryExtension.swift in Sources */,
|
||||||
C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */,
|
C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */,
|
||||||
C409349D298EE8E900D25014 /* AppUpdater.swift in Sources */,
|
C409349D298EE8E900D25014 /* AppUpdater.swift in Sources */,
|
||||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */,
|
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */,
|
||||||
C43931CA29C4C03F0069165B /* Brew.swift in Sources */,
|
C43931CA29C4C03F0069165B /* Brew.swift in Sources */,
|
||||||
C42C49DB27C2806F0074ABAC /* MainMenu+FixMyValet.swift in Sources */,
|
C42C49DB27C2806F0074ABAC /* MainMenu+FixMyValet.swift in Sources */,
|
||||||
|
C4292D562B024006004F0D2A /* PhpExtensionManagerView.swift in Sources */,
|
||||||
C48D6C70279CD2AC00F26D7E /* VersionNumber.swift in Sources */,
|
C48D6C70279CD2AC00F26D7E /* VersionNumber.swift in Sources */,
|
||||||
C4998F0A2617633900B2526E /* PreferencesWindowController.swift in Sources */,
|
C4998F0A2617633900B2526E /* PreferencesWindowController.swift in Sources */,
|
||||||
C46FA9882822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */,
|
C46FA9882822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */,
|
||||||
@@ -2439,6 +2538,7 @@
|
|||||||
C45B91532956123A00F4EC78 /* FakeServicesManager.swift in Sources */,
|
C45B91532956123A00F4EC78 /* FakeServicesManager.swift in Sources */,
|
||||||
C41C708D28AA7F7900E8D498 /* NoWarningsView.swift in Sources */,
|
C41C708D28AA7F7900E8D498 /* NoWarningsView.swift in Sources */,
|
||||||
C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
|
C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
|
||||||
|
0309E6672B0D4B2F002AC007 /* BrewExtensionsObservable.swift in Sources */,
|
||||||
C4E0F7ED27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */,
|
C4E0F7ED27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */,
|
||||||
C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */,
|
C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */,
|
||||||
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
|
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
|
||||||
@@ -2462,6 +2562,7 @@
|
|||||||
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */,
|
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */,
|
||||||
C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */,
|
C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */,
|
||||||
C4F2E4372752F0870020E974 /* BrewDiagnostics.swift in Sources */,
|
C4F2E4372752F0870020E974 /* BrewDiagnostics.swift in Sources */,
|
||||||
|
031E2B692B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */,
|
||||||
C4AD38B228ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */,
|
C4AD38B228ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */,
|
||||||
C4EB53E528551F9B006F9937 /* HeaderView.swift in Sources */,
|
C4EB53E528551F9B006F9937 /* HeaderView.swift in Sources */,
|
||||||
C40FE737282ABA4F00A302C2 /* AppVersion.swift in Sources */,
|
C40FE737282ABA4F00A302C2 /* AppVersion.swift in Sources */,
|
||||||
@@ -2510,6 +2611,7 @@
|
|||||||
5420395F2613607600FB00FA /* Preferences.swift in Sources */,
|
5420395F2613607600FB00FA /* Preferences.swift in Sources */,
|
||||||
C48D0C9325CC804200CC7490 /* XibLoadable.swift in Sources */,
|
C48D0C9325CC804200CC7490 /* XibLoadable.swift in Sources */,
|
||||||
54FCFD2A276C8AA4004CE748 /* CheckboxPreferenceView.swift in Sources */,
|
54FCFD2A276C8AA4004CE748 /* CheckboxPreferenceView.swift in Sources */,
|
||||||
|
033D45982B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */,
|
||||||
C47699F128A2F3150060FEB8 /* Warning.swift in Sources */,
|
C47699F128A2F3150060FEB8 /* Warning.swift in Sources */,
|
||||||
54D9E0B227E4F51E003B9AD9 /* HotKeysController.swift in Sources */,
|
54D9E0B227E4F51E003B9AD9 /* HotKeysController.swift in Sources */,
|
||||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
|
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
|
||||||
@@ -2545,6 +2647,7 @@
|
|||||||
C4B5853E2770FE3900DA4FBE /* Paths.swift in Sources */,
|
C4B5853E2770FE3900DA4FBE /* Paths.swift in Sources */,
|
||||||
C41C1B4B22B019FF00E7CF16 /* ActivePhpInstallation.swift in Sources */,
|
C41C1B4B22B019FF00E7CF16 /* ActivePhpInstallation.swift in Sources */,
|
||||||
C4FE011128084FC200D1DE6D /* SelectionVC.swift in Sources */,
|
C4FE011128084FC200D1DE6D /* SelectionVC.swift in Sources */,
|
||||||
|
033D459E2B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */,
|
||||||
C4709CA228524B3400088BB8 /* StatsView.swift in Sources */,
|
C4709CA228524B3400088BB8 /* StatsView.swift in Sources */,
|
||||||
C44CCD4027AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
|
C44CCD4027AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
|
||||||
C4B6091D2853AB9700C95265 /* ServicesView.swift in Sources */,
|
C4B6091D2853AB9700C95265 /* ServicesView.swift in Sources */,
|
||||||
@@ -2555,34 +2658,36 @@
|
|||||||
C4D36601291132B7006BD146 /* ValetScanners.swift in Sources */,
|
C4D36601291132B7006BD146 /* ValetScanners.swift in Sources */,
|
||||||
C4EED88927A48778006D7272 /* InterAppHandler.swift in Sources */,
|
C4EED88927A48778006D7272 /* InterAppHandler.swift in Sources */,
|
||||||
C40C7F1E2772136000DDDCDC /* PhpEnvironments.swift in Sources */,
|
C40C7F1E2772136000DDDCDC /* PhpEnvironments.swift in Sources */,
|
||||||
C4B79EB629CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */,
|
C4B79EB629CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */,
|
||||||
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
|
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
|
||||||
|
033D45A32B0D531D00070080 /* PhpExtensionManagerView+Actions.swift in Sources */,
|
||||||
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
|
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
|
||||||
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
||||||
C4D36615291160A1006BD146 /* WIP.swift in Sources */,
|
C4D36615291160A1006BD146 /* WIP.swift in Sources */,
|
||||||
C485707028BF452300539B36 /* PhpDoctorWindowController.swift in Sources */,
|
C485707028BF452300539B36 /* PhpDoctorWindowController.swift in Sources */,
|
||||||
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */,
|
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */,
|
||||||
C40D725A2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */,
|
C40D725A2A018ACC0054A067 /* BusyStatus.swift in Sources */,
|
||||||
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
||||||
C4FACE83288F1F9700FC478F /* OnboardingWindowController.swift in Sources */,
|
C4FACE83288F1F9700FC478F /* OnboardingWindowController.swift in Sources */,
|
||||||
|
C4415E8D2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */,
|
||||||
C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
|
C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
|
||||||
C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */,
|
C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */,
|
||||||
C490E3A729BC940D006D2DE6 /* ProgressWindowView.swift in Sources */,
|
|
||||||
C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */,
|
C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */,
|
||||||
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
||||||
C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */,
|
C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */,
|
||||||
54D9E0B627E4F51E003B9AD9 /* HotKey.swift in Sources */,
|
54D9E0B627E4F51E003B9AD9 /* HotKey.swift in Sources */,
|
||||||
C4AFC4AE29C4F32F00BF4E0D /* BrewFormula.swift in Sources */,
|
C4AFC4AE29C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */,
|
||||||
C4D936C927E3EB6100BD69FE /* PhpHelper.swift in Sources */,
|
C4D936C927E3EB6100BD69FE /* PhpHelper.swift in Sources */,
|
||||||
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 */,
|
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */,
|
||||||
|
C42106662AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C40508AF28ADA23D008FAC1F /* NoDomainResultsView.swift in Sources */,
|
C40508AF28ADA23D008FAC1F /* NoDomainResultsView.swift in Sources */,
|
||||||
C4B79ECB29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
C4B79ECB29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
||||||
C40D725F2A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
C40D725F2A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
||||||
C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */,
|
C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */,
|
||||||
C43BCD4429FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */,
|
C43BCD4429FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */,
|
||||||
C4E2E84A28FC1E70003B070C /* DataExtension.swift in Sources */,
|
C4E2E84A28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||||
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */,
|
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */,
|
||||||
C42337A3281F19F000459A48 /* Xdebug.swift in Sources */,
|
C42337A3281F19F000459A48 /* Xdebug.swift in Sources */,
|
||||||
@@ -2608,7 +2713,7 @@
|
|||||||
C4FD87A929AB9ABD0002D701 /* PhpConfigChecker.swift in Sources */,
|
C4FD87A929AB9ABD0002D701 /* PhpConfigChecker.swift in Sources */,
|
||||||
C471E83028F9BB650021E251 /* Application.swift in Sources */,
|
C471E83028F9BB650021E251 /* Application.swift in Sources */,
|
||||||
C471E83128F9BB650021E251 /* LocalNotification.swift in Sources */,
|
C471E83128F9BB650021E251 /* LocalNotification.swift in Sources */,
|
||||||
C4B79EB829CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */,
|
C4B79EB829CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */,
|
||||||
C471E83228F9BB650021E251 /* MenuBarImageGenerator.swift in Sources */,
|
C471E83228F9BB650021E251 /* MenuBarImageGenerator.swift in Sources */,
|
||||||
C4BB393B2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
|
C4BB393B2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
|
||||||
C471E83328F9BB650021E251 /* PMWindowController.swift in Sources */,
|
C471E83328F9BB650021E251 /* PMWindowController.swift in Sources */,
|
||||||
@@ -2620,6 +2725,7 @@
|
|||||||
C471E83928F9BB650021E251 /* ValetSite.swift in Sources */,
|
C471E83928F9BB650021E251 /* ValetSite.swift in Sources */,
|
||||||
C471E83A28F9BB650021E251 /* FakeValetSite.swift in Sources */,
|
C471E83A28F9BB650021E251 /* FakeValetSite.swift in Sources */,
|
||||||
C471E83C28F9BB650021E251 /* ValetDomainScanner.swift in Sources */,
|
C471E83C28F9BB650021E251 /* ValetDomainScanner.swift in Sources */,
|
||||||
|
033D459A2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */,
|
||||||
C4E2E86928FC3002003B070C /* Utility.swift in Sources */,
|
C4E2E86928FC3002003B070C /* Utility.swift in Sources */,
|
||||||
C471E83D28F9BB650021E251 /* FakeDomainScanner.swift in Sources */,
|
C471E83D28F9BB650021E251 /* FakeDomainScanner.swift in Sources */,
|
||||||
C471E83F28F9BB650021E251 /* AppDelegate.swift in Sources */,
|
C471E83F28F9BB650021E251 /* AppDelegate.swift in Sources */,
|
||||||
@@ -2632,6 +2738,7 @@
|
|||||||
C45E2A7529199248005C7CFD /* InternalSwitcherTest.swift in Sources */,
|
C45E2A7529199248005C7CFD /* InternalSwitcherTest.swift in Sources */,
|
||||||
C471E84428F9BB650021E251 /* App+ActivationPolicy.swift in Sources */,
|
C471E84428F9BB650021E251 /* App+ActivationPolicy.swift in Sources */,
|
||||||
C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */,
|
C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */,
|
||||||
|
C4513F922B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */,
|
||||||
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */,
|
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */,
|
||||||
C471E84728F9BB650021E251 /* Startup.swift in Sources */,
|
C471E84728F9BB650021E251 /* Startup.swift in Sources */,
|
||||||
C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */,
|
C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */,
|
||||||
@@ -2665,7 +2772,6 @@
|
|||||||
C471E85E28F9BB650021E251 /* DomainListVC+ContextMenu.swift in Sources */,
|
C471E85E28F9BB650021E251 /* DomainListVC+ContextMenu.swift in Sources */,
|
||||||
C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */,
|
C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */,
|
||||||
C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */,
|
C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */,
|
||||||
C490E3B429BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */,
|
|
||||||
C4D5576629C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
C4D5576629C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
||||||
C4ACE9E329F84EDD00110766 /* PhpGuard.swift in Sources */,
|
C4ACE9E329F84EDD00110766 /* PhpGuard.swift in Sources */,
|
||||||
C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */,
|
C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */,
|
||||||
@@ -2683,11 +2789,12 @@
|
|||||||
C471E86828F9BB650021E251 /* PreferencesWindowController.swift in Sources */,
|
C471E86828F9BB650021E251 /* PreferencesWindowController.swift in Sources */,
|
||||||
C471E86928F9BB650021E251 /* PreferencesWindowController+Hotkey.swift in Sources */,
|
C471E86928F9BB650021E251 /* PreferencesWindowController+Hotkey.swift in Sources */,
|
||||||
C48DDD0F29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */,
|
C48DDD0F29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */,
|
||||||
C4AFC4B029C4F32F00BF4E0D /* BrewFormula.swift in Sources */,
|
C4AFC4B029C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */,
|
||||||
C471E86A28F9BB650021E251 /* PreferencesVC.swift in Sources */,
|
C471E86A28F9BB650021E251 /* PreferencesVC.swift in Sources */,
|
||||||
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
|
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
|
||||||
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
|
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
|
||||||
C4D3660D29113F20006BD146 /* System.swift in Sources */,
|
C4D3660D29113F20006BD146 /* System.swift in Sources */,
|
||||||
|
033D45A02B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */,
|
||||||
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
|
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
|
||||||
C45D654E29F52F74004C28F9 /* BrewPermissionFixer.swift in Sources */,
|
C45D654E29F52F74004C28F9 /* BrewPermissionFixer.swift in Sources */,
|
||||||
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
|
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||||
@@ -2697,7 +2804,6 @@
|
|||||||
C471E87028F9BB650021E251 /* GlobalKeybindPreference.swift in Sources */,
|
C471E87028F9BB650021E251 /* GlobalKeybindPreference.swift in Sources */,
|
||||||
C471E87228F9BB650021E251 /* CheckboxPreferenceView.swift in Sources */,
|
C471E87228F9BB650021E251 /* CheckboxPreferenceView.swift in Sources */,
|
||||||
C471E87428F9BB650021E251 /* SelectPreferenceView.swift in Sources */,
|
C471E87428F9BB650021E251 /* SelectPreferenceView.swift in Sources */,
|
||||||
C490E3B029BC9FE8006D2DE6 /* ProgressViewSubject.swift in Sources */,
|
|
||||||
C471E87628F9BB650021E251 /* HotkeyPreferenceView.swift in Sources */,
|
C471E87628F9BB650021E251 /* HotkeyPreferenceView.swift in Sources */,
|
||||||
C471E87728F9BB650021E251 /* Keys.swift in Sources */,
|
C471E87728F9BB650021E251 /* Keys.swift in Sources */,
|
||||||
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */,
|
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */,
|
||||||
@@ -2712,6 +2818,7 @@
|
|||||||
C471E88228F9BB650021E251 /* OnboardingView.swift in Sources */,
|
C471E88228F9BB650021E251 /* OnboardingView.swift in Sources */,
|
||||||
C471E88328F9BB650021E251 /* VersionPopoverView.swift in Sources */,
|
C471E88328F9BB650021E251 /* VersionPopoverView.swift in Sources */,
|
||||||
C471E88428F9BB650021E251 /* NoDomainResultsView.swift in Sources */,
|
C471E88428F9BB650021E251 /* NoDomainResultsView.swift in Sources */,
|
||||||
|
C4513F952B13E30C001AD760 /* BrewExtensionsObservable.swift in Sources */,
|
||||||
C471E88528F9BB650021E251 /* ServicesView.swift in Sources */,
|
C471E88528F9BB650021E251 /* ServicesView.swift in Sources */,
|
||||||
C471E88628F9BB650021E251 /* StatsView.swift in Sources */,
|
C471E88628F9BB650021E251 /* StatsView.swift in Sources */,
|
||||||
C451AFF82969E40F0078E617 /* HelpButton.swift in Sources */,
|
C451AFF82969E40F0078E617 /* HelpButton.swift in Sources */,
|
||||||
@@ -2729,6 +2836,7 @@
|
|||||||
C471E7E928F9BAC20021E251 /* Paths.swift in Sources */,
|
C471E7E928F9BAC20021E251 /* Paths.swift in Sources */,
|
||||||
C45B91552956123A00F4EC78 /* FakeServicesManager.swift in Sources */,
|
C45B91552956123A00F4EC78 /* FakeServicesManager.swift in Sources */,
|
||||||
C471E7FE28F9BACE0021E251 /* HomebrewDecodable.swift in Sources */,
|
C471E7FE28F9BACE0021E251 /* HomebrewDecodable.swift in Sources */,
|
||||||
|
C4415E8F2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */,
|
||||||
C471E7D828F9BA8F0021E251 /* FileSystemProtocol.swift in Sources */,
|
C471E7D828F9BA8F0021E251 /* FileSystemProtocol.swift in Sources */,
|
||||||
C471E7F328F9BAC70021E251 /* PhpHelper.swift in Sources */,
|
C471E7F328F9BAC70021E251 /* PhpHelper.swift in Sources */,
|
||||||
C471E7E728F9BAC20021E251 /* Constants.swift in Sources */,
|
C471E7E728F9BAC20021E251 /* Constants.swift in Sources */,
|
||||||
@@ -2742,6 +2850,7 @@
|
|||||||
C471E80528F9BAD40021E251 /* ActivePhpInstallation.swift in Sources */,
|
C471E80528F9BAD40021E251 /* ActivePhpInstallation.swift in Sources */,
|
||||||
C471E80628F9BAD40021E251 /* PhpInstallation.swift in Sources */,
|
C471E80628F9BAD40021E251 /* PhpInstallation.swift in Sources */,
|
||||||
C471E81828F9BAE80021E251 /* StringExtension.swift in Sources */,
|
C471E81828F9BAE80021E251 /* StringExtension.swift in Sources */,
|
||||||
|
C4E6840B2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */,
|
||||||
C471E7FA28F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
|
C471E7FA28F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
|
||||||
C471E82628F9BB2E0021E251 /* ComposerJson.swift in Sources */,
|
C471E82628F9BB2E0021E251 /* ComposerJson.swift in Sources */,
|
||||||
C471E82428F9BB2E0021E251 /* ProjectTypeDetection.swift in Sources */,
|
C471E82428F9BB2E0021E251 /* ProjectTypeDetection.swift in Sources */,
|
||||||
@@ -2752,6 +2861,7 @@
|
|||||||
C471E80828F9BAD40021E251 /* PhpExtension.swift in Sources */,
|
C471E80828F9BAD40021E251 /* PhpExtension.swift in Sources */,
|
||||||
C471E7F928F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
|
C471E7F928F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
|
||||||
C471E82A28F9BB330021E251 /* ValetListable.swift in Sources */,
|
C471E82A28F9BB330021E251 /* ValetListable.swift in Sources */,
|
||||||
|
031E2B6B2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */,
|
||||||
C471E82728F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
|
C471E82728F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
|
||||||
C471E81C28F9BB250021E251 /* BetterAlert.swift in Sources */,
|
C471E81C28F9BB250021E251 /* BetterAlert.swift in Sources */,
|
||||||
C471E7DB28F9BA8F0021E251 /* RealShell.swift in Sources */,
|
C471E7DB28F9BA8F0021E251 /* RealShell.swift in Sources */,
|
||||||
@@ -2761,11 +2871,13 @@
|
|||||||
C471E7F228F9BAC70021E251 /* PhpEnvironments.swift in Sources */,
|
C471E7F228F9BAC70021E251 /* PhpEnvironments.swift in Sources */,
|
||||||
C471E7E628F9BAC20021E251 /* Process.swift in Sources */,
|
C471E7E628F9BAC20021E251 /* Process.swift in Sources */,
|
||||||
C471E81928F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
|
C471E81928F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
|
||||||
|
C4513F982B13E338001AD760 /* PhpExtensionManagerView+Actions.swift in Sources */,
|
||||||
C45B914B295607F400F4EC78 /* Service.swift in Sources */,
|
C45B914B295607F400F4EC78 /* Service.swift in Sources */,
|
||||||
C471E7D928F9BA8F0021E251 /* TestableShell.swift in Sources */,
|
C471E7D928F9BA8F0021E251 /* TestableShell.swift in Sources */,
|
||||||
C471E81428F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
C471E81428F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
||||||
C43BCD4629FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */,
|
C43BCD4629FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */,
|
||||||
C471E7D328F9BA8F0021E251 /* ActiveShell.swift in Sources */,
|
C471E7D328F9BA8F0021E251 /* ActiveShell.swift in Sources */,
|
||||||
|
C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */,
|
C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */,
|
||||||
C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
||||||
C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */,
|
C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */,
|
||||||
@@ -2782,12 +2894,13 @@
|
|||||||
C45E2A77291992DA005C7CFD /* FeatureTestCase.swift in Sources */,
|
C45E2A77291992DA005C7CFD /* FeatureTestCase.swift in Sources */,
|
||||||
C471E82028F9BB290021E251 /* NginxConfigurationFile.swift in Sources */,
|
C471E82028F9BB290021E251 /* NginxConfigurationFile.swift in Sources */,
|
||||||
C471E7D428F9BA8F0021E251 /* ActiveFileSystem.swift in Sources */,
|
C471E7D428F9BA8F0021E251 /* ActiveFileSystem.swift in Sources */,
|
||||||
|
C4513F902B13E2E6001AD760 /* PhpExtensionManagerWindowController.swift in Sources */,
|
||||||
C471E81528F9BAE80021E251 /* ArrayExtension.swift in Sources */,
|
C471E81528F9BAE80021E251 /* ArrayExtension.swift in Sources */,
|
||||||
C471E7DA28F9BA8F0021E251 /* TestableCommand.swift in Sources */,
|
C471E7DA28F9BA8F0021E251 /* TestableCommand.swift in Sources */,
|
||||||
C471E7E528F9BAC20021E251 /* Events.swift in Sources */,
|
C471E7E528F9BAC20021E251 /* Events.swift in Sources */,
|
||||||
C471E7D628F9BA8F0021E251 /* RealFileSystem.swift in Sources */,
|
C471E7D628F9BA8F0021E251 /* RealFileSystem.swift in Sources */,
|
||||||
C471E81728F9BAE80021E251 /* NSMenuExtension.swift in Sources */,
|
C471E81728F9BAE80021E251 /* NSMenuExtension.swift in Sources */,
|
||||||
C40D725C2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */,
|
C40D725C2A018ACC0054A067 /* BusyStatus.swift in Sources */,
|
||||||
C471E81328F9BAE80021E251 /* XibLoadable.swift in Sources */,
|
C471E81328F9BAE80021E251 /* XibLoadable.swift in Sources */,
|
||||||
C4D3661C291173EA006BD146 /* DictionaryExtension.swift in Sources */,
|
C4D3661C291173EA006BD146 /* DictionaryExtension.swift in Sources */,
|
||||||
C4B79ECD29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
C4B79ECD29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
||||||
@@ -2805,12 +2918,13 @@
|
|||||||
C471E89128F9BB8F0021E251 /* Errors.swift in Sources */,
|
C471E89128F9BB8F0021E251 /* Errors.swift in Sources */,
|
||||||
C4B79EC929CA474200A483EE /* FakeCommand.swift in Sources */,
|
C4B79EC929CA474200A483EE /* FakeCommand.swift in Sources */,
|
||||||
C471E89228F9BB8F0021E251 /* Alert.swift in Sources */,
|
C471E89228F9BB8F0021E251 /* Alert.swift in Sources */,
|
||||||
|
033D45A12B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */,
|
||||||
C471E89328F9BB8F0021E251 /* Application.swift in Sources */,
|
C471E89328F9BB8F0021E251 /* Application.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 */,
|
||||||
C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */,
|
C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */,
|
||||||
C40D725D2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */,
|
C40D725D2A018ACC0054A067 /* BusyStatus.swift in Sources */,
|
||||||
C471E89628F9BB8F0021E251 /* PMWindowController.swift in Sources */,
|
C471E89628F9BB8F0021E251 /* PMWindowController.swift in Sources */,
|
||||||
C471E89728F9BB8F0021E251 /* VersionExtractor.swift in Sources */,
|
C471E89728F9BB8F0021E251 /* VersionExtractor.swift in Sources */,
|
||||||
C47DF1B2299D5A3B0007055D /* LoginItemManager.swift in Sources */,
|
C47DF1B2299D5A3B0007055D /* LoginItemManager.swift in Sources */,
|
||||||
@@ -2822,17 +2936,17 @@
|
|||||||
C471E89F28F9BB8F0021E251 /* ValetDomainScanner.swift in Sources */,
|
C471E89F28F9BB8F0021E251 /* ValetDomainScanner.swift in Sources */,
|
||||||
C471E8A028F9BB8F0021E251 /* FakeDomainScanner.swift in Sources */,
|
C471E8A028F9BB8F0021E251 /* FakeDomainScanner.swift in Sources */,
|
||||||
C471E8A228F9BB8F0021E251 /* AppDelegate.swift in Sources */,
|
C471E8A228F9BB8F0021E251 /* AppDelegate.swift in Sources */,
|
||||||
|
C42106692AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C43931CD29C4C03F0069165B /* Brew.swift in Sources */,
|
C43931CD29C4C03F0069165B /* Brew.swift in Sources */,
|
||||||
C451AFF92969E40F0078E617 /* HelpButton.swift in Sources */,
|
C451AFF92969E40F0078E617 /* HelpButton.swift in Sources */,
|
||||||
C4ACE9E429F84EDD00110766 /* PhpGuard.swift in Sources */,
|
C4ACE9E429F84EDD00110766 /* PhpGuard.swift in Sources */,
|
||||||
C471E8A328F9BB8F0021E251 /* AppDelegate+MenuOutlets.swift in Sources */,
|
C471E8A328F9BB8F0021E251 /* AppDelegate+MenuOutlets.swift in Sources */,
|
||||||
C4B79EB929CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */,
|
C4B79EB929CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */,
|
||||||
C471E8A428F9BB8F0021E251 /* AppDelegate+Notifications.swift in Sources */,
|
C471E8A428F9BB8F0021E251 /* AppDelegate+Notifications.swift in Sources */,
|
||||||
C490E3B329BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */,
|
|
||||||
C489E0BE2A220A4200323F5E /* FakeBrewFormulaeHandler.swift in Sources */,
|
C489E0BE2A220A4200323F5E /* FakeBrewFormulaeHandler.swift in Sources */,
|
||||||
C490E3B229BC9FE8006D2DE6 /* ProgressViewSubject.swift in Sources */,
|
|
||||||
C471E8A528F9BB8F0021E251 /* AppDelegate+InterApp.swift in Sources */,
|
C471E8A528F9BB8F0021E251 /* AppDelegate+InterApp.swift in Sources */,
|
||||||
C471E8A628F9BB8F0021E251 /* App.swift in Sources */,
|
C471E8A628F9BB8F0021E251 /* App.swift in Sources */,
|
||||||
|
C4513F912B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */,
|
||||||
C471E8A728F9BB8F0021E251 /* App+ActivationPolicy.swift in Sources */,
|
C471E8A728F9BB8F0021E251 /* App+ActivationPolicy.swift in Sources */,
|
||||||
C45B914C295607F400F4EC78 /* Service.swift in Sources */,
|
C45B914C295607F400F4EC78 /* Service.swift in Sources */,
|
||||||
C471E8A828F9BB8F0021E251 /* App+GlobalHotkey.swift in Sources */,
|
C471E8A828F9BB8F0021E251 /* App+GlobalHotkey.swift in Sources */,
|
||||||
@@ -2857,6 +2971,7 @@
|
|||||||
C471E8BD28F9BB8F0021E251 /* DomainListTypeCell.swift in Sources */,
|
C471E8BD28F9BB8F0021E251 /* DomainListTypeCell.swift in Sources */,
|
||||||
C471E8BE28F9BB8F0021E251 /* DomainListKindCell.swift in Sources */,
|
C471E8BE28F9BB8F0021E251 /* DomainListKindCell.swift in Sources */,
|
||||||
C4E2E86A28FC3002003B070C /* Utility.swift in Sources */,
|
C4E2E86A28FC3002003B070C /* Utility.swift in Sources */,
|
||||||
|
031E2B6C2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */,
|
||||||
C471E8BF28F9BB8F0021E251 /* DomainListWindowController.swift in Sources */,
|
C471E8BF28F9BB8F0021E251 /* DomainListWindowController.swift in Sources */,
|
||||||
C471E8C028F9BB8F0021E251 /* DomainListVC.swift in Sources */,
|
C471E8C028F9BB8F0021E251 /* DomainListVC.swift in Sources */,
|
||||||
C4D5576729C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
C4D5576729C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
||||||
@@ -2881,6 +2996,7 @@
|
|||||||
C471E8CD28F9BB8F0021E251 /* PreferencesVC.swift in Sources */,
|
C471E8CD28F9BB8F0021E251 /* PreferencesVC.swift in Sources */,
|
||||||
C471E8CE28F9BB8F0021E251 /* PreferenceName.swift in Sources */,
|
C471E8CE28F9BB8F0021E251 /* PreferenceName.swift in Sources */,
|
||||||
C471E8CF28F9BB8F0021E251 /* Preferences.swift in Sources */,
|
C471E8CF28F9BB8F0021E251 /* Preferences.swift in Sources */,
|
||||||
|
C4415E902B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */,
|
||||||
C4E2E84D28FC1E70003B070C /* DataExtension.swift in Sources */,
|
C4E2E84D28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||||
C471E8D028F9BB8F0021E251 /* CustomPrefs.swift in Sources */,
|
C471E8D028F9BB8F0021E251 /* CustomPrefs.swift in Sources */,
|
||||||
C471E8D128F9BB8F0021E251 /* MenuBarIcons.swift in Sources */,
|
C471E8D128F9BB8F0021E251 /* MenuBarIcons.swift in Sources */,
|
||||||
@@ -2959,31 +3075,36 @@
|
|||||||
C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */,
|
C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */,
|
||||||
C471E82828F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
|
C471E82828F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
|
||||||
C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */,
|
C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */,
|
||||||
C43BCD4729FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */,
|
C43BCD4729FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */,
|
||||||
C44E985F29B23EBF0059F773 /* UpdateCheckTest.swift in Sources */,
|
C44E985F29B23EBF0059F773 /* UpdateCheckTest.swift in Sources */,
|
||||||
|
C4513F8E2B13E2E5001AD760 /* PhpExtensionManagerWindowController.swift in Sources */,
|
||||||
C471E7D228F9BA630021E251 /* ActiveFileSystem.swift in Sources */,
|
C471E7D228F9BA630021E251 /* ActiveFileSystem.swift in Sources */,
|
||||||
C471E80028F9BAD10021E251 /* Xdebug.swift in Sources */,
|
C471E80028F9BAD10021E251 /* Xdebug.swift in Sources */,
|
||||||
C471E7F528F9BAC80021E251 /* PhpEnvironments.swift in Sources */,
|
C471E7F528F9BAC80021E251 /* PhpEnvironments.swift in Sources */,
|
||||||
C471E7ED28F9BAC30021E251 /* Process.swift in Sources */,
|
C471E7ED28F9BAC30021E251 /* Process.swift in Sources */,
|
||||||
C471E81128F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
|
C471E81128F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
|
||||||
C471E7CC28F9BA5B0021E251 /* TestableShell.swift in Sources */,
|
C471E7CC28F9BA5B0021E251 /* TestableShell.swift in Sources */,
|
||||||
|
C4E6840C2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */,
|
||||||
C471E80C28F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
C471E80C28F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
||||||
C471E7CA28F9BA480021E251 /* TestableFileSystem.swift in Sources */,
|
C471E7CA28F9BA480021E251 /* TestableFileSystem.swift in Sources */,
|
||||||
C471E7DD28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
C471E7DD28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
||||||
C471E7D128F9BA630021E251 /* RealFileSystem.swift in Sources */,
|
C471E7D128F9BA630021E251 /* RealFileSystem.swift in Sources */,
|
||||||
|
033D459B2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */,
|
||||||
C471E81D28F9BB260021E251 /* BetterAlertVC.swift in Sources */,
|
C471E81D28F9BB260021E251 /* BetterAlertVC.swift in Sources */,
|
||||||
C471E82B28F9BB340021E251 /* Valet.swift in Sources */,
|
C471E82B28F9BB340021E251 /* Valet.swift in Sources */,
|
||||||
C471E80328F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */,
|
C471E80328F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */,
|
||||||
C471E7C928F9BA2F0021E251 /* TestableConfigurations.swift in Sources */,
|
C471E7C928F9BA2F0021E251 /* TestableConfigurations.swift in Sources */,
|
||||||
C471E7EA28F9BAC30021E251 /* Logger.swift in Sources */,
|
C471E7EA28F9BAC30021E251 /* Logger.swift in Sources */,
|
||||||
C471E7FB28F9BACE0021E251 /* HomebrewService.swift in Sources */,
|
C471E7FB28F9BACE0021E251 /* HomebrewService.swift in Sources */,
|
||||||
|
C4513F942B13E30B001AD760 /* BrewExtensionsObservable.swift in Sources */,
|
||||||
C471E7EB28F9BAC30021E251 /* Helpers.swift in Sources */,
|
C471E7EB28F9BAC30021E251 /* Helpers.swift in Sources */,
|
||||||
C4CB6E68292C362C002E9027 /* Homebrew.swift in Sources */,
|
C4CB6E68292C362C002E9027 /* Homebrew.swift in Sources */,
|
||||||
C4181F1128FAF9330042EA28 /* UITestCase.swift in Sources */,
|
C4181F1128FAF9330042EA28 /* UITestCase.swift in Sources */,
|
||||||
C4611E622AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
C4611E622AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
||||||
C4AFC4B129C4F32F00BF4E0D /* BrewFormula.swift in Sources */,
|
C4AFC4B129C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */,
|
||||||
C471E81F28F9BB290021E251 /* NginxConfigurationFile.swift in Sources */,
|
C471E81F28F9BB290021E251 /* NginxConfigurationFile.swift in Sources */,
|
||||||
C471E7BF28F9B90F0021E251 /* StartupTest.swift in Sources */,
|
C471E7BF28F9B90F0021E251 /* StartupTest.swift in Sources */,
|
||||||
|
C4513F972B13E338001AD760 /* PhpExtensionManagerView+Actions.swift in Sources */,
|
||||||
C4D3661D291173EA006BD146 /* DictionaryExtension.swift in Sources */,
|
C4D3661D291173EA006BD146 /* DictionaryExtension.swift in Sources */,
|
||||||
C471E80D28F9BAE80021E251 /* ArrayExtension.swift in Sources */,
|
C471E80D28F9BAE80021E251 /* ArrayExtension.swift in Sources */,
|
||||||
C471E7CD28F9BA600021E251 /* ShellProtocol.swift in Sources */,
|
C471E7CD28F9BA600021E251 /* ShellProtocol.swift in Sources */,
|
||||||
@@ -3033,6 +3154,7 @@
|
|||||||
C485707728BF455300539B36 /* HeaderView.swift in Sources */,
|
C485707728BF455300539B36 /* HeaderView.swift in Sources */,
|
||||||
C4F780B125D80B4D000DBC97 /* PhpExtension.swift in Sources */,
|
C4F780B125D80B4D000DBC97 /* PhpExtension.swift in Sources */,
|
||||||
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
||||||
|
C4E6840A2AF26B830023ED25 /* BrewTapFormulae.swift in Sources */,
|
||||||
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
|
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
|
||||||
C4F780CE25D80B75000DBC97 /* LocalNotification.swift in Sources */,
|
C4F780CE25D80B75000DBC97 /* LocalNotification.swift in Sources */,
|
||||||
C41ADCE92970CCC700120423 /* FSNotifier.swift in Sources */,
|
C41ADCE92970CCC700120423 /* FSNotifier.swift in Sources */,
|
||||||
@@ -3051,7 +3173,6 @@
|
|||||||
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */,
|
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */,
|
||||||
C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */,
|
C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */,
|
||||||
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */,
|
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */,
|
||||||
C490E3B129BC9FE8006D2DE6 /* ProgressViewSubject.swift in Sources */,
|
|
||||||
C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */,
|
C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */,
|
||||||
C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */,
|
C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */,
|
||||||
C45B914A295607F400F4EC78 /* Service.swift in Sources */,
|
C45B914A295607F400F4EC78 /* Service.swift in Sources */,
|
||||||
@@ -3061,6 +3182,7 @@
|
|||||||
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
||||||
C463E381284930EE00422731 /* PresetHelper.swift in Sources */,
|
C463E381284930EE00422731 /* PresetHelper.swift in Sources */,
|
||||||
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||||
|
C4F520672AF03791006787F2 /* ExtensionEnumeratorTest.swift in Sources */,
|
||||||
C46FA98C2822F08F00D78807 /* PhpConfigurationFileTest.swift in Sources */,
|
C46FA98C2822F08F00D78807 /* PhpConfigurationFileTest.swift in Sources */,
|
||||||
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
||||||
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
|
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
|
||||||
@@ -3071,13 +3193,14 @@
|
|||||||
C4611E5F2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */,
|
C4611E5F2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */,
|
||||||
C4F780AE25D80B37000DBC97 /* PhpExtensionTest.swift in Sources */,
|
C4F780AE25D80B37000DBC97 /* PhpExtensionTest.swift in Sources */,
|
||||||
C456A0C72AA614BD0080144F /* PhpPreference.swift in Sources */,
|
C456A0C72AA614BD0080144F /* PhpPreference.swift in Sources */,
|
||||||
|
C42106672AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
|
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
|
||||||
C4FC21B128391F8E00D368BB /* MainMenu+Actions.swift in Sources */,
|
C4FC21B128391F8E00D368BB /* MainMenu+Actions.swift in Sources */,
|
||||||
54D9E0B927E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
|
54D9E0B927E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
|
||||||
C4EED88A27A48778006D7272 /* InterAppHandler.swift in Sources */,
|
C4EED88A27A48778006D7272 /* InterAppHandler.swift in Sources */,
|
||||||
C4159AF728E4D40400545349 /* RealShellTest.swift in Sources */,
|
C4159AF728E4D40400545349 /* RealShellTest.swift in Sources */,
|
||||||
C450C8C728C919EC002A2B4B /* PreferenceName.swift in Sources */,
|
C450C8C728C919EC002A2B4B /* PreferenceName.swift in Sources */,
|
||||||
C40D725B2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */,
|
C40D725B2A018ACC0054A067 /* BusyStatus.swift in Sources */,
|
||||||
C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */,
|
C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */,
|
||||||
C40D72602A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
C40D72602A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
||||||
C485707B28BF458900539B36 /* VersionPopoverView.swift in Sources */,
|
C485707B28BF458900539B36 /* VersionPopoverView.swift in Sources */,
|
||||||
@@ -3091,9 +3214,11 @@
|
|||||||
C4AFC4B429C4F43300BF4E0D /* HomebrewUpgradableTest.swift in Sources */,
|
C4AFC4B429C4F43300BF4E0D /* HomebrewUpgradableTest.swift in Sources */,
|
||||||
C4E2E84828FC1D93003B070C /* TestableConfigurationTest.swift in Sources */,
|
C4E2E84828FC1D93003B070C /* TestableConfigurationTest.swift in Sources */,
|
||||||
C4D936CB27E3EE4A00BD69FE /* DomainListCellProtocol.swift in Sources */,
|
C4D936CB27E3EE4A00BD69FE /* DomainListCellProtocol.swift in Sources */,
|
||||||
|
C4513F962B13E30C001AD760 /* BrewExtensionsObservable.swift in Sources */,
|
||||||
C4B97B76275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */,
|
C4B97B76275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */,
|
||||||
C4AFC4AF29C4F32F00BF4E0D /* BrewFormula.swift in Sources */,
|
C4AFC4AF29C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */,
|
||||||
C4F780CD25D80B75000DBC97 /* Alert.swift in Sources */,
|
C4F780CD25D80B75000DBC97 /* Alert.swift in Sources */,
|
||||||
|
C4415E8E2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */,
|
||||||
C485706D28BF450900539B36 /* NSMenuItemExtension.swift in Sources */,
|
C485706D28BF450900539B36 /* NSMenuItemExtension.swift in Sources */,
|
||||||
C481F79726164A78004FBCFF /* PreferencesVC.swift in Sources */,
|
C481F79726164A78004FBCFF /* PreferencesVC.swift in Sources */,
|
||||||
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */,
|
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */,
|
||||||
@@ -3108,7 +3233,6 @@
|
|||||||
C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
||||||
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */,
|
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */,
|
||||||
C4AF9F78275447F100D44ED0 /* ValetConfigurationTest.swift in Sources */,
|
C4AF9F78275447F100D44ED0 /* ValetConfigurationTest.swift in Sources */,
|
||||||
C490E3B529BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */,
|
|
||||||
C4611E612AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
C4611E612AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
||||||
C40175B92903108900763A68 /* ValetInteractor.swift in Sources */,
|
C40175B92903108900763A68 /* ValetInteractor.swift in Sources */,
|
||||||
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */,
|
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */,
|
||||||
@@ -3118,6 +3242,7 @@
|
|||||||
C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
|
C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
|
||||||
C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
|
C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
|
||||||
5489625928313231004F647A /* CreatedFromFile.swift in Sources */,
|
5489625928313231004F647A /* CreatedFromFile.swift in Sources */,
|
||||||
|
C4513F932B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */,
|
||||||
C471E79328F9B21F0021E251 /* ActiveFileSystem.swift in Sources */,
|
C471E79328F9B21F0021E251 /* ActiveFileSystem.swift in Sources */,
|
||||||
54D9E0B327E4F51E003B9AD9 /* HotKeysController.swift in Sources */,
|
54D9E0B327E4F51E003B9AD9 /* HotKeysController.swift in Sources */,
|
||||||
C4D36616291160A1006BD146 /* WIP.swift in Sources */,
|
C4D36616291160A1006BD146 /* WIP.swift in Sources */,
|
||||||
@@ -3144,6 +3269,7 @@
|
|||||||
C4F780BA25D80B62000DBC97 /* AppDelegate.swift in Sources */,
|
C4F780BA25D80B62000DBC97 /* AppDelegate.swift in Sources */,
|
||||||
C456A0D22AA6179D0080144F /* BytePhpPreferenceTest.swift in Sources */,
|
C456A0D22AA6179D0080144F /* BytePhpPreferenceTest.swift in Sources */,
|
||||||
54FCFD31276C8DA4004CE748 /* HotkeyPreferenceView.swift in Sources */,
|
54FCFD31276C8DA4004CE748 /* HotkeyPreferenceView.swift in Sources */,
|
||||||
|
031E2B6A2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */,
|
||||||
C4998F0B2617633900B2526E /* PreferencesWindowController.swift in Sources */,
|
C4998F0B2617633900B2526E /* PreferencesWindowController.swift in Sources */,
|
||||||
C485707228BF453800539B36 /* SwiftUIHelper.swift in Sources */,
|
C485707228BF453800539B36 /* SwiftUIHelper.swift in Sources */,
|
||||||
C4F2E43B27530F750020E974 /* PhpInstallation.swift in Sources */,
|
C4F2E43B27530F750020E974 /* PhpInstallation.swift in Sources */,
|
||||||
@@ -3151,6 +3277,8 @@
|
|||||||
C44C198E276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */,
|
C44C198E276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */,
|
||||||
C4B79EBD29CA38DB00A483EE /* BrewCommand.swift in Sources */,
|
C4B79EBD29CA38DB00A483EE /* BrewCommand.swift in Sources */,
|
||||||
C485707828BF456300539B36 /* Warning.swift in Sources */,
|
C485707828BF456300539B36 /* Warning.swift in Sources */,
|
||||||
|
033D459F2B0D513900070080 /* RemovePhpExtensionCommand.swift in Sources */,
|
||||||
|
C4513F8F2B13E2E5001AD760 /* PhpExtensionManagerWindowController.swift in Sources */,
|
||||||
C415938027A1B54F00D2E1B7 /* ProjectTypeDetection.swift in Sources */,
|
C415938027A1B54F00D2E1B7 /* ProjectTypeDetection.swift in Sources */,
|
||||||
C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */,
|
C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */,
|
||||||
C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
||||||
@@ -3160,6 +3288,7 @@
|
|||||||
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */,
|
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */,
|
||||||
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */,
|
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */,
|
||||||
C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */,
|
C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */,
|
||||||
|
033D45992B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */,
|
||||||
C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */,
|
C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */,
|
||||||
C40B24F227A310770018C7D2 /* Events.swift in Sources */,
|
C40B24F227A310770018C7D2 /* Events.swift in Sources */,
|
||||||
C490E3B829BCA367006D2DE6 /* App+BrewWatch.swift in Sources */,
|
C490E3B829BCA367006D2DE6 /* App+BrewWatch.swift in Sources */,
|
||||||
@@ -3190,16 +3319,17 @@
|
|||||||
C4F780C925D80B75000DBC97 /* StringExtension.swift in Sources */,
|
C4F780C925D80B75000DBC97 /* StringExtension.swift in Sources */,
|
||||||
C4D9F24C280B69E100DCD39A /* AddProxyVC.swift in Sources */,
|
C4D9F24C280B69E100DCD39A /* AddProxyVC.swift in Sources */,
|
||||||
C4D4CB3829C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */,
|
C4D4CB3829C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */,
|
||||||
C4B79EB729CA387F00A483EE /* BrewFormulaeHandler.swift in Sources */,
|
C4B79EB729CA387F00A483EE /* BrewPhpFormulaeHandler.swift in Sources */,
|
||||||
C4B5853F2770FE3900DA4FBE /* Paths.swift in Sources */,
|
C4B5853F2770FE3900DA4FBE /* Paths.swift in Sources */,
|
||||||
C481F79A26164A7C004FBCFF /* Preferences.swift in Sources */,
|
C481F79A26164A7C004FBCFF /* Preferences.swift in Sources */,
|
||||||
|
C4513F992B13E338001AD760 /* PhpExtensionManagerView+Actions.swift in Sources */,
|
||||||
C4E0F7EE27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */,
|
C4E0F7EE27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */,
|
||||||
C4A81CA528C67101008DD9D1 /* PMTableView.swift in Sources */,
|
C4A81CA528C67101008DD9D1 /* PMTableView.swift in Sources */,
|
||||||
C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */,
|
C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */,
|
||||||
C4D36602291132B7006BD146 /* ValetScanners.swift in Sources */,
|
C4D36602291132B7006BD146 /* ValetScanners.swift in Sources */,
|
||||||
C40934AB298EEDA900D25014 /* CaskFileParserTest.swift in Sources */,
|
C40934AB298EEDA900D25014 /* CaskFileParserTest.swift in Sources */,
|
||||||
C436B39E29F3C42500B6A64E /* PreferencesTabs.swift in Sources */,
|
C436B39E29F3C42500B6A64E /* PreferencesTabs.swift in Sources */,
|
||||||
C43BCD4529FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */,
|
C43BCD4529FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */,
|
||||||
C4551657297AED18009B8466 /* ValetRcTest.swift in Sources */,
|
C4551657297AED18009B8466 /* ValetRcTest.swift in Sources */,
|
||||||
C464ADAD275A7A3F003FCD53 /* DomainListWindowController.swift in Sources */,
|
C464ADAD275A7A3F003FCD53 /* DomainListWindowController.swift in Sources */,
|
||||||
C40C7F1F2772136000DDDCDC /* PhpEnvironments.swift in Sources */,
|
C40C7F1F2772136000DDDCDC /* PhpEnvironments.swift in Sources */,
|
||||||
@@ -3397,6 +3527,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -3461,6 +3592,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -3523,7 +3655,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1350;
|
CURRENT_PROJECT_VERSION = 1422;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@@ -3536,7 +3668,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||||
MARKETING_VERSION = 6.2.2;
|
MARKETING_VERSION = 7.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -3554,7 +3686,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1350;
|
CURRENT_PROJECT_VERSION = 1422;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@@ -3567,7 +3699,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||||
MARKETING_VERSION = 6.2.2;
|
MARKETING_VERSION = 7.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -3732,6 +3864,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -3794,7 +3927,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1350;
|
CURRENT_PROJECT_VERSION = 1422;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@@ -3807,7 +3940,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||||
MARKETING_VERSION = 6.2.2;
|
MARKETING_VERSION = 7.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
||||||
@@ -3841,6 +3974,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -3910,7 +4044,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1350;
|
CURRENT_PROJECT_VERSION = 1422;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@@ -3923,7 +4057,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||||
MARKETING_VERSION = 6.2.2;
|
MARKETING_VERSION = 7.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
||||||
@@ -3957,6 +4091,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -4026,7 +4161,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1350;
|
CURRENT_PROJECT_VERSION = 1422;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@@ -4039,7 +4174,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||||
MARKETING_VERSION = 6.2.2;
|
MARKETING_VERSION = 7.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
|
||||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME) EAP";
|
PRODUCT_NAME = "$(TARGET_NAME) EAP";
|
||||||
@@ -4145,6 +4280,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -4207,7 +4343,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1350;
|
CURRENT_PROJECT_VERSION = 1422;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@@ -4220,7 +4356,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||||
MARKETING_VERSION = 6.2.2;
|
MARKETING_VERSION = 7.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
|
||||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME) EAP";
|
PRODUCT_NAME = "$(TARGET_NAME) EAP";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1430"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1430"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1430"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1430"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.7">
|
version = "1.7">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1430"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ All stable and supported PHP versions are also supported by PHP Monitor. However
|
|||||||
|
|
||||||
Backports that are installable via PHP Monitor's **PHP Version Manager** functionality are subject to availability via [this tap](https://github.com/shivammathur/homebrew-php).
|
Backports that are installable via PHP Monitor's **PHP Version Manager** functionality are subject to availability via [this tap](https://github.com/shivammathur/homebrew-php).
|
||||||
|
|
||||||
|
PHP extensions that are installable via PHP Monitor's **PHP Extension Manager** functionality are subject to availability via [this tap](https://github.com/shivammathur/homebrew-extensions).
|
||||||
|
|
||||||
For maximum compatibility with older PHP versions, you may wish to keep using Valet 2 or 3. For more information, please see [SECURITY.md](./SECURITY.md) to find out which versions of PHP are supported with different versions of Valet.
|
For maximum compatibility with older PHP versions, you may wish to keep using Valet 2 or 3. For more information, please see [SECURITY.md](./SECURITY.md) to find out which versions of PHP are supported with different versions of Valet.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 674 KiB After Width: | Height: | Size: 723 KiB |
@@ -14,8 +14,6 @@ class Actions {
|
|||||||
|
|
||||||
public static func linkPhp() async {
|
public static func linkPhp() async {
|
||||||
await brew("link php --overwrite --force")
|
await brew("link php --overwrite --force")
|
||||||
|
|
||||||
// TODO: Verify that this worked, if not, notify the user
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func restartPhpFpm() async {
|
public static func restartPhpFpm() async {
|
||||||
|
|||||||
@@ -18,6 +18,20 @@ struct Constants {
|
|||||||
*/
|
*/
|
||||||
static let MinimumRecommendedValetVersion = "2.16.2"
|
static let MinimumRecommendedValetVersion = "2.16.2"
|
||||||
|
|
||||||
|
/**
|
||||||
|
PHP Monitor supplies a hardcoded list of PHP packages in its own
|
||||||
|
PHP Version Manager.
|
||||||
|
|
||||||
|
This hardcoded list will expire and will need to be modified when
|
||||||
|
the cutoff date occurs, which is when the `php` formula will
|
||||||
|
become PHP 8.4, and a new build will need to be made.
|
||||||
|
|
||||||
|
If users launch an older version of the app, then a warning
|
||||||
|
will be displayed to let them know that certain operations
|
||||||
|
will not work correctly and that they need to update their app.
|
||||||
|
*/
|
||||||
|
static let PhpFormulaeCutoffDate = "2024-11-01"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The PHP versions that are considered pre-release versions.
|
* The PHP versions that are considered pre-release versions.
|
||||||
* Past a certain date, an experimental version "graduates"
|
* Past a certain date, an experimental version "graduates"
|
||||||
@@ -25,8 +39,7 @@ struct Constants {
|
|||||||
*/
|
*/
|
||||||
static var ExperimentalPhpVersions: Set<String> {
|
static var ExperimentalPhpVersions: Set<String> {
|
||||||
let releaseDates = [
|
let releaseDates = [
|
||||||
"8.4": Date.fromString("2024-12-01"), // PLACEHOLDER DATE
|
"8.4": Date.fromString("2024-12-01") // PLACEHOLDER DATE
|
||||||
"8.3": Date.fromString("2023-11-23") // OFFICIAL RELEASE
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return Set(releaseDates
|
return Set(releaseDates
|
||||||
@@ -48,8 +61,7 @@ struct Constants {
|
|||||||
static let DetectedPhpVersions: Set = [
|
static let DetectedPhpVersions: Set = [
|
||||||
"5.6",
|
"5.6",
|
||||||
"7.0", "7.1", "7.2", "7.3", "7.4",
|
"7.0", "7.1", "7.2", "7.3", "7.4",
|
||||||
"8.0", "8.1", "8.2",
|
"8.0", "8.1", "8.2", "8.3",
|
||||||
"8.3",
|
|
||||||
"8.4"
|
"8.4"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ public class Paths {
|
|||||||
return "\(shared.baseDir.rawValue)/etc"
|
return "\(shared.baseDir.rawValue)/etc"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static var tapPath: String {
|
||||||
|
return "\(shared.baseDir.rawValue)/Library/Taps"
|
||||||
|
}
|
||||||
|
|
||||||
public static var caskroomPath: String {
|
public static var caskroomPath: String {
|
||||||
return "\(shared.baseDir.rawValue)/Caskroom/"
|
return "\(shared.baseDir.rawValue)/Caskroom/"
|
||||||
+ (App.identifier.contains(".dev") ? "phpmon-dev" : "phpmon")
|
+ (App.identifier.contains(".dev") ? "phpmon-dev" : "phpmon")
|
||||||
|
|||||||
@@ -8,6 +8,18 @@ import Foundation
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct Localization {
|
struct Localization {
|
||||||
|
static var preferredLanguage: String? {
|
||||||
|
guard let language = Preferences.preferences[.languageOverride] as? String else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if language.isEmpty {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return language
|
||||||
|
}
|
||||||
|
|
||||||
static var bundle: Bundle = {
|
static var bundle: Bundle = {
|
||||||
if !isRunningTests {
|
if !isRunningTests {
|
||||||
return Bundle.main
|
return Bundle.main
|
||||||
@@ -32,7 +44,15 @@ struct Localization {
|
|||||||
|
|
||||||
extension String {
|
extension String {
|
||||||
var localized: String {
|
var localized: String {
|
||||||
let string = NSLocalizedString(self, tableName: nil, bundle: Localization.bundle, value: "", comment: "")
|
var preferredBundle: Bundle = Localization.bundle
|
||||||
|
|
||||||
|
if let preferred = Localization.preferredLanguage,
|
||||||
|
let path = Localization.bundle.path(forResource: preferred, ofType: "lproj"),
|
||||||
|
let bundle = Bundle(path: path) {
|
||||||
|
preferredBundle = bundle
|
||||||
|
}
|
||||||
|
|
||||||
|
let string = NSLocalizedString(self, tableName: nil, bundle: preferredBundle, value: "", comment: "")
|
||||||
|
|
||||||
// Fallback to English translation if the localized value is equal to the key (should not happen)
|
// Fallback to English translation if the localized value is equal to the key (should not happen)
|
||||||
if string == self {
|
if string == self {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class RealFileSystem: FileSystemProtocol {
|
|||||||
// MARK: — FS Attributes
|
// MARK: — FS Attributes
|
||||||
|
|
||||||
func makeExecutable(_ path: String) throws {
|
func makeExecutable(_ path: String) throws {
|
||||||
_ = system("chmod +x \(path.replacingTildeWithHomeDirectory)")
|
_ = ActiveShell.shared.sync("chmod +x \(path.replacingTildeWithHomeDirectory)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Checks
|
// MARK: - Checks
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class MenuBarImageGenerator {
|
|||||||
|
|
||||||
// Then we'll fetch the image we want on the left
|
// Then we'll fetch the image we want on the left
|
||||||
var iconType = Preferences.preferences[.iconTypeToDisplay] as? String
|
var iconType = Preferences.preferences[.iconTypeToDisplay] as? String
|
||||||
if iconType == nil {
|
if iconType == nil || !MenuBarIcon.allCases.map({ $0.rawValue }).contains(iconType) {
|
||||||
Log.warn("Invalid icon type found, using the default")
|
Log.warn("Invalid icon type found, using the default")
|
||||||
iconType = MenuBarIcon.iconPhp.rawValue
|
iconType = MenuBarIcon.iconPhp.rawValue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import Foundation
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Run a simple blocking Shell command on the user's own system.
|
Run a simple blocking Shell command on the user's own system.
|
||||||
Avoid using this method in favor of the fakeable Shell class unless needed for express system operations.
|
|
||||||
*/
|
*/
|
||||||
public func system(_ command: String) -> String {
|
public func system(_ command: String) -> String {
|
||||||
let task = Process()
|
let task = Process()
|
||||||
|
|||||||
@@ -62,13 +62,6 @@ class ActivePhpInstallation {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load extension information
|
|
||||||
let mainConfigurationFileUrl = URL(fileURLWithPath: "\(Paths.etcPath)/php/\(version.short)/php.ini")
|
|
||||||
|
|
||||||
if let file = PhpConfigurationFile.from(filePath: mainConfigurationFileUrl.path) {
|
|
||||||
iniFiles.append(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get configuration values
|
// Get configuration values
|
||||||
limits = Limits(
|
limits = Limits(
|
||||||
memory_limit: getByteCount(key: "memory_limit"),
|
memory_limit: getByteCount(key: "memory_limit"),
|
||||||
@@ -76,14 +69,9 @@ class ActivePhpInstallation {
|
|||||||
post_max_size: getByteCount(key: "post_max_size")
|
post_max_size: getByteCount(key: "post_max_size")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Return a list of .ini files parsed after php.ini
|
let paths = ActiveShell.shared
|
||||||
let paths = Command.execute(
|
.sync("\(Paths.php) --ini | grep -E -o '(/[^ ]+\\.ini)'").out
|
||||||
path: Paths.php,
|
.split(separator: "\n")
|
||||||
arguments: ["-r", "echo php_ini_scanned_files();"],
|
|
||||||
trimNewlines: false
|
|
||||||
)
|
|
||||||
.replacingOccurrences(of: "\n", with: "")
|
|
||||||
.split(separator: ",")
|
|
||||||
.map { String($0) }
|
.map { String($0) }
|
||||||
|
|
||||||
// See if any extensions are present in said .ini files
|
// See if any extensions are present in said .ini files
|
||||||
|
|||||||
@@ -87,7 +87,14 @@ class PhpEnvironments {
|
|||||||
var cachedPhpInstallations: [String: PhpInstallation] = [:]
|
var cachedPhpInstallations: [String: PhpInstallation] = [:]
|
||||||
|
|
||||||
/** Information about the currently linked PHP installation. */
|
/** Information about the currently linked PHP installation. */
|
||||||
var currentInstall: ActivePhpInstallation?
|
var currentInstall: ActivePhpInstallation? {
|
||||||
|
didSet {
|
||||||
|
// Let the PHP extension manager, if it exists, know the version changed
|
||||||
|
if let version = currentInstall?.version.short {
|
||||||
|
App.shared.phpExtensionManagerWindowController?.view?.manager.phpVersion = version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The version that the `php` formula via Brew is aliased to on the current system.
|
The version that the `php` formula via Brew is aliased to on the current system.
|
||||||
@@ -173,7 +180,7 @@ class PhpEnvironments {
|
|||||||
let phpAliasInstall = PhpInstallation(phpAlias)
|
let phpAliasInstall = PhpInstallation(phpAlias)
|
||||||
// Before inserting, ensure that the actual output matches the alias
|
// Before inserting, ensure that the actual output matches the alias
|
||||||
// if that isn't the case, our formula remains out-of-date
|
// if that isn't the case, our formula remains out-of-date
|
||||||
if !phpAliasInstall.missingBinary {
|
if !phpAliasInstall.isMissingBinary {
|
||||||
supportedVersions.insert(phpAlias)
|
supportedVersions.insert(phpAlias)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,21 +12,36 @@ class PhpInstallation {
|
|||||||
|
|
||||||
var versionNumber: VersionNumber
|
var versionNumber: VersionNumber
|
||||||
|
|
||||||
var missingBinary: Bool = false
|
var iniFiles: [PhpConfigurationFile] = []
|
||||||
|
|
||||||
|
var isMissingBinary: Bool = false
|
||||||
|
|
||||||
var isHealthy: Bool = true
|
var isHealthy: Bool = true
|
||||||
|
|
||||||
|
var extensions: [PhpExtension] {
|
||||||
|
return self.iniFiles.flatMap({ $0.extensions })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
In order to determine details about a PHP installation,
|
In order to determine details about a PHP installation,
|
||||||
we’ll simply run `php-config --version` in the relevant directory.
|
we’ll simply run `php-config --version` in the relevant directory.
|
||||||
*/
|
*/
|
||||||
init(_ version: String) {
|
init(_ version: String) {
|
||||||
let phpConfigExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php-config"
|
let phpConfigExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php-config",
|
||||||
|
phpExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php"
|
||||||
|
|
||||||
let phpExecutablePath = "\(Paths.optPath)/php@\(version)/bin/php"
|
versionNumber = VersionNumber.make(from: version)!
|
||||||
|
|
||||||
self.versionNumber = VersionNumber.make(from: version)!
|
determineVersion(phpConfigExecutablePath, phpExecutablePath)
|
||||||
|
determineHealth(phpExecutablePath)
|
||||||
|
determineIniFiles(phpExecutablePath)
|
||||||
|
|
||||||
|
// Find all enabled extensions
|
||||||
|
let enabled = self.extensions.filter({ $0.enabled }).map({ $0.name })
|
||||||
|
Log.info("PHP \(versionNumber.short) has the following extensions enabled: \(enabled)")
|
||||||
|
}
|
||||||
|
|
||||||
|
private func determineVersion(_ phpConfigExecutablePath: String, _ phpExecutablePath: String) {
|
||||||
if FileSystem.fileExists(phpConfigExecutablePath) {
|
if FileSystem.fileExists(phpConfigExecutablePath) {
|
||||||
let longVersionString = Command.execute(
|
let longVersionString = Command.execute(
|
||||||
path: phpConfigExecutablePath,
|
path: phpConfigExecutablePath,
|
||||||
@@ -36,13 +51,15 @@ class PhpInstallation {
|
|||||||
|
|
||||||
// The parser should always work, or the string has to be very unusual.
|
// The parser should always work, or the string has to be very unusual.
|
||||||
// If so, the app SHOULD crash, so that the users report what's up.
|
// If so, the app SHOULD crash, so that the users report what's up.
|
||||||
self.versionNumber = try! VersionNumber.parse(longVersionString)
|
versionNumber = try! VersionNumber.parse(longVersionString)
|
||||||
} else {
|
} else {
|
||||||
// Keep track that the `php-config` binary is missing; this often means there's a mismatch between
|
// Keep track that the `php-config` binary is missing; this often means there's a mismatch between
|
||||||
// the `php` version alias and the actual installed version (e.g. you haven't upgraded `php`)
|
// the `php` version alias and the actual installed version (e.g. you haven't upgraded `php`)
|
||||||
missingBinary = true
|
isMissingBinary = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func determineHealth(_ phpExecutablePath: String) {
|
||||||
if FileSystem.fileExists(phpExecutablePath) {
|
if FileSystem.fileExists(phpExecutablePath) {
|
||||||
let testCommand = Command.execute(
|
let testCommand = Command.execute(
|
||||||
path: phpExecutablePath,
|
path: phpExecutablePath,
|
||||||
@@ -59,4 +76,18 @@ class PhpInstallation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func determineIniFiles(_ phpExecutablePath: String) {
|
||||||
|
let paths = ActiveShell.shared
|
||||||
|
.sync("\(phpExecutablePath) --ini | grep -E -o '(/[^ ]+\\.ini)'").out
|
||||||
|
.split(separator: "\n")
|
||||||
|
.map { String($0) }
|
||||||
|
|
||||||
|
// See if any extensions are present in said .ini files
|
||||||
|
paths.forEach { (iniFilePath) in
|
||||||
|
if let file = PhpConfigurationFile.from(filePath: iniFilePath) {
|
||||||
|
iniFiles.append(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ extension InternalSwitcher {
|
|||||||
return corrections.contains(true)
|
return corrections.contains(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - PHP FPM pool
|
// MARK: - Corrections
|
||||||
|
|
||||||
public func disableDefaultPhpFpmPool(_ version: String) async -> FixApplied {
|
public func disableDefaultPhpFpmPool(_ version: String) async -> FixApplied {
|
||||||
let pool = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf"
|
let pool = "\(Paths.etcPath)/php/\(version)/php-fpm.d/www.conf"
|
||||||
@@ -54,37 +54,7 @@ extension InternalSwitcher {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExpectedConfigurationFiles(for version: String) -> [ExpectedConfigurationFile] {
|
public func ensureConfigurationFilesExist(_ version: String) async -> FixApplied {
|
||||||
return [
|
|
||||||
ExpectedConfigurationFile(
|
|
||||||
destination: "/php-fpm.d/valet-fpm.conf",
|
|
||||||
source: "/cli/stubs/etc-phpfpm-valet.conf",
|
|
||||||
replacements: [
|
|
||||||
"VALET_USER": Paths.whoami,
|
|
||||||
"VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory,
|
|
||||||
"valet.sock": "valet\(version.replacingOccurrences(of: ".", with: "")).sock"
|
|
||||||
],
|
|
||||||
applies: { Valet.shared.version!.major > 2 }
|
|
||||||
),
|
|
||||||
ExpectedConfigurationFile(
|
|
||||||
destination: "/conf.d/error_log.ini",
|
|
||||||
source: "/cli/stubs/etc-phpfpm-error_log.ini",
|
|
||||||
replacements: [
|
|
||||||
"VALET_USER": Paths.whoami,
|
|
||||||
"VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory
|
|
||||||
],
|
|
||||||
applies: { return true }
|
|
||||||
),
|
|
||||||
ExpectedConfigurationFile(
|
|
||||||
destination: "/conf.d/php-memory-limits.ini",
|
|
||||||
source: "/cli/stubs/php-memory-limits.ini",
|
|
||||||
replacements: [:],
|
|
||||||
applies: { return true }
|
|
||||||
)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensureConfigurationFilesExist(_ version: String) async -> FixApplied {
|
|
||||||
let files = self.getExpectedConfigurationFiles(for: version)
|
let files = self.getExpectedConfigurationFiles(for: version)
|
||||||
|
|
||||||
// For each of the files, attempt to fix anything that is wrong
|
// For each of the files, attempt to fix anything that is wrong
|
||||||
@@ -124,6 +94,38 @@ extension InternalSwitcher {
|
|||||||
return outcomes.contains(true)
|
return outcomes.contains(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Internals
|
||||||
|
|
||||||
|
private func getExpectedConfigurationFiles(for version: String) -> [ExpectedConfigurationFile] {
|
||||||
|
return [
|
||||||
|
ExpectedConfigurationFile(
|
||||||
|
destination: "/php-fpm.d/valet-fpm.conf",
|
||||||
|
source: "/cli/stubs/etc-phpfpm-valet.conf",
|
||||||
|
replacements: [
|
||||||
|
"VALET_USER": Paths.whoami,
|
||||||
|
"VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory,
|
||||||
|
"valet.sock": "valet\(version.replacingOccurrences(of: ".", with: "")).sock"
|
||||||
|
],
|
||||||
|
applies: { Valet.shared.version!.major > 2 }
|
||||||
|
),
|
||||||
|
ExpectedConfigurationFile(
|
||||||
|
destination: "/conf.d/error_log.ini",
|
||||||
|
source: "/cli/stubs/etc-phpfpm-error_log.ini",
|
||||||
|
replacements: [
|
||||||
|
"VALET_USER": Paths.whoami,
|
||||||
|
"VALET_HOME_PATH": "~/.config/valet".replacingTildeWithHomeDirectory
|
||||||
|
],
|
||||||
|
applies: { return true }
|
||||||
|
),
|
||||||
|
ExpectedConfigurationFile(
|
||||||
|
destination: "/conf.d/php-memory-limits.ini",
|
||||||
|
source: "/cli/stubs/php-memory-limits.ini",
|
||||||
|
replacements: [:],
|
||||||
|
applies: { return true }
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ExpectedConfigurationFile {
|
public struct ExpectedConfigurationFile {
|
||||||
|
|||||||
@@ -86,14 +86,37 @@ class RealShell: ShellProtocol {
|
|||||||
|
|
||||||
// MARK: - Shellable Protocol
|
// MARK: - Shellable Protocol
|
||||||
|
|
||||||
|
func sync(_ command: String) -> ShellOutput {
|
||||||
|
let task = getShellProcess(for: command)
|
||||||
|
|
||||||
|
let outputPipe = Pipe()
|
||||||
|
let errorPipe = Pipe()
|
||||||
|
|
||||||
|
if ProcessInfo.processInfo.environment["SLOW_SHELL_MODE"] != nil {
|
||||||
|
sleep(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
task.standardOutput = outputPipe
|
||||||
|
task.standardError = errorPipe
|
||||||
|
task.launch()
|
||||||
|
task.waitUntilExit()
|
||||||
|
|
||||||
|
let stdOut = String(data: outputPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
|
||||||
|
let stdErr = String(data: errorPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
|
||||||
|
|
||||||
|
if Log.shared.verbosity == .cli {
|
||||||
|
log(task: task, stdOut: stdOut, stdErr: stdErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .out(stdOut, stdErr)
|
||||||
|
}
|
||||||
|
|
||||||
func pipe(_ command: String) async -> ShellOutput {
|
func pipe(_ command: String) async -> ShellOutput {
|
||||||
let task = getShellProcess(for: command)
|
let task = getShellProcess(for: command)
|
||||||
|
|
||||||
let outputPipe = Pipe()
|
let outputPipe = Pipe()
|
||||||
let errorPipe = Pipe()
|
let errorPipe = Pipe()
|
||||||
|
|
||||||
// Seriously slow down how long it takes for the shell to return output
|
|
||||||
// (in order to debug or identify async issues)
|
|
||||||
if ProcessInfo.processInfo.environment["SLOW_SHELL_MODE"] != nil {
|
if ProcessInfo.processInfo.environment["SLOW_SHELL_MODE"] != nil {
|
||||||
Log.info("[SLOW SHELL] \(command)")
|
Log.info("[SLOW SHELL] \(command)")
|
||||||
await delay(seconds: 3.0)
|
await delay(seconds: 3.0)
|
||||||
@@ -104,17 +127,17 @@ class RealShell: ShellProtocol {
|
|||||||
task.launch()
|
task.launch()
|
||||||
task.waitUntilExit()
|
task.waitUntilExit()
|
||||||
|
|
||||||
let stdOut = String(
|
let stdOut = String(data: outputPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
|
||||||
data: outputPipe.fileHandleForReading.readDataToEndOfFile(),
|
let stdErr = String(data: errorPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)!
|
||||||
encoding: .utf8
|
|
||||||
)!
|
|
||||||
|
|
||||||
let stdErr = String(
|
|
||||||
data: errorPipe.fileHandleForReading.readDataToEndOfFile(),
|
|
||||||
encoding: .utf8
|
|
||||||
)!
|
|
||||||
|
|
||||||
if Log.shared.verbosity == .cli {
|
if Log.shared.verbosity == .cli {
|
||||||
|
log(task: task, stdOut: stdOut, stdErr: stdErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .out(stdOut, stdErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func log(task: Process, stdOut: String, stdErr: String) {
|
||||||
var args = task.arguments ?? []
|
var args = task.arguments ?? []
|
||||||
let last = "\"" + (args.popLast() ?? "") + "\""
|
let last = "\"" + (args.popLast() ?? "") + "\""
|
||||||
var log = """
|
var log = """
|
||||||
@@ -141,9 +164,6 @@ class RealShell: ShellProtocol {
|
|||||||
Log.info(log)
|
Log.info(log)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .out(stdOut, stdErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func quiet(_ command: String) async {
|
func quiet(_ command: String) async {
|
||||||
_ = await self.pipe(command)
|
_ = await self.pipe(command)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,16 @@ protocol ShellProtocol {
|
|||||||
*/
|
*/
|
||||||
var PATH: String { get }
|
var PATH: String { get }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Run a command synchronously. Use with caution.
|
||||||
|
|
||||||
|
Common usage:
|
||||||
|
```
|
||||||
|
let output = Shell.sync("php -v")
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
func sync(_ command: String) -> ShellOutput
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Run a command asynchronously.
|
Run a command asynchronously.
|
||||||
Returns the most relevant output (prefers error output if it exists).
|
Returns the most relevant output (prefers error output if it exists).
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// PhpFormulaeStatus.swift
|
// BusyStatus.swift
|
||||||
// PHP Monitor
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 02/05/2023.
|
// Created by Nico Verbruggen on 02/05/2023.
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class PhpFormulaeStatus: ObservableObject {
|
class BusyStatus: ObservableObject {
|
||||||
@Published var busy: Bool
|
@Published var busy: Bool
|
||||||
@Published var title: String
|
@Published var title: String
|
||||||
@Published var description: String
|
@Published var description: String
|
||||||
@@ -18,4 +18,12 @@ class PhpFormulaeStatus: ObservableObject {
|
|||||||
self.title = title
|
self.title = title
|
||||||
self.description = description
|
self.description = description
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func notBusy() -> BusyStatus {
|
||||||
|
return BusyStatus(busy: false, title: "", description: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func busy() -> BusyStatus {
|
||||||
|
return BusyStatus(busy: false, title: "", description: "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -63,8 +63,8 @@ public struct TestableConfiguration: Codable {
|
|||||||
: .fake(.binary),
|
: .fake(.binary),
|
||||||
"/opt/homebrew/Cellar/php/\(version.long)/bin/php-config"
|
"/opt/homebrew/Cellar/php/\(version.long)/bin/php-config"
|
||||||
: .fake(.binary),
|
: .fake(.binary),
|
||||||
// "/opt/homebrew/etc/php/\(version.short)/php-fpm.d/www.conf"
|
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/www.conf"
|
||||||
// : .fake(.text),
|
: .fake(.text),
|
||||||
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/valet-fpm.conf"
|
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/valet-fpm.conf"
|
||||||
: .fake(.text),
|
: .fake(.text),
|
||||||
"/opt/homebrew/etc/php/\(version.short)/php.ini"
|
"/opt/homebrew/etc/php/\(version.short)/php.ini"
|
||||||
@@ -73,12 +73,26 @@ public struct TestableConfiguration: Codable {
|
|||||||
: .fake(.text)
|
: .fake(.text)
|
||||||
]) { (_, new) in new }
|
]) { (_, new) in new }
|
||||||
|
|
||||||
self.commandOutput["/opt/homebrew/opt/php@\(version.short)/bin/php-config --version"]
|
// PHP configuration files
|
||||||
= version.long
|
self.shellOutput["/opt/homebrew/opt/php@\(version.short)/bin/php --ini | grep -E -o '(/[^ ]+\\.ini)'"] =
|
||||||
|
.instant("/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini")
|
||||||
|
|
||||||
|
// PHP Homebrew operations
|
||||||
|
self.shellOutput["/opt/homebrew/bin/brew unlink php@\(version.short)"] = .delayed(0.2, "OK")
|
||||||
|
self.shellOutput["sudo /opt/homebrew/bin/brew services stop php@\(version.short)"] = .delayed(0.2, "OK")
|
||||||
|
self.shellOutput["sudo /opt/homebrew/bin/brew services start php@\(version.short)"] = .delayed(0.2, "OK")
|
||||||
|
self.shellOutput["/opt/homebrew/bin/brew link php@\(version.short) --overwrite --force"] = .delayed(0.2, "OK")
|
||||||
|
|
||||||
|
// PHP version output
|
||||||
|
self.commandOutput["/opt/homebrew/opt/php@\(version.short)/bin/php-config --version"] = version.long
|
||||||
|
self.commandOutput["/opt/homebrew/opt/php@\(version.short)/bin/php -v"] = "OK"
|
||||||
|
|
||||||
if primary {
|
if primary {
|
||||||
self.shellOutput["ls /opt/homebrew/opt | grep php"]
|
// Files expected to be present for currently linked PHP version
|
||||||
= .instant("php")
|
self.shellOutput["ls /opt/homebrew/opt | grep php"] =
|
||||||
|
.instant("php")
|
||||||
|
self.shellOutput["/opt/homebrew/bin/php --ini | grep -E -o '(/[^ ]+\\.ini)'"] =
|
||||||
|
.instant("/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini")
|
||||||
self.filesystem["/opt/homebrew/opt/php"]
|
self.filesystem["/opt/homebrew/opt/php"]
|
||||||
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)")
|
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)")
|
||||||
self.filesystem["/opt/homebrew/opt/php/bin/php"]
|
self.filesystem["/opt/homebrew/opt/php/bin/php"]
|
||||||
@@ -89,12 +103,8 @@ public struct TestableConfiguration: Codable {
|
|||||||
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.short)/bin/php-config")
|
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.short)/bin/php-config")
|
||||||
self.commandOutput["/opt/homebrew/bin/php-config --version"]
|
self.commandOutput["/opt/homebrew/bin/php-config --version"]
|
||||||
= version.long
|
= version.long
|
||||||
self.commandOutput["/opt/homebrew/bin/php -r echo php_ini_scanned_files();"] =
|
|
||||||
"""
|
|
||||||
/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini,
|
|
||||||
"""
|
|
||||||
} else {
|
} else {
|
||||||
self.shellOutput["sudo /opt/homebrew/bin/brew services stop php@\(version.short)"] = .instant("")
|
// Output expected to be present for non-linked PHP versions
|
||||||
self.shellOutput["ls /opt/homebrew/opt | grep php@"] =
|
self.shellOutput["ls /opt/homebrew/opt | grep php@"] =
|
||||||
BatchFakeShellOutput.instant(
|
BatchFakeShellOutput.instant(
|
||||||
self.secondaryPhpVersions
|
self.secondaryPhpVersions
|
||||||
@@ -103,6 +113,7 @@ public struct TestableConfiguration: Codable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// swiftlint:enable function_body_length
|
||||||
|
|
||||||
// MARK: Interactions
|
// MARK: Interactions
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,17 @@ public class TestableShell: ShellProtocol {
|
|||||||
|
|
||||||
var expectations: [String: BatchFakeShellOutput] = [:]
|
var expectations: [String: BatchFakeShellOutput] = [:]
|
||||||
|
|
||||||
|
func sync(_ command: String) -> ShellOutput {
|
||||||
|
// This assertion will only fire during test builds
|
||||||
|
assert(expectations.keys.contains(command), "No response declared for command: \(command)")
|
||||||
|
|
||||||
|
guard let expectation = expectations[command] else {
|
||||||
|
return .err("No Expected Output")
|
||||||
|
}
|
||||||
|
|
||||||
|
return expectation.syncOutput()
|
||||||
|
}
|
||||||
|
|
||||||
func quiet(_ command: String) async {
|
func quiet(_ command: String) async {
|
||||||
_ = try! await self.attach(command, didReceiveOutput: { _, _ in }, withTimeout: 60)
|
_ = try! await self.attach(command, didReceiveOutput: { _, _ in }, withTimeout: 60)
|
||||||
}
|
}
|
||||||
@@ -112,6 +123,29 @@ struct BatchFakeShellOutput: Codable {
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Outputs the fake shell output as expected, but does this synchronously.
|
||||||
|
*/
|
||||||
|
public func syncOutput(
|
||||||
|
ignoreDelay: Bool = false
|
||||||
|
) -> ShellOutput {
|
||||||
|
let output = ShellOutput.empty()
|
||||||
|
|
||||||
|
for item in items {
|
||||||
|
if !ignoreDelay {
|
||||||
|
Thread.sleep(forTimeInterval: item.delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.stream == .stdErr {
|
||||||
|
output.err += item.output
|
||||||
|
} else if item.stream == .stdOut {
|
||||||
|
output.out += item.output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
For testing purposes (and speed) we may omit the delay, regardless of its timespan.
|
For testing purposes (and speed) we may omit the delay, regardless of its timespan.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ class App {
|
|||||||
/** The window controller of the PHP version manager window. */
|
/** The window controller of the PHP version manager window. */
|
||||||
var phpVersionManagerWindowController: PhpVersionManagerWindowController?
|
var phpVersionManagerWindowController: PhpVersionManagerWindowController?
|
||||||
|
|
||||||
|
/** The window controller of the PHP extension manager window. */
|
||||||
|
var phpExtensionManagerWindowController: PhpExtensionManagerWindowController?
|
||||||
|
|
||||||
/** List of detected (installed) applications that PHP Monitor can work with. */
|
/** List of detected (installed) applications that PHP Monitor can work with. */
|
||||||
var detectedApplications: [Application] = []
|
var detectedApplications: [Application] = []
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
|||||||
|
|
||||||
static func initializeTestingProfile(_ path: String) {
|
static func initializeTestingProfile(_ path: String) {
|
||||||
Log.info("The configuration with path `\(path)` is being requested...")
|
Log.info("The configuration with path `\(path)` is being requested...")
|
||||||
|
// Clear for PHP Guard
|
||||||
|
Stats.clearCurrentGlobalPhpVersion()
|
||||||
|
// Load the configuration file
|
||||||
TestableConfiguration.loadFrom(path: path).apply()
|
TestableConfiguration.loadFrom(path: path).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class Startup {
|
|||||||
return await Shell.pipe("\(Paths.binPath)/php -v").err
|
return await Shell.pipe("\(Paths.binPath)/php -v").err
|
||||||
.contains("Library not loaded")
|
.contains("Library not loaded")
|
||||||
},
|
},
|
||||||
name: "`no dyld issue detected",
|
name: "no `dyld` issue (`Library not loaded`) detected",
|
||||||
titleText: "startup.errors.dyld_library.title".localized,
|
titleText: "startup.errors.dyld_library.title".localized,
|
||||||
subtitleText: "startup.errors.dyld_library.subtitle".localized(
|
subtitleText: "startup.errors.dyld_library.subtitle".localized(
|
||||||
Paths.optPath
|
Paths.optPath
|
||||||
|
|||||||
@@ -8,16 +8,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class BrewFormulaeObservable: ObservableObject {
|
|
||||||
@Published var phpVersions: [BrewFormula] = []
|
|
||||||
|
|
||||||
var upgradeable: [BrewFormula] {
|
|
||||||
return phpVersions.filter { formula in
|
|
||||||
formula.hasUpgrade
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Brew {
|
class Brew {
|
||||||
static let shared = Brew()
|
static let shared = Brew()
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,21 @@ class BrewDiagnostics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Logs a bunch of useful information during startup.
|
||||||
|
*/
|
||||||
|
public static func logBootInformation() {
|
||||||
|
Log.info(BrewDiagnostics.customCaskInstalled
|
||||||
|
? "[BREW] The app has been installed via Homebrew Cask."
|
||||||
|
: "[BREW] The app has been installed directly (optimal)."
|
||||||
|
)
|
||||||
|
|
||||||
|
Log.info(BrewDiagnostics.usesNginxFullFormula
|
||||||
|
? "[BREW] The app will be using the `nginx-full` formula."
|
||||||
|
: "[BREW] The app will be using the `nginx` formula."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Determines whether the PHP Monitor Cask is installed.
|
Determines whether the PHP Monitor Cask is installed.
|
||||||
*/
|
*/
|
||||||
@@ -46,6 +61,43 @@ class BrewDiagnostics {
|
|||||||
return destination.contains("/nginx-full/")
|
return destination.contains("/nginx-full/")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
/**
|
||||||
|
It is possible to have outdated symlinks for PHP installations. This can mean that certain PHP installations
|
||||||
|
are going to be reported incorrectly (e.g. `php@8.2` links to an installation in a `8.3` folder after an upgrade).
|
||||||
|
|
||||||
|
To ensure this does not cause issues, PHP Monitor will automatically remove all incorrect PHP symlinks.
|
||||||
|
*/
|
||||||
|
public static func checkForOutdatedPhpInstallationSymlinks() async {
|
||||||
|
// Set up a regular expression
|
||||||
|
let regex = try! NSRegularExpression(pattern: "^php@[0-9]+\\.[0-9]+$", options: .caseInsensitive)
|
||||||
|
|
||||||
|
// Check for incorrect versions
|
||||||
|
if let contents = try? FileSystem.getShallowContentsOfDirectory("\(Paths.optPath)")
|
||||||
|
.filter({
|
||||||
|
let range = NSRange($0.startIndex..., in: $0)
|
||||||
|
return regex.firstMatch(in: $0, options: [], range: range) != nil
|
||||||
|
}) {
|
||||||
|
|
||||||
|
for symlink in contents {
|
||||||
|
let version = symlink.replacingOccurrences(of: "php@", with: "")
|
||||||
|
if let destination = try? FileSystem.getDestinationOfSymlink("\(Paths.optPath)/\(symlink)") {
|
||||||
|
if !destination.contains("Cellar/php/\(version)")
|
||||||
|
&& !destination.contains("Cellar/php@\(version)") {
|
||||||
|
Log.err("Symlink for \(symlink) is incorrect. Removing...")
|
||||||
|
do {
|
||||||
|
try FileSystem.remove("\(Paths.optPath)/\(symlink)")
|
||||||
|
Log.info("Incorrect symlink for \(symlink) has been successfully removed.")
|
||||||
|
} catch {
|
||||||
|
Log.err("Symlink for \(symlink) was incorrect but could not be removed!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.warn("Could not read symlink at: \(Paths.optPath)/\(symlink)! Symlink check skipped.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
It is possible to have the `shivammathur/php` tap installed, and for the core homebrew information to be outdated.
|
It is possible to have the `shivammathur/php` tap installed, and for the core homebrew information to be outdated.
|
||||||
This will then result in two different aliases claiming to point to the same formula (`php`).
|
This will then result in two different aliases claiming to point to the same formula (`php`).
|
||||||
|
|||||||
98
phpmon/Domain/Integrations/Homebrew/BrewPhpExtension.swift
Normal file
98
phpmon/Domain/Integrations/Homebrew/BrewPhpExtension.swift
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
//
|
||||||
|
// BrewPhpExtension.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 27/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct BrewPhpExtension: Hashable, Comparable {
|
||||||
|
let name: String
|
||||||
|
let phpVersion: String
|
||||||
|
let isInstalled: Bool
|
||||||
|
let path: String
|
||||||
|
let dependencies: [String]
|
||||||
|
|
||||||
|
var extensionDependencies: [String] {
|
||||||
|
return dependencies
|
||||||
|
.filter {
|
||||||
|
$0.contains("shivammathur/extensions/") && $0.contains("@\(phpVersion)")
|
||||||
|
}
|
||||||
|
.map {
|
||||||
|
$0.replacingOccurrences(of: "shivammathur/extensions/", with: "")
|
||||||
|
.replacingOccurrences(of: "@\(phpVersion)", with: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var formulaName: String {
|
||||||
|
return "\(name)@\(phpVersion)"
|
||||||
|
}
|
||||||
|
|
||||||
|
init(path: String, name: String, phpVersion: String) {
|
||||||
|
self.path = path
|
||||||
|
self.name = name
|
||||||
|
self.phpVersion = phpVersion
|
||||||
|
|
||||||
|
self.isInstalled = BrewPhpExtension.hasInstallationReceipt(
|
||||||
|
for: "\(name)@\(phpVersion)"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.dependencies = BrewPhpExtension.extractDependencies(from: path)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasAlternativeInstall: Bool {
|
||||||
|
guard let php = PhpEnvironments.shared.cachedPhpInstallations[self.phpVersion] else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let alreadyDiscovered = php.extensions.contains(where: { $0.name == self.name })
|
||||||
|
|
||||||
|
return alreadyDiscovered && !isInstalled
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func firstDependent(in exts: [BrewPhpExtension]) -> BrewPhpExtension? {
|
||||||
|
return exts
|
||||||
|
.filter({ $0.isInstalled })
|
||||||
|
.first { $0.dependencies.contains("shivammathur/extensions/\(self.formulaName)") }
|
||||||
|
}
|
||||||
|
|
||||||
|
static func hasInstallationReceipt(for formulaName: String) -> Bool {
|
||||||
|
return FileSystem.fileExists("\(Paths.optPath)/\(formulaName)/INSTALL_RECEIPT.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func < (lhs: BrewPhpExtension, rhs: BrewPhpExtension) -> Bool {
|
||||||
|
return lhs.name < rhs.name
|
||||||
|
}
|
||||||
|
|
||||||
|
static func == (lhs: BrewPhpExtension, rhs: BrewPhpExtension) -> Bool {
|
||||||
|
return lhs.name == rhs.name
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func extractDependencies(from path: String) -> [String] {
|
||||||
|
let regexPattern = #"depends_on "(.*)""#
|
||||||
|
var dependencies: [String] = []
|
||||||
|
|
||||||
|
guard let content = try? FileSystem.getStringFromFile(path) else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
let regex = try NSRegularExpression(pattern: regexPattern, options: [])
|
||||||
|
let range = NSRange(content.startIndex..<content.endIndex, in: content)
|
||||||
|
let matches = regex.matches(in: content, options: [], range: range)
|
||||||
|
|
||||||
|
for match in matches {
|
||||||
|
if let range = Range(match.range(at: 1), in: content) {
|
||||||
|
let dependencyName = String(content[range])
|
||||||
|
dependencies.append(dependencyName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
return dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// BrewFormula.swift
|
// BrewPhpFormula.swift
|
||||||
// PHP Monitor
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 17/03/2023.
|
// Created by Nico Verbruggen on 17/03/2023.
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct BrewFormula: Equatable {
|
struct BrewPhpFormula: Equatable {
|
||||||
/// Name of the formula.
|
/// Name of the formula.
|
||||||
let name: String
|
let name: String
|
||||||
|
|
||||||
@@ -21,6 +21,8 @@ struct BrewFormula: Equatable {
|
|||||||
/// The upgrade that is currently available, if it exists.
|
/// The upgrade that is currently available, if it exists.
|
||||||
let upgradeVersion: String?
|
let upgradeVersion: String?
|
||||||
|
|
||||||
|
// TODO: A rebuild attribute could be checked, to check if a Tap update exists for a pre-release version
|
||||||
|
|
||||||
/// Whether this formula is a stable version of PHP.
|
/// Whether this formula is a stable version of PHP.
|
||||||
let prerelease: Bool
|
let prerelease: Bool
|
||||||
|
|
||||||
@@ -100,6 +102,7 @@ struct BrewFormula: Equatable {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return PhpEnvironments.shared.cachedPhpInstallations[shortVersion]?.isHealthy ?? nil
|
return PhpEnvironments.shared.cachedPhpInstallations[shortVersion]?
|
||||||
|
.isHealthy ?? nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol HandlesBrewFormulae {
|
protocol HandlesBrewPhpFormulae {
|
||||||
func loadPhpVersions(loadOutdated: Bool) async -> [BrewFormula]
|
func loadPhpVersions(loadOutdated: Bool) async -> [BrewPhpFormula]
|
||||||
func refreshPhpVersions(loadOutdated: Bool) async
|
func refreshPhpVersions(loadOutdated: Bool) async
|
||||||
}
|
}
|
||||||
|
|
||||||
extension HandlesBrewFormulae {
|
extension HandlesBrewPhpFormulae {
|
||||||
public func refreshPhpVersions(loadOutdated: Bool) async {
|
public func refreshPhpVersions(loadOutdated: Bool) async {
|
||||||
let items = await loadPhpVersions(loadOutdated: loadOutdated)
|
let items = await loadPhpVersions(loadOutdated: loadOutdated)
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
@@ -23,8 +23,8 @@ extension HandlesBrewFormulae {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BrewFormulaeHandler: HandlesBrewFormulae {
|
class BrewPhpFormulaeHandler: HandlesBrewPhpFormulae {
|
||||||
public func loadPhpVersions(loadOutdated: Bool) async -> [BrewFormula] {
|
public func loadPhpVersions(loadOutdated: Bool) async -> [BrewPhpFormula] {
|
||||||
var outdated: [OutdatedFormula]?
|
var outdated: [OutdatedFormula]?
|
||||||
|
|
||||||
if loadOutdated {
|
if loadOutdated {
|
||||||
@@ -55,15 +55,13 @@ class BrewFormulaeHandler: HandlesBrewFormulae {
|
|||||||
})?.current_version
|
})?.current_version
|
||||||
}
|
}
|
||||||
|
|
||||||
let formula = BrewFormula(
|
return BrewPhpFormula(
|
||||||
name: formula,
|
name: formula,
|
||||||
displayName: "PHP \(version)",
|
displayName: "PHP \(version)",
|
||||||
installedVersion: fullVersion,
|
installedVersion: fullVersion,
|
||||||
upgradeVersion: upgradeVersion,
|
upgradeVersion: upgradeVersion,
|
||||||
prerelease: Constants.ExperimentalPhpVersions.contains(version)
|
prerelease: Constants.ExperimentalPhpVersions.contains(version)
|
||||||
)
|
)
|
||||||
|
|
||||||
return formula
|
|
||||||
}.sorted { $0.displayName > $1.displayName }
|
}.sorted { $0.displayName > $1.displayName }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
53
phpmon/Domain/Integrations/Homebrew/BrewTapFormulae.swift
Normal file
53
phpmon/Domain/Integrations/Homebrew/BrewTapFormulae.swift
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// BrewTapFormulae.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 01/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class BrewTapFormulae {
|
||||||
|
public static func from(tap: String) -> [String: [BrewPhpExtension]] {
|
||||||
|
let directory = "\(Paths.tapPath)/\(tap)/Formula"
|
||||||
|
|
||||||
|
let files = try? FileSystem.getShallowContentsOfDirectory(directory)
|
||||||
|
|
||||||
|
var availableExtensions = [String: [BrewPhpExtension]]()
|
||||||
|
|
||||||
|
guard let files = files else {
|
||||||
|
return availableExtensions
|
||||||
|
}
|
||||||
|
|
||||||
|
let regex = try! NSRegularExpression(pattern: "(\\w+)@(\\d+\\.\\d+)\\.rb")
|
||||||
|
|
||||||
|
for file in files {
|
||||||
|
let matches = regex.matches(in: file, range: NSRange(file.startIndex..., in: file))
|
||||||
|
if let match = matches.first {
|
||||||
|
if let phpExtensionRange = Range(match.range(at: 1), in: file),
|
||||||
|
let versionRange = Range(match.range(at: 2), in: file) {
|
||||||
|
// Determine what the extension's name is
|
||||||
|
let phpExtensionName = String(file[phpExtensionRange])
|
||||||
|
|
||||||
|
// Determine what PHP version this is for
|
||||||
|
let phpVersion = String(file[versionRange])
|
||||||
|
|
||||||
|
// Create a new BrewPhpExtension object (determines if installed)
|
||||||
|
let phpExtension = BrewPhpExtension(
|
||||||
|
path: "\(Paths.tapPath)/\(tap)/Formula/\(file)",
|
||||||
|
name: phpExtensionName,
|
||||||
|
phpVersion: phpVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
// Append the extension to the list
|
||||||
|
var extensions = availableExtensions[phpVersion, default: []]
|
||||||
|
extensions.append(phpExtension)
|
||||||
|
availableExtensions[phpVersion] = extensions.sorted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableExtensions
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ import Foundation
|
|||||||
|
|
||||||
protocol BrewCommand {
|
protocol BrewCommand {
|
||||||
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws
|
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws
|
||||||
|
|
||||||
|
func getCommandTitle() -> String
|
||||||
}
|
}
|
||||||
|
|
||||||
extension BrewCommand {
|
extension BrewCommand {
|
||||||
@@ -31,6 +33,44 @@ extension BrewCommand {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal func run(_ command: String, _ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
|
var loggedMessages: [String] = []
|
||||||
|
|
||||||
|
let (process, _) = try! await Shell.attach(
|
||||||
|
command,
|
||||||
|
didReceiveOutput: { text, _ in
|
||||||
|
if !text.isEmpty {
|
||||||
|
Log.perf(text)
|
||||||
|
loggedMessages.append(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let (number, text) = self.reportInstallationProgress(text) {
|
||||||
|
onProgress(.create(value: number, title: getCommandTitle(), description: text))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
withTimeout: .minutes(15)
|
||||||
|
)
|
||||||
|
|
||||||
|
if process.terminationStatus <= 0 {
|
||||||
|
loggedMessages = []
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
throw BrewCommandError(error: "The command failed to run correctly.", log: loggedMessages)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func checkPhpTap(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
|
if !BrewDiagnostics.installedTaps.contains("shivammathur/php") {
|
||||||
|
let command = "brew tap shivammathur/php"
|
||||||
|
try await run(command, onProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !BrewDiagnostics.installedTaps.contains("shivammathur/extensions") {
|
||||||
|
let command = "brew tap shivammathur/extensions"
|
||||||
|
try await run(command, onProgress)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BrewCommandProgress {
|
struct BrewCommandProgress {
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// InstallPhpExtensionCommand.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 21/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class InstallPhpExtensionCommand: BrewCommand {
|
||||||
|
let installing: [BrewPhpExtension]
|
||||||
|
|
||||||
|
func getExtensionNames() -> String {
|
||||||
|
return installing.map { $0.name }.joined(separator: ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCommandTitle() -> String {
|
||||||
|
return "phpman.steps.installing".localized(getExtensionNames())
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(install extensions: [BrewPhpExtension]) {
|
||||||
|
self.installing = extensions
|
||||||
|
}
|
||||||
|
|
||||||
|
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
|
let progressTitle = "phpman.steps.wait".localized
|
||||||
|
|
||||||
|
onProgress(.create(
|
||||||
|
value: 0.2,
|
||||||
|
title: progressTitle,
|
||||||
|
description: "phpman.steps.preparing".localized
|
||||||
|
))
|
||||||
|
|
||||||
|
// Make sure the tap is installed
|
||||||
|
try await self.checkPhpTap(onProgress)
|
||||||
|
|
||||||
|
// Make sure that the extension(s) are installed
|
||||||
|
try await self.installPackages(onProgress)
|
||||||
|
|
||||||
|
// Finally, complete all operations
|
||||||
|
await self.completedOperations(onProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func installPackages(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
|
// If no installations are needed, early exit
|
||||||
|
if self.installing.isEmpty {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let command = """
|
||||||
|
export HOMEBREW_NO_INSTALL_UPGRADE=true; \
|
||||||
|
export HOMEBREW_NO_INSTALL_CLEANUP=true; \
|
||||||
|
\(Paths.brew) install \(self.installing.map { $0.formulaName }.joined(separator: " ")) --force
|
||||||
|
"""
|
||||||
|
|
||||||
|
try await run(command, onProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func completedOperations(_ onProgress: @escaping (BrewCommandProgress) -> Void) async {
|
||||||
|
// Reload and restart PHP versions
|
||||||
|
onProgress(.create(value: 0.95, title: self.getCommandTitle(), description: "phpman.steps.reloading".localized))
|
||||||
|
|
||||||
|
// Check which version of PHP are now installed
|
||||||
|
await PhpEnvironments.detectPhpVersions()
|
||||||
|
|
||||||
|
// Keep track of the currently installed version
|
||||||
|
await MainMenu.shared.refreshActiveInstallation()
|
||||||
|
|
||||||
|
// Also rebuild the content of the main menu
|
||||||
|
await MainMenu.shared.rebuild()
|
||||||
|
|
||||||
|
// Let the UI know that the installation has been completed
|
||||||
|
onProgress(.create(
|
||||||
|
value: 1,
|
||||||
|
title: "phpman.steps.completed".localized,
|
||||||
|
description: "phpman.steps.success".localized
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// RemovePhpExtensionCommand.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 21/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class RemovePhpExtensionCommand: BrewCommand {
|
||||||
|
public let phpExtension: BrewPhpExtension
|
||||||
|
|
||||||
|
public init(remove formula: BrewPhpExtension) {
|
||||||
|
self.phpExtension = formula
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCommandTitle() -> String {
|
||||||
|
return "phpman.steps.removing".localized(phpExtension.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
|
onProgress(.create(
|
||||||
|
value: 0.2,
|
||||||
|
title: getCommandTitle(),
|
||||||
|
description: "phpman.steps.removing".localized("`\(phpExtension.name)`...")
|
||||||
|
))
|
||||||
|
|
||||||
|
// Keep track of the file that contains the information about the extension
|
||||||
|
let existing = PhpEnvironments.shared
|
||||||
|
.cachedPhpInstallations[phpExtension.phpVersion]?
|
||||||
|
.extensions.first(where: { ext in
|
||||||
|
ext.name == phpExtension.name
|
||||||
|
})
|
||||||
|
|
||||||
|
let command = """
|
||||||
|
export HOMEBREW_NO_INSTALL_UPGRADE=true; \
|
||||||
|
export HOMEBREW_NO_INSTALL_CLEANUP=true; \
|
||||||
|
\(Paths.brew) remove \(phpExtension.formulaName) --force --ignore-dependencies
|
||||||
|
"""
|
||||||
|
|
||||||
|
var loggedMessages: [String] = []
|
||||||
|
|
||||||
|
let (process, _) = try! await Shell.attach(
|
||||||
|
command,
|
||||||
|
didReceiveOutput: { text, _ in
|
||||||
|
if !text.isEmpty {
|
||||||
|
Log.perf(text)
|
||||||
|
loggedMessages.append(text)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
withTimeout: .minutes(5)
|
||||||
|
)
|
||||||
|
|
||||||
|
if process.terminationStatus <= 0 {
|
||||||
|
onProgress(.create(value: 0.95, title: getCommandTitle(), description: "phpman.steps.reloading".localized))
|
||||||
|
|
||||||
|
if let ext = existing {
|
||||||
|
await performExtensionCleanup(for: ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
await PhpEnvironments.detectPhpVersions()
|
||||||
|
|
||||||
|
await MainMenu.shared.refreshActiveInstallation()
|
||||||
|
|
||||||
|
onProgress(.create(value: 1, title: getCommandTitle(), description: "phpman.steps.success".localized))
|
||||||
|
} else {
|
||||||
|
throw BrewCommandError(error: "phpman.steps.failure".localized, log: loggedMessages)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func performExtensionCleanup(for ext: PhpExtension) async {
|
||||||
|
if ext.file.hasSuffix("20-\(ext.name).ini") {
|
||||||
|
// The extension's default configuration file can be removed
|
||||||
|
Log.info("The extension was found in a default extension .ini location. Purging that .ini file.")
|
||||||
|
do {
|
||||||
|
try FileSystem.remove(ext.file)
|
||||||
|
} catch {
|
||||||
|
Log.err("The file `\(ext.file)` could not be removed.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The extension's default configuration file cannot be removed, it should be disabled instead
|
||||||
|
Log.info("The extension was not found in a default location. Disabling the extension only.")
|
||||||
|
if ext.enabled {
|
||||||
|
await ext.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,23 +8,33 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class InstallAndUpgradeCommand: BrewCommand {
|
class ModifyPhpVersionCommand: BrewCommand {
|
||||||
|
|
||||||
let title: String
|
let title: String
|
||||||
let installing: [BrewFormula]
|
let installing: [BrewPhpFormula]
|
||||||
let upgrading: [BrewFormula]
|
let upgrading: [BrewPhpFormula]
|
||||||
let phpGuard: PhpGuard
|
let phpGuard: PhpGuard
|
||||||
|
|
||||||
|
func getCommandTitle() -> String {
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
You can pass in which PHP versions need to be upgraded and which ones need to be installed.
|
You can pass in which PHP versions need to be upgraded and which ones need to be installed.
|
||||||
The process will be executed in two steps: first upgrades, then installations.
|
The process will be executed in two steps: first upgrades, then installations.
|
||||||
|
|
||||||
Upgrades come first because... well, otherwise installations may very well break.
|
Upgrades come first because... well, otherwise installations may very well break.
|
||||||
Each version that is installed will need to be checked afterwards (if it is OK).
|
Each version that is installed will need to be checked afterwards. Installing a
|
||||||
|
newer formula may break other PHP installations, which in turn need to be fixed.
|
||||||
|
|
||||||
|
- Important: If any PHP formula is a major upgrade that causes a PHP "version" to be
|
||||||
|
uninstalled, this is remedied by running `upgradeMainPhpFormula()`. This process
|
||||||
|
will ensure that the upgrade is applied, but the also that old version is
|
||||||
|
re-installed and linked again.
|
||||||
*/
|
*/
|
||||||
public init(
|
public init(
|
||||||
title: String,
|
title: String,
|
||||||
upgrading: [BrewFormula],
|
upgrading: [BrewPhpFormula],
|
||||||
installing: [BrewFormula]
|
installing: [BrewPhpFormula]
|
||||||
) {
|
) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.installing = installing
|
self.installing = installing
|
||||||
@@ -33,14 +43,16 @@ class InstallAndUpgradeCommand: BrewCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
let progressTitle = "Please wait..."
|
let progressTitle = "phpman.steps.wait".localized
|
||||||
|
|
||||||
onProgress(.create(
|
onProgress(.create(
|
||||||
value: 0.2,
|
value: 0.2,
|
||||||
title: progressTitle,
|
title: progressTitle,
|
||||||
description: "PHP Monitor is preparing Homebrew..."
|
description: "phpman.steps.preparing".localized
|
||||||
))
|
))
|
||||||
|
|
||||||
|
// Determine if a formula will become unavailable
|
||||||
|
// This is the case when `php` will be bumped to a new version
|
||||||
let unavailable = upgrading.first(where: { formula in
|
let unavailable = upgrading.first(where: { formula in
|
||||||
formula.unavailableAfterUpgrade
|
formula.unavailableAfterUpgrade
|
||||||
})
|
})
|
||||||
@@ -69,7 +81,7 @@ class InstallAndUpgradeCommand: BrewCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func upgradeMainPhpFormula(
|
private func upgradeMainPhpFormula(
|
||||||
_ unavailable: BrewFormula,
|
_ unavailable: BrewPhpFormula,
|
||||||
_ onProgress: @escaping (BrewCommandProgress) -> Void
|
_ onProgress: @escaping (BrewCommandProgress) -> Void
|
||||||
) async throws {
|
) async throws {
|
||||||
// Determine which version was previously available (that will become unavailable)
|
// Determine which version was previously available (that will become unavailable)
|
||||||
@@ -89,18 +101,6 @@ class InstallAndUpgradeCommand: BrewCommand {
|
|||||||
try await run(command, onProgress)
|
try await run(command, onProgress)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkPhpTap(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
|
||||||
if !BrewDiagnostics.installedTaps.contains("shivammathur/php") {
|
|
||||||
let command = "brew tap shivammathur/php"
|
|
||||||
try await run(command, onProgress)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !BrewDiagnostics.installedTaps.contains("shivammathur/extensions") {
|
|
||||||
let command = "brew tap shivammathur/extensions"
|
|
||||||
try await run(command, onProgress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func upgradePackages(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
private func upgradePackages(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
// If no upgrades are needed, early exit
|
// If no upgrades are needed, early exit
|
||||||
if self.upgrading.isEmpty {
|
if self.upgrading.isEmpty {
|
||||||
@@ -163,35 +163,12 @@ class InstallAndUpgradeCommand: BrewCommand {
|
|||||||
try await run(command, onProgress)
|
try await run(command, onProgress)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func run(_ command: String, _ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
|
||||||
var loggedMessages: [String] = []
|
|
||||||
|
|
||||||
let (process, _) = try! await Shell.attach(
|
|
||||||
command,
|
|
||||||
didReceiveOutput: { text, _ in
|
|
||||||
if !text.isEmpty {
|
|
||||||
Log.perf(text)
|
|
||||||
loggedMessages.append(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (number, text) = self.reportInstallationProgress(text) {
|
|
||||||
onProgress(.create(value: number, title: self.title, description: text))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
withTimeout: .minutes(15)
|
|
||||||
)
|
|
||||||
|
|
||||||
if process.terminationStatus <= 0 {
|
|
||||||
loggedMessages = []
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
throw BrewCommandError(error: "The command failed to run correctly.", log: loggedMessages)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func completedOperations(_ onProgress: @escaping (BrewCommandProgress) -> Void) async {
|
private func completedOperations(_ onProgress: @escaping (BrewCommandProgress) -> Void) async {
|
||||||
// Reload and restart PHP versions
|
// Reload and restart PHP versions
|
||||||
onProgress(.create(value: 0.95, title: self.title, description: "Reloading PHP versions..."))
|
onProgress(.create(value: 0.95, title: self.title, description: "phpman.steps.reloading".localized))
|
||||||
|
|
||||||
|
// Ensure all symlinks are correctly linked
|
||||||
|
await BrewDiagnostics.checkForOutdatedPhpInstallationSymlinks()
|
||||||
|
|
||||||
// Check which version of PHP are now installed
|
// Check which version of PHP are now installed
|
||||||
await PhpEnvironments.detectPhpVersions()
|
await PhpEnvironments.detectPhpVersions()
|
||||||
@@ -210,9 +187,8 @@ class InstallAndUpgradeCommand: BrewCommand {
|
|||||||
// Let the UI know that the installation has been completed
|
// Let the UI know that the installation has been completed
|
||||||
onProgress(.create(
|
onProgress(.create(
|
||||||
value: 1,
|
value: 1,
|
||||||
title: "Operation completed!",
|
title: "phpman.steps.completed".localized,
|
||||||
description: "The installation has succeeded."
|
description: "phpman.steps.success".localized
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,13 +21,15 @@ class RemovePhpVersionCommand: BrewCommand {
|
|||||||
self.phpGuard = PhpGuard()
|
self.phpGuard = PhpGuard()
|
||||||
}
|
}
|
||||||
|
|
||||||
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
func getCommandTitle() -> String {
|
||||||
let progressTitle = "Removing PHP \(version)..."
|
return "phpman.steps.removing".localized("PHP \(version)...")
|
||||||
|
}
|
||||||
|
|
||||||
|
func execute(onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||||
onProgress(.create(
|
onProgress(.create(
|
||||||
value: 0.2,
|
value: 0.2,
|
||||||
title: progressTitle,
|
title: getCommandTitle(),
|
||||||
description: "Please wait while Homebrew removes PHP \(version)..."
|
description: "phpman.steps.wait".localized
|
||||||
))
|
))
|
||||||
|
|
||||||
let command = """
|
let command = """
|
||||||
@@ -56,7 +58,7 @@ class RemovePhpVersionCommand: BrewCommand {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if process.terminationStatus <= 0 {
|
if process.terminationStatus <= 0 {
|
||||||
onProgress(.create(value: 0.95, title: progressTitle, description: "Reloading PHP versions..."))
|
onProgress(.create(value: 0.95, title: getCommandTitle(), description: "phpman.steps.reloading".localized))
|
||||||
|
|
||||||
await PhpEnvironments.detectPhpVersions()
|
await PhpEnvironments.detectPhpVersions()
|
||||||
|
|
||||||
@@ -66,7 +68,7 @@ class RemovePhpVersionCommand: BrewCommand {
|
|||||||
await MainMenu.shared.switchToPhpVersionAndWait(version, silently: true)
|
await MainMenu.shared.switchToPhpVersionAndWait(version, silently: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
onProgress(.create(value: 1, title: progressTitle, description: "The operation has succeeded."))
|
onProgress(.create(value: 1, title: getCommandTitle(), description: "phpman.steps.success".localized))
|
||||||
} else {
|
} else {
|
||||||
throw BrewCommandError(error: "The command failed to run correctly.", log: loggedMessages)
|
throw BrewCommandError(error: "The command failed to run correctly.", log: loggedMessages)
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class FakeCommand: BrewCommand {
|
class FakeCommand: BrewCommand {
|
||||||
|
func getCommandTitle() -> String {
|
||||||
|
return "Hello"
|
||||||
|
}
|
||||||
|
|
||||||
let version: String
|
let version: String
|
||||||
|
|
||||||
init(version: String) {
|
init(version: String) {
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ extension MainMenu {
|
|||||||
PhpEnvironments.shared.delegate = self
|
PhpEnvironments.shared.delegate = self
|
||||||
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
||||||
|
|
||||||
updatePhpVersionInStatusBar()
|
refreshIcon()
|
||||||
rebuild()
|
rebuild()
|
||||||
await PhpEnvironments.switcher.performSwitch(to: version)
|
await PhpEnvironments.switcher.performSwitch(to: version)
|
||||||
|
|
||||||
@@ -302,7 +302,7 @@ extension MainMenu {
|
|||||||
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
||||||
|
|
||||||
Task(priority: .userInitiated) { [unowned self] in
|
Task(priority: .userInitiated) { [unowned self] in
|
||||||
updatePhpVersionInStatusBar()
|
refreshIcon()
|
||||||
rebuild()
|
rebuild()
|
||||||
await PhpEnvironments.switcher.performSwitch(to: version)
|
await PhpEnvironments.switcher.performSwitch(to: version)
|
||||||
|
|
||||||
@@ -328,7 +328,7 @@ extension MainMenu {
|
|||||||
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePhpVersionInStatusBar()
|
refreshIcon()
|
||||||
rebuild()
|
rebuild()
|
||||||
await PhpEnvironments.switcher.performSwitch(to: version)
|
await PhpEnvironments.switcher.performSwitch(to: version)
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ extension MainMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if behaviours.contains(.updatesMenuBarContents) {
|
if behaviours.contains(.updatesMenuBarContents) {
|
||||||
updatePhpVersionInStatusBar()
|
refreshIcon()
|
||||||
|
rebuild()
|
||||||
}
|
}
|
||||||
|
|
||||||
if behaviours.contains(.broadcastServicesUpdate) {
|
if behaviours.contains(.broadcastServicesUpdate) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ extension MainMenu {
|
|||||||
func startup() async {
|
func startup() async {
|
||||||
// Start with the icon
|
// Start with the icon
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
self.setStatusBar(image: NSImage.statusBarIcon)
|
||||||
}
|
}
|
||||||
|
|
||||||
if await Startup().checkEnvironment() {
|
if await Startup().checkEnvironment() {
|
||||||
@@ -32,19 +32,14 @@ extension MainMenu {
|
|||||||
// Determine what the `php` formula is aliased to
|
// Determine what the `php` formula is aliased to
|
||||||
await PhpEnvironments.shared.determinePhpAlias()
|
await PhpEnvironments.shared.determinePhpAlias()
|
||||||
|
|
||||||
|
// Make sure that broken symlinks are removed ASAP
|
||||||
|
await BrewDiagnostics.checkForOutdatedPhpInstallationSymlinks()
|
||||||
|
|
||||||
// Initialize preferences
|
// Initialize preferences
|
||||||
_ = Preferences.shared
|
_ = Preferences.shared
|
||||||
|
|
||||||
// Determine install method
|
// Put some useful diagnostics information in log
|
||||||
Log.info(BrewDiagnostics.customCaskInstalled
|
BrewDiagnostics.logBootInformation()
|
||||||
? "[BREW] The app has been installed via Homebrew Cask."
|
|
||||||
: "[BREW] The app has been installed directly (optimal)."
|
|
||||||
)
|
|
||||||
|
|
||||||
Log.info(BrewDiagnostics.usesNginxFullFormula
|
|
||||||
? "[BREW] The app will be using the `nginx-full` formula."
|
|
||||||
: "[BREW] The app will be using the `nginx` formula."
|
|
||||||
)
|
|
||||||
|
|
||||||
// Attempt to find out more info about Valet
|
// Attempt to find out more info about Valet
|
||||||
if Valet.shared.version != nil {
|
if Valet.shared.version != nil {
|
||||||
@@ -63,9 +58,6 @@ extension MainMenu {
|
|||||||
// Check for an alias conflict
|
// Check for an alias conflict
|
||||||
await BrewDiagnostics.checkForCaskConflict()
|
await BrewDiagnostics.checkForCaskConflict()
|
||||||
|
|
||||||
// Update the icon
|
|
||||||
updatePhpVersionInStatusBar()
|
|
||||||
|
|
||||||
// Attempt to find out if PHP-FPM is broken
|
// Attempt to find out if PHP-FPM is broken
|
||||||
PhpEnvironments.prepare()
|
PhpEnvironments.prepare()
|
||||||
|
|
||||||
@@ -76,7 +68,6 @@ extension MainMenu {
|
|||||||
WarningManager.shared.evaluateWarnings()
|
WarningManager.shared.evaluateWarnings()
|
||||||
|
|
||||||
// Set up the config watchers on launch (updated automatically when switching)
|
// Set up the config watchers on launch (updated automatically when switching)
|
||||||
Log.info("Setting up watchers...")
|
|
||||||
App.shared.handlePhpConfigWatcher()
|
App.shared.handlePhpConfigWatcher()
|
||||||
|
|
||||||
// Detect built-in and custom applications
|
// Detect built-in and custom applications
|
||||||
@@ -106,11 +97,32 @@ extension MainMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Keep track of which PHP versions are currently about to release
|
// Keep track of which PHP versions are currently about to release
|
||||||
Log.info("Experimental PHP versions: \(Constants.ExperimentalPhpVersions)")
|
Log.info("Experimental PHP versions are: \(Constants.ExperimentalPhpVersions)")
|
||||||
|
|
||||||
// Find out which services are active
|
// Find out which services are active
|
||||||
Log.info("The services manager knows about \(ServicesManager.shared.services.count) services.")
|
Log.info("The services manager knows about \(ServicesManager.shared.services.count) services.")
|
||||||
|
|
||||||
|
// Post-launch stats and update check, but only if not running tests
|
||||||
|
await performPostLaunchActions()
|
||||||
|
|
||||||
|
// Check if the linked version has changed between launches of phpmon
|
||||||
|
PhpGuard().compareToLastGlobalVersion()
|
||||||
|
|
||||||
|
// We are ready!
|
||||||
|
PhpEnvironments.shared.isBusy = false
|
||||||
|
|
||||||
|
// Finally!
|
||||||
|
Log.info("PHP Monitor is ready to serve!")
|
||||||
|
|
||||||
|
// Check if we upgraded from a previous version
|
||||||
|
AppUpdater.checkIfUpdateWasPerformed()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs a set of post-launch actions, like incrementing stats and checking for updates.
|
||||||
|
(This code is skipped when running SwiftUI previews.)
|
||||||
|
*/
|
||||||
|
private func performPostLaunchActions() async {
|
||||||
if !isRunningSwiftUIPreview {
|
if !isRunningSwiftUIPreview {
|
||||||
Stats.incrementSuccessfulLaunchCount()
|
Stats.incrementSuccessfulLaunchCount()
|
||||||
Stats.evaluateSponsorMessageShouldBeDisplayed()
|
Stats.evaluateSponsorMessageShouldBeDisplayed()
|
||||||
@@ -124,15 +136,6 @@ extension MainMenu {
|
|||||||
await AppUpdater().checkForUpdates(userInitiated: false)
|
await AppUpdater().checkForUpdates(userInitiated: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the linked version has changed between launches of phpmon
|
|
||||||
PhpGuard().compareToLastGlobalVersion()
|
|
||||||
|
|
||||||
// We are ready!
|
|
||||||
Log.info("PHP Monitor is ready to serve!")
|
|
||||||
|
|
||||||
// Check if we upgraded just now
|
|
||||||
AppUpdater.checkIfUpdateWasPerformed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ extension MainMenu {
|
|||||||
|
|
||||||
// Perform UI updates on main thread
|
// Perform UI updates on main thread
|
||||||
Task { @MainActor [self] in
|
Task { @MainActor [self] in
|
||||||
updatePhpVersionInStatusBar()
|
refreshIcon()
|
||||||
rebuild()
|
rebuild()
|
||||||
|
|
||||||
if Valet.installed && !PhpEnvironments.shared.validate(version) {
|
if Valet.installed && !PhpEnvironments.shared.validate(version) {
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
|||||||
// MARK: - UI related
|
// MARK: - UI related
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Rebuilds the menu (either asynchronously or synchronously).
|
Rebuilds the menu on the main thread.
|
||||||
Defaults to rebuilding the menu asynchronously.
|
|
||||||
*/
|
*/
|
||||||
func rebuild() {
|
func rebuild() {
|
||||||
Task { @MainActor [self] in
|
Task { @MainActor [self] in
|
||||||
@@ -80,7 +79,8 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
|||||||
@objc func refreshActiveInstallation() {
|
@objc func refreshActiveInstallation() {
|
||||||
if !PhpEnvironments.shared.isBusy {
|
if !PhpEnvironments.shared.isBusy {
|
||||||
PhpEnvironments.shared.currentInstall = ActivePhpInstallation.load()
|
PhpEnvironments.shared.currentInstall = ActivePhpInstallation.load()
|
||||||
updatePhpVersionInStatusBar()
|
refreshIcon()
|
||||||
|
rebuild()
|
||||||
} else {
|
} else {
|
||||||
Log.perf("Skipping version refresh due to busy status!")
|
Log.perf("Skipping version refresh due to busy status!")
|
||||||
}
|
}
|
||||||
@@ -155,12 +155,12 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
|||||||
Task { @MainActor [self] in
|
Task { @MainActor [self] in
|
||||||
if PhpEnvironments.shared.isBusy {
|
if PhpEnvironments.shared.isBusy {
|
||||||
Log.perf("Refreshing icon: currently busy")
|
Log.perf("Refreshing icon: currently busy")
|
||||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
setStatusBar(image: NSImage.statusBarIcon)
|
||||||
} else {
|
} else {
|
||||||
Log.perf("Refreshing icon: no longer busy")
|
Log.perf("Refreshing icon: no longer busy")
|
||||||
if Preferences.preferences[.shouldDisplayDynamicIcon] as! Bool == false {
|
if Preferences.preferences[.shouldDisplayDynamicIcon] as! Bool == false {
|
||||||
// Static icon has been requested
|
// Static icon has been requested
|
||||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIconStatic"))!)
|
setStatusBar(image: NSImage.statusBarIconStatic)
|
||||||
} else {
|
} else {
|
||||||
// The dynamic icon has been requested
|
// The dynamic icon has been requested
|
||||||
let long = Preferences.preferences[.fullPhpVersionDynamicIcon] as! Bool
|
let long = Preferences.preferences[.fullPhpVersionDynamicIcon] as! Bool
|
||||||
@@ -215,6 +215,10 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
|||||||
PhpVersionManagerWindowController.show()
|
PhpVersionManagerWindowController.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func openPhpExtensionManager() {
|
||||||
|
PhpExtensionManagerWindowController.show()
|
||||||
|
}
|
||||||
|
|
||||||
@objc func openDonate() {
|
@objc func openDonate() {
|
||||||
NSWorkspace.shared.open(Constants.Urls.DonationPage)
|
NSWorkspace.shared.open(Constants.Urls.DonationPage)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ extension StatusMenu {
|
|||||||
NSMenuItem(title: "mi_php_version_manager".localized,
|
NSMenuItem(title: "mi_php_version_manager".localized,
|
||||||
action: #selector(MainMenu.openPhpVersionManager),
|
action: #selector(MainMenu.openPhpVersionManager),
|
||||||
keyEquivalent: "m"),
|
keyEquivalent: "m"),
|
||||||
|
NSMenuItem(title: "mi_php_ext_manager".localized,
|
||||||
|
action: #selector(MainMenu.openPhpExtensionManager),
|
||||||
|
keyEquivalent: "e"),
|
||||||
NSMenuItem(title: "mi_php_config".localized,
|
NSMenuItem(title: "mi_php_config".localized,
|
||||||
action: #selector(MainMenu.openActiveConfigFolder),
|
action: #selector(MainMenu.openActiveConfigFolder),
|
||||||
keyEquivalent: "c"),
|
keyEquivalent: "c"),
|
||||||
@@ -200,16 +203,6 @@ extension StatusMenu {
|
|||||||
post: stats.post_max_size,
|
post: stats.post_max_size,
|
||||||
upload: stats.upload_max_filesize)
|
upload: stats.upload_max_filesize)
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: As soon as this does more than just edit memory limits, move this
|
|
||||||
/*
|
|
||||||
addItem(NSMenuItem.separator())
|
|
||||||
addItem(NSMenuItem(
|
|
||||||
title: "mi_manage_limits".localized,
|
|
||||||
action: #selector(MainMenu.openConfigGUI),
|
|
||||||
keyEquivalent: "l")
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Extensions
|
// MARK: - Extensions
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ enum PreferenceName: String, Codable {
|
|||||||
case globalHotkey = "global_hotkey"
|
case globalHotkey = "global_hotkey"
|
||||||
case automaticBackgroundUpdateCheck = "backgroundUpdateCheck"
|
case automaticBackgroundUpdateCheck = "backgroundUpdateCheck"
|
||||||
case showPhpDoctorSuggestions = "show_php_doctor_suggestions"
|
case showPhpDoctorSuggestions = "show_php_doctor_suggestions"
|
||||||
|
case languageOverride = "language_override"
|
||||||
|
|
||||||
// APPEARANCE
|
// APPEARANCE
|
||||||
case shouldDisplayDynamicIcon = "use_dynamic_icon"
|
case shouldDisplayDynamicIcon = "use_dynamic_icon"
|
||||||
@@ -84,7 +85,8 @@ enum PreferenceName: String, Codable {
|
|||||||
],
|
],
|
||||||
.string: [
|
.string: [
|
||||||
.globalHotkey,
|
.globalHotkey,
|
||||||
.iconTypeToDisplay
|
.iconTypeToDisplay,
|
||||||
|
.languageOverride
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class Preferences {
|
|||||||
PreferenceName.allowProtocolForIntegrations.rawValue: true,
|
PreferenceName.allowProtocolForIntegrations.rawValue: true,
|
||||||
PreferenceName.automaticBackgroundUpdateCheck.rawValue: true,
|
PreferenceName.automaticBackgroundUpdateCheck.rawValue: true,
|
||||||
PreferenceName.showPhpDoctorSuggestions.rawValue: true,
|
PreferenceName.showPhpDoctorSuggestions.rawValue: true,
|
||||||
|
PreferenceName.languageOverride.rawValue: "",
|
||||||
|
|
||||||
/// Preferences: Appearance
|
/// Preferences: Appearance
|
||||||
PreferenceName.shouldDisplayDynamicIcon.rawValue: true,
|
PreferenceName.shouldDisplayDynamicIcon.rawValue: true,
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ class GeneralPreferencesVC: GenericPreferenceVC {
|
|||||||
let vc = NSStoryboard(name: "Main", bundle: nil)
|
let vc = NSStoryboard(name: "Main", bundle: nil)
|
||||||
.instantiateController(withIdentifier: "preferencesTemplateVC") as! GenericPreferenceVC
|
.instantiateController(withIdentifier: "preferencesTemplateVC") as! GenericPreferenceVC
|
||||||
|
|
||||||
_ = vc.addView(when: true, vc.getShowPhpDoctorSuggestionsPV())
|
_ = vc
|
||||||
|
.addView(when: true, vc.getLanguageOptionsPV())
|
||||||
|
.addView(when: true, vc.getShowPhpDoctorSuggestionsPV())
|
||||||
.addView(when: true, vc.getAutoRestartServicesPV())
|
.addView(when: true, vc.getAutoRestartServicesPV())
|
||||||
.addView(when: true, vc.getAutomaticComposerUpdatePV())
|
.addView(when: true, vc.getAutomaticComposerUpdatePV())
|
||||||
.addView(when: true, vc.getShortcutPV())
|
.addView(when: true, vc.getShortcutPV())
|
||||||
|
|||||||
@@ -48,11 +48,44 @@ class GenericPreferenceVC: NSViewController {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLanguageOptionsPV() -> NSView {
|
||||||
|
var options = Bundle.main.localizations
|
||||||
|
.filter({ $0 != "Base"})
|
||||||
|
.map({ lang in
|
||||||
|
return PreferenceDropdownOption(
|
||||||
|
label: Locale.current.localizedString(forLanguageCode: lang)!,
|
||||||
|
value: lang
|
||||||
|
)
|
||||||
|
})
|
||||||
|
options.insert(PreferenceDropdownOption(label: "System Default", value: ""), at: 0)
|
||||||
|
|
||||||
|
return SelectPreferenceView.make(
|
||||||
|
sectionText: "prefs.language".localized,
|
||||||
|
descriptionText: "prefs.language_options_desc".localized,
|
||||||
|
options: options,
|
||||||
|
preference: .languageOverride,
|
||||||
|
action: {
|
||||||
|
MainMenu.shared.refreshIcon()
|
||||||
|
MainMenu.shared.rebuild()
|
||||||
|
|
||||||
|
if let window = App.shared.preferencesWindowController?.window {
|
||||||
|
let alert = NSAlert()
|
||||||
|
alert.messageText = "alert.language_changed.title".localized
|
||||||
|
alert.informativeText = "alert.language_changed.subtitle".localized
|
||||||
|
alert.alertStyle = .warning
|
||||||
|
alert.addButton(withTitle: "generic.ok".localized)
|
||||||
|
alert.beginSheetModal(for: window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func getIconOptionsPV() -> NSView {
|
func getIconOptionsPV() -> NSView {
|
||||||
return SelectPreferenceView.make(
|
return SelectPreferenceView.make(
|
||||||
sectionText: "",
|
sectionText: "",
|
||||||
descriptionText: "prefs.icon_options_desc".localized,
|
descriptionText: "prefs.icon_options_desc".localized,
|
||||||
options: MenuBarIcon.allCases.map({ return $0.rawValue }),
|
options: MenuBarIcon.allCases
|
||||||
|
.map({ return PreferenceDropdownOption(label: $0.rawValue, value: $0.rawValue) }),
|
||||||
localizationPrefix: "prefs.icon_options",
|
localizationPrefix: "prefs.icon_options",
|
||||||
preference: .iconTypeToDisplay,
|
preference: .iconTypeToDisplay,
|
||||||
action: {
|
action: {
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ class PreferencesWindowController: PMWindowController {
|
|||||||
App.shared.preferencesWindowController?.positionWindowInTopRightCorner()
|
App.shared.preferencesWindowController?.positionWindowInTopRightCorner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App.shared.preferencesWindowController?.window?.orderFrontRegardless()
|
||||||
|
|
||||||
NSApp.activate(ignoringOtherApps: true)
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ class Stats {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func clearCurrentGlobalPhpVersion() {
|
||||||
|
UserDefaults.standard.removeObject(forKey: InternalStats.lastGlobalPhpVersion.rawValue)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Determine if the sponsor message should be displayed.
|
Determine if the sponsor message should be displayed.
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<action selector="toggled:" target="c22-O7-iKe" id="c9y-JM-TdE"/>
|
<action selector="toggled:" target="c22-O7-iKe" id="c9y-JM-TdE"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bcg-X1-qca">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bcg-X1-qca">
|
||||||
<rect key="frame" x="168" y="5" width="410" height="14"/>
|
<rect key="frame" x="168" y="5" width="410" height="14"/>
|
||||||
<textFieldCell key="cell" title="DESCRIPTION" id="9fH-up-Sob">
|
<textFieldCell key="cell" title="DESCRIPTION" id="9fH-up-Sob">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B8f-nb-Y0A">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B8f-nb-Y0A">
|
||||||
<rect key="frame" x="-2" y="27" width="154" height="16"/>
|
<rect key="frame" x="-2" y="27" width="154" height="16"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="150" id="euj-t0-xv4"/>
|
<constraint firstAttribute="width" constant="150" id="euj-t0-xv4"/>
|
||||||
|
|||||||
@@ -9,30 +9,34 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
class SelectPreferenceView: NSView, XibLoadable {
|
struct PreferenceDropdownOption {
|
||||||
|
let label: String
|
||||||
|
let value: String
|
||||||
|
}
|
||||||
|
|
||||||
|
class SelectPreferenceView: NSView, XibLoadable {
|
||||||
@IBOutlet weak var labelSection: NSTextField!
|
@IBOutlet weak var labelSection: NSTextField!
|
||||||
@IBOutlet weak var labelDescription: NSTextField!
|
@IBOutlet weak var labelDescription: NSTextField!
|
||||||
@IBOutlet weak var popupButton: NSPopUpButton!
|
@IBOutlet weak var popupButton: NSPopUpButton!
|
||||||
|
|
||||||
var localizationPrefix: String = ""
|
var localizationPrefix: String?
|
||||||
var imagePrefix: String?
|
var imagePrefix: String?
|
||||||
|
|
||||||
var options: [String] = [] {
|
var options: [PreferenceDropdownOption] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
self.popupButton.removeAllItems()
|
self.popupButton.removeAllItems()
|
||||||
self.options.forEach { value in
|
self.options.forEach { option in
|
||||||
self.popupButton.addItem(
|
if let prefix = localizationPrefix {
|
||||||
withTitle: "\(localizationPrefix).\(value)".localized
|
self.popupButton.addItem(withTitle: "\(prefix).\(option.label)".localized)
|
||||||
)
|
} else {
|
||||||
}
|
self.popupButton.addItem(withTitle: option.label)
|
||||||
|
}
|
||||||
if imagePrefix == nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let prefix = imagePrefix {
|
||||||
self.popupButton.itemArray.enumerated().forEach { item in
|
self.popupButton.itemArray.enumerated().forEach { item in
|
||||||
item.element.image = NSImage(named: "\(imagePrefix!)_\(self.options[item.offset])")
|
item.element.image = NSImage(named: "\(prefix)_\(self.options[item.offset].value)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,19 +47,18 @@ class SelectPreferenceView: NSView, XibLoadable {
|
|||||||
didSet {
|
didSet {
|
||||||
let value = Preferences.preferences[preference] as! String
|
let value = Preferences.preferences[preference] as! String
|
||||||
self.options.enumerated().forEach { option in
|
self.options.enumerated().forEach { option in
|
||||||
if option.element == value {
|
if option.element.value == value {
|
||||||
self.popupButton.selectItem(at: option.offset)
|
self.popupButton.selectItem(at: option.offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable function_parameter_count
|
|
||||||
static func make(
|
static func make(
|
||||||
sectionText: String,
|
sectionText: String,
|
||||||
descriptionText: String,
|
descriptionText: String,
|
||||||
options: [String],
|
options: [PreferenceDropdownOption],
|
||||||
localizationPrefix: String,
|
localizationPrefix: String? = nil,
|
||||||
imagePrefix: String? = nil,
|
imagePrefix: String? = nil,
|
||||||
preference: PreferenceName,
|
preference: PreferenceName,
|
||||||
action: @escaping () -> Void) -> NSView {
|
action: @escaping () -> Void) -> NSView {
|
||||||
@@ -72,11 +75,10 @@ class SelectPreferenceView: NSView, XibLoadable {
|
|||||||
|
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
// swiftlint:enable function_parameter_count
|
|
||||||
|
|
||||||
@IBAction func valueChanged(_ sender: Any) {
|
@IBAction func valueChanged(_ sender: Any) {
|
||||||
let index = self.popupButton.indexOfSelectedItem
|
let index = self.popupButton.indexOfSelectedItem
|
||||||
Preferences.update(.iconTypeToDisplay, value: self.options[index])
|
Preferences.update(self.preference, value: self.options[index].value)
|
||||||
self.action()
|
self.action()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@@ -13,16 +13,16 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="596" height="50"/>
|
<rect key="frame" x="0.0" y="0.0" width="596" height="50"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bcg-X1-qca">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bcg-X1-qca">
|
||||||
<rect key="frame" x="183" y="5" width="395" height="14"/>
|
<rect key="frame" x="168" y="5" width="410" height="14"/>
|
||||||
<textFieldCell key="cell" title="DESCRIPTION" id="9fH-up-Sob">
|
<textFieldCell key="cell" title="DESCRIPTION" id="9fH-up-Sob">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B8f-nb-Y0A">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B8f-nb-Y0A">
|
||||||
<rect key="frame" x="13" y="29" width="154" height="16"/>
|
<rect key="frame" x="-2" y="29" width="154" height="16"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="150" id="euj-t0-xv4"/>
|
<constraint firstAttribute="width" constant="150" id="euj-t0-xv4"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YaB-Tg-Ir3">
|
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YaB-Tg-Ir3">
|
||||||
<rect key="frame" x="182" y="23" width="110" height="25"/>
|
<rect key="frame" x="167" y="23" width="110" height="25"/>
|
||||||
<popUpButtonCell key="cell" type="push" title="Icon Option" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="SaA-mm-HBo" id="Su6-C4-aGo">
|
<popUpButtonCell key="cell" type="push" title="Icon Option" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="SaA-mm-HBo" id="Su6-C4-aGo">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="menu"/>
|
<font key="font" metaFont="menu"/>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<constraint firstItem="Bcg-X1-qca" firstAttribute="top" secondItem="YaB-Tg-Ir3" secondAttribute="bottom" constant="8" symbolic="YES" id="Mji-pe-CNl"/>
|
<constraint firstItem="Bcg-X1-qca" firstAttribute="top" secondItem="YaB-Tg-Ir3" secondAttribute="bottom" constant="8" symbolic="YES" id="Mji-pe-CNl"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="Bcg-X1-qca" secondAttribute="trailing" constant="20" symbolic="YES" id="UPo-Il-l81"/>
|
<constraint firstAttribute="trailing" secondItem="Bcg-X1-qca" secondAttribute="trailing" constant="20" symbolic="YES" id="UPo-Il-l81"/>
|
||||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="YaB-Tg-Ir3" secondAttribute="trailing" constant="20" symbolic="YES" id="Zlg-jj-uKY"/>
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="YaB-Tg-Ir3" secondAttribute="trailing" constant="20" symbolic="YES" id="Zlg-jj-uKY"/>
|
||||||
<constraint firstItem="B8f-nb-Y0A" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="15" id="Ztd-uk-4aw"/>
|
<constraint firstItem="B8f-nb-Y0A" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" id="aBU-J8-gRK"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="Bcg-X1-qca" secondAttribute="bottom" constant="5" id="hNE-mU-jcu"/>
|
<constraint firstAttribute="bottom" secondItem="Bcg-X1-qca" secondAttribute="bottom" constant="5" id="hNE-mU-jcu"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<connections>
|
<connections>
|
||||||
|
|||||||
@@ -27,15 +27,15 @@ struct HelpButton: View {
|
|||||||
.buttonStyle(BorderlessButtonStyle())
|
.buttonStyle(BorderlessButtonStyle())
|
||||||
.focusable(false)
|
.focusable(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
struct HelpButton_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
#Preview("Light Mode") {
|
||||||
Group {
|
HelpButton(action: {})
|
||||||
HelpButton(action: {}).padding()
|
.padding(100)
|
||||||
.previewDisplayName("Light Mode")
|
}
|
||||||
HelpButton(action: {}).padding().preferredColorScheme(.dark)
|
|
||||||
.previewDisplayName("Dark Mode")
|
#Preview("Dark Mode") {
|
||||||
}
|
HelpButton(action: {})
|
||||||
}
|
.padding(100)
|
||||||
}
|
.preferredColorScheme(.dark)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ var isRunningSwiftUIPreview: Bool {
|
|||||||
|
|
||||||
extension Color {
|
extension Color {
|
||||||
public static var appPrimary: Color = Color("AppColor")
|
public static var appPrimary: Color = Color("AppColor")
|
||||||
public static var appSecondary: Color = Color("AppSecondary")
|
|
||||||
|
// This next one is generated automatically via asset catalogs now
|
||||||
|
// public static var appSecondary: Color = Color("AppSecondary")
|
||||||
|
|
||||||
public static var debug: Color = {
|
public static var debug: Color = {
|
||||||
if ProcessInfo.processInfo.environment["PAINT_PHPMON_SWIFTUI_VIEWS"] != nil {
|
if ProcessInfo.processInfo.environment["PAINT_PHPMON_SWIFTUI_VIEWS"] != nil {
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ struct NoDomainResults: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoDomainResults_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
|
||||||
NoDomainResults()
|
NoDomainResults()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,8 +126,7 @@ struct DisclaimerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VersionPopoverView_Previews: PreviewProvider {
|
#Preview("Unknown Requirement") {
|
||||||
static var previews: some View {
|
|
||||||
VersionPopoverView(
|
VersionPopoverView(
|
||||||
site: FakeValetSite(
|
site: FakeValetSite(
|
||||||
fakeWithName: "amazingwebsite",
|
fakeWithName: "amazingwebsite",
|
||||||
@@ -140,8 +139,9 @@ struct VersionPopoverView_Previews: PreviewProvider {
|
|||||||
validPhpVersions: [],
|
validPhpVersions: [],
|
||||||
parent: nil
|
parent: nil
|
||||||
)
|
)
|
||||||
.previewDisplayName("Unknown Requirement")
|
}
|
||||||
|
|
||||||
|
#Preview("Requirement Matches") {
|
||||||
VersionPopoverView(
|
VersionPopoverView(
|
||||||
site: FakeValetSite(
|
site: FakeValetSite(
|
||||||
fakeWithName: "amazingwebsite",
|
fakeWithName: "amazingwebsite",
|
||||||
@@ -154,7 +154,9 @@ struct VersionPopoverView_Previews: PreviewProvider {
|
|||||||
validPhpVersions: [],
|
validPhpVersions: [],
|
||||||
parent: nil
|
parent: nil
|
||||||
)
|
)
|
||||||
.previewDisplayName("Requirement Matches")
|
}
|
||||||
|
|
||||||
|
#Preview("Isolated") {
|
||||||
VersionPopoverView(
|
VersionPopoverView(
|
||||||
site: FakeValetSite(
|
site: FakeValetSite(
|
||||||
fakeWithName: "anothersite",
|
fakeWithName: "anothersite",
|
||||||
@@ -168,7 +170,9 @@ struct VersionPopoverView_Previews: PreviewProvider {
|
|||||||
validPhpVersions: [],
|
validPhpVersions: [],
|
||||||
parent: nil
|
parent: nil
|
||||||
)
|
)
|
||||||
.previewDisplayName("Isolated")
|
}
|
||||||
|
|
||||||
|
#Preview("Isolated Mismatch") {
|
||||||
VersionPopoverView(
|
VersionPopoverView(
|
||||||
site: FakeValetSite(
|
site: FakeValetSite(
|
||||||
fakeWithName: "anothersite",
|
fakeWithName: "anothersite",
|
||||||
@@ -182,7 +186,9 @@ struct VersionPopoverView_Previews: PreviewProvider {
|
|||||||
validPhpVersions: [],
|
validPhpVersions: [],
|
||||||
parent: nil
|
parent: nil
|
||||||
)
|
)
|
||||||
.previewDisplayName("Isolated Mismatch")
|
}
|
||||||
|
|
||||||
|
#Preview("Recommend Alternatives") {
|
||||||
VersionPopoverView(
|
VersionPopoverView(
|
||||||
site: FakeValetSite(
|
site: FakeValetSite(
|
||||||
fakeWithName: "anothersite",
|
fakeWithName: "anothersite",
|
||||||
@@ -198,6 +204,4 @@ struct VersionPopoverView_Previews: PreviewProvider {
|
|||||||
],
|
],
|
||||||
parent: nil
|
parent: nil
|
||||||
)
|
)
|
||||||
.previewDisplayName("Recommend Alternatives")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ struct HeaderView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HeaderView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
|
||||||
HeaderView(text: "Hello world")
|
HeaderView(text: "Hello world")
|
||||||
.frame(width: 330.0)
|
.frame(width: 330.0)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,15 +172,15 @@ struct ServiceView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ServicesView_Previews: PreviewProvider {
|
#Preview("Active 1") {
|
||||||
static var previews: some View {
|
|
||||||
ServicesView(manager: FakeServicesManager(
|
ServicesView(manager: FakeServicesManager(
|
||||||
formulae: ["php", "nginx", "dnsmasq"],
|
formulae: ["php", "nginx", "dnsmasq"],
|
||||||
status: .active
|
status: .active
|
||||||
), perRow: 4)
|
), perRow: 4)
|
||||||
.frame(width: 330.0)
|
.frame(width: 330.0)
|
||||||
.previewDisplayName("Active 1")
|
}
|
||||||
|
|
||||||
|
#Preview("Active 2") {
|
||||||
ServicesView(manager: FakeServicesManager(
|
ServicesView(manager: FakeServicesManager(
|
||||||
formulae: [
|
formulae: [
|
||||||
"php", "nginx", "dnsmasq", "thing1",
|
"php", "nginx", "dnsmasq", "thing1",
|
||||||
@@ -189,6 +189,4 @@ struct ServicesView_Previews: PreviewProvider {
|
|||||||
status: .inactive
|
status: .inactive
|
||||||
), perRow: 4)
|
), perRow: 4)
|
||||||
.frame(width: 330.0)
|
.frame(width: 330.0)
|
||||||
.previewDisplayName("Active 2")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ struct StatsView: View {
|
|||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "gearshape.fill")
|
Image(systemName: "gearshape.fill")
|
||||||
}
|
}
|
||||||
|
.accessibility(identifier: "phpConfigButton")
|
||||||
.focusable(false)
|
.focusable(false)
|
||||||
.frame(minWidth: 30, alignment: .center)
|
.frame(minWidth: 30, alignment: .center)
|
||||||
}
|
}
|
||||||
@@ -98,12 +99,10 @@ struct StatsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StatsView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
|
||||||
StatsView(
|
StatsView(
|
||||||
memoryLimit: "1024 MB",
|
memoryLimit: "1024 MB",
|
||||||
maxPostSize: "1024 MB",
|
maxPostSize: "1024 MB",
|
||||||
maxUploadSize: "1024 MB"
|
maxUploadSize: "1024 MB"
|
||||||
).frame(height: 100)
|
).frame(height: 100)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
//
|
|
||||||
// ProgressViewSubject.swift
|
|
||||||
// PHP Monitor
|
|
||||||
//
|
|
||||||
// Created by Nico Verbruggen on 11/03/2023.
|
|
||||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
class ProgressViewSubject: ObservableObject {
|
|
||||||
@Published var title: String
|
|
||||||
@Published var description: String?
|
|
||||||
@Published var progress: Double
|
|
||||||
|
|
||||||
init(title: String, description: String) {
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.progress = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
//
|
|
||||||
// ProgressWindowView.swift
|
|
||||||
// PHP Monitor
|
|
||||||
//
|
|
||||||
// Created by Nico Verbruggen on 11/03/2023.
|
|
||||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct ProgressWindowView: View {
|
|
||||||
@ObservedObject var subject: ProgressViewSubject
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack(alignment: .leading) {
|
|
||||||
VStack(alignment: .leading) {
|
|
||||||
Text(subject.title)
|
|
||||||
.font(.system(size: 14))
|
|
||||||
.bold()
|
|
||||||
if subject.description != nil {
|
|
||||||
Text(subject.description!)
|
|
||||||
.font(.system(size: 13))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.padding(.leading, 20)
|
|
||||||
.padding(.top, 12)
|
|
||||||
ProgressView(value: subject.progress)
|
|
||||||
.padding(.top, 0)
|
|
||||||
.padding(.bottom, 12)
|
|
||||||
.padding(.horizontal, 20)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor static func display(_ subject: ProgressViewSubject) async -> NSWindowController {
|
|
||||||
let view = ProgressWindowView(subject: subject)
|
|
||||||
|
|
||||||
let window = NSWindow(
|
|
||||||
contentRect: NSRect(x: 0, y: 0, width: 420, height: 240),
|
|
||||||
styleMask: [.titled, .closable, .utilityWindow],
|
|
||||||
backing: .buffered,
|
|
||||||
defer: false
|
|
||||||
)
|
|
||||||
|
|
||||||
window.title = ""
|
|
||||||
window.titlebarAppearsTransparent = true
|
|
||||||
window.contentView = NSHostingView(rootView: view)
|
|
||||||
let controller = NSWindowController(window: window)
|
|
||||||
controller.showWindow(nil)
|
|
||||||
controller.positionWindowInTopRightCorner()
|
|
||||||
controller.window?.makeKeyAndOrderFront(self)
|
|
||||||
// NSApp.activate(ignoringOtherApps: true)
|
|
||||||
return controller
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ProgressWindowView_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
ProgressWindowView(
|
|
||||||
subject: ProgressViewSubject(
|
|
||||||
title: "Long running task",
|
|
||||||
description: "Please be patient"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -56,7 +56,6 @@ class ConfigFSNotifier {
|
|||||||
return App.shared.handlePhpConfigWatcher(forceReload: true)
|
return App.shared.handlePhpConfigWatcher(forceReload: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
self?.parent.didChange?(self!.url)
|
self?.parent.didChange?(self!.url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,21 +16,19 @@ class DomainListKindCell: NSTableCellView, DomainListCellProtocol {
|
|||||||
|
|
||||||
func populateCell(with site: ValetSite) {
|
func populateCell(with site: ValetSite) {
|
||||||
// If the `aliasPath` is nil, we're dealing with a parked site (otherwise: linked).
|
// If the `aliasPath` is nil, we're dealing with a parked site (otherwise: linked).
|
||||||
imageViewType.image = NSImage(
|
imageViewType.image = site.aliasPath == nil
|
||||||
named: site.aliasPath == nil
|
? NSImage.iconParked
|
||||||
? "IconParked"
|
: NSImage.iconLinked
|
||||||
: "IconLinked"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Unless, of course, this is a default site
|
// Unless, of course, this is a default site
|
||||||
if site.absolutePath == Valet.shared.config.defaultSite {
|
if site.absolutePath == Valet.shared.config.defaultSite {
|
||||||
imageViewType.image = NSImage(named: "IconDefault")
|
imageViewType.image = NSImage.iconDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
imageViewType.contentTintColor = NSColor.tertiaryLabelColor
|
imageViewType.contentTintColor = NSColor.tertiaryLabelColor
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateCell(with proxy: ValetProxy) {
|
func populateCell(with proxy: ValetProxy) {
|
||||||
imageViewType.image = NSImage(named: "IconProxy")
|
imageViewType.image = NSImage.iconProxy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,14 +34,13 @@ class DomainListPhpCell: NSTableCellView, DomainListCellProtocol {
|
|||||||
|
|
||||||
if site.isolatedPhpVersion != nil {
|
if site.isolatedPhpVersion != nil {
|
||||||
imageViewPhpVersionOK.isHidden = false
|
imageViewPhpVersionOK.isHidden = false
|
||||||
imageViewPhpVersionOK.image = NSImage(named: "Isolated")
|
imageViewPhpVersionOK.image = NSImage.isolated
|
||||||
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.isolated".localized(site.servingPhpVersion)
|
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.isolated".localized(site.servingPhpVersion)
|
||||||
} else {
|
} else {
|
||||||
imageViewPhpVersionOK.isHidden = (site.preferredPhpVersion == "???"
|
imageViewPhpVersionOK.isHidden = (site.preferredPhpVersion == "???"
|
||||||
|| !site.isCompatibleWithPreferredPhpVersion)
|
|| !site.isCompatibleWithPreferredPhpVersion)
|
||||||
imageViewPhpVersionOK.image = NSImage(named: "Checkmark")
|
imageViewPhpVersionOK.image = NSImage.checkmark
|
||||||
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.checkmark".localized(site.preferredPhpVersion)
|
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.checkmark".localized(site.preferredPhpVersion)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,22 @@ extension DomainListVC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func toggleExtension(sender: ExtensionMenuItem) {
|
||||||
|
Task {
|
||||||
|
self.setUIBusy()
|
||||||
|
|
||||||
|
await sender.phpExtension?.toggle()
|
||||||
|
|
||||||
|
if Preferences.isEnabled(.autoServiceRestartAfterExtensionToggle) {
|
||||||
|
await Actions.restartPhpFpm()
|
||||||
|
}
|
||||||
|
|
||||||
|
reloadContextMenu()
|
||||||
|
|
||||||
|
self.setUINotBusy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc func isolateSite(sender: PhpMenuItem) {
|
@objc func isolateSite(sender: PhpMenuItem) {
|
||||||
guard let site = selectedSite else {
|
guard let site = selectedSite else {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -42,7 +42,20 @@ extension DomainListVC {
|
|||||||
addDisabledIsolation(to: menu)
|
addDisabledIsolation(to: menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addSeparator(to: menu)
|
||||||
|
|
||||||
|
if let extensions = site.isolatedPhpVersion?.extensions ?? PhpEnvironments.phpInstall?.extensions,
|
||||||
|
let version = site.isolatedPhpVersion?.versionNumber.short ?? PhpEnvironments.phpInstall?.version.short {
|
||||||
|
menu.addItem(HeaderView.asMenuItem(text: "mi_detected_extensions".localized))
|
||||||
|
addMenuItemsForExtensions(
|
||||||
|
to: menu,
|
||||||
|
for: extensions,
|
||||||
|
version: version
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
menu.addItem(HeaderView.asMenuItem(text: "domain_list.actions".localized))
|
menu.addItem(HeaderView.asMenuItem(text: "domain_list.actions".localized))
|
||||||
|
|
||||||
addToggleSecure(to: menu, secured: site.secured)
|
addToggleSecure(to: menu, secured: site.secured)
|
||||||
addUnlink(to: menu, with: site)
|
addUnlink(to: menu, with: site)
|
||||||
|
|
||||||
@@ -150,6 +163,28 @@ extension DomainListVC {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func addMenuItemsForExtensions(to menu: NSMenu, for extensions: [PhpExtension], version: String) {
|
||||||
|
var items: [NSMenuItem] = [
|
||||||
|
NSMenuItem(title: "domain_list.applies_to".localized(version))
|
||||||
|
]
|
||||||
|
|
||||||
|
for phpExtension in extensions {
|
||||||
|
let item = ExtensionMenuItem(
|
||||||
|
title: "\(phpExtension.name) (\(phpExtension.fileNameOnly))",
|
||||||
|
action: #selector(self.toggleExtension),
|
||||||
|
keyEquivalent: ""
|
||||||
|
)
|
||||||
|
|
||||||
|
item.state = phpExtension.enabled ? .on : .off
|
||||||
|
item.phpExtension = phpExtension
|
||||||
|
|
||||||
|
items.append(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.addItem(NSMenuItem(title: "domain_list.extensions".localized, submenu: items))
|
||||||
|
menu.addItem(NSMenuItem.separator())
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Menu Items for Proxy
|
// MARK: - Menu Items for Proxy
|
||||||
|
|
||||||
private func addMenuItemsForProxy(_ proxy: ValetProxy) {
|
private func addMenuItemsForProxy(_ proxy: ValetProxy) {
|
||||||
|
|||||||
@@ -139,10 +139,6 @@ struct OnboardingView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OnboardingView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
|
||||||
Group {
|
|
||||||
OnboardingView()
|
OnboardingView()
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,8 +98,7 @@ struct ByteLimitView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ByteLimitView_Previews: PreviewProvider {
|
#Preview("Byte Limit View") {
|
||||||
static var previews: some View {
|
|
||||||
PreferenceContainer(
|
PreferenceContainer(
|
||||||
name: "Max Size",
|
name: "Max Size",
|
||||||
description:
|
description:
|
||||||
@@ -108,9 +107,10 @@ struct ByteLimitView_Previews: PreviewProvider {
|
|||||||
) {
|
) {
|
||||||
ByteLimitView(preference: BytePhpPreference(key: "max_memory"))
|
ByteLimitView(preference: BytePhpPreference(key: "max_memory"))
|
||||||
}.frame(width: 600, height: 200)
|
}.frame(width: 600, height: 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview("Config Manager") {
|
||||||
ConfigManagerView()
|
ConfigManagerView()
|
||||||
.frame(width: 600, height: .infinity)
|
.frame(width: 600, height: .infinity)
|
||||||
.previewDisplayName("Config Manager")
|
.previewDisplayName("Config Manager")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,10 +84,6 @@ struct ConfigManagerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConfigManagerView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
ConfigManagerView().frame(width: 600)
|
||||||
ConfigManagerView()
|
|
||||||
.frame(width: 600)
|
|
||||||
.previewDisplayName("Live Preview")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ class WarningManager: ObservableObject {
|
|||||||
.trimmingCharacters(in: .whitespacesAndNewlines) == "1"
|
.trimmingCharacters(in: .whitespacesAndNewlines) == "1"
|
||||||
},
|
},
|
||||||
name: "Running PHP Monitor with Rosetta on M1",
|
name: "Running PHP Monitor with Rosetta on M1",
|
||||||
title: "warnings.arm_compatibility.title".localized,
|
title: "warnings.arm_compatibility.title",
|
||||||
paragraphs: { return ["warnings.arm_compatibility.description".localized] },
|
paragraphs: { return ["warnings.arm_compatibility.description"] },
|
||||||
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-and-Apple-Silicon"
|
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-and-Apple-Silicon"
|
||||||
),
|
),
|
||||||
Warning(
|
Warning(
|
||||||
@@ -44,11 +44,11 @@ class WarningManager: ObservableObject {
|
|||||||
!FileSystem.isWriteableFile("/usr/local/bin/")
|
!FileSystem.isWriteableFile("/usr/local/bin/")
|
||||||
},
|
},
|
||||||
name: "Helpers cannot be symlinked and not in PATH",
|
name: "Helpers cannot be symlinked and not in PATH",
|
||||||
title: "warnings.helper_permissions.title".localized,
|
title: "warnings.helper_permissions.title",
|
||||||
paragraphs: { return [
|
paragraphs: { return [
|
||||||
"warnings.helper_permissions.description".localized,
|
"warnings.helper_permissions.description",
|
||||||
"warnings.helper_permissions.unavailable".localized,
|
"warnings.helper_permissions.unavailable",
|
||||||
"warnings.helper_permissions.symlink".localized
|
"warnings.helper_permissions.symlink"
|
||||||
] },
|
] },
|
||||||
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-helper-binaries"
|
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-helper-binaries"
|
||||||
),
|
),
|
||||||
@@ -58,7 +58,7 @@ class WarningManager: ObservableObject {
|
|||||||
return !PhpConfigChecker.shared.missing.isEmpty
|
return !PhpConfigChecker.shared.missing.isEmpty
|
||||||
},
|
},
|
||||||
name: "Your PHP installation is missing configuration files",
|
name: "Your PHP installation is missing configuration files",
|
||||||
title: "warnings.files_missing.title".localized,
|
title: "warnings.files_missing.title",
|
||||||
paragraphs: { return [
|
paragraphs: { return [
|
||||||
"warnings.files_missing.description".localized(
|
"warnings.files_missing.description".localized(
|
||||||
PhpConfigChecker.shared.missing.joined(separator: "\n• ")
|
PhpConfigChecker.shared.missing.joined(separator: "\n• ")
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ struct NoWarningsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoWarningsView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
NoWarningsView().padding()
|
||||||
NoWarningsView()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,14 +96,12 @@ struct PhpDoctorView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WarningListView_Previews: PreviewProvider {
|
#Preview("Empty List") {
|
||||||
static var previews: some View {
|
|
||||||
PhpDoctorView(empty: true, fake: true, manager: WarningManager())
|
PhpDoctorView(empty: true, fake: true, manager: WarningManager())
|
||||||
.frame(width: 600, height: 480)
|
.frame(width: 600, height: 480)
|
||||||
.previewDisplayName("Empty List")
|
}
|
||||||
|
|
||||||
|
#Preview("List With All Warnings") {
|
||||||
PhpDoctorView(empty: false, fake: true, manager: WarningManager())
|
PhpDoctorView(empty: false, fake: true, manager: WarningManager())
|
||||||
.frame(width: 600, height: 480)
|
.frame(width: 600, height: 480)
|
||||||
.previewDisplayName("List With All Warnings")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct WarningView: View {
|
|||||||
Text(title.localizedForSwiftUI)
|
Text(title.localizedForSwiftUI)
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
ForEach(paragraphs, id: \.self) { paragraph in
|
ForEach(paragraphs, id: \.self) { paragraph in
|
||||||
Text(paragraph)
|
Text(paragraph.localizedForSwiftUI)
|
||||||
.font(.system(size: 13))
|
.font(.system(size: 13))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,15 +47,17 @@ struct WarningView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WarningView_Previews: PreviewProvider {
|
#Preview("Light Mode") {
|
||||||
static var previews: some View {
|
|
||||||
WarningView(
|
WarningView(
|
||||||
title: "warnings.helper_permissions.title",
|
title: "warnings.helper_permissions.title",
|
||||||
paragraphs: ["warnings.helper_permissions.description"],
|
paragraphs: ["warnings.helper_permissions.description"],
|
||||||
documentationUrl: "https://nicoverbruggen.be"
|
documentationUrl: "https://nicoverbruggen.be"
|
||||||
)
|
)
|
||||||
.frame(width: 600, height: 105)
|
.frame(width: 600, height: 105)
|
||||||
|
.padding(25)
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview("Dark Mode") {
|
||||||
WarningView(
|
WarningView(
|
||||||
title: "warnings.helper_permissions.title",
|
title: "warnings.helper_permissions.title",
|
||||||
paragraphs: ["warnings.helper_permissions.description"],
|
paragraphs: ["warnings.helper_permissions.description"],
|
||||||
@@ -63,7 +65,5 @@ struct WarningView_Previews: PreviewProvider {
|
|||||||
)
|
)
|
||||||
.preferredColorScheme(.dark)
|
.preferredColorScheme(.dark)
|
||||||
.frame(width: 600, height: 105)
|
.frame(width: 600, height: 105)
|
||||||
|
.padding(25)
|
||||||
// WarningListView().frame(width: 600, height: 580)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// BrewExtensionsObservable.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 21/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class BrewExtensionsObservable: ObservableObject {
|
||||||
|
@Published var phpVersion: String {
|
||||||
|
didSet {
|
||||||
|
self.loadExtensionData(for: phpVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Published var extensions: [BrewPhpExtension] = []
|
||||||
|
|
||||||
|
init(phpVersion: String) {
|
||||||
|
self.phpVersion = phpVersion
|
||||||
|
self.loadExtensionData(for: phpVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func loadExtensionData(for version: String) {
|
||||||
|
let tapFormulae = BrewTapFormulae.from(tap: "shivammathur/homebrew-extensions")
|
||||||
|
|
||||||
|
if let filteredTapFormulae = tapFormulae[version] {
|
||||||
|
self.extensions = filteredTapFormulae
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// PhpExtensionManagerView+Actions.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 21/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
extension PhpExtensionManagerView {
|
||||||
|
public func presentErrorAlert(
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
button: String,
|
||||||
|
style: NSAlert.Style = .critical
|
||||||
|
) {
|
||||||
|
Alert.confirm(
|
||||||
|
onWindow: App.shared.phpExtensionManagerWindowController!.window!,
|
||||||
|
messageText: title,
|
||||||
|
informativeText: description,
|
||||||
|
buttonTitle: button,
|
||||||
|
secondButtonTitle: "",
|
||||||
|
style: style,
|
||||||
|
onFirstButtonPressed: {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func install(_ ext: BrewPhpExtension) {
|
||||||
|
Task {
|
||||||
|
await self.runCommand(InstallPhpExtensionCommand(install: [ext]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func confirmUninstall(_ ext: BrewPhpExtension) {
|
||||||
|
Alert.confirm(
|
||||||
|
onWindow: App.shared.phpExtensionManagerWindowController!.window!,
|
||||||
|
messageText: "phpextman.warnings.removal.title".localized(ext.name),
|
||||||
|
informativeText: "phpextman.warnings.removal.desc".localized(ext.name),
|
||||||
|
buttonTitle: "phpextman.warnings.removal.button".localized,
|
||||||
|
buttonIsDestructive: true,
|
||||||
|
secondButtonTitle: "generic.cancel".localized,
|
||||||
|
style: .warning,
|
||||||
|
onFirstButtonPressed: {
|
||||||
|
Task {
|
||||||
|
await self.runCommand(RemovePhpExtensionCommand(remove: ext))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func runCommand(_ command: BrewCommand) async {
|
||||||
|
if PhpEnvironments.shared.isBusy {
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.action_prevented_busy.title".localized,
|
||||||
|
description: "phpman.action_prevented_busy.desc".localized,
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let phpVersionManaged = self.manager.phpVersion
|
||||||
|
|
||||||
|
do {
|
||||||
|
self.status.busy = true
|
||||||
|
try await command.execute { progress in
|
||||||
|
Task { @MainActor in
|
||||||
|
self.status.title = progress.title
|
||||||
|
self.status.description = progress.description
|
||||||
|
self.status.busy = progress.value != 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.manager.phpVersion = phpVersionManaged
|
||||||
|
self.status.busy = false
|
||||||
|
} catch let error {
|
||||||
|
let error = error as! BrewCommandError
|
||||||
|
let messages = error.log.suffix(2).joined(separator: "\n")
|
||||||
|
|
||||||
|
self.status.busy = false
|
||||||
|
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.failures.install.title".localized,
|
||||||
|
description: "phpman.failures.install.desc".localized(messages),
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
//
|
||||||
|
// PhpExtensionManagerView.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 13/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PhpExtensionManagerView: View {
|
||||||
|
@ObservedObject var manager: BrewExtensionsObservable
|
||||||
|
@ObservedObject var status: BusyStatus
|
||||||
|
@State var searchText: String
|
||||||
|
|
||||||
|
init() {
|
||||||
|
self.searchText = ""
|
||||||
|
self.status = BusyStatus.busy()
|
||||||
|
let version = PhpEnvironments.shared.currentInstall!.version.short
|
||||||
|
self.manager = BrewExtensionsObservable(phpVersion: version)
|
||||||
|
self.status.busy = false
|
||||||
|
}
|
||||||
|
|
||||||
|
var filteredExtensions: [BrewPhpExtension] {
|
||||||
|
guard !searchText.isEmpty else {
|
||||||
|
return manager.extensions
|
||||||
|
}
|
||||||
|
return manager.extensions.filter { $0.name.contains(searchText) }
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
header.padding(20)
|
||||||
|
|
||||||
|
HStack(spacing: 0) {
|
||||||
|
Text("phpextman.list.showing_count".localized("\(filteredExtensions.count)"))
|
||||||
|
.padding(10)
|
||||||
|
.font(.system(size: 12))
|
||||||
|
phpVersionPicker.disabled(self.status.busy)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: 35)
|
||||||
|
.background(Color.blue.opacity(0.3))
|
||||||
|
.padding(.bottom, 0)
|
||||||
|
|
||||||
|
BlockingOverlayView(
|
||||||
|
busy: self.status.busy,
|
||||||
|
title: self.status.title,
|
||||||
|
text: self.status.description
|
||||||
|
) {
|
||||||
|
List(Array(self.filteredExtensions.enumerated()), id: \.1.name) { (_, ext) in
|
||||||
|
listContent(for: ext)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
}
|
||||||
|
.edgesIgnoringSafeArea(.top)
|
||||||
|
.listStyle(PlainListStyle())
|
||||||
|
.searchable(text: $searchText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: 600, height: 600)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: View Variables
|
||||||
|
|
||||||
|
private var phpVersionPicker: some View {
|
||||||
|
Picker("",
|
||||||
|
selection: $manager.phpVersion) {
|
||||||
|
ForEach(PhpEnvironments.shared.availablePhpVersions, id: \.self) {
|
||||||
|
Text("PHP \($0)")
|
||||||
|
.tag($0)
|
||||||
|
.font(.system(size: 12))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.focusable(false)
|
||||||
|
.labelsHidden()
|
||||||
|
.pickerStyle(MenuPickerStyle())
|
||||||
|
.font(.system(size: 12))
|
||||||
|
.frame(width: 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var header: some View {
|
||||||
|
HStack(alignment: .center, spacing: 15) {
|
||||||
|
Image(systemName: "puzzlepiece.extension.fill")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 40, height: 40)
|
||||||
|
.foregroundColor(Color.blue)
|
||||||
|
.padding(12)
|
||||||
|
VStack(alignment: .leading, spacing: 5) {
|
||||||
|
Text("phpextman.description".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 12))
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
Text("phpextman.disclaimer".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 12))
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func dependency(named name: String) -> some View {
|
||||||
|
return Text(name)
|
||||||
|
.font(.system(size: 9))
|
||||||
|
.padding(.horizontal, 5)
|
||||||
|
.padding(.vertical, 1)
|
||||||
|
.background(Color.appPrimary)
|
||||||
|
.foregroundColor(Color.white)
|
||||||
|
.clipShape(Capsule())
|
||||||
|
.fixedSize(horizontal: true, vertical: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func extensionLabel(for ext: BrewPhpExtension) -> some View {
|
||||||
|
return Group {
|
||||||
|
if ext.isInstalled {
|
||||||
|
if let dependent = ext.firstDependent(in: self.manager.extensions) {
|
||||||
|
Text("phpextman.list.status.dependent".localized(dependent.name))
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
} else {
|
||||||
|
Text("phpextman.list.status.can_manage".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ext.hasAlternativeInstall {
|
||||||
|
Text("phpextman.list.status.external".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundStyle(.orange)
|
||||||
|
} else {
|
||||||
|
Text("phpextman.list.status.installable".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func listContent(for ext: BrewPhpExtension) -> some View {
|
||||||
|
HStack(alignment: .center, spacing: 7.0) {
|
||||||
|
VStack(alignment: .center, spacing: 0) {
|
||||||
|
HStack {
|
||||||
|
HStack {
|
||||||
|
Image(systemName: ext.isInstalled || ext.hasAlternativeInstall
|
||||||
|
? "puzzlepiece.extension.fill"
|
||||||
|
: "puzzlepiece.extension")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 24, height: 20)
|
||||||
|
.foregroundColor(ext.hasAlternativeInstall ? Color.gray : Color.blue)
|
||||||
|
}.frame(width: 36, height: 24)
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: 5) {
|
||||||
|
HStack {
|
||||||
|
Text(ext.name).bold()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ext.extensionDependencies.isEmpty {
|
||||||
|
HStack(spacing: 3) {
|
||||||
|
Text("phpextman.list.depends_on".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 10))
|
||||||
|
ForEach(ext.extensionDependencies, id: \.self) {
|
||||||
|
dependency(named: $0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionLabel(for: ext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
if ext.isInstalled {
|
||||||
|
Button("phpman.buttons.uninstall".localizedForSwiftUI, role: .destructive) {
|
||||||
|
self.confirmUninstall(ext)
|
||||||
|
}.disabled(ext.firstDependent(in: self.manager.extensions) != nil)
|
||||||
|
} else {
|
||||||
|
Button("phpman.buttons.install".localizedForSwiftUI) {
|
||||||
|
self.install(ext)
|
||||||
|
}.disabled(ext.hasAlternativeInstall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
PhpExtensionManagerView()
|
||||||
|
.frame(width: 600, height: 600)
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// PhpVersionManagerWindowController.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 13/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Cocoa
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
class PhpExtensionManagerWindowController: PMWindowController {
|
||||||
|
|
||||||
|
// MARK: - Window Identifier
|
||||||
|
|
||||||
|
var view: PhpExtensionManagerView!
|
||||||
|
|
||||||
|
override var windowName: String {
|
||||||
|
return "PhpExtensionManager"
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func create(delegate: NSWindowDelegate?) {
|
||||||
|
let windowController = Self()
|
||||||
|
|
||||||
|
windowController.window = NSWindow()
|
||||||
|
windowController.view = PhpExtensionManagerView()
|
||||||
|
|
||||||
|
guard let window = windowController.window else { return }
|
||||||
|
window.title = "phpextman.window.title".localized
|
||||||
|
window.styleMask = [.titled, .closable, .miniaturizable]
|
||||||
|
window.titlebarAppearsTransparent = false
|
||||||
|
window.delegate = delegate ?? windowController
|
||||||
|
window.contentView = NSHostingView(rootView: windowController.view)
|
||||||
|
window.setContentSize(NSSize(width: 600, height: 800))
|
||||||
|
|
||||||
|
App.shared.phpExtensionManagerWindowController = windowController
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func show(delegate: NSWindowDelegate? = nil) {
|
||||||
|
if App.shared.phpExtensionManagerWindowController == nil {
|
||||||
|
Self.create(delegate: delegate)
|
||||||
|
}
|
||||||
|
|
||||||
|
App.shared.phpExtensionManagerWindowController?.showWindow(self)
|
||||||
|
App.shared.phpExtensionManagerWindowController?.positionWindowInTopRightCorner()
|
||||||
|
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
|
||||||
|
App.shared.phpExtensionManagerWindowController?.window?.orderFrontRegardless()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// BrewFormula+UI.swift
|
// BrewPhpFormula+UI.swift
|
||||||
// PHP Monitor
|
// PHP Monitor
|
||||||
//
|
//
|
||||||
// Created by Nico Verbruggen on 02/05/2023.
|
// Created by Nico Verbruggen on 02/05/2023.
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
extension BrewFormula {
|
extension BrewPhpFormula {
|
||||||
var icon: String {
|
var icon: String {
|
||||||
if self.hasUpgrade {
|
if self.hasUpgrade {
|
||||||
return "arrow.up.square.fill"
|
return "arrow.up.square.fill"
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// BrewPhpFormula.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 13/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class BrewFormulaeObservable: ObservableObject {
|
||||||
|
@Published var phpVersions: [BrewPhpFormula] = []
|
||||||
|
|
||||||
|
var upgradeable: [BrewPhpFormula] {
|
||||||
|
return phpVersions.filter { formula in
|
||||||
|
formula.hasUpgrade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,61 +8,68 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class FakeBrewFormulaeHandler: HandlesBrewFormulae {
|
// swiftlint:disable function_body_length
|
||||||
// swiftlint:disable function_body_length
|
class FakeBrewFormulaeHandler: HandlesBrewPhpFormulae {
|
||||||
public func loadPhpVersions(loadOutdated: Bool) async -> [BrewFormula] {
|
public func loadPhpVersions(loadOutdated: Bool) async -> [BrewPhpFormula] {
|
||||||
return [
|
return [
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@9.9",
|
name: "php@9.9",
|
||||||
displayName: "PHP 9.9",
|
displayName: "PHP 9.9",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
upgradeVersion: "9.9.0",
|
upgradeVersion: "9.9.0",
|
||||||
prerelease: true
|
prerelease: true
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@8.3",
|
name: "php@8.4",
|
||||||
|
displayName: "PHP 8.4",
|
||||||
|
installedVersion: nil,
|
||||||
|
upgradeVersion: "8.4.0",
|
||||||
|
prerelease: true
|
||||||
|
),
|
||||||
|
BrewPhpFormula(
|
||||||
|
name: "php",
|
||||||
displayName: "PHP 8.3",
|
displayName: "PHP 8.3",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
upgradeVersion: "8.3.0",
|
upgradeVersion: "8.3.0",
|
||||||
prerelease: true
|
prerelease: true
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php",
|
name: "php@8.2",
|
||||||
displayName: "PHP 8.2",
|
displayName: "PHP 8.2",
|
||||||
installedVersion: "8.2.3",
|
installedVersion: "8.2.3",
|
||||||
upgradeVersion: "8.2.4"
|
upgradeVersion: "8.2.4"
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@8.1",
|
name: "php@8.1",
|
||||||
displayName: "PHP 8.1",
|
displayName: "PHP 8.1",
|
||||||
installedVersion: "8.1.17",
|
installedVersion: "8.1.17",
|
||||||
upgradeVersion: nil
|
upgradeVersion: nil
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@8.0",
|
name: "php@8.0",
|
||||||
displayName: "PHP 8.0",
|
displayName: "PHP 8.0",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
upgradeVersion: nil
|
upgradeVersion: nil
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@7.4",
|
name: "php@7.4",
|
||||||
displayName: "PHP 7.4",
|
displayName: "PHP 7.4",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
upgradeVersion: nil
|
upgradeVersion: nil
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@7.3",
|
name: "php@7.3",
|
||||||
displayName: "PHP 7.3",
|
displayName: "PHP 7.3",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
upgradeVersion: nil
|
upgradeVersion: nil
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@7.2",
|
name: "php@7.2",
|
||||||
displayName: "PHP 7.2",
|
displayName: "PHP 7.2",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
upgradeVersion: nil
|
upgradeVersion: nil
|
||||||
),
|
),
|
||||||
BrewFormula(
|
BrewPhpFormula(
|
||||||
name: "php@7.1",
|
name: "php@7.1",
|
||||||
displayName: "PHP 7.1",
|
displayName: "PHP 7.1",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
@@ -71,3 +78,4 @@ class FakeBrewFormulaeHandler: HandlesBrewFormulae {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// swiftlint:enable function_body_length
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
//
|
||||||
|
// PhpVersionManagerView+Interactivity.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 07/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
extension PhpVersionManagerView {
|
||||||
|
public func runCommand(_ command: ModifyPhpVersionCommand) async {
|
||||||
|
if PhpEnvironments.shared.isBusy {
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.action_prevented_busy.title".localized,
|
||||||
|
description: "phpman.action_prevented_busy.desc".localized,
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
self.setBusyStatus(true)
|
||||||
|
try await command.execute { progress in
|
||||||
|
Task { @MainActor in
|
||||||
|
self.status.title = progress.title
|
||||||
|
self.status.description = progress.description
|
||||||
|
self.status.busy = progress.value != 1
|
||||||
|
|
||||||
|
// Whenever a key step is finished, refresh the PHP versions
|
||||||
|
if progress.value == 1 {
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Finally, after completing the command, also refresh PHP versions
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
// and mark the app as no longer busy
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
} catch let error {
|
||||||
|
let error = error as! BrewCommandError
|
||||||
|
let messages = error.log.suffix(2).joined(separator: "\n")
|
||||||
|
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.failures.install.title".localized,
|
||||||
|
description: "phpman.failures.install.desc".localized(messages),
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func repairAll() async {
|
||||||
|
await self.runCommand(ModifyPhpVersionCommand(
|
||||||
|
title: "phpman.operations.repairing".localized,
|
||||||
|
upgrading: [],
|
||||||
|
installing: []
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func upgradeAll(_ formulae: [BrewPhpFormula]) async {
|
||||||
|
await self.runCommand(ModifyPhpVersionCommand(
|
||||||
|
title: "phpman.operations.updating".localized,
|
||||||
|
upgrading: formulae,
|
||||||
|
installing: []
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func install(_ formula: BrewPhpFormula) async {
|
||||||
|
await self.runCommand(ModifyPhpVersionCommand(
|
||||||
|
title: "phpman.operations.installing".localized(formula.displayName),
|
||||||
|
upgrading: [],
|
||||||
|
installing: [formula]
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func confirmUninstall(_ formula: BrewPhpFormula) async {
|
||||||
|
// Disallow removal of the currently active versipn
|
||||||
|
if formula.installedVersion == PhpEnvironments.shared.currentInstall?.version.text {
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.uninstall_prevented.title".localized,
|
||||||
|
description: "phpman.uninstall_prevented.desc".localized,
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Alert.confirm(
|
||||||
|
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
||||||
|
messageText: "phpman.warnings.removal.title".localized(formula.displayName),
|
||||||
|
informativeText: "phpman.warnings.removal.desc".localized(formula.displayName),
|
||||||
|
buttonTitle: "phpman.warnings.removal.button".localized,
|
||||||
|
buttonIsDestructive: true,
|
||||||
|
secondButtonTitle: "generic.cancel".localized,
|
||||||
|
style: .warning,
|
||||||
|
onFirstButtonPressed: {
|
||||||
|
Task { await self.uninstall(formula) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func uninstall(_ formula: BrewPhpFormula) async {
|
||||||
|
let command = RemovePhpVersionCommand(formula: formula.name)
|
||||||
|
|
||||||
|
do {
|
||||||
|
self.setBusyStatus(true)
|
||||||
|
try await command.execute { progress in
|
||||||
|
Task { @MainActor in
|
||||||
|
self.status.title = progress.title
|
||||||
|
self.status.description = progress.description
|
||||||
|
self.status.busy = progress.value != 1
|
||||||
|
|
||||||
|
if progress.value == 1 {
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.failures.uninstall.title".localized,
|
||||||
|
description: "phpman.failures.uninstall.desc".localized(
|
||||||
|
"brew uninstall \(formula.name) --force"
|
||||||
|
),
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setBusyStatus(_ busy: Bool) {
|
||||||
|
Task { @MainActor in
|
||||||
|
PhpEnvironments.shared.isBusy = busy
|
||||||
|
self.status.busy = busy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func presentErrorAlert(
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
button: String,
|
||||||
|
style: NSAlert.Style = .critical
|
||||||
|
) {
|
||||||
|
Alert.confirm(
|
||||||
|
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
||||||
|
messageText: title,
|
||||||
|
informativeText: description,
|
||||||
|
buttonTitle: button,
|
||||||
|
secondButtonTitle: "",
|
||||||
|
style: style,
|
||||||
|
onFirstButtonPressed: {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasUpdates: Bool {
|
||||||
|
return self.formulae.phpVersions.contains { formula in
|
||||||
|
return formula.hasUpgrade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,37 +9,38 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
// swiftlint:disable type_body_length
|
|
||||||
struct PhpVersionManagerView: View {
|
struct PhpVersionManagerView: View {
|
||||||
@ObservedObject var formulae: BrewFormulaeObservable
|
@ObservedObject var formulae: BrewFormulaeObservable
|
||||||
@ObservedObject var status: PhpFormulaeStatus
|
@ObservedObject var status: BusyStatus
|
||||||
var handler: HandlesBrewFormulae
|
var handler: HandlesBrewPhpFormulae
|
||||||
|
|
||||||
init(
|
init(
|
||||||
formulae: BrewFormulaeObservable,
|
formulae: BrewFormulaeObservable,
|
||||||
handler: HandlesBrewFormulae
|
handler: HandlesBrewPhpFormulae
|
||||||
) {
|
) {
|
||||||
self.formulae = formulae
|
self.formulae = formulae
|
||||||
self.handler = handler
|
self.handler = handler
|
||||||
|
|
||||||
self.status = PhpFormulaeStatus(
|
self.status = BusyStatus(
|
||||||
busy: true,
|
busy: true,
|
||||||
title: "phpman.busy.title".localized,
|
title: "phpman.busy.title".localized,
|
||||||
description: "phpman.busy.description.outdated".localized
|
description: "phpman.busy.description.outdated".localized
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Task { [self] in
|
||||||
if handler is FakeBrewFormulaeHandler {
|
if handler is FakeBrewFormulaeHandler {
|
||||||
Task { [self] in
|
await self.fakeInitialLoad()
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
|
||||||
self.status.busy = false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Task { [self] in
|
|
||||||
await self.initialLoad()
|
await self.initialLoad()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func fakeInitialLoad() async {
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
self.status.busy = false
|
||||||
|
}
|
||||||
|
|
||||||
private func initialLoad() async {
|
private func initialLoad() async {
|
||||||
guard let version = Brew.shared.version else {
|
guard let version = Brew.shared.version else {
|
||||||
return
|
return
|
||||||
@@ -47,6 +48,7 @@ struct PhpVersionManagerView: View {
|
|||||||
|
|
||||||
await delay(seconds: 1)
|
await delay(seconds: 1)
|
||||||
|
|
||||||
|
// PHP formulae may not be installable with older Homebrew version
|
||||||
if version.major != 4 {
|
if version.major != 4 {
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
self.presentErrorAlert(
|
self.presentErrorAlert(
|
||||||
@@ -58,6 +60,16 @@ struct PhpVersionManagerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PHP formulae may be out of date past the cutoff date
|
||||||
|
if Date.fromString(Constants.PhpFormulaeCutoffDate)! < Date.now {
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.warnings.outdated.title".localized,
|
||||||
|
description: "phpman.warnings.outdated.desc".localized(version.text),
|
||||||
|
button: "generic.ok".localized,
|
||||||
|
style: .warning
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
await PhpEnvironments.detectPhpVersions()
|
await PhpEnvironments.detectPhpVersions()
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: true)
|
await self.handler.refreshPhpVersions(loadOutdated: true)
|
||||||
@@ -70,7 +82,9 @@ struct PhpVersionManagerView: View {
|
|||||||
self.status.title = "phpman.busy.title".localized
|
self.status.title = "phpman.busy.title".localized
|
||||||
self.status.description = "phpman.busy.description.outdated".localized
|
self.status.description = "phpman.busy.description.outdated".localized
|
||||||
}
|
}
|
||||||
|
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: true)
|
await self.handler.refreshPhpVersions(loadOutdated: true)
|
||||||
|
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
self.status.busy = false
|
self.status.busy = false
|
||||||
}
|
}
|
||||||
@@ -78,6 +92,54 @@ struct PhpVersionManagerView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
|
header.padding(10)
|
||||||
|
|
||||||
|
if self.hasUpdates {
|
||||||
|
hasUpdatesView
|
||||||
|
} else {
|
||||||
|
noUpdatesView
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockingOverlayView(
|
||||||
|
busy: self.status.busy,
|
||||||
|
title: self.status.title,
|
||||||
|
text: self.status.description
|
||||||
|
) {
|
||||||
|
if #available(macOS 13, *) {
|
||||||
|
List(Array(formulae.phpVersions.enumerated()), id: \.1.name) { (index, formula) in
|
||||||
|
listContent(for: formula)
|
||||||
|
.listRowBackground(
|
||||||
|
index % 2 == 0
|
||||||
|
? Color.gray.opacity(0)
|
||||||
|
: Color.gray.opacity(0.08)
|
||||||
|
)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
.listRowSeparator(.hidden)
|
||||||
|
}
|
||||||
|
.edgesIgnoringSafeArea(.top)
|
||||||
|
.listStyle(PlainListStyle())
|
||||||
|
} else {
|
||||||
|
List(Array(formulae.phpVersions.enumerated()), id: \.1.name) { (index, formula) in
|
||||||
|
listContent(for: formula)
|
||||||
|
.listRowBackground(
|
||||||
|
index % 2 == 0
|
||||||
|
? Color.gray.opacity(0)
|
||||||
|
: Color.gray.opacity(0.08)
|
||||||
|
)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
}
|
||||||
|
.edgesIgnoringSafeArea(.top)
|
||||||
|
.listStyle(PlainListStyle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.frame(width: 600, height: 600)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: View Variables
|
||||||
|
|
||||||
|
private var header: some View {
|
||||||
HStack(alignment: .center, spacing: 15) {
|
HStack(alignment: .center, spacing: 15) {
|
||||||
Image(systemName: "arrow.down.to.line.circle.fill")
|
Image(systemName: "arrow.down.to.line.circle.fill")
|
||||||
.resizable()
|
.resizable()
|
||||||
@@ -94,9 +156,10 @@ struct PhpVersionManagerView: View {
|
|||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(10)
|
}
|
||||||
|
|
||||||
if self.hasUpdates {
|
private var hasUpdatesView: some View {
|
||||||
|
Group {
|
||||||
Divider()
|
Divider()
|
||||||
HStack(alignment: .center, spacing: 15) {
|
HStack(alignment: .center, spacing: 15) {
|
||||||
Text("phpman.has_updates.description".localizedForSwiftUI)
|
Text("phpman.has_updates.description".localizedForSwiftUI)
|
||||||
@@ -111,7 +174,11 @@ struct PhpVersionManagerView: View {
|
|||||||
.disabled(self.status.busy)
|
.disabled(self.status.busy)
|
||||||
}
|
}
|
||||||
.padding(10)
|
.padding(10)
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var noUpdatesView: some View {
|
||||||
|
Group {
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
HStack(alignment: .center, spacing: 15) {
|
HStack(alignment: .center, spacing: 15) {
|
||||||
@@ -131,21 +198,9 @@ struct PhpVersionManagerView: View {
|
|||||||
}
|
}
|
||||||
.padding(10)
|
.padding(10)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BlockingOverlayView(busy: self.status.busy, title: self.status.title, text: self.status.description) {
|
private var prereleaseBadge: some View {
|
||||||
List(Array(formulae.phpVersions.enumerated()), id: \.1.name) { (index, formula) in
|
|
||||||
HStack(alignment: .center, spacing: 7.0) {
|
|
||||||
Image(systemName: formula.icon)
|
|
||||||
.resizable()
|
|
||||||
.aspectRatio(contentMode: .fit)
|
|
||||||
.frame(width: 16, height: 16)
|
|
||||||
.foregroundColor(formula.iconColor)
|
|
||||||
.padding(.horizontal, 5)
|
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
|
||||||
HStack {
|
|
||||||
Text(formula.displayName).bold()
|
|
||||||
|
|
||||||
if formula.prerelease {
|
|
||||||
Text("phpman.version.prerelease".localized.uppercased())
|
Text("phpman.version.prerelease".localized.uppercased())
|
||||||
.font(.system(size: 9))
|
.font(.system(size: 9))
|
||||||
.padding(.horizontal, 5)
|
.padding(.horizontal, 5)
|
||||||
@@ -155,6 +210,45 @@ struct PhpVersionManagerView: View {
|
|||||||
.clipShape(Capsule())
|
.clipShape(Capsule())
|
||||||
.fixedSize(horizontal: true, vertical: true)
|
.fixedSize(horizontal: true, vertical: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: View Builders
|
||||||
|
|
||||||
|
private func listContent(for formula: BrewPhpFormula) -> some View {
|
||||||
|
HStack(alignment: .center, spacing: 7.0) {
|
||||||
|
formulaIcon(for: formula)
|
||||||
|
formulaDescription(for: formula)
|
||||||
|
formulaButtons(for: formula)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func formulaButtons(for formula: BrewPhpFormula) -> some View {
|
||||||
|
HStack {
|
||||||
|
if !formula.healthy {
|
||||||
|
Button("phpman.buttons.repair".localizedForSwiftUI, role: .destructive) {
|
||||||
|
Task { await self.repairAll() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if formula.isInstalled {
|
||||||
|
Button("phpman.buttons.uninstall".localizedForSwiftUI, role: .destructive) {
|
||||||
|
Task { await self.confirmUninstall(formula) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Button("phpman.buttons.install".localizedForSwiftUI) {
|
||||||
|
Task { await self.install(formula) }
|
||||||
|
}.disabled(formula.hasUpgradedFormulaAlias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func formulaDescription(for formula: BrewPhpFormula) -> some View {
|
||||||
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
HStack {
|
||||||
|
Text(formula.displayName).bold()
|
||||||
|
|
||||||
|
if formula.prerelease {
|
||||||
|
prereleaseBadge
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if formula.hasUpgradedFormulaAlias {
|
if formula.hasUpgradedFormulaAlias {
|
||||||
@@ -185,191 +279,21 @@ struct PhpVersionManagerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
if !formula.healthy {
|
|
||||||
Button("phpman.buttons.repair".localizedForSwiftUI, role: .destructive) {
|
|
||||||
Task { await self.repairAll() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if formula.isInstalled {
|
private func formulaIcon(for formula: BrewPhpFormula) -> some View {
|
||||||
Button("phpman.buttons.uninstall".localizedForSwiftUI, role: .destructive) {
|
Image(systemName: formula.icon)
|
||||||
Task { await self.confirmUninstall(formula) }
|
.resizable()
|
||||||
}
|
.aspectRatio(contentMode: .fit)
|
||||||
} else {
|
.frame(width: 16, height: 16)
|
||||||
Button("phpman.buttons.install".localizedForSwiftUI) {
|
.foregroundColor(formula.iconColor)
|
||||||
Task { await self.install(formula) }
|
.padding(.horizontal, 5)
|
||||||
}.disabled(formula.hasUpgradedFormulaAlias)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.listRowBackground(index % 2 == 0 ? Color.gray.opacity(0): Color.gray.opacity(0.08))
|
|
||||||
.padding(.vertical, 8)
|
|
||||||
.padding(.horizontal, 8)
|
|
||||||
}
|
|
||||||
.edgesIgnoringSafeArea(.top)
|
|
||||||
.listStyle(PlainListStyle())
|
|
||||||
}
|
|
||||||
}.frame(width: 600, height: 600)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func runCommand(_ command: InstallAndUpgradeCommand) async {
|
|
||||||
if PhpEnvironments.shared.isBusy {
|
|
||||||
self.presentErrorAlert(
|
|
||||||
title: "phpman.action_prevented_busy.title".localized,
|
|
||||||
description: "phpman.action_prevented_busy.desc".localized,
|
|
||||||
button: "generic.ok".localized
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
self.setBusyStatus(true)
|
|
||||||
try await command.execute { progress in
|
|
||||||
Task { @MainActor in
|
|
||||||
self.status.title = progress.title
|
|
||||||
self.status.description = progress.description
|
|
||||||
self.status.busy = progress.value != 1
|
|
||||||
|
|
||||||
// Whenever a key step is finished, refresh the PHP versions
|
|
||||||
if progress.value == 1 {
|
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Finally, after completing the command, also refresh PHP versions
|
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
|
||||||
// and mark the app as no longer busy
|
|
||||||
self.setBusyStatus(false)
|
|
||||||
} catch let error {
|
|
||||||
let error = error as! BrewCommandError
|
|
||||||
let messages = error.log.suffix(2).joined(separator: "\n")
|
|
||||||
|
|
||||||
self.setBusyStatus(false)
|
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
|
||||||
|
|
||||||
self.presentErrorAlert(
|
|
||||||
title: "phpman.failures.install.title".localized,
|
|
||||||
description: "phpman.failures.install.desc".localized(messages),
|
|
||||||
button: "generic.ok".localized
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func repairAll() async {
|
|
||||||
await self.runCommand(InstallAndUpgradeCommand(
|
|
||||||
title: "phpman.operations.repairing".localized,
|
|
||||||
upgrading: [],
|
|
||||||
installing: []
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func upgradeAll(_ formulae: [BrewFormula]) async {
|
|
||||||
await self.runCommand(InstallAndUpgradeCommand(
|
|
||||||
title: "phpman.operations.updating".localized,
|
|
||||||
upgrading: formulae,
|
|
||||||
installing: []
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func install(_ formula: BrewFormula) async {
|
|
||||||
await self.runCommand(InstallAndUpgradeCommand(
|
|
||||||
title: "phpman.operations.installing".localized(formula.displayName),
|
|
||||||
upgrading: [],
|
|
||||||
installing: [formula]
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func confirmUninstall(_ formula: BrewFormula) async {
|
|
||||||
// Disallow removal of the currently active versipn
|
|
||||||
if formula.installedVersion == PhpEnvironments.shared.currentInstall?.version.text {
|
|
||||||
self.presentErrorAlert(
|
|
||||||
title: "phpman.uninstall_prevented.title".localized,
|
|
||||||
description: "phpman.uninstall_prevented.desc".localized,
|
|
||||||
button: "generic.ok".localized
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Alert.confirm(
|
|
||||||
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
|
||||||
messageText: "phpman.warnings.removal.title".localized(formula.displayName),
|
|
||||||
informativeText: "phpman.warnings.removal.desc".localized(formula.displayName),
|
|
||||||
buttonTitle: "phpman.warnings.removal.button".localized,
|
|
||||||
buttonIsDestructive: true,
|
|
||||||
secondButtonTitle: "generic.cancel".localized,
|
|
||||||
style: .warning,
|
|
||||||
onFirstButtonPressed: {
|
|
||||||
Task { await self.uninstall(formula) }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func uninstall(_ formula: BrewFormula) async {
|
|
||||||
let command = RemovePhpVersionCommand(formula: formula.name)
|
|
||||||
|
|
||||||
do {
|
|
||||||
self.setBusyStatus(true)
|
|
||||||
try await command.execute { progress in
|
|
||||||
Task { @MainActor in
|
|
||||||
self.status.title = progress.title
|
|
||||||
self.status.description = progress.description
|
|
||||||
self.status.busy = progress.value != 1
|
|
||||||
|
|
||||||
if progress.value == 1 {
|
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
|
||||||
self.setBusyStatus(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
self.setBusyStatus(false)
|
|
||||||
self.presentErrorAlert(
|
|
||||||
title: "phpman.failures.uninstall.title".localized,
|
|
||||||
description: "phpman.failures.uninstall.desc".localized(
|
|
||||||
"brew uninstall \(formula.name) --force"
|
|
||||||
),
|
|
||||||
button: "generic.ok".localized
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func setBusyStatus(_ busy: Bool) {
|
|
||||||
Task { @MainActor in
|
|
||||||
PhpEnvironments.shared.isBusy = busy
|
|
||||||
self.status.busy = busy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func presentErrorAlert(
|
|
||||||
title: String,
|
|
||||||
description: String,
|
|
||||||
button: String,
|
|
||||||
style: NSAlert.Style = .critical
|
|
||||||
) {
|
|
||||||
Alert.confirm(
|
|
||||||
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
|
||||||
messageText: title,
|
|
||||||
informativeText: description,
|
|
||||||
buttonTitle: button,
|
|
||||||
secondButtonTitle: "",
|
|
||||||
style: style,
|
|
||||||
onFirstButtonPressed: {}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasUpdates: Bool {
|
|
||||||
return self.formulae.phpVersions.contains { formula in
|
|
||||||
return formula.hasUpgrade
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// swiftlint:enable type_body_length
|
|
||||||
|
|
||||||
struct PhpVersionManagerView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
|
||||||
PhpVersionManagerView(
|
PhpVersionManagerView(
|
||||||
formulae: Brew.shared.formulae,
|
formulae: Brew.shared.formulae,
|
||||||
handler: FakeBrewFormulaeHandler()
|
handler: FakeBrewFormulaeHandler()
|
||||||
).frame(width: 600, height: 600)
|
).frame(width: 600, height: 600)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class PhpVersionManagerWindowController: PMWindowController {
|
|||||||
windowController.window = NSWindow()
|
windowController.window = NSWindow()
|
||||||
windowController.view = PhpVersionManagerView(
|
windowController.view = PhpVersionManagerView(
|
||||||
formulae: Brew.shared.formulae,
|
formulae: Brew.shared.formulae,
|
||||||
handler: BrewFormulaeHandler()
|
handler: BrewPhpFormulaeHandler()
|
||||||
)
|
)
|
||||||
|
|
||||||
guard let window = windowController.window else { return }
|
guard let window = windowController.window else { return }
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
"mi_no_php_linked" = "Keine PHP-Version verknüpft!";
|
"mi_no_php_linked" = "Keine PHP-Version verknüpft!";
|
||||||
"mi_fix_php_link" = "Automatisch beheben...";
|
"mi_fix_php_link" = "Automatisch beheben...";
|
||||||
"mi_no_php_linked_explain" = "Was ist das?";
|
"mi_no_php_linked_explain" = "Was ist das?";
|
||||||
"mi_php_version_manager" = "PHP Versionen Manager...";
|
|
||||||
|
"mi_php_version_manager" = "PHP-Installationen verwalten...";
|
||||||
|
"mi_php_ext_manager" = "PHP-Erweiterungen verwalten...";
|
||||||
|
"mi_php_config_manager" = "PHP-Konfigurationseditor...";
|
||||||
|
"mi_manage_limits" = "Limits verwalten...";
|
||||||
|
|
||||||
"mi_diagnostics" = "Diagnosen";
|
"mi_diagnostics" = "Diagnosen";
|
||||||
"mi_active_services" = "Aktive Dienste";
|
"mi_active_services" = "Aktive Dienste";
|
||||||
@@ -81,6 +85,27 @@
|
|||||||
"mi_xdebug_actions" = "Aktionen";
|
"mi_xdebug_actions" = "Aktionen";
|
||||||
"mi_xdebug_disable_all" = "Alle Modi deaktivieren";
|
"mi_xdebug_disable_all" = "Alle Modi deaktivieren";
|
||||||
|
|
||||||
|
// PHPEXTMAN
|
||||||
|
|
||||||
|
"phpextman.window.title" = "Erweiterungen";
|
||||||
|
"phpextman.description" = "**PHP Extension Manager** ermöglicht Ihnen die Verwaltung verschiedener PHP-Erweiterungen mit einem einfachen Klick auf die Schaltfläche. Da Homebrew verwendet wird, müssen Erweiterungen nicht on-the-fly mit `pecl` kompiliert werden.";
|
||||||
|
"phpextman.disclaimer" = "Bestimmte Erweiterungen erfordern möglicherweise die Installation anderer Abhängigkeiten, im Allgemeinen sollte jedoch die Installation von Erweiterungen viel schneller sein als die Installation von PHP-Versionen.";
|
||||||
|
|
||||||
|
"phpextman.warnings.removal.title" = "Die Erweiterung `%@` deinstallieren?";
|
||||||
|
"phpextman.warnings.removal.desc" = "Die Erweiterung und ihre einzigartige Konfigurationsdatei werden entfernt. Die Funktionalität der Erweiterung wird für diese PHP-Installation nicht mehr verfügbar sein. Sind Sie sicher?
|
||||||
|
|
||||||
|
(Wenn die Erweiterung mit einem nicht standardmäßigen Dateinamen aktiviert ist, wird sie nicht entfernt. Wenn Sie also nicht möchten, dass die .ini-Datei entfernt wird, benennen Sie sie am besten einfach um. In diesem Fall wird die Erweiterung nur als Teil des Bereinigungsprozesses deaktiviert.)";
|
||||||
|
"phpextman.warnings.removal.button" = "Deinstallieren";
|
||||||
|
|
||||||
|
"phpextman.list.showing_count" = "Aktuell werden %@ Erweiterungen für folgendes angezeigt:";
|
||||||
|
"phpextman.list.depends_on" = "Hängt ab von:";
|
||||||
|
|
||||||
|
"phpextman.list.status.external" = "Diese Erweiterung ist bereits über eine andere Quelle installiert und kann nicht verwaltet werden.";
|
||||||
|
"phpextman.list.status.installable" = "Diese Erweiterung kann installiert werden.";
|
||||||
|
"phpextman.list.status.dependent" = "Sie können diese nicht deinstallieren, bevor Sie %@ deinstallieren.";
|
||||||
|
"phpextman.list.status.can_manage" = "Diese Erweiterung ist installiert und kann von PHP Monitor verwaltet werden.";
|
||||||
|
|
||||||
|
|
||||||
// PHPMAN
|
// PHPMAN
|
||||||
|
|
||||||
"phpman.busy.title" = "Suche nach Aktualisierungen...";
|
"phpman.busy.title" = "Suche nach Aktualisierungen...";
|
||||||
@@ -213,6 +238,9 @@ Möglicherweise werden Sie während des Deinstallationsvorgangs nach Ihrem Passw
|
|||||||
"domain_list.columns.kind" = "Art";
|
"domain_list.columns.kind" = "Art";
|
||||||
"domain_list.columns.project_type" = "Projekttyp";
|
"domain_list.columns.project_type" = "Projekttyp";
|
||||||
|
|
||||||
|
"domain_list.extensions" = "Erweiterungen umschalten";
|
||||||
|
"domain_list.applies_to" = "Gilt für PHP %@";
|
||||||
|
|
||||||
// CHOOSE WHAT TO ADD
|
// CHOOSE WHAT TO ADD
|
||||||
|
|
||||||
"selection.title" = "Welche Art von Domain möchten Sie einrichten?";
|
"selection.title" = "Welche Art von Domain möchten Sie einrichten?";
|
||||||
@@ -789,3 +817,11 @@ Bitte beachten Sie, dass einige Funktionen (unten ausgegraut) derzeit nicht verf
|
|||||||
"onboarding.tour.feature_unavailable" = "Diese Funktion ist derzeit nicht verfügbar und erfordert die Installation von Laravel Valet.";
|
"onboarding.tour.feature_unavailable" = "Diese Funktion ist derzeit nicht verfügbar und erfordert die Installation von Laravel Valet.";
|
||||||
"onboarding.tour.once" = "Sie sehen die Willkommenstour nur einmal. Sie können die Willkommenstour später über das Symbol in der Menüleiste (im Menü unter Erste Hilfe & Dienste) erneut öffnen.";
|
"onboarding.tour.once" = "Sie sehen die Willkommenstour nur einmal. Sie können die Willkommenstour später über das Symbol in der Menüleiste (im Menü unter Erste Hilfe & Dienste) erneut öffnen.";
|
||||||
"onboarding.tour.close" = "Tour beenden";
|
"onboarding.tour.close" = "Tour beenden";
|
||||||
|
|
||||||
|
// LANGUAGE CHOICE
|
||||||
|
|
||||||
|
"prefs.language" = "Sprache:";
|
||||||
|
"prefs.language_options_desc" = "Wählen Sie eine andere Sprache für die Verwendung mit PHP Monitor. Um diese Änderung vollständig anzuwenden, müssen Sie die App neu starten.";
|
||||||
|
|
||||||
|
"alert.language_changed.title" = "Sie sollten PHP Monitor neu starten!";
|
||||||
|
"alert.language_changed.subtitle" = "Sie haben soeben die Anzeigesprache von PHP Monitor geändert. Das Menü wird sofort die korrekte Sprache verwenden, aber Sie müssen die App möglicherweise neu starten, damit alle Texte in der App Ihre neue Sprachwahl widerspiegeln.";
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
"mi_no_php_linked" = "No PHP version linked!";
|
"mi_no_php_linked" = "No PHP version linked!";
|
||||||
"mi_fix_php_link" = "Fix Automatically...";
|
"mi_fix_php_link" = "Fix Automatically...";
|
||||||
"mi_no_php_linked_explain" = "What's This?";
|
"mi_no_php_linked_explain" = "What's This?";
|
||||||
"mi_php_version_manager" = "PHP Version Manager...";
|
|
||||||
|
"mi_php_version_manager" = "Manage PHP Installations...";
|
||||||
|
"mi_php_ext_manager" = "Manage PHP Extensions...";
|
||||||
"mi_php_config_manager" = "PHP Configuration Editor...";
|
"mi_php_config_manager" = "PHP Configuration Editor...";
|
||||||
"mi_manage_limits" = "Manage Limits...";
|
"mi_manage_limits" = "Manage Limits...";
|
||||||
|
|
||||||
@@ -98,6 +100,26 @@
|
|||||||
"php_ini.upload_max_filesize.title" = "Upload Max Size";
|
"php_ini.upload_max_filesize.title" = "Upload Max Size";
|
||||||
"php_ini.upload_max_filesize.description" = "The maximum size of an uploaded file. POST Max Size must be larger than this value.";
|
"php_ini.upload_max_filesize.description" = "The maximum size of an uploaded file. POST Max Size must be larger than this value.";
|
||||||
|
|
||||||
|
// PHPEXTMAN
|
||||||
|
|
||||||
|
"phpextman.window.title" = "Extensions";
|
||||||
|
"phpextman.description" = "**PHP Extension Manager** lets you manage different PHP extensions with a simple click of the button. Because Homebrew is used, extensions won't need to be compiled on the fly using `pecl`.";
|
||||||
|
"phpextman.disclaimer" = "Certain extensions may require other dependencies to be installed, but generally speaking installing extensions should be much faster than installing PHP versions.";
|
||||||
|
|
||||||
|
"phpextman.warnings.removal.title" = "Uninstall the extension `%@`?";
|
||||||
|
"phpextman.warnings.removal.desc" = "The extension and its unique configuration file will be removed. The extension's functionality will no longer be available for this PHP installation. Are you sure?
|
||||||
|
|
||||||
|
(If the extension is enabled using a non-standard filename, it will not be removed. So if you don't want the .ini file to be removed, it's best to simply rename it to something else. In that case, the extension will only be disabled as part of the clean-up process.)";
|
||||||
|
"phpextman.warnings.removal.button" = "Uninstall";
|
||||||
|
|
||||||
|
"phpextman.list.showing_count" = "Currently showing %@ extensions for:";
|
||||||
|
"phpextman.list.depends_on" = "Depends on:";
|
||||||
|
|
||||||
|
"phpextman.list.status.external" = "This extension is already installed via another source, and cannot be managed.";
|
||||||
|
"phpextman.list.status.installable" = "This extension can be installed.";
|
||||||
|
"phpextman.list.status.dependent" = "You cannot uninstall this before uninstalling %@.";
|
||||||
|
"phpextman.list.status.can_manage" = "This extension is installed and can be managed by PHP Monitor.";
|
||||||
|
|
||||||
// PHPMAN
|
// PHPMAN
|
||||||
|
|
||||||
"phpman.busy.title" = "Checking for updates!";
|
"phpman.busy.title" = "Checking for updates!";
|
||||||
@@ -114,6 +136,15 @@
|
|||||||
"phpman.buttons.repair" = "Repair";
|
"phpman.buttons.repair" = "Repair";
|
||||||
"phpman.version.prerelease" = "Pre-release";
|
"phpman.version.prerelease" = "Pre-release";
|
||||||
|
|
||||||
|
"phpman.steps.installing" = "Installing %@";
|
||||||
|
"phpman.steps.removing" = "Removing %@";
|
||||||
|
"phpman.steps.reloading" = "Reloading PHP versions...";
|
||||||
|
"phpman.steps.preparing" = "PHP Monitor is preparing Homebrew...";
|
||||||
|
"phpman.steps.wait" = "Please wait...";
|
||||||
|
"phpman.steps.completed" = "Operation completed!";
|
||||||
|
"phpman.steps.success" = "The operation has succeeded.";
|
||||||
|
"phpman.steps.failure" = "The command failed to run correctly.";
|
||||||
|
|
||||||
"phpman.title" = "PHP Version Manager";
|
"phpman.title" = "PHP Version Manager";
|
||||||
"phpman.description" = "**PHP Version Manager** lets you install, upgrade and delete different PHP versions via Homebrew without needing to run the commands in the terminal yourself.";
|
"phpman.description" = "**PHP Version Manager** lets you install, upgrade and delete different PHP versions via Homebrew without needing to run the commands in the terminal yourself.";
|
||||||
"phpman.disclaimer" = "Please note that installing or upgrading PHP versions may cause other Homebrew packages to be upgraded as well. Most installation steps usually take some time, so please be patient while Homebrew does its job.";
|
"phpman.disclaimer" = "Please note that installing or upgrading PHP versions may cause other Homebrew packages to be upgraded as well. Most installation steps usually take some time, so please be patient while Homebrew does its job.";
|
||||||
@@ -123,6 +154,9 @@
|
|||||||
"phpman.has_updates.description" = "One or more updates are available. (Please note that PHP Monitor will always install or update PHP versions in bulk, so you will always upgrade all installations at once.)";
|
"phpman.has_updates.description" = "One or more updates are available. (Please note that PHP Monitor will always install or update PHP versions in bulk, so you will always upgrade all installations at once.)";
|
||||||
"phpman.has_updates.button" = "Upgrade All";
|
"phpman.has_updates.button" = "Upgrade All";
|
||||||
|
|
||||||
|
"phpman.warnings.outdated.title" = "This version of PHP Monitor is outdated";
|
||||||
|
"phpman.warnings.outdated.desc" = "It is highly likely that the Homebrew formulae have changed since this version of PHP Monitor was created. I highly recommend updating the application before using the version manager to install, remove or upgrade PHP versions.";
|
||||||
|
|
||||||
"phpman.warnings.unsupported.title" = "Your version of Homebrew may cause issues";
|
"phpman.warnings.unsupported.title" = "Your version of Homebrew may cause issues";
|
||||||
"phpman.warnings.unsupported.desc" = "No functionality is disabled, but some commands may not work as expected. You are currently running Homebrew %@.
|
"phpman.warnings.unsupported.desc" = "No functionality is disabled, but some commands may not work as expected. You are currently running Homebrew %@.
|
||||||
|
|
||||||
@@ -230,6 +264,9 @@ You may be asked for your password during the uninstallation process if file per
|
|||||||
"domain_list.columns.kind" = "Kind";
|
"domain_list.columns.kind" = "Kind";
|
||||||
"domain_list.columns.project_type" = "Project Type";
|
"domain_list.columns.project_type" = "Project Type";
|
||||||
|
|
||||||
|
"domain_list.extensions" = "Toggle Extensions";
|
||||||
|
"domain_list.applies_to" = "Applies to PHP %@";
|
||||||
|
|
||||||
// CHOOSE WHAT TO ADD
|
// CHOOSE WHAT TO ADD
|
||||||
|
|
||||||
"selection.title" = "What kind of domain would you like to set up?";
|
"selection.title" = "What kind of domain would you like to set up?";
|
||||||
@@ -806,3 +843,11 @@ Please note that some features (greyed out below) are currently unavailable beca
|
|||||||
"onboarding.tour.feature_unavailable" = "This feature is currently unavailable and requires Laravel Valet to be installed.";
|
"onboarding.tour.feature_unavailable" = "This feature is currently unavailable and requires Laravel Valet to be installed.";
|
||||||
"onboarding.tour.once" = "You will only see the Welcome Tour once. You can re-open the Welcome Tour later via the menu bar icon (available in the menu, under First Aid & Services).";
|
"onboarding.tour.once" = "You will only see the Welcome Tour once. You can re-open the Welcome Tour later via the menu bar icon (available in the menu, under First Aid & Services).";
|
||||||
"onboarding.tour.close" = "Close Tour";
|
"onboarding.tour.close" = "Close Tour";
|
||||||
|
|
||||||
|
// LANGUAGE CHOICE
|
||||||
|
|
||||||
|
"prefs.language" = "Language:";
|
||||||
|
"prefs.language_options_desc" = "Choose a different language to use with PHP Monitor. To fully apply this change, you must restart the app.";
|
||||||
|
|
||||||
|
"alert.language_changed.title" = "You must restart PHP Monitor!";
|
||||||
|
"alert.language_changed.subtitle" = "You just changed the display language of PHP Monitor. The menu will immediately use the correct language, but you may need to restart the app for all text throughout the app to reflect your new language choice.";
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
"mi_no_php_linked" = "Aucune version de PHP n'est liée !";
|
"mi_no_php_linked" = "Aucune version de PHP n'est liée !";
|
||||||
"mi_fix_php_link" = "Réparer Automatiquement...";
|
"mi_fix_php_link" = "Réparer Automatiquement...";
|
||||||
"mi_no_php_linked_explain" = "Qu'est-ce que c'est ?";
|
"mi_no_php_linked_explain" = "Qu'est-ce que c'est ?";
|
||||||
"mi_php_version_manager" = "Gestionnaire de Versions PHP...";
|
|
||||||
|
"mi_php_version_manager" = "Gérer les Installations PHP...";
|
||||||
|
"mi_php_ext_manager" = "Gérer les Extensions PHP...";
|
||||||
"mi_php_config_manager" = "Éditeur de Configuration PHP...";
|
"mi_php_config_manager" = "Éditeur de Configuration PHP...";
|
||||||
"mi_manage_limits" = "Gérer les Limites...";
|
"mi_manage_limits" = "Gérer les Limites...";
|
||||||
|
|
||||||
@@ -98,6 +100,26 @@
|
|||||||
"php_ini.upload_max_filesize.title" = "Taille maximale de téléchargement montant";
|
"php_ini.upload_max_filesize.title" = "Taille maximale de téléchargement montant";
|
||||||
"php_ini.upload_max_filesize.description" = "Taille maximale d'un téléchargement montant. La taille maximale POST doit être supérieure à cette valeur.";
|
"php_ini.upload_max_filesize.description" = "Taille maximale d'un téléchargement montant. La taille maximale POST doit être supérieure à cette valeur.";
|
||||||
|
|
||||||
|
// PHPEXTMAN
|
||||||
|
|
||||||
|
"phpextman.window.title" = "Extensions";
|
||||||
|
"phpextman.description" = "**PHP Extension Manager** vous permet de gérer différentes extensions PHP d'un simple clic sur le bouton. Comme Homebrew est utilisé, les extensions n'ont pas besoin d'être compilées à la volée avec `pecl`.";
|
||||||
|
"phpextman.disclaimer" = "Certaines extensions peuvent nécessiter l'installation d'autres dépendances, mais en général, l'installation des extensions devrait être beaucoup plus rapide que l'installation des versions de PHP.";
|
||||||
|
|
||||||
|
"phpextman.warnings.removal.title" = "Désinstaller l'extension `%@`?";
|
||||||
|
"phpextman.warnings.removal.desc" = "L'extension et son fichier de configuration unique seront supprimés. La fonctionnalité de l'extension ne sera plus disponible pour cette installation PHP. Êtes-vous sûr?
|
||||||
|
|
||||||
|
(Si l'extension est activée à l'aide d'un nom de fichier non standard, elle ne sera pas supprimée. Donc, si vous ne voulez pas que le fichier .ini soit supprimé, il est préférable de simplement le renommer. Dans ce cas, l'extension ne sera désactivée que dans le cadre du processus de nettoyage.)";
|
||||||
|
"phpextman.warnings.removal.button" = "Désinstaller";
|
||||||
|
|
||||||
|
"phpextman.list.showing_count" = "Affiche actuellement %@ extensions pour:";
|
||||||
|
"phpextman.list.depends_on" = "Dépend de:";
|
||||||
|
|
||||||
|
"phpextman.list.status.external" = "Cette extension est déjà installée via une autre source et ne peut pas être gérée.";
|
||||||
|
"phpextman.list.status.installable" = "Cette extension peut être installée.";
|
||||||
|
"phpextman.list.status.dependent" = "Vous ne pouvez pas désinstaller ceci avant de désinstaller %@.";
|
||||||
|
"phpextman.list.status.can_manage" = "Cette extension est installée et peut être gérée par PHP Monitor.";
|
||||||
|
|
||||||
// PHPMAN
|
// PHPMAN
|
||||||
|
|
||||||
"phpman.busy.title" = "Vérification des mises à jour en cours !";
|
"phpman.busy.title" = "Vérification des mises à jour en cours !";
|
||||||
@@ -230,6 +252,9 @@ Il se peut que vous deviez saisir votre mot de passe pendant le processus de dé
|
|||||||
"domain_list.columns.kind" = "Sorte";
|
"domain_list.columns.kind" = "Sorte";
|
||||||
"domain_list.columns.project_type" = "Type de Projet";
|
"domain_list.columns.project_type" = "Type de Projet";
|
||||||
|
|
||||||
|
"domain_list.extensions" = "Activer/désactiver les extensions";
|
||||||
|
"domain_list.applies_to" = "S'applique à PHP %@";
|
||||||
|
|
||||||
// CHOOSE WHAT TO ADD
|
// CHOOSE WHAT TO ADD
|
||||||
|
|
||||||
"selection.title" = "Quel type de domaine souhaitez-vous configurer ?";
|
"selection.title" = "Quel type de domaine souhaitez-vous configurer ?";
|
||||||
@@ -803,3 +828,11 @@ Veuillez noter que certaines fonctionnalités (grisées ci-dessous) sont actuell
|
|||||||
"onboarding.tour.feature_unavailable" = "Cette fonctionnalité n'est actuellement pas disponible et nécessite l'installation de Laravel Valet.";
|
"onboarding.tour.feature_unavailable" = "Cette fonctionnalité n'est actuellement pas disponible et nécessite l'installation de Laravel Valet.";
|
||||||
"onboarding.tour.once" = "Vous ne verrez la visite de bienvenue qu'une seule fois. Vous pouvez rouvrir la visite de bienvenue ultérieurement via l'icône de la barre de menu (disponible dans le menu, sous Premiers Secours et Services).";
|
"onboarding.tour.once" = "Vous ne verrez la visite de bienvenue qu'une seule fois. Vous pouvez rouvrir la visite de bienvenue ultérieurement via l'icône de la barre de menu (disponible dans le menu, sous Premiers Secours et Services).";
|
||||||
"onboarding.tour.close" = "Fermer la Visite d'Accueil";
|
"onboarding.tour.close" = "Fermer la Visite d'Accueil";
|
||||||
|
|
||||||
|
// LANGUAGE CHOICE
|
||||||
|
|
||||||
|
"prefs.language" = "Langue :";
|
||||||
|
"prefs.language_options_desc" = "Choisissez une autre langue à utiliser avec PHP Monitor. Pour appliquer pleinement ce changement, vous devez redémarrer l'application.";
|
||||||
|
|
||||||
|
"alert.language_changed.title" = "Vous devriez redémarrer PHP Monitor !";
|
||||||
|
"alert.language_changed.subtitle" = "Vous venez de changer la langue d'affichage de PHP Monitor. Le menu utilisera immédiatement la bonne langue, mais vous devrez peut-être redémarrer l'application pour que tout le texte dans l'application reflète votre nouveau choix de langue.";
|
||||||
|
|||||||
@@ -13,7 +13,11 @@
|
|||||||
"mi_no_php_linked" = "Geen PHP versie gelinkt!";
|
"mi_no_php_linked" = "Geen PHP versie gelinkt!";
|
||||||
"mi_fix_php_link" = "Automatisch oplossen...";
|
"mi_fix_php_link" = "Automatisch oplossen...";
|
||||||
"mi_no_php_linked_explain" = "What is dit?";
|
"mi_no_php_linked_explain" = "What is dit?";
|
||||||
"mi_php_version_manager" = "PHP versies beheren...";
|
|
||||||
|
"mi_php_version_manager" = "Beheer PHP Installaties...";
|
||||||
|
"mi_php_ext_manager" = "Beheer PHP Extensies...";
|
||||||
|
"mi_php_config_manager" = "PHP Configuratie Editor...";
|
||||||
|
"mi_manage_limits" = "Beheer Limieten...";
|
||||||
|
|
||||||
"mi_diagnostics" = "Diagnostische informatie";
|
"mi_diagnostics" = "Diagnostische informatie";
|
||||||
"mi_active_services" = "Actieve services";
|
"mi_active_services" = "Actieve services";
|
||||||
@@ -82,6 +86,26 @@
|
|||||||
"mi_xdebug_actions" = "Acties";
|
"mi_xdebug_actions" = "Acties";
|
||||||
"mi_xdebug_disable_all" = "Alle modes uitschakelen";
|
"mi_xdebug_disable_all" = "Alle modes uitschakelen";
|
||||||
|
|
||||||
|
// PHPEXTMAN
|
||||||
|
|
||||||
|
"phpextman.window.title" = "Extensies";
|
||||||
|
"phpextman.description" = "**PHP Extension Manager** stelt u in staat om verschillende PHP-extensies te beheren met een simpele klik op de knop. Omdat Homebrew wordt gebruikt, hoeven extensies niet ter plekke te worden gecompileerd met `pecl`.";
|
||||||
|
"phpextman.disclaimer" = "Bepaalde extensies kunnen vereisen dat andere afhankelijkheden worden geïnstalleerd, maar over het algemeen zou het installeren van extensies veel sneller moeten zijn dan het installeren van PHP-versies.";
|
||||||
|
|
||||||
|
"phpextman.warnings.removal.title" = "De extensie `%@` verwijderen?";
|
||||||
|
"phpextman.warnings.removal.desc" = "De extensie en het unieke configuratiebestand zullen worden verwijderd. De functionaliteit van de extensie zal niet meer beschikbaar zijn voor deze PHP-installatie. Weet u het zeker?
|
||||||
|
|
||||||
|
(Als de extensie is ingeschakeld met een afwijkende bestandsnaam, zal deze niet worden verwijderd. Dus als u niet wilt dat het .ini-bestand wordt verwijderd, kunt u het best een andere naam geven. In dat geval zal de extensie alleen worden uitgeschakeld als onderdeel van het opruimproces.)";
|
||||||
|
"phpextman.warnings.removal.button" = "Verwijderen";
|
||||||
|
|
||||||
|
"phpextman.list.showing_count" = "Momenteel worden %@ extensies weergegeven voor:";
|
||||||
|
"phpextman.list.depends_on" = "Is afhankelijk van:";
|
||||||
|
|
||||||
|
"phpextman.list.status.external" = "Deze extensie is al geïnstalleerd via een andere bron en kan niet worden beheerd.";
|
||||||
|
"phpextman.list.status.installable" = "Deze extensie kan worden geïnstalleerd.";
|
||||||
|
"phpextman.list.status.dependent" = "U kunt dit niet deïnstalleren voordat u %@ deïnstalleert.";
|
||||||
|
"phpextman.list.status.can_manage" = "Deze extensie is geïnstalleerd en kan worden beheerd door PHP Monitor.";
|
||||||
|
|
||||||
// PHPMAN
|
// PHPMAN
|
||||||
|
|
||||||
"phpman.busy.title" = "Bezig met zoeken naar updates!";
|
"phpman.busy.title" = "Bezig met zoeken naar updates!";
|
||||||
@@ -214,6 +238,9 @@ Tijdens het verwijderingsproces kan u worden gevraagd om uw wachtwoord indien de
|
|||||||
"domain_list.columns.kind" = "Type";
|
"domain_list.columns.kind" = "Type";
|
||||||
"domain_list.columns.project_type" = "Projecttype";
|
"domain_list.columns.project_type" = "Projecttype";
|
||||||
|
|
||||||
|
"domain_list.extensions" = "Extensies in-/uitschakelen";
|
||||||
|
"domain_list.applies_to" = "Van toepassing op PHP %@";
|
||||||
|
|
||||||
// CHOOSE WHAT TO ADD
|
// CHOOSE WHAT TO ADD
|
||||||
|
|
||||||
"selection.title" = "Wat voor soort domein wilt u instellen?";
|
"selection.title" = "Wat voor soort domein wilt u instellen?";
|
||||||
@@ -788,3 +815,11 @@ Houd er rekening mee dat sommige functies (hieronder grijs weergegeven) momentee
|
|||||||
"onboarding.tour.feature_unavailable" = "Deze functie is momenteel niet beschikbaar en vereist de installatie van Laravel Valet.";
|
"onboarding.tour.feature_unavailable" = "Deze functie is momenteel niet beschikbaar en vereist de installatie van Laravel Valet.";
|
||||||
"onboarding.tour.once" = "U zult de Welkomsttour slechts één keer zien. U kunt de Welkomsttour later opnieuw openen via het menubalkpictogram (beschikbaar in het menu onder First Aid & Services).";
|
"onboarding.tour.once" = "U zult de Welkomsttour slechts één keer zien. U kunt de Welkomsttour later opnieuw openen via het menubalkpictogram (beschikbaar in het menu onder First Aid & Services).";
|
||||||
"onboarding.tour.close" = "Tour sluiten";
|
"onboarding.tour.close" = "Tour sluiten";
|
||||||
|
|
||||||
|
// LANGUAGE CHOICE
|
||||||
|
|
||||||
|
"prefs.language" = "Taal:";
|
||||||
|
"prefs.language_options_desc" = "Kies een andere taal om te gebruiken met PHP Monitor. Om deze wijziging volledig toe te passen, moet u de app herstarten.";
|
||||||
|
|
||||||
|
"alert.language_changed.title" = "U moet PHP Monitor herstarten!";
|
||||||
|
"alert.language_changed.subtitle" = "U heeft zojuist de weergavetaal van PHP Monitor gewijzigd. Het menu zal onmiddellijk de juiste taal gebruiken, maar u moet mogelijk de app herstarten om overal de nieuwe taal te zien.";
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
"mi_no_php_linked" = "Nenhuma versão PHP associada!";
|
"mi_no_php_linked" = "Nenhuma versão PHP associada!";
|
||||||
"mi_fix_php_link" = "Corrigir automáticamente...";
|
"mi_fix_php_link" = "Corrigir automáticamente...";
|
||||||
"mi_no_php_linked_explain" = "O que é isto?";
|
"mi_no_php_linked_explain" = "O que é isto?";
|
||||||
"mi_php_version_manager" = "Gestor de versões PHP...";
|
|
||||||
|
"mi_php_version_manager" = "Gerenciar instalações PHP...";
|
||||||
|
"mi_php_ext_manager" = "Gerenciar extensões PHP...";
|
||||||
|
"mi_php_config_manager" = "Editor de configuração PHP...";
|
||||||
|
"mi_manage_limits" = "Gerenciar limites...";
|
||||||
|
|
||||||
"mi_diagnostics" = "Diagnóstico";
|
"mi_diagnostics" = "Diagnóstico";
|
||||||
"mi_active_services" = "Serviços ativos";
|
"mi_active_services" = "Serviços ativos";
|
||||||
@@ -81,6 +85,26 @@
|
|||||||
"mi_xdebug_actions" = "Ações";
|
"mi_xdebug_actions" = "Ações";
|
||||||
"mi_xdebug_disable_all" = "Desativar todos os modos";
|
"mi_xdebug_disable_all" = "Desativar todos os modos";
|
||||||
|
|
||||||
|
// PHPEXTMAN
|
||||||
|
|
||||||
|
"phpextman.window.title" = "Extensões";
|
||||||
|
"phpextman.description" = "**PHP Extension Manager** permite que você gerencie diferentes extensões PHP com um simples clique no botão. Como o Homebrew é usado, as extensões não precisam ser compiladas em tempo real usando `pecl`.";
|
||||||
|
"phpextman.disclaimer" = "Algumas extensões podem exigir que outras dependências sejam instaladas, mas, em geral, a instalação de extensões deve ser muito mais rápida do que a instalação de versões do PHP.";
|
||||||
|
|
||||||
|
"phpextman.warnings.removal.title" = "Desinstalar a extensão `%@`?";
|
||||||
|
"phpextman.warnings.removal.desc" = "A extensão e seu arquivo de configuração único serão removidos. A funcionalidade da extensão não estará mais disponível para esta instalação PHP. Você tem certeza?
|
||||||
|
|
||||||
|
(Se a extensão estiver ativada usando um nome de arquivo não padrão, ela não será removida. Então, se você não quer que o arquivo .ini seja removido, é melhor simplesmente renomeá-lo. Nesse caso, a extensão será apenas desativada como parte do processo de limpeza.)";
|
||||||
|
"phpextman.warnings.removal.button" = "Desinstalar";
|
||||||
|
|
||||||
|
"phpextman.list.showing_count" = "Atualmente mostrando %@ extensões para:";
|
||||||
|
"phpextman.list.depends_on" = "Depende de:";
|
||||||
|
|
||||||
|
"phpextman.list.status.external" = "Esta extensão já está instalada por outra fonte e não pode ser gerenciada.";
|
||||||
|
"phpextman.list.status.installable" = "Esta extensão pode ser instalada.";
|
||||||
|
"phpextman.list.status.dependent" = "Você não pode desinstalar isso antes de desinstalar %@.";
|
||||||
|
"phpextman.list.status.can_manage" = "Esta extensão está instalada e pode ser gerenciada pelo PHP Monitor.";
|
||||||
|
|
||||||
// PHPMAN
|
// PHPMAN
|
||||||
|
|
||||||
"phpman.busy.title" = "Procurando atualizações!";
|
"phpman.busy.title" = "Procurando atualizações!";
|
||||||
@@ -213,6 +237,10 @@ Poderá ser-lhe solicitada a sua palavra-passe durante o processo de desinstala
|
|||||||
"domain_list.columns.kind" = "Tipo";
|
"domain_list.columns.kind" = "Tipo";
|
||||||
"domain_list.columns.project_type" = "Tipo de projeto";
|
"domain_list.columns.project_type" = "Tipo de projeto";
|
||||||
|
|
||||||
|
"domain_list.extensions" = "Alternar Extensões";
|
||||||
|
"domain_list.applies_to" = "Aplica-se ao PHP %@";
|
||||||
|
|
||||||
|
|
||||||
// CHOOSE WHAT TO ADD
|
// CHOOSE WHAT TO ADD
|
||||||
|
|
||||||
"selection.title" = "Que tipo de domínio pretende configurar?";
|
"selection.title" = "Que tipo de domínio pretende configurar?";
|
||||||
@@ -785,3 +813,11 @@ Tenha em conta que algumas funcionalidades (esmaecidos abaixo) estão indisponí
|
|||||||
"onboarding.tour.feature_unavailable" = "Esta funcionalidade não está disponível de momento e requer a instalação do Laravel Valet.";
|
"onboarding.tour.feature_unavailable" = "Esta funcionalidade não está disponível de momento e requer a instalação do Laravel Valet.";
|
||||||
"onboarding.tour.once" = "Apenas irá ver este 'Boas-vindas' uma vez. Pode visualiza-lo mais tarde através da barra de menum em 'Primeiros Socorros e Serviços'.";
|
"onboarding.tour.once" = "Apenas irá ver este 'Boas-vindas' uma vez. Pode visualiza-lo mais tarde através da barra de menum em 'Primeiros Socorros e Serviços'.";
|
||||||
"onboarding.tour.close" = "Fechar";
|
"onboarding.tour.close" = "Fechar";
|
||||||
|
|
||||||
|
// LANGUAGE CHOICE
|
||||||
|
|
||||||
|
"prefs.language" = "Idioma:";
|
||||||
|
"prefs.language_options_desc" = "Escolha um idioma diferente para usar com o PHP Monitor. Para aplicar completamente esta mudança, deve reiniciar a aplicação.";
|
||||||
|
|
||||||
|
"alert.language_changed.title" = "Deve reiniciar o PHP Monitor!";
|
||||||
|
"alert.language_changed.subtitle" = "Acabou de mudar o idioma de exibição do PHP Monitor. O menu usará imediatamente a língua correta, mas pode ser necessário reiniciar a aplicação para que todo o texto na aplicação reflita a sua nova escolha de idioma.";
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
"mi_no_php_linked" = "Không có phiên bản PHP nào được liên kết!";
|
"mi_no_php_linked" = "Không có phiên bản PHP nào được liên kết!";
|
||||||
"mi_fix_php_link" = "Sửa tự động...";
|
"mi_fix_php_link" = "Sửa tự động...";
|
||||||
"mi_no_php_linked_explain" = "Cái này là gì?";
|
"mi_no_php_linked_explain" = "Cái này là gì?";
|
||||||
"mi_php_version_manager" = "Quản lý Phiên bản PHP...";
|
|
||||||
|
"mi_php_version_manager" = "Quản lý cài đặt PHP...";
|
||||||
|
"mi_php_ext_manager" = "Quản lý tiện ích mở rộng PHP...";
|
||||||
|
"mi_php_config_manager" = "Trình chỉnh sửa cấu hình PHP...";
|
||||||
|
"mi_manage_limits" = "Quản lý giới hạn...";
|
||||||
|
|
||||||
"mi_diagnostics" = "Chẩn đoán";
|
"mi_diagnostics" = "Chẩn đoán";
|
||||||
"mi_active_services" = "Dịch vụ hoạt động";
|
"mi_active_services" = "Dịch vụ hoạt động";
|
||||||
@@ -81,6 +85,26 @@
|
|||||||
"mi_xdebug_actions" = "Hành động";
|
"mi_xdebug_actions" = "Hành động";
|
||||||
"mi_xdebug_disable_all" = "Tắt Tất cả Chế độ";
|
"mi_xdebug_disable_all" = "Tắt Tất cả Chế độ";
|
||||||
|
|
||||||
|
// PHPEXTMAN
|
||||||
|
|
||||||
|
"phpextman.window.title" = "Tiện ích mở rộng";
|
||||||
|
"phpextman.description" = "**PHP Extension Manager** cho phép bạn quản lý các tiện ích mở rộng PHP khác nhau chỉ bằng một cú nhấp chuột đơn giản. Vì sử dụng Homebrew, các tiện ích mở rộng không cần phải được biên dịch trực tiếp bằng `pecl`.";
|
||||||
|
"phpextman.disclaimer" = "Một số tiện ích mở rộng có thể yêu cầu cài đặt các phụ thuộc khác, nhưng nói chung, việc cài đặt tiện ích mở rộng sẽ nhanh hơn nhiều so với việc cài đặt các phiên bản PHP.";
|
||||||
|
|
||||||
|
"phpextman.warnings.removal.title" = "Gỡ cài đặt tiện ích mở rộng `%@`?";
|
||||||
|
"phpextman.warnings.removal.desc" = "Tiện ích mở rộng và tệp cấu hình duy nhất của nó sẽ bị xóa. Chức năng của tiện ích mở rộng sẽ không còn sẵn có cho cài đặt PHP này. Bạn có chắc không?
|
||||||
|
|
||||||
|
(Nếu tiện ích mở rộng được kích hoạt bằng một tên tệp không chuẩn, nó sẽ không bị xóa. Vì vậy, nếu bạn không muốn tệp .ini bị xóa, tốt nhất là đơn giản hãy đổi tên nó. Trong trường hợp đó, tiện ích mở rộng chỉ sẽ bị vô hiệu hóa như một phần của quá trình dọn dẹp.)";
|
||||||
|
"phpextman.warnings.removal.button" = "Gỡ cài đặt";
|
||||||
|
|
||||||
|
"phpextman.list.showing_count" = "Hiện đang hiển thị %@ tiện ích mở rộng cho:";
|
||||||
|
"phpextman.list.depends_on" = "Phụ thuộc vào:";
|
||||||
|
|
||||||
|
"phpextman.list.status.external" = "Tiện ích mở rộng này đã được cài đặt thông qua một nguồn khác và không thể được quản lý.";
|
||||||
|
"phpextman.list.status.installable" = "Tiện ích mở rộng này có thể được cài đặt.";
|
||||||
|
"phpextman.list.status.dependent" = "Bạn không thể gỡ cài đặt điều này trước khi gỡ cài đặt %@.";
|
||||||
|
"phpextman.list.status.can_manage" = "Tiện ích mở rộng này đã được cài đặt và có thể được quản lý bởi PHP Monitor.";
|
||||||
|
|
||||||
// PHPMAN
|
// PHPMAN
|
||||||
|
|
||||||
"phpman.busy.title" = "Đang kiểm tra cập nhật!";
|
"phpman.busy.title" = "Đang kiểm tra cập nhật!";
|
||||||
@@ -293,6 +317,9 @@ Bạn có thể được yêu cầu nhập mật khẩu của mình trong quá t
|
|||||||
"domain_list.columns.kind" = "Loại";
|
"domain_list.columns.kind" = "Loại";
|
||||||
"domain_list.columns.project_type" = "Loại dự án";
|
"domain_list.columns.project_type" = "Loại dự án";
|
||||||
|
|
||||||
|
"domain_list.extensions" = "Bật/tắt Tiện ích mở rộng";
|
||||||
|
"domain_list.applies_to" = "Áp dụng cho PHP %@";
|
||||||
|
|
||||||
// DRIVERS
|
// DRIVERS
|
||||||
|
|
||||||
"driver.not_detected" = "Khác";
|
"driver.not_detected" = "Khác";
|
||||||
@@ -782,3 +809,11 @@ Vui lòng lưu ý rằng một số tính năng (xám bên dưới) hiện khôn
|
|||||||
"onboarding.tour.feature_unavailable" = "Tính năng này hiện không khả dụng và yêu cầu Laravel Valet được cài đặt.";
|
"onboarding.tour.feature_unavailable" = "Tính năng này hiện không khả dụng và yêu cầu Laravel Valet được cài đặt.";
|
||||||
"onboarding.tour.once" = "Bạn chỉ sẽ thấy Hướng Dẫn Chào Mừng một lần. Bạn có thể mở lại Hướng Dẫn Chào Mừng sau này qua biểu tượng thanh menu (có sẵn trong menu, ở dưới Cứu hộ và Các dịch vụ).";
|
"onboarding.tour.once" = "Bạn chỉ sẽ thấy Hướng Dẫn Chào Mừng một lần. Bạn có thể mở lại Hướng Dẫn Chào Mừng sau này qua biểu tượng thanh menu (có sẵn trong menu, ở dưới Cứu hộ và Các dịch vụ).";
|
||||||
"onboarding.tour.close" = "Đóng Tour";
|
"onboarding.tour.close" = "Đóng Tour";
|
||||||
|
|
||||||
|
// LANGUAGE CHOICE
|
||||||
|
|
||||||
|
"prefs.language" = "Ngôn ngữ:";
|
||||||
|
"prefs.language_options_desc" = "Chọn một ngôn ngữ khác để sử dụng với PHP Monitor. Để áp dụng hoàn toàn thay đổi này, bạn phải khởi động lại ứng dụng.";
|
||||||
|
|
||||||
|
"alert.language_changed.title" = "Bạn nên khởi động lại PHP Monitor!";
|
||||||
|
"alert.language_changed.subtitle" = "Bạn vừa thay đổi ngôn ngữ hiển thị của PHP Monitor. Menu sẽ ngay lập tức sử dụng ngôn ngữ đúng, nhưng bạn có thể cần phải khởi động lại ứng dụng để toàn bộ văn bản trong ứng dụng phản ánh sự lựa chọn ngôn ngữ mới của bạn.";
|
||||||
|
|||||||
@@ -181,9 +181,6 @@ class TestableConfigurations {
|
|||||||
"/opt/homebrew/bin/php -r echo ini_get('memory_limit');": "512M",
|
"/opt/homebrew/bin/php -r echo ini_get('memory_limit');": "512M",
|
||||||
"/opt/homebrew/bin/php -r echo ini_get('upload_max_filesize');": "512M",
|
"/opt/homebrew/bin/php -r echo ini_get('upload_max_filesize');": "512M",
|
||||||
"/opt/homebrew/bin/php -r echo ini_get('post_max_size');": "512M",
|
"/opt/homebrew/bin/php -r echo ini_get('post_max_size');": "512M",
|
||||||
"/opt/homebrew/opt/php@8.2/bin/php -v": "OK (no full output needed for testing)",
|
|
||||||
"/opt/homebrew/opt/php@8.1/bin/php -v": "OK (no full output needed for testing)",
|
|
||||||
"/opt/homebrew/opt/php@8.0/bin/php -v": "OK (no full output needed for testing)"
|
|
||||||
],
|
],
|
||||||
preferenceOverrides: [
|
preferenceOverrides: [
|
||||||
.automaticBackgroundUpdateCheck: false
|
.automaticBackgroundUpdateCheck: false
|
||||||
@@ -191,7 +188,8 @@ class TestableConfigurations {
|
|||||||
phpVersions: [
|
phpVersions: [
|
||||||
VersionNumber(major: 8, minor: 2, patch: 6),
|
VersionNumber(major: 8, minor: 2, patch: 6),
|
||||||
VersionNumber(major: 8, minor: 1, patch: 0),
|
VersionNumber(major: 8, minor: 1, patch: 0),
|
||||||
VersionNumber(major: 8, minor: 0, patch: 0)
|
VersionNumber(major: 8, minor: 0, patch: 0),
|
||||||
|
VersionNumber(major: 7, minor: 4, patch: 33)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,16 @@ final class MainMenuTest: UITestCase {
|
|||||||
app.mainMenuItem(withText: "mi_about".localized).click()
|
app.mainMenuItem(withText: "mi_about".localized).click()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final func test_can_open_config_editor() throws {
|
||||||
|
let app = launch(openMenu: true)
|
||||||
|
|
||||||
|
app.buttons["phpConfigButton"].click()
|
||||||
|
|
||||||
|
Thread.sleep(forTimeInterval: 0.5)
|
||||||
|
|
||||||
|
assertExists(app.staticTexts["confman.title".localized], 1)
|
||||||
|
}
|
||||||
|
|
||||||
final func test_can_open_settings() throws {
|
final func test_can_open_settings() throws {
|
||||||
let app = launch(openMenu: true)
|
let app = launch(openMenu: true)
|
||||||
app.mainMenuItem(withText: "mi_preferences".localized).click()
|
app.mainMenuItem(withText: "mi_preferences".localized).click()
|
||||||
|
|||||||
41
tests/unit/Parsers/ExtensionEnumeratorTest.swift
Normal file
41
tests/unit/Parsers/ExtensionEnumeratorTest.swift
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// ExtensionEnumeratorTest.swift
|
||||||
|
// Unit Tests
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 30/10/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class ExtensionEnumeratorTest: XCTestCase {
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
ActiveFileSystem.useTestable([
|
||||||
|
"\(Paths.tapPath)/shivammathur/homebrew-extensions/Formula/xdebug@8.1.rb": .fake(.text, "<test>"),
|
||||||
|
"\(Paths.tapPath)/shivammathur/homebrew-extensions/Formula/xdebug@8.2.rb": .fake(.text, "<test>"),
|
||||||
|
"\(Paths.tapPath)/shivammathur/homebrew-extensions/Formula/xdebug@8.3.rb": .fake(.text, "<test>"),
|
||||||
|
"\(Paths.tapPath)/shivammathur/homebrew-extensions/Formula/xdebug@8.4.rb": .fake(.text, "<test>"),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCanReadFormulae() throws {
|
||||||
|
let directory = "\(Paths.tapPath)/shivammathur/homebrew-extensions/Formula"
|
||||||
|
let files = try FileSystem.getShallowContentsOfDirectory(directory)
|
||||||
|
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(["xdebug@8.1.rb", "xdebug@8.2.rb", "xdebug@8.3.rb", "xdebug@8.4.rb"]),
|
||||||
|
Set(files)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCanParseFormulaeBasedOnSyntax() throws {
|
||||||
|
let formulae = BrewTapFormulae.from(tap: "shivammathur/homebrew-extensions")
|
||||||
|
|
||||||
|
XCTAssertEqual(formulae["8.1"], [BrewPhpExtension(path: "/", name: "xdebug", phpVersion: "8.1")])
|
||||||
|
XCTAssertEqual(formulae["8.2"], [BrewPhpExtension(path: "/", name: "xdebug", phpVersion: "8.2")])
|
||||||
|
XCTAssertEqual(formulae["8.3"], [BrewPhpExtension(path: "/", name: "xdebug", phpVersion: "8.3")])
|
||||||
|
XCTAssertEqual(formulae["8.4"], [BrewPhpExtension(path: "/", name: "xdebug", phpVersion: "8.4")])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,7 +17,15 @@ class HomebrewUpgradableTest: XCTestCase {
|
|||||||
func test_upgradable_php_versions_can_be_parsed() async throws {
|
func test_upgradable_php_versions_can_be_parsed() async throws {
|
||||||
ActiveShell.useTestable([
|
ActiveShell.useTestable([
|
||||||
"/opt/homebrew/bin/brew update >/dev/null && /opt/homebrew/bin/brew outdated --json --formulae"
|
"/opt/homebrew/bin/brew update >/dev/null && /opt/homebrew/bin/brew outdated --json --formulae"
|
||||||
: .instant(try! String(contentsOf: Self.outdatedFileUrl))
|
: .instant(try! String(contentsOf: Self.outdatedFileUrl)),
|
||||||
|
"/opt/homebrew/bin/php --ini | grep -E -o '(/[^ ]+\\.ini)'"
|
||||||
|
: .instant("/opt/homebrew/etc/php/8.2/conf.d/php-memory-limits.ini"),
|
||||||
|
"/opt/homebrew/opt/php@8.1.16/bin/php --ini | grep -E -o '(/[^ ]+\\.ini)'"
|
||||||
|
: .instant("/opt/homebrew/etc/php/8.1/conf.d/php-memory-limits.ini"),
|
||||||
|
"/opt/homebrew/opt/php@8.2.3/bin/php --ini | grep -E -o '(/[^ ]+\\.ini)'"
|
||||||
|
: .instant("/opt/homebrew/etc/php/8.2/conf.d/php-memory-limits.ini"),
|
||||||
|
"/opt/homebrew/opt/php@7.4.11/bin/php --ini | grep -E -o '(/[^ ]+\\.ini)'"
|
||||||
|
: .instant("/opt/homebrew/etc/php/7.4/conf.d/php-memory-limits.ini")
|
||||||
])
|
])
|
||||||
|
|
||||||
let env = PhpEnvironments.shared
|
let env = PhpEnvironments.shared
|
||||||
@@ -27,7 +35,7 @@ class HomebrewUpgradableTest: XCTestCase {
|
|||||||
"7.4": PhpInstallation("7.4.11")
|
"7.4": PhpInstallation("7.4.11")
|
||||||
]
|
]
|
||||||
|
|
||||||
let data = await BrewFormulaeHandler().loadPhpVersions(loadOutdated: true)
|
let data = await BrewPhpFormulaeHandler().loadPhpVersions(loadOutdated: true)
|
||||||
|
|
||||||
XCTAssertTrue(data.contains(where: { formula in
|
XCTAssertTrue(data.contains(where: { formula in
|
||||||
formula.installedVersion == "8.1.16" && formula.upgradeVersion == "8.1.17"
|
formula.installedVersion == "8.1.16" && formula.upgradeVersion == "8.1.17"
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ class RealShellTest: XCTestCase {
|
|||||||
XCTAssertTrue(output.out.contains("Copyright (c) The PHP Group"))
|
XCTAssertTrue(output.out.contains("Copyright (c) The PHP Group"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_system_shell_can_be_used_synchronously() {
|
||||||
|
XCTAssertTrue(Shell is RealShell)
|
||||||
|
|
||||||
|
let output = Shell.sync("php -v")
|
||||||
|
|
||||||
|
XCTAssertTrue(output.out.contains("Copyright (c) The PHP Group"))
|
||||||
|
}
|
||||||
|
|
||||||
func test_system_shell_has_path() {
|
func test_system_shell_has_path() {
|
||||||
let systemShell = Shell as! RealShell
|
let systemShell = Shell as! RealShell
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,35 @@ class TestableShellTest: XCTestCase {
|
|||||||
XCTAssertEqual("Hello world\nGoodbye world", output.out)
|
XCTAssertEqual("Hello world\nGoodbye world", output.out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_fake_shell_synchronous_output() {
|
||||||
|
let greeting = BatchFakeShellOutput(items: [
|
||||||
|
.instant("Hello world\n"),
|
||||||
|
.delayed(0.2, "Goodbye world")
|
||||||
|
])
|
||||||
|
|
||||||
|
let output = greeting.syncOutput()
|
||||||
|
|
||||||
|
XCTAssertEqual("Hello world\nGoodbye world", output.out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_fake_shell_usage() {
|
||||||
|
let expectedOutput = """
|
||||||
|
PHP 8.3.0 (cli) (built: Nov 21 2023 14:40:35) (NTS)
|
||||||
|
Copyright (c) The PHP Group
|
||||||
|
Zend Engine v4.3.0, Copyright (c) Zend Technologies
|
||||||
|
with Xdebug v3.2.2, Copyright (c) 2002-2023, by Derick Rethans
|
||||||
|
with Zend OPcache v8.3.0, Copyright (c), by Zend Technologies
|
||||||
|
"""
|
||||||
|
|
||||||
|
let shell = TestableShell(expectations: [
|
||||||
|
"php -v": .instant(expectedOutput),
|
||||||
|
"echo $PATH": .instant("/Users/user/bin:/opt/homebrew/bin")
|
||||||
|
])
|
||||||
|
|
||||||
|
XCTAssertEqual(expectedOutput, shell.sync("php -v").out)
|
||||||
|
XCTAssertEqual("/Users/user/bin:/opt/homebrew/bin", shell.sync("echo $PATH").out)
|
||||||
|
}
|
||||||
|
|
||||||
func test_fake_shell_has_path() {
|
func test_fake_shell_has_path() {
|
||||||
ActiveShell.useTestable([:])
|
ActiveShell.useTestable([:])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user