mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
21a1d6576e | |||
b08912ce11 | |||
7285d24ef3 | |||
ac60c66bb9 | |||
9a7575790a | |||
cd5cbccb04 | |||
20291bf034 | |||
2c40f433d3 | |||
5ac4817048 | |||
1216fe4974 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,4 +2,5 @@ phpmon.xcodeproj/project.xcworkspace
|
|||||||
phpmon.xcodeproj/xcuserdata
|
phpmon.xcodeproj/xcuserdata
|
||||||
PHP Monitor.xcodeproj/project.xcworkspace
|
PHP Monitor.xcodeproj/project.xcworkspace
|
||||||
PHP Monitor.xcodeproj/xcuserdata
|
PHP Monitor.xcodeproj/xcuserdata
|
||||||
|
phpmon-updater/PHP Monitor Self-Updater.app
|
||||||
.DS_Store
|
.DS_Store
|
@ -182,9 +182,6 @@
|
|||||||
C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
|
C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
|
||||||
C469E701294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
|
C469E701294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
|
||||||
C469E706294CFDF700A82AB2 /* DomainsListTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E702294CFDF700A82AB2 /* DomainsListTest.swift */; };
|
C469E706294CFDF700A82AB2 /* DomainsListTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E702294CFDF700A82AB2 /* DomainsListTest.swift */; };
|
||||||
C46E206D28299B3800D909D6 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
|
|
||||||
C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
|
|
||||||
C46E20702829D27F00D909D6 /* AppUpdaterCheckTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */; };
|
|
||||||
C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
|
C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
|
||||||
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
|
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
|
||||||
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
|
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
|
||||||
@ -324,7 +321,6 @@
|
|||||||
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
|
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
|
||||||
C471E84728F9BB650021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
C471E84728F9BB650021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
||||||
C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
|
C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
|
||||||
C471E84928F9BB650021E251 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
|
|
||||||
C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
|
C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
|
||||||
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||||
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
|
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
|
||||||
@ -414,7 +410,6 @@
|
|||||||
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
|
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
|
||||||
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
||||||
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
|
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
|
||||||
C471E8AC28F9BB8F0021E251 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
|
|
||||||
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
|
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
|
||||||
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||||
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
|
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
|
||||||
@ -511,6 +506,17 @@
|
|||||||
C48D6C70279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; };
|
C48D6C70279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; };
|
||||||
C48D6C71279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; };
|
C48D6C71279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; };
|
||||||
C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */; };
|
C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */; };
|
||||||
|
C491997729901DD6001F3A21 /* CaskFileParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997629901DD6001F3A21 /* CaskFileParserTest.swift */; };
|
||||||
|
C491997929901DE2001F3A21 /* phpmon-dev.rb in Resources */ = {isa = PBXBuildFile; fileRef = C491997829901DE2001F3A21 /* phpmon-dev.rb */; };
|
||||||
|
C491997B29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
|
||||||
|
C491997C29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
|
||||||
|
C491997D29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
|
||||||
|
C491997E29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
|
||||||
|
C491998029901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
|
||||||
|
C491998129901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
|
||||||
|
C491998229901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
|
||||||
|
C491998329901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
|
||||||
|
C491998A29902089001F3A21 /* PHP Monitor Self-Updater.app in Resources */ = {isa = PBXBuildFile; fileRef = C491998929902089001F3A21 /* PHP Monitor Self-Updater.app */; };
|
||||||
C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
|
C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
|
||||||
C4927F0C27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
|
C4927F0C27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
|
||||||
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4930849279F331F009C240B /* AddSiteVC.swift */; };
|
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4930849279F331F009C240B /* AddSiteVC.swift */; };
|
||||||
@ -833,8 +839,6 @@
|
|||||||
C464ADB1275A87CA003FCD53 /* DomainListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListCellProtocol.swift; sourceTree = "<group>"; };
|
C464ADB1275A87CA003FCD53 /* DomainListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListCellProtocol.swift; sourceTree = "<group>"; };
|
||||||
C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeValetProxy.swift; sourceTree = "<group>"; };
|
C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeValetProxy.swift; sourceTree = "<group>"; };
|
||||||
C469E702294CFDF700A82AB2 /* DomainsListTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainsListTest.swift; sourceTree = "<group>"; };
|
C469E702294CFDF700A82AB2 /* DomainsListTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainsListTest.swift; sourceTree = "<group>"; };
|
||||||
C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdateChecker.swift; sourceTree = "<group>"; };
|
|
||||||
C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppUpdaterCheckTest.swift; sourceTree = "<group>"; };
|
|
||||||
C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = "<group>"; };
|
C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = "<group>"; };
|
||||||
C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = "<group>"; };
|
C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = "<group>"; };
|
||||||
C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = "<group>"; };
|
C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = "<group>"; };
|
||||||
@ -858,6 +862,11 @@
|
|||||||
C48D0C9225CC804200CC7490 /* XibLoadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XibLoadable.swift; sourceTree = "<group>"; };
|
C48D0C9225CC804200CC7490 /* XibLoadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XibLoadable.swift; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
|
C491997629901DD6001F3A21 /* CaskFileParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaskFileParserTest.swift; sourceTree = "<group>"; };
|
||||||
|
C491997829901DE2001F3A21 /* phpmon-dev.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = "phpmon-dev.rb"; sourceTree = "<group>"; };
|
||||||
|
C491997A29901DF7001F3A21 /* CaskFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaskFile.swift; sourceTree = "<group>"; };
|
||||||
|
C491997F29901E0F001F3A21 /* AppUpdater.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppUpdater.swift; sourceTree = "<group>"; };
|
||||||
|
C491998929902089001F3A21 /* PHP Monitor Self-Updater.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = "PHP Monitor Self-Updater.app"; 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>"; };
|
||||||
@ -1140,6 +1149,7 @@
|
|||||||
C4F5FBCC28218C93001065C5 /* .swiftlint.yml */,
|
C4F5FBCC28218C93001065C5 /* .swiftlint.yml */,
|
||||||
C4E713572570151400007428 /* docs */,
|
C4E713572570151400007428 /* docs */,
|
||||||
C41C1B3522B0097F00E7CF16 /* phpmon */,
|
C41C1B3522B0097F00E7CF16 /* phpmon */,
|
||||||
|
C491998829902061001F3A21 /* phpmon-updater */,
|
||||||
C471E79628F9B4260021E251 /* tests */,
|
C471E79628F9B4260021E251 /* tests */,
|
||||||
C41C1B3422B0097F00E7CF16 /* Products */,
|
C41C1B3422B0097F00E7CF16 /* Products */,
|
||||||
C4D309E72770EF2F00958BCF /* Frameworks */,
|
C4D309E72770EF2F00958BCF /* Frameworks */,
|
||||||
@ -1300,6 +1310,7 @@
|
|||||||
C459B4BF27F6094100E9B4B4 /* brew */ = {
|
C459B4BF27F6094100E9B4B4 /* brew */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C491997829901DE2001F3A21 /* phpmon-dev.rb */,
|
||||||
C4E2E85228FC256B003B070C /* brew-services-normal.json */,
|
C4E2E85228FC256B003B070C /* brew-services-normal.json */,
|
||||||
C4E2E85128FC256B003B070C /* brew-services-sudo.json */,
|
C4E2E85128FC256B003B070C /* brew-services-sudo.json */,
|
||||||
C43A8A1F25D9D1D700591B77 /* brew-formula.json */,
|
C43A8A1F25D9D1D700591B77 /* brew-formula.json */,
|
||||||
@ -1444,6 +1455,14 @@
|
|||||||
path = "PHP Version";
|
path = "PHP Version";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C491998829902061001F3A21 /* phpmon-updater */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C491998929902089001F3A21 /* PHP Monitor Self-Updater.app */,
|
||||||
|
);
|
||||||
|
path = "phpmon-updater";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
C4AF9F6A275445C900D44ED0 /* Valet */ = {
|
C4AF9F6A275445C900D44ED0 /* Valet */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1471,6 +1490,7 @@
|
|||||||
C4AF9F6C275445D900D44ED0 /* Homebrew */ = {
|
C4AF9F6C275445D900D44ED0 /* Homebrew */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C491997A29901DF7001F3A21 /* CaskFile.swift */,
|
||||||
C4F2E4362752F0870020E974 /* HomebrewDiagnostics.swift */,
|
C4F2E4362752F0870020E974 /* HomebrewDiagnostics.swift */,
|
||||||
);
|
);
|
||||||
path = Homebrew;
|
path = Homebrew;
|
||||||
@ -1491,8 +1511,8 @@
|
|||||||
C4EED88827A48778006D7272 /* InterAppHandler.swift */,
|
C4EED88827A48778006D7272 /* InterAppHandler.swift */,
|
||||||
C4D8016522B1584700C6DA1B /* Startup.swift */,
|
C4D8016522B1584700C6DA1B /* Startup.swift */,
|
||||||
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */,
|
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */,
|
||||||
C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */,
|
|
||||||
C40FE736282ABA4F00A302C2 /* AppVersion.swift */,
|
C40FE736282ABA4F00A302C2 /* AppVersion.swift */,
|
||||||
|
C491997F29901E0F001F3A21 /* AppUpdater.swift */,
|
||||||
C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */,
|
C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */,
|
||||||
);
|
);
|
||||||
path = App;
|
path = App;
|
||||||
@ -1580,6 +1600,7 @@
|
|||||||
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */,
|
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */,
|
||||||
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */,
|
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */,
|
||||||
C4551656297AED18009B8466 /* ValetRcTest.swift */,
|
C4551656297AED18009B8466 /* ValetRcTest.swift */,
|
||||||
|
C491997629901DD6001F3A21 /* CaskFileParserTest.swift */,
|
||||||
);
|
);
|
||||||
path = Parsers;
|
path = Parsers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1592,7 +1613,6 @@
|
|||||||
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */,
|
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */,
|
||||||
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */,
|
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */,
|
||||||
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */,
|
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */,
|
||||||
C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */,
|
|
||||||
);
|
);
|
||||||
path = Versions;
|
path = Versions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1903,6 +1923,7 @@
|
|||||||
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */,
|
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */,
|
||||||
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */,
|
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */,
|
||||||
C405A4D124B9B9140062FAFA /* InternetAccessPolicy.plist in Resources */,
|
C405A4D124B9B9140062FAFA /* InternetAccessPolicy.plist in Resources */,
|
||||||
|
C491998A29902089001F3A21 /* PHP Monitor Self-Updater.app in Resources */,
|
||||||
C44C1991276E44CB0072762D /* ProgressWindow.storyboard in Resources */,
|
C44C1991276E44CB0072762D /* ProgressWindow.storyboard in Resources */,
|
||||||
C4232EE52612526500158FC6 /* Credits.html in Resources */,
|
C4232EE52612526500158FC6 /* Credits.html in Resources */,
|
||||||
54FCFD26276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
|
54FCFD26276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
|
||||||
@ -1958,6 +1979,7 @@
|
|||||||
C455165B297AEDB5009B8466 /* valetrc.broken in Resources */,
|
C455165B297AEDB5009B8466 /* valetrc.broken in Resources */,
|
||||||
54A18D40282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test in Resources */,
|
54A18D40282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test in Resources */,
|
||||||
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */,
|
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */,
|
||||||
|
C491997929901DE2001F3A21 /* phpmon-dev.rb in Resources */,
|
||||||
C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */,
|
C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */,
|
||||||
C4E2E85428FC256B003B070C /* brew-services-sudo.json in Resources */,
|
C4E2E85428FC256B003B070C /* brew-services-sudo.json in Resources */,
|
||||||
);
|
);
|
||||||
@ -2070,6 +2092,7 @@
|
|||||||
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
||||||
C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
||||||
54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */,
|
54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */,
|
||||||
|
C491997B29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||||
C4297F7A28970D59004C4630 /* WarningView.swift in Sources */,
|
C4297F7A28970D59004C4630 /* WarningView.swift in Sources */,
|
||||||
C4C0E8E227F88B13002D32A9 /* ValetDomainScanner.swift in Sources */,
|
C4C0E8E227F88B13002D32A9 /* ValetDomainScanner.swift in Sources */,
|
||||||
C42F26732805B4B400938AC7 /* ValetListable.swift in Sources */,
|
C42F26732805B4B400938AC7 /* ValetListable.swift in Sources */,
|
||||||
@ -2081,7 +2104,6 @@
|
|||||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
|
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
|
||||||
C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */,
|
C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */,
|
||||||
C41CA5ED2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */,
|
C41CA5ED2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */,
|
||||||
C46E206D28299B3800D909D6 /* AppUpdateChecker.swift in Sources */,
|
|
||||||
C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */,
|
C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */,
|
||||||
03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */,
|
03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */,
|
||||||
C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */,
|
C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */,
|
||||||
@ -2147,6 +2169,7 @@
|
|||||||
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
|
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
|
||||||
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */,
|
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */,
|
||||||
C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */,
|
C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */,
|
||||||
|
C491998029901E0F001F3A21 /* AppUpdater.swift in Sources */,
|
||||||
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
|
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -2178,13 +2201,13 @@
|
|||||||
C471E84228F9BB650021E251 /* AppDelegate+InterApp.swift in Sources */,
|
C471E84228F9BB650021E251 /* AppDelegate+InterApp.swift in Sources */,
|
||||||
C471E84328F9BB650021E251 /* App.swift in Sources */,
|
C471E84328F9BB650021E251 /* App.swift in Sources */,
|
||||||
C4E2E85E28FC282B003B070C /* TestableConfiguration.swift in Sources */,
|
C4E2E85E28FC282B003B070C /* TestableConfiguration.swift in Sources */,
|
||||||
|
C491997D29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||||
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 */,
|
||||||
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 */,
|
||||||
C471E84928F9BB650021E251 /* AppUpdateChecker.swift in Sources */,
|
|
||||||
C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */,
|
C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */,
|
||||||
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */,
|
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */,
|
||||||
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */,
|
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */,
|
||||||
@ -2226,6 +2249,7 @@
|
|||||||
C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */,
|
C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */,
|
||||||
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
|
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
|
||||||
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
|
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
|
||||||
|
C491998229901E0F001F3A21 /* AppUpdater.swift in Sources */,
|
||||||
C4D3660D29113F20006BD146 /* System.swift in Sources */,
|
C4D3660D29113F20006BD146 /* System.swift in Sources */,
|
||||||
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
|
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
|
||||||
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
|
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||||
@ -2350,7 +2374,6 @@
|
|||||||
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */,
|
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */,
|
||||||
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */,
|
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */,
|
||||||
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */,
|
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */,
|
||||||
C471E8AC28F9BB8F0021E251 /* AppUpdateChecker.swift in Sources */,
|
|
||||||
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */,
|
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */,
|
||||||
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */,
|
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */,
|
||||||
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */,
|
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */,
|
||||||
@ -2444,6 +2467,7 @@
|
|||||||
C471E81028F9BAE80021E251 /* StringExtension.swift in Sources */,
|
C471E81028F9BAE80021E251 /* StringExtension.swift in Sources */,
|
||||||
C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
|
C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
|
||||||
C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */,
|
C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */,
|
||||||
|
C491997E29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||||
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
|
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
|
||||||
C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */,
|
C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */,
|
||||||
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
||||||
@ -2457,6 +2481,7 @@
|
|||||||
C471E7D228F9BA630021E251 /* ActiveFileSystem.swift in Sources */,
|
C471E7D228F9BA630021E251 /* ActiveFileSystem.swift in Sources */,
|
||||||
C471E80028F9BAD10021E251 /* Xdebug.swift in Sources */,
|
C471E80028F9BAD10021E251 /* Xdebug.swift in Sources */,
|
||||||
C471E7F528F9BAC80021E251 /* PhpEnv.swift in Sources */,
|
C471E7F528F9BAC80021E251 /* PhpEnv.swift in Sources */,
|
||||||
|
C491998329901E0F001F3A21 /* AppUpdater.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 */,
|
||||||
@ -2524,6 +2549,7 @@
|
|||||||
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
||||||
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
|
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
|
||||||
C4F780CE25D80B75000DBC97 /* LocalNotification.swift in Sources */,
|
C4F780CE25D80B75000DBC97 /* LocalNotification.swift in Sources */,
|
||||||
|
C491997C29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||||
C40C7F2927721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */,
|
C40C7F2927721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */,
|
||||||
C485707A28BF457800539B36 /* WarningListView.swift in Sources */,
|
C485707A28BF457800539B36 /* WarningListView.swift in Sources */,
|
||||||
C4C0E8E827F88B41002D32A9 /* DomainScanner.swift in Sources */,
|
C4C0E8E827F88B41002D32A9 /* DomainScanner.swift in Sources */,
|
||||||
@ -2574,6 +2600,7 @@
|
|||||||
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */,
|
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */,
|
||||||
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */,
|
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */,
|
||||||
C41E871B2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
|
C41E871B2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
|
||||||
|
C491998129901E0F001F3A21 /* AppUpdater.swift in Sources */,
|
||||||
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */,
|
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */,
|
||||||
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
|
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
|
||||||
C4AD38B328ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */,
|
C4AD38B328ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */,
|
||||||
@ -2600,7 +2627,6 @@
|
|||||||
C4E2E86528FC2F1B003B070C /* XCPMApplication.swift in Sources */,
|
C4E2E86528FC2F1B003B070C /* XCPMApplication.swift in Sources */,
|
||||||
C4E49DE828F764050026AC4E /* ActiveCommand.swift in Sources */,
|
C4E49DE828F764050026AC4E /* ActiveCommand.swift in Sources */,
|
||||||
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */,
|
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */,
|
||||||
C46E20702829D27F00D909D6 /* AppUpdaterCheckTest.swift in Sources */,
|
|
||||||
C485707D28BF45A200539B36 /* WarningView.swift in Sources */,
|
C485707D28BF45A200539B36 /* WarningView.swift in Sources */,
|
||||||
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */,
|
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */,
|
||||||
C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
|
C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
|
||||||
@ -2623,6 +2649,7 @@
|
|||||||
C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */,
|
C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */,
|
||||||
C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
||||||
C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */,
|
C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */,
|
||||||
|
C491997729901DD6001F3A21 /* CaskFileParserTest.swift in Sources */,
|
||||||
C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */,
|
C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */,
|
||||||
C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */,
|
C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */,
|
||||||
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */,
|
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */,
|
||||||
@ -2667,7 +2694,6 @@
|
|||||||
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */,
|
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */,
|
||||||
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */,
|
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */,
|
||||||
C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */,
|
C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */,
|
||||||
C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -2831,7 +2857,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 = 1035;
|
CURRENT_PROJECT_VERSION = 1064;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -2843,7 +2869,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 5.7.2;
|
MARKETING_VERSION = 5.8;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -2860,7 +2886,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 = 1035;
|
CURRENT_PROJECT_VERSION = 1064;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -2872,7 +2898,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 5.7.2;
|
MARKETING_VERSION = 5.8;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -3088,7 +3114,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 = 1035;
|
CURRENT_PROJECT_VERSION = 1064;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@ -3099,7 +3125,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 5.7.2;
|
MARKETING_VERSION = 5.8;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -3198,7 +3224,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 = 1035;
|
CURRENT_PROJECT_VERSION = 1064;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@ -3209,7 +3235,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 5.7.2;
|
MARKETING_VERSION = 5.8;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
@ -91,7 +91,7 @@
|
|||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "--cli"
|
argument = "--cli"
|
||||||
isEnabled = "YES">
|
isEnabled = "NO">
|
||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "--configuration:~/.phpmon_fconf_working.json"
|
argument = "--configuration:~/.phpmon_fconf_working.json"
|
||||||
|
16
README.md
16
README.md
@ -43,22 +43,24 @@ valet install
|
|||||||
valet trust
|
valet trust
|
||||||
```
|
```
|
||||||
|
|
||||||
Once that's done, you can install PHP Monitor via Homebrew (recommended), or (alternatively) you may download the latest release on GitHub.
|
#### Manual installation (first time only)
|
||||||
|
|
||||||
To install via Homebrew, run:
|
Once that's done, you can [download the latest release](https://github.com/nicoverbruggen/phpmon/releases/latest), unzip it and place it in `/Applications`.
|
||||||
|
|
||||||
|
#### Installation via Homebrew
|
||||||
|
|
||||||
|
If you prefer to install the app via Homebrew, you can also do this:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
brew tap nicoverbruggen/homebrew-cask
|
brew tap nicoverbruggen/homebrew-cask
|
||||||
brew install --cask phpmon
|
brew install --cask phpmon
|
||||||
```
|
```
|
||||||
|
|
||||||
To upgrade your existing installation, run:
|
## ⬆️ How to update
|
||||||
|
|
||||||
```sh
|
The recommended method of updating your app to the latest version is to use **the built-in updater**.
|
||||||
brew upgrade phpmon
|
|
||||||
```
|
|
||||||
|
|
||||||
(You may need to run `brew update` or `brew update-reset` first in order to update the cask file if you ran a Homebrew operation recently.)
|
If that doesn't work or you prefer Homebrew, you can also upgrade via those methods.
|
||||||
|
|
||||||
## ⚡️ Launchers (Alfred, Raycast)
|
## ⚡️ Launchers (Alfred, Raycast)
|
||||||
|
|
||||||
|
@ -13,21 +13,21 @@ class Actions {
|
|||||||
// MARK: - Services
|
// MARK: - Services
|
||||||
|
|
||||||
public static func restartPhpFpm() async {
|
public static func restartPhpFpm() async {
|
||||||
await brew("services restart \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated)
|
await brew("services restart \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func restartNginx() async {
|
public static func restartNginx() async {
|
||||||
await brew("services restart \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated)
|
await brew("services restart \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func restartDnsMasq() async {
|
public static func restartDnsMasq() async {
|
||||||
await brew("services restart \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
await brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func stopValetServices() async {
|
public static func stopValetServices() async {
|
||||||
await brew("services stop \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated)
|
await brew("services stop \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
|
||||||
await brew("services stop \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated)
|
await brew("services stop \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||||
await brew("services stop \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
await brew("services stop \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func fixHomebrewPermissions() throws {
|
public static func fixHomebrewPermissions() throws {
|
||||||
@ -54,9 +54,10 @@ class Actions {
|
|||||||
+ " && "
|
+ " && "
|
||||||
+ cellarCommands.joined(separator: " && ")
|
+ cellarCommands.joined(separator: " && ")
|
||||||
|
|
||||||
let appleScript = NSAppleScript(
|
let source = "do shell script \"\(script)\" with administrator privileges"
|
||||||
source: "do shell script \"\(script)\" with administrator privileges"
|
|
||||||
)
|
Log.perf(source)
|
||||||
|
let appleScript = NSAppleScript(source: source)
|
||||||
|
|
||||||
let eventResult: NSAppleEventDescriptor? = appleScript?.executeAndReturnError(nil)
|
let eventResult: NSAppleEventDescriptor? = appleScript?.executeAndReturnError(nil)
|
||||||
|
|
||||||
|
@ -36,10 +36,14 @@ class Homebrew {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomebrewFormula: Equatable, Hashable {
|
class HomebrewFormula: Equatable, Hashable, CustomStringConvertible {
|
||||||
let name: String
|
let name: String
|
||||||
let elevated: Bool
|
let elevated: Bool
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
init(_ name: String, elevated: Bool = true) {
|
init(_ name: String, elevated: Bool = true) {
|
||||||
self.name = name
|
self.name = name
|
||||||
self.elevated = elevated
|
self.elevated = elevated
|
||||||
|
@ -41,21 +41,24 @@ class RealFileSystem: FileSystemProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getShallowContentsOfDirectory(_ path: String) throws -> [String] {
|
func getShallowContentsOfDirectory(_ path: String) throws -> [String] {
|
||||||
return try FileManager.default.contentsOfDirectory(atPath: path)
|
return try FileManager.default.contentsOfDirectory(atPath: path.replacingTildeWithHomeDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDestinationOfSymlink(_ path: String) throws -> String {
|
func getDestinationOfSymlink(_ path: String) throws -> String {
|
||||||
return try FileManager.default.destinationOfSymbolicLink(atPath: path)
|
return try FileManager.default.destinationOfSymbolicLink(atPath: path.replacingTildeWithHomeDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Move & Delete Files
|
// MARK: - Move & Delete Files
|
||||||
|
|
||||||
func move(from path: String, to newPath: String) throws {
|
func move(from path: String, to newPath: String) throws {
|
||||||
try FileManager.default.moveItem(atPath: path, toPath: newPath)
|
try FileManager.default.moveItem(
|
||||||
|
atPath: path.replacingTildeWithHomeDirectory,
|
||||||
|
toPath: newPath.replacingTildeWithHomeDirectory
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove(_ path: String) throws {
|
func remove(_ path: String) throws {
|
||||||
try FileManager.default.removeItem(atPath: path)
|
try FileManager.default.removeItem(atPath: path.replacingTildeWithHomeDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: — FS Attributes
|
// MARK: — FS Attributes
|
||||||
|
@ -10,8 +10,8 @@ import UserNotifications
|
|||||||
|
|
||||||
class LocalNotification {
|
class LocalNotification {
|
||||||
|
|
||||||
@MainActor public static func send(title: String, subtitle: String, preference: PreferenceName) {
|
@MainActor public static func send(title: String, subtitle: String, preference: PreferenceName?) {
|
||||||
if !Preferences.isEnabled(preference) {
|
if preference != nil && !Preferences.isEnabled(preference!) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,3 +26,7 @@ public func system(_ command: String) -> String {
|
|||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func system_quiet(_ command: String) {
|
||||||
|
_ = system(command)
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@ public struct PhpVersionNumberCollection: Equatable {
|
|||||||
- Parameter strict: Whether the patch version check is strict. See more below.
|
- Parameter strict: Whether the patch version check is strict. See more below.
|
||||||
|
|
||||||
The strict mode does not matter if a patch version is provided for all versions in the collection.
|
The strict mode does not matter if a patch version is provided for all versions in the collection.
|
||||||
|
It also does not matter for certain comparisons (e.g. when dealing with wildcards).
|
||||||
|
|
||||||
Strict mode assumes that any PHP version lacking precise patch information, e.g. inferred
|
Strict mode assumes that any PHP version lacking precise patch information, e.g. inferred
|
||||||
from Homebrew corresponds to the .0 patch version of that version. The default, which is imprecise,
|
from Homebrew corresponds to the .0 patch version of that version. The default, which is imprecise,
|
||||||
@ -45,6 +46,7 @@ public struct PhpVersionNumberCollection: Equatable {
|
|||||||
|
|
||||||
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in strict mode only 8.1.? will
|
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in strict mode only 8.1.? will
|
||||||
be considered valid (8.0 translates to 8.0.0 and as such is older than 8.0.1, 8.1.0 is OK).
|
be considered valid (8.0 translates to 8.0.0 and as such is older than 8.0.1, 8.1.0 is OK).
|
||||||
|
|
||||||
When checking against actual PHP versions installed by the user (with patch precision), use
|
When checking against actual PHP versions installed by the user (with patch precision), use
|
||||||
strict mode.
|
strict mode.
|
||||||
|
|
||||||
@ -52,11 +54,26 @@ public struct PhpVersionNumberCollection: Equatable {
|
|||||||
|
|
||||||
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in non-strict mode version 8.0
|
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in non-strict mode version 8.0
|
||||||
is assumed to be equal to version 8.0.999, which is actually fine if 8.0.1 is the required version.
|
is assumed to be equal to version 8.0.999, which is actually fine if 8.0.1 is the required version.
|
||||||
|
|
||||||
In non-strict mode, the patch version is ignored for regular version checks (no caret / tilde).
|
In non-strict mode, the patch version is ignored for regular version checks (no caret / tilde).
|
||||||
If checking compatibility with general Homebrew versions of PHP, do NOT use strict mode, since
|
If checking compatibility with general Homebrew versions of PHP, do NOT use strict mode, since
|
||||||
the patch version there is not used. (The formula php@8.0 suffices for ^8.0.1.)
|
the patch version there is not used. (The formula php@8.0 suffices for ^8.0.1.)
|
||||||
*/
|
*/
|
||||||
public func matching(constraint: String, strict: Bool = false) -> [VersionNumber] {
|
public func matching(constraint: String, strict: Bool = false) -> [VersionNumber] {
|
||||||
|
if constraint == "*" {
|
||||||
|
return self.versions
|
||||||
|
}
|
||||||
|
|
||||||
|
if let version = VersionNumber.make(from: constraint, type: .wildCardPatch) {
|
||||||
|
// Wildcard for patch (e.g. "7.4.*") must match major and minor (any patch)
|
||||||
|
return self.versions.filter { $0.hasSameMajorAndMinor(version) }
|
||||||
|
}
|
||||||
|
|
||||||
|
if let version = VersionNumber.make(from: constraint, type: .wildCardMinor) {
|
||||||
|
// Strict constraint (e.g. "7.*") -> must only match major (any patch, minor)
|
||||||
|
return self.versions.filter { $0.isSameMajorVersionAs(version) }
|
||||||
|
}
|
||||||
|
|
||||||
if let version = VersionNumber.make(from: constraint, type: .versionOnly) {
|
if let version = VersionNumber.make(from: constraint, type: .versionOnly) {
|
||||||
// Strict constraint (e.g. "7.0") -> returns specific version
|
// Strict constraint (e.g. "7.0") -> returns specific version
|
||||||
return self.versions.filter { $0.isSameAs(version, strict) }
|
return self.versions.filter { $0.isSameAs(version, strict) }
|
||||||
|
@ -39,6 +39,8 @@ public struct VersionNumber: Equatable, Hashable {
|
|||||||
|
|
||||||
public enum MatchType: String {
|
public enum MatchType: String {
|
||||||
case versionOnly = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case versionOnly = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
|
case wildCardPatch = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\*)?\z"#
|
||||||
|
case wildCardMinor = #"^(?<major>\d+).(?<minor>\*)?\z"#
|
||||||
case caretVersionRange = #"^\^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case caretVersionRange = #"^\^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
case tildeVersionRange = #"^~(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case tildeVersionRange = #"^~(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
case greaterThanOrEqual = #"^>=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
case greaterThanOrEqual = #"^>=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
|
||||||
@ -64,21 +66,25 @@ public struct VersionNumber: Equatable, Hashable {
|
|||||||
range: NSRange(location: 0, length: versionString.count)
|
range: NSRange(location: 0, length: versionString.count)
|
||||||
).first
|
).first
|
||||||
|
|
||||||
if match != nil {
|
guard let match else { return nil }
|
||||||
let major = Int(
|
|
||||||
versionString[Range(match!.range(withName: "major"), in: versionString)!]
|
let major = Int(versionString[Range(match.range(withName: "major"), in: versionString)!])!
|
||||||
)!
|
var minor: Int = 0
|
||||||
let minor = Int(
|
var patch: Int?
|
||||||
versionString[Range(match!.range(withName: "minor"), in: versionString)!]
|
|
||||||
)!
|
if let minorRange = Range(match.range(withName: "minor"), in: versionString) {
|
||||||
var patch: Int?
|
let value = versionString[minorRange] as String
|
||||||
if let minorRange = Range(match!.range(withName: "patch"), in: versionString) {
|
// Zero is the fallback if a wildcard was used
|
||||||
patch = Int(versionString[minorRange])
|
minor = Int(value) ?? 0
|
||||||
}
|
|
||||||
return Self(major: major, minor: minor, patch: patch)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if let patchRange = Range(match.range(withName: "patch"), in: versionString) {
|
||||||
|
let value = versionString[patchRange] as String
|
||||||
|
// nil is the fallback if a wildcard was used
|
||||||
|
patch = Int(value) ?? nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return Self(major: major, minor: minor, patch: patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Comparison Logic
|
// MARK: Comparison Logic
|
||||||
@ -93,6 +99,10 @@ public struct VersionNumber: Equatable, Hashable {
|
|||||||
&& (strict ? self.patch(strict, version) == version.patch(strict) : true)
|
&& (strict ? self.patch(strict, version) == version.patch(strict) : true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal func hasSameMajorAndMinor(_ version: VersionNumber) -> Bool {
|
||||||
|
return self.major == version.major && self.minor == version.minor
|
||||||
|
}
|
||||||
|
|
||||||
internal func isNewerThan(_ version: VersionNumber, _ strict: Bool) -> Bool {
|
internal func isNewerThan(_ version: VersionNumber, _ strict: Bool) -> Bool {
|
||||||
return (
|
return (
|
||||||
self.major > version.major ||
|
self.major > version.major ||
|
||||||
|
@ -22,7 +22,6 @@ class InternalSwitcher: PhpSwitcher {
|
|||||||
*/
|
*/
|
||||||
func performSwitch(to version: String) async {
|
func performSwitch(to version: String) async {
|
||||||
Log.info("Switching to \(version), unlinking all versions...")
|
Log.info("Switching to \(version), unlinking all versions...")
|
||||||
|
|
||||||
let versions = getVersionsToBeHandled(version)
|
let versions = getVersionsToBeHandled(version)
|
||||||
|
|
||||||
await withTaskGroup(of: String.self, body: { group in
|
await withTaskGroup(of: String.self, body: { group in
|
||||||
|
@ -115,14 +115,12 @@ class RealShell: ShellProtocol {
|
|||||||
)!
|
)!
|
||||||
|
|
||||||
if Log.shared.verbosity == .cli {
|
if Log.shared.verbosity == .cli {
|
||||||
var args = task.arguments
|
var args = task.arguments ?? []
|
||||||
let last: String = "\"" + (args?.popLast() ?? "") + "\""
|
let last = "\"" + (args.popLast() ?? "") + "\""
|
||||||
let concat = [self.launchPath] + task.arguments! + [last]
|
|
||||||
let command = concat.joined(separator: " ")
|
|
||||||
var log = """
|
var log = """
|
||||||
|
|
||||||
<~~~~~~~~~~~~~~~~~~~~~~~
|
<~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
$ \(command)
|
$ \(([self.launchPath] + args + [last]).joined(separator: " "))
|
||||||
|
|
||||||
[OUT]:
|
[OUT]:
|
||||||
\(stdOut)
|
\(stdOut)
|
||||||
|
@ -1,182 +0,0 @@
|
|||||||
//
|
|
||||||
// Updater.swift
|
|
||||||
// PHP Monitor
|
|
||||||
//
|
|
||||||
// Created by Nico Verbruggen on 09/05/2022.
|
|
||||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import AppKit
|
|
||||||
|
|
||||||
class AppUpdateChecker {
|
|
||||||
|
|
||||||
public static var enabled: Bool = {
|
|
||||||
return Preferences.isEnabled(.automaticBackgroundUpdateCheck)
|
|
||||||
}()
|
|
||||||
|
|
||||||
public static var isDev: Bool = {
|
|
||||||
return App.version.contains("-dev")
|
|
||||||
}()
|
|
||||||
|
|
||||||
public static func retrieveVersionFromCask(
|
|
||||||
_ initiatedFromBackground: Bool = true
|
|
||||||
) async -> String {
|
|
||||||
let caskFile = App.version.contains("-dev")
|
|
||||||
? Constants.Urls.DevBuildCaskFile.absoluteString
|
|
||||||
: Constants.Urls.StableBuildCaskFile.absoluteString
|
|
||||||
|
|
||||||
var command = "curl -s"
|
|
||||||
|
|
||||||
if initiatedFromBackground {
|
|
||||||
command = "curl -s --max-time 5"
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Shell.pipe(
|
|
||||||
"\(command) '\(caskFile)' | grep version"
|
|
||||||
).out
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func checkIfNewerVersionIsAvailable(
|
|
||||||
initiatedFromBackground: Bool = true
|
|
||||||
) async {
|
|
||||||
if initiatedFromBackground {
|
|
||||||
if !Preferences.isEnabled(.automaticBackgroundUpdateCheck) {
|
|
||||||
Log.info("Automatic updates are disabled. No check will be performed.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.info("Automatic updates are enabled, a check will be performed.")
|
|
||||||
}
|
|
||||||
|
|
||||||
let versionString = await retrieveVersionFromCask(initiatedFromBackground)
|
|
||||||
|
|
||||||
guard let onlineVersion = AppVersion.from(versionString) else {
|
|
||||||
Log.err("We couldn't check for updates!")
|
|
||||||
|
|
||||||
// Only notify about connection issues if the request to check for updates was explicit
|
|
||||||
if !initiatedFromBackground {
|
|
||||||
notifyAboutConnectionIssue()
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentVersion = AppVersion.fromCurrentVersion()
|
|
||||||
|
|
||||||
handleVersionComparison(
|
|
||||||
currentVersion,
|
|
||||||
onlineVersion,
|
|
||||||
initiatedFromBackground
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func handleVersionComparison(
|
|
||||||
_ currentVersion: AppVersion,
|
|
||||||
_ onlineVersion: AppVersion,
|
|
||||||
_ background: Bool
|
|
||||||
) {
|
|
||||||
switch onlineVersion.version.versionCompare(currentVersion.version) {
|
|
||||||
case .orderedAscending:
|
|
||||||
Log.info("You are running a newer version of PHP Monitor "
|
|
||||||
+ "(\(currentVersion.computerReadable) > \(onlineVersion.computerReadable)).")
|
|
||||||
if !background { notifyVersionDoesNotNeedUpgrade() }
|
|
||||||
case .orderedDescending:
|
|
||||||
Log.info("There is a newer version (\(onlineVersion)) available! "
|
|
||||||
+ "(\(onlineVersion.computerReadable) > \(currentVersion.computerReadable))")
|
|
||||||
notifyAboutNewerVersion(version: onlineVersion)
|
|
||||||
case .orderedSame:
|
|
||||||
if currentVersion.build != nil
|
|
||||||
&& onlineVersion.build != nil
|
|
||||||
&& buildDiffers(currentVersion, onlineVersion, background) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.info("The installed version (\(currentVersion.computerReadable)) matches the latest release "
|
|
||||||
+ "(\(onlineVersion.computerReadable)).")
|
|
||||||
if !background { notifyVersionDoesNotNeedUpgrade() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func buildDiffers(
|
|
||||||
_ currentVersion: AppVersion,
|
|
||||||
_ onlineVersion: AppVersion,
|
|
||||||
_ background: Bool
|
|
||||||
) -> Bool {
|
|
||||||
if Int(onlineVersion.build!)! > Int(currentVersion.build!)! {
|
|
||||||
Log.info("There is a newer build of PHP Monitor available! "
|
|
||||||
+ "(\(onlineVersion.computerReadable) > \(currentVersion.computerReadable))")
|
|
||||||
notifyAboutNewerVersion(version: onlineVersion)
|
|
||||||
return true
|
|
||||||
} else if Int(onlineVersion.build!)! < Int(currentVersion.build!)! {
|
|
||||||
Log.info("You are running a newer build of PHP Monitor "
|
|
||||||
+ "(\(currentVersion.computerReadable) > \(onlineVersion.computerReadable)).")
|
|
||||||
if !background { notifyVersionDoesNotNeedUpgrade() }
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func notifyVersionDoesNotNeedUpgrade() {
|
|
||||||
Task { @MainActor in
|
|
||||||
BetterAlert().withInformation(
|
|
||||||
title: "updater.alerts.is_latest_version.title".localized,
|
|
||||||
subtitle: "updater.alerts.is_latest_version.subtitle".localized(App.shortVersion),
|
|
||||||
description: ""
|
|
||||||
)
|
|
||||||
.withPrimary(text: "generic.ok".localized)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func notifyAboutNewerVersion(version: AppVersion) {
|
|
||||||
let devSuffix = isDev ? "-dev" : ""
|
|
||||||
let command = isDev ? "brew upgrade phpmon-dev" : "brew upgrade phpmon"
|
|
||||||
|
|
||||||
Task { @MainActor in
|
|
||||||
BetterAlert().withInformation(
|
|
||||||
title: "updater.alerts.newer_version_available.title".localized(version.humanReadable),
|
|
||||||
subtitle: "updater.alerts.newer_version_available.subtitle".localized,
|
|
||||||
description: HomebrewDiagnostics.customCaskInstalled
|
|
||||||
? "updater.installation_source.brew".localized(command)
|
|
||||||
: "updater.installation_source.direct".localized
|
|
||||||
)
|
|
||||||
.withPrimary(
|
|
||||||
text: "updater.alerts.buttons.release_notes".localized,
|
|
||||||
action: { vc in
|
|
||||||
vc.close(with: .OK)
|
|
||||||
|
|
||||||
NSWorkspace.shared.open(
|
|
||||||
Constants.Urls.GitHubReleases.appendingPathComponent("/tag/v\(version.tagged)\(devSuffix)")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.withTertiary(text: "Dismiss", action: { vc in
|
|
||||||
vc.close(with: .OK)
|
|
||||||
})
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func notifyAboutConnectionIssue() {
|
|
||||||
Task { @MainActor in
|
|
||||||
BetterAlert().withInformation(
|
|
||||||
title: "updater.alerts.cannot_check_for_update.title".localized,
|
|
||||||
subtitle: "updater.alerts.cannot_check_for_update.subtitle".localized,
|
|
||||||
description: "updater.alerts.cannot_check_for_update.description".localized(
|
|
||||||
App.version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.withTertiary(
|
|
||||||
text: "updater.alerts.buttons.releases_on_github".localized,
|
|
||||||
action: { _ in
|
|
||||||
NSWorkspace.shared.open(Constants.Urls.GitHubReleases)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.withPrimary(text: "generic.ok".localized)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
184
phpmon/Domain/App/AppUpdater.swift
Normal file
184
phpmon/Domain/App/AppUpdater.swift
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
//
|
||||||
|
// AppUpdater.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 04/02/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class AppUpdater {
|
||||||
|
var caskFile: CaskFile!
|
||||||
|
var latestVersionOnline: AppVersion!
|
||||||
|
var interactive: Bool = false
|
||||||
|
|
||||||
|
public func checkForUpdates(interactive: Bool) async {
|
||||||
|
self.interactive = interactive
|
||||||
|
|
||||||
|
if interactive && !Preferences.isEnabled(.automaticBackgroundUpdateCheck) {
|
||||||
|
Log.info("Skipping automatic update check due to user preference.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info("The app will search for updates...")
|
||||||
|
|
||||||
|
let caskUrl = App.identifier.contains(".dev")
|
||||||
|
? Constants.Urls.DevBuildCaskFile
|
||||||
|
: Constants.Urls.StableBuildCaskFile
|
||||||
|
|
||||||
|
guard let caskFile = await CaskFile.from(url: caskUrl) else {
|
||||||
|
Log.err("The contents of the CaskFile at '\(caskUrl.absoluteString)' could not be retrieved.")
|
||||||
|
return presentCouldNotRetrieveUpdateIfInteractive()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.caskFile = caskFile
|
||||||
|
|
||||||
|
let currentVersion = AppVersion.fromCurrentVersion()
|
||||||
|
|
||||||
|
guard let onlineVersion = AppVersion.from(caskFile.version) else {
|
||||||
|
Log.err("The version string from the CaskFile could not be read.")
|
||||||
|
return presentCouldNotRetrieveUpdateIfInteractive()
|
||||||
|
}
|
||||||
|
|
||||||
|
latestVersionOnline = onlineVersion
|
||||||
|
Log.info("The latest version read from '\(caskUrl.lastPathComponent)' is: v\(onlineVersion.computerReadable).")
|
||||||
|
|
||||||
|
if latestVersionOnline > currentVersion {
|
||||||
|
presentNewerVersionAvailableAlert()
|
||||||
|
} else if interactive {
|
||||||
|
presentNoNewerVersionAvailableAlert()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func presentCouldNotRetrieveUpdateIfInteractive() {
|
||||||
|
if interactive {
|
||||||
|
return presentCouldNotRetrieveUpdate()
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Alerts
|
||||||
|
|
||||||
|
public func presentNewerVersionAvailableAlert() {
|
||||||
|
let command = App.identifier.contains(".dev")
|
||||||
|
? "brew upgrade phpmon-dev"
|
||||||
|
: "brew upgrade phpmon"
|
||||||
|
|
||||||
|
Task { @MainActor in
|
||||||
|
BetterAlert().withInformation(
|
||||||
|
title: "updater.alerts.newer_version_available.title"
|
||||||
|
.localized(latestVersionOnline.humanReadable),
|
||||||
|
subtitle: "updater.alerts.newer_version_available.subtitle"
|
||||||
|
.localized,
|
||||||
|
description: HomebrewDiagnostics.customCaskInstalled
|
||||||
|
? "updater.installation_source.brew".localized(command)
|
||||||
|
: "updater.installation_source.direct".localized
|
||||||
|
)
|
||||||
|
.withPrimary(
|
||||||
|
text: "updater.alerts.buttons.install".localized,
|
||||||
|
action: { vc in
|
||||||
|
self.prepareForDownload()
|
||||||
|
vc.close(with: .OK)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSecondary(
|
||||||
|
text: "updater.alerts.buttons.release_notes".localized,
|
||||||
|
action: { _ in
|
||||||
|
let urlSegments = self.caskFile.url.split(separator: "/")
|
||||||
|
let tag = urlSegments[urlSegments.count - 2] // ../download/{tag}/{file.zip}
|
||||||
|
NSWorkspace.shared.open(
|
||||||
|
Constants.Urls.GitHubReleases.appendingPathComponent("/tag/\(tag)")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withTertiary(text: "updater.alerts.buttons.dismiss".localized, action: { vc in
|
||||||
|
vc.close(with: .OK)
|
||||||
|
})
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func presentNoNewerVersionAvailableAlert() {
|
||||||
|
Task { @MainActor in
|
||||||
|
BetterAlert().withInformation(
|
||||||
|
title: "updater.alerts.is_latest_version.title".localized,
|
||||||
|
subtitle: "updater.alerts.is_latest_version.subtitle".localized(App.shortVersion),
|
||||||
|
description: ""
|
||||||
|
)
|
||||||
|
.withPrimary(text: "generic.ok".localized)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func presentCouldNotRetrieveUpdate() {
|
||||||
|
Task { @MainActor in
|
||||||
|
BetterAlert().withInformation(
|
||||||
|
title: "updater.alerts.cannot_check_for_update.title".localized,
|
||||||
|
subtitle: "updater.alerts.cannot_check_for_update.subtitle".localized,
|
||||||
|
description: "updater.alerts.cannot_check_for_update.description".localized(
|
||||||
|
App.version
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.withTertiary(
|
||||||
|
text: "updater.alerts.buttons.releases_on_github".localized,
|
||||||
|
action: { _ in
|
||||||
|
NSWorkspace.shared.open(Constants.Urls.GitHubReleases)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withPrimary(text: "generic.ok".localized)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Preparing for Self-Updater
|
||||||
|
|
||||||
|
private func prepareForDownload() {
|
||||||
|
let updater = Bundle.main.resourceURL!.path + "/PHP Monitor Self-Updater.app"
|
||||||
|
|
||||||
|
system_quiet("mkdir -p ~/.config/phpmon/updater 2> /dev/null")
|
||||||
|
|
||||||
|
let updaterDirectory = "~/.config/phpmon/updater"
|
||||||
|
.replacingOccurrences(of: "~", with: NSHomeDirectory())
|
||||||
|
|
||||||
|
system_quiet("cp -R \"\(updater)\" \"\(updaterDirectory)/PHP Monitor Self-Updater.app\"")
|
||||||
|
|
||||||
|
try! FileSystem.writeAtomicallyToFile(
|
||||||
|
"\(updaterDirectory)/update.json",
|
||||||
|
content: "{ \"url\": \"\(caskFile.url)\", \"sha256\": \"\(caskFile.sha256)\" }"
|
||||||
|
)
|
||||||
|
|
||||||
|
let updaterUrl = NSURL(fileURLWithPath: updater, isDirectory: true) as URL
|
||||||
|
let configuration = NSWorkspace.OpenConfiguration()
|
||||||
|
|
||||||
|
NSWorkspace.shared.openApplication(at: updaterUrl, configuration: configuration) { _, _ in
|
||||||
|
Log.info("The updater has been launched successfully!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Checking if Self-Updater Worked
|
||||||
|
|
||||||
|
public static func checkIfUpdateWasPerformed() {
|
||||||
|
// Cleanup the upgrade.success file
|
||||||
|
if FileSystem.fileExists("~/.config/phpmon/updater/upgrade.success") {
|
||||||
|
Task { @MainActor in
|
||||||
|
LocalNotification.send(
|
||||||
|
title: "notification.phpmon_updated.title".localized,
|
||||||
|
subtitle: "notification.phpmon_updated.desc".localized(App.shortVersion),
|
||||||
|
preference: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info("The `upgrade.success` file was found! An update was installed. Cleaning up...")
|
||||||
|
try! FileSystem.remove("~/.config/phpmon/updater/upgrade.success")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup the previous updater
|
||||||
|
if FileSystem.anyExists("~/.config/phpmon/updater/PHP Monitor Self-Updater.app") {
|
||||||
|
Log.info("A remnant of the self-updater must still be removed...")
|
||||||
|
try? FileSystem.remove("~/.config/phpmon/updater/PHP Monitor Self-Updater.app")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,14 +8,14 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class AppVersion {
|
class AppVersion: Comparable {
|
||||||
var version: String
|
var version: String
|
||||||
var build: String?
|
var build: Int?
|
||||||
var suffix: String?
|
var suffix: String?
|
||||||
|
|
||||||
init(version: String, build: String?, suffix: String? = nil) {
|
init(version: String, build: String?, suffix: String? = nil) {
|
||||||
self.version = version
|
self.version = version
|
||||||
self.build = build
|
self.build = Int(build ?? "0")
|
||||||
self.suffix = suffix
|
self.suffix = suffix
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,11 +75,27 @@ class AppVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var computerReadable: String {
|
var computerReadable: String {
|
||||||
return "\(version)_\(build ?? "0")"
|
return "\(version)_\(build ?? 0)"
|
||||||
}
|
}
|
||||||
|
|
||||||
var humanReadable: String {
|
var humanReadable: String {
|
||||||
return "\(version) (\(build ?? "???"))"
|
return "\(version) (\(build ?? 0))"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Comparable Protocol
|
||||||
|
|
||||||
|
static func < (lhs: AppVersion, rhs: AppVersion) -> Bool {
|
||||||
|
let comparisonResult = lhs.version.versionCompare(rhs.version)
|
||||||
|
|
||||||
|
if comparisonResult == .orderedAscending {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return lhs.build ?? 0 < rhs.build ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
static func == (lhs: AppVersion, rhs: AppVersion) -> Bool {
|
||||||
|
lhs.version.versionCompare(rhs.version) == .orderedSame
|
||||||
|
&& lhs.build == rhs.build
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,8 @@ class DomainListPhpCell: NSTableCellView, DomainListCellProtocol {
|
|||||||
imageViewPhpVersionOK.image = NSImage(named: "Isolated")
|
imageViewPhpVersionOK.image = NSImage(named: "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 == "???" || !site.isCompatibleWithPreferredPhpVersion)
|
imageViewPhpVersionOK.isHidden = (site.preferredPhpVersion == "???"
|
||||||
|
|| !site.isCompatibleWithPreferredPhpVersion)
|
||||||
imageViewPhpVersionOK.image = NSImage(named: "Checkmark")
|
imageViewPhpVersionOK.image = NSImage(named: "Checkmark")
|
||||||
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.checkmark".localized(site.preferredPhpVersion)
|
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.checkmark".localized(site.preferredPhpVersion)
|
||||||
|
|
||||||
|
78
phpmon/Domain/Integrations/Homebrew/CaskFile.swift
Normal file
78
phpmon/Domain/Integrations/Homebrew/CaskFile.swift
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
//
|
||||||
|
// CaskFile.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 04/02/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct CaskFile {
|
||||||
|
var properties: [String: String]
|
||||||
|
|
||||||
|
var name: String {
|
||||||
|
return self.properties["name"]!
|
||||||
|
}
|
||||||
|
var url: String {
|
||||||
|
return self.properties["url"]!
|
||||||
|
}
|
||||||
|
var sha256: String {
|
||||||
|
return self.properties["sha256"]!
|
||||||
|
}
|
||||||
|
var version: String {
|
||||||
|
return self.properties["version"]!
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func from(url: URL) async -> CaskFile? {
|
||||||
|
var string: String?
|
||||||
|
|
||||||
|
if url.scheme == "file" {
|
||||||
|
string = try? String(contentsOf: url)
|
||||||
|
} else {
|
||||||
|
string = await Shell.pipe("curl -s --max-time 10 '\(url.absoluteString)'").out
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let string else {
|
||||||
|
Log.err("The content of the URL for the CaskFile could not be retrieved")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let lines = string.split(separator: "\n")
|
||||||
|
.filter { $0 != "" }
|
||||||
|
|
||||||
|
if lines.count < 4 {
|
||||||
|
Log.err("The CaskFile is <4 lines long, which is too short")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !lines.first!.starts(with: "cask") || !lines.last!.starts(with: "end") {
|
||||||
|
Log.err("The CaskFile does not start with 'cask' or does not end with 'end'")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var props: [String: String] = [:]
|
||||||
|
|
||||||
|
let regex = try! NSRegularExpression(pattern: "(\\w+)\\s+'([^']+)'")
|
||||||
|
|
||||||
|
for line in lines {
|
||||||
|
if let match = regex.firstMatch(
|
||||||
|
in: String(line),
|
||||||
|
range: NSRange(location: 0, length: line.utf16.count)
|
||||||
|
) {
|
||||||
|
let keyRange = match.range(at: 1)
|
||||||
|
let valueRange = match.range(at: 2)
|
||||||
|
let key = (line as NSString).substring(with: keyRange)
|
||||||
|
let value = (line as NSString).substring(with: valueRange)
|
||||||
|
props[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for required in ["version", "sha256", "url", "name"] where !props.keys.contains(required) {
|
||||||
|
Log.err("Property '\(required)' expected on CaskFile, assuming CaskFile is invalid")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return CaskFile(properties: props)
|
||||||
|
}
|
||||||
|
}
|
@ -110,14 +110,17 @@ extension MainMenu {
|
|||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
OnboardingWindowController.show()
|
OnboardingWindowController.show()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await AppUpdater().checkForUpdates(interactive: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
await AppUpdateChecker.checkIfNewerVersionIsAvailable()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the linked version has changed between launches of phpmon
|
// Check if the linked version has changed between launches of phpmon
|
||||||
Stats.evaluateLastLinkedPhpVersion()
|
Stats.evaluateLastLinkedPhpVersion()
|
||||||
|
|
||||||
|
// Check if an update was performed earlier
|
||||||
|
AppUpdater.checkIfUpdateWasPerformed()
|
||||||
|
|
||||||
// We are ready!
|
// We are ready!
|
||||||
Log.info("PHP Monitor is ready to serve!")
|
Log.info("PHP Monitor is ready to serve!")
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc func checkForUpdates() {
|
@objc func checkForUpdates() {
|
||||||
Task { await AppUpdateChecker.checkIfNewerVersionIsAvailable(initiatedFromBackground: false) }
|
Task { await AppUpdater().checkForUpdates(interactive: true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Menu Delegate
|
// MARK: - Menu Delegate
|
||||||
|
@ -42,4 +42,13 @@ class OnboardingWindowController: PMWindowController {
|
|||||||
|
|
||||||
NSApp.activate(ignoringOtherApps: true)
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func close() {
|
||||||
|
super.close()
|
||||||
|
|
||||||
|
// Search for updates after closing the window
|
||||||
|
if Stats.successfulLaunchCount == 1 {
|
||||||
|
Task { await AppUpdater().checkForUpdates(interactive: false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,6 +355,9 @@ This has no effect on other terminals, only for the particular terminal session
|
|||||||
"notification.preset_reverted_title" = "Preset reverted";
|
"notification.preset_reverted_title" = "Preset reverted";
|
||||||
"notification.preset_reverted_desc" = "The last preset you applied has been undone. Your previous configuration is now active.";
|
"notification.preset_reverted_desc" = "The last preset you applied has been undone. Your previous configuration is now active.";
|
||||||
|
|
||||||
|
"notification.phpmon_updated.title" = "PHP Monitor has been updated!";
|
||||||
|
"notification.phpmon_updated.desc" = "You are now running PHP Monitor v%@.";
|
||||||
|
|
||||||
// Composer Update
|
// Composer Update
|
||||||
"alert.composer_missing.title" = "Composer not found!";
|
"alert.composer_missing.title" = "Composer not found!";
|
||||||
"alert.composer_missing.subtitle" = "PHP Monitor could not find Composer. Make sure that Composer is installed and try again.";
|
"alert.composer_missing.subtitle" = "PHP Monitor could not find Composer. Make sure that Composer is installed and try again.";
|
||||||
@ -617,9 +620,8 @@ COMMON TROUBLESHOOTING TIPS
|
|||||||
|
|
||||||
"updater.alerts.newer_version_available.title" = "PHP Monitor v%@ is now available!";
|
"updater.alerts.newer_version_available.title" = "PHP Monitor v%@ is now available!";
|
||||||
"updater.alerts.newer_version_available.subtitle" = "Keeping PHP Monitor up-to-date is highly recommended, since newer versions usually fix bugs and include fixes to support the latest versions of Valet and PHP.";
|
"updater.alerts.newer_version_available.subtitle" = "Keeping PHP Monitor up-to-date is highly recommended, since newer versions usually fix bugs and include fixes to support the latest versions of Valet and PHP.";
|
||||||
"updater.alerts.newer_version_available.description" = "PHP Monitor is supposed to be updated via Homebrew, so there is no built-in updater. This check is only meant to inform you of the existence of a new version, you do not need to upgrade.";
|
"updater.installation_source.brew" = "The recommended method of installing updates to PHP Monitor is to simply press 'Install Update'.\n\n(You may also upgrade via the terminal by running `%@`, but this is not recommended.)";
|
||||||
"updater.installation_source.brew" = "You appear to have installed PHP Monitor via Homebrew (or have at least tapped the required Caskfile) so it is recommended that you upgrade via the terminal by running `%@`.";
|
"updater.installation_source.direct" = "The recommended method of installing updates to PHP Monitor is to simply press 'Install Update'.";
|
||||||
"updater.installation_source.direct" = "You do not appear to have installed PHP Monitor via Homebrew, so you will need to visit GitHub to download the latest update.";
|
|
||||||
"updater.alerts.buttons.release_notes" = "View Release Notes";
|
"updater.alerts.buttons.release_notes" = "View Release Notes";
|
||||||
|
|
||||||
"updater.alerts.is_latest_version.title" = "PHP Monitor is up-to-date!";
|
"updater.alerts.is_latest_version.title" = "PHP Monitor is up-to-date!";
|
||||||
@ -629,6 +631,8 @@ COMMON TROUBLESHOOTING TIPS
|
|||||||
"updater.alerts.cannot_check_for_update.subtitle" = "You might not be connected to the internet, are blocking traffic or GitHub is down and won't allow you to check for updates. If you keep seeing this message, you may want to manually check the releases page.";
|
"updater.alerts.cannot_check_for_update.subtitle" = "You might not be connected to the internet, are blocking traffic or GitHub is down and won't allow you to check for updates. If you keep seeing this message, you may want to manually check the releases page.";
|
||||||
"updater.alerts.cannot_check_for_update.description" = "The currently installed version is: %@. You can go to the list of the latest releases (on GitHub) by clicking on the button on the left.";
|
"updater.alerts.cannot_check_for_update.description" = "The currently installed version is: %@. You can go to the list of the latest releases (on GitHub) by clicking on the button on the left.";
|
||||||
"updater.alerts.buttons.releases_on_github" = "View Releases";
|
"updater.alerts.buttons.releases_on_github" = "View Releases";
|
||||||
|
"updater.alerts.buttons.install" = "Install Update";
|
||||||
|
"updater.alerts.buttons.dismiss" = "Dismiss";
|
||||||
|
|
||||||
// WARNINGS ABOUT NON-DEFAULT TLD
|
// WARNINGS ABOUT NON-DEFAULT TLD
|
||||||
|
|
||||||
|
53
tests/unit/Parsers/CaskFileParserTest.swift
Normal file
53
tests/unit/Parsers/CaskFileParserTest.swift
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// CaskFileParserTest.swift
|
||||||
|
// Unit Tests
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 04/02/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class CaskFileParserTest: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: - Test Files
|
||||||
|
static var exampleFilePath: URL {
|
||||||
|
return Bundle(for: Self.self)
|
||||||
|
.url(forResource: "phpmon-dev", withExtension: "rb")!
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_can_extract_fields_from_cask_file() async throws {
|
||||||
|
guard let caskFile = await CaskFile.from(url: CaskFileParserTest.exampleFilePath) else {
|
||||||
|
return XCTFail("The CaskFile could not be parsed, check the log for more info")
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(
|
||||||
|
caskFile.version,
|
||||||
|
"5.7.2_1035"
|
||||||
|
)
|
||||||
|
XCTAssertEqual(
|
||||||
|
caskFile.sha256,
|
||||||
|
"1cb147bd1b1fbd52971d90dff577465b644aee7c878f15ede57f46e8f217067a"
|
||||||
|
)
|
||||||
|
XCTAssertEqual(
|
||||||
|
caskFile.name,
|
||||||
|
"PHP Monitor DEV"
|
||||||
|
)
|
||||||
|
XCTAssertEqual(
|
||||||
|
caskFile.url,
|
||||||
|
"https://github.com/nicoverbruggen/phpmon/releases/download/v5.7.2/phpmon-dev.zip"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_can_extract_fields_from_remote_cask_file() async throws {
|
||||||
|
guard let caskFile = await CaskFile.from(url: Constants.Urls.StableBuildCaskFile) else {
|
||||||
|
return XCTFail("The remote CaskFile could not be parsed, check the log for more info")
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertTrue(caskFile.properties.keys.contains("version"))
|
||||||
|
XCTAssertTrue(caskFile.properties.keys.contains("homepage"))
|
||||||
|
XCTAssertTrue(caskFile.properties.keys.contains("url"))
|
||||||
|
XCTAssertTrue(caskFile.properties.keys.contains("appcast"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
tests/unit/Test Files/brew/phpmon-dev.rb
Normal file
14
tests/unit/Test Files/brew/phpmon-dev.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
cask 'phpmon-dev' do
|
||||||
|
depends_on formula: 'gnu-sed'
|
||||||
|
|
||||||
|
version '5.7.2_1035'
|
||||||
|
sha256 '1cb147bd1b1fbd52971d90dff577465b644aee7c878f15ede57f46e8f217067a'
|
||||||
|
|
||||||
|
url 'https://github.com/nicoverbruggen/phpmon/releases/download/v5.7.2/phpmon-dev.zip'
|
||||||
|
appcast 'https://github.com/nicoverbruggen/phpmon/releases.atom'
|
||||||
|
name 'PHP Monitor DEV'
|
||||||
|
homepage 'https://phpmon.app'
|
||||||
|
|
||||||
|
app 'PHP Monitor DEV.app', target: "PHP Monitor DEV.app"
|
||||||
|
end
|
||||||
|
|
@ -1,47 +0,0 @@
|
|||||||
//
|
|
||||||
// AppUpdaterCheckTest.swift
|
|
||||||
// PHP Monitor
|
|
||||||
//
|
|
||||||
// Created by Nico Verbruggen on 10/05/2022.
|
|
||||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import XCTest
|
|
||||||
|
|
||||||
class AppUpdaterCheckTest: XCTestCase {
|
|
||||||
|
|
||||||
func test_can_retrieve_version_from_cask() async {
|
|
||||||
let caskVersion = await AppUpdateChecker.retrieveVersionFromCask()
|
|
||||||
|
|
||||||
let version = VersionExtractor.from(caskVersion)
|
|
||||||
|
|
||||||
XCTAssertNotNil(version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_tagged_release_omits_zero_patch() {
|
|
||||||
let version = AppVersion.from("3.5.0_333")!
|
|
||||||
|
|
||||||
XCTAssertEqual(version.tagged, "3.5")
|
|
||||||
XCTAssertEqual(version.version, "3.5.0")
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_tagged_release_doesnt_omit_non_zero_patch() {
|
|
||||||
let version = AppVersion.from("3.5.1_333")!
|
|
||||||
|
|
||||||
XCTAssertEqual(version.tagged, "3.5.1")
|
|
||||||
XCTAssertEqual(version.version, "3.5.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_tag_truncation_does_not_affect_major_versions() {
|
|
||||||
var version = AppVersion.from("5.0_333")!
|
|
||||||
|
|
||||||
XCTAssertEqual(version.tagged, "5.0")
|
|
||||||
XCTAssertEqual(version.version, "5.0")
|
|
||||||
|
|
||||||
version = AppVersion.from("5.0.0_333")!
|
|
||||||
|
|
||||||
XCTAssertEqual(version.tagged, "5.0")
|
|
||||||
XCTAssertEqual(version.version, "5.0.0")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -28,7 +28,7 @@ class AppVersionTest: XCTestCase {
|
|||||||
|
|
||||||
XCTAssertNotNil(version)
|
XCTAssertNotNil(version)
|
||||||
XCTAssertEqual("1.0.0", version?.version)
|
XCTAssertEqual("1.0.0", version?.version)
|
||||||
XCTAssertEqual("600", version?.build)
|
XCTAssertEqual(600, version?.build)
|
||||||
XCTAssertEqual(nil, version?.suffix)
|
XCTAssertEqual(nil, version?.suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class AppVersionTest: XCTestCase {
|
|||||||
|
|
||||||
XCTAssertNotNil(version)
|
XCTAssertNotNil(version)
|
||||||
XCTAssertEqual("1.0.0", version?.version)
|
XCTAssertEqual("1.0.0", version?.version)
|
||||||
XCTAssertEqual("870", version?.build)
|
XCTAssertEqual(870, version?.build)
|
||||||
XCTAssertEqual("dev", version?.suffix)
|
XCTAssertEqual("dev", version?.suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +55,48 @@ class AppVersionTest: XCTestCase {
|
|||||||
|
|
||||||
XCTAssertNotNil(version)
|
XCTAssertNotNil(version)
|
||||||
XCTAssertEqual("1.0.0", version?.version)
|
XCTAssertEqual("1.0.0", version?.version)
|
||||||
XCTAssertEqual("870", version?.build)
|
XCTAssertEqual(870, version?.build)
|
||||||
XCTAssertEqual("dev", version?.suffix)
|
XCTAssertEqual("dev", version?.suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_tagged_release_omits_zero_patch() {
|
||||||
|
let version = AppVersion.from("3.5.0_333")!
|
||||||
|
|
||||||
|
XCTAssertEqual(version.tagged, "3.5")
|
||||||
|
XCTAssertEqual(version.version, "3.5.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_tagged_release_doesnt_omit_non_zero_patch() {
|
||||||
|
let version = AppVersion.from("3.5.1_333")!
|
||||||
|
|
||||||
|
XCTAssertEqual(version.tagged, "3.5.1")
|
||||||
|
XCTAssertEqual(version.version, "3.5.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_tag_truncation_does_not_affect_major_versions() {
|
||||||
|
var version = AppVersion.from("5.0_333")!
|
||||||
|
|
||||||
|
XCTAssertEqual(version.tagged, "5.0")
|
||||||
|
XCTAssertEqual(version.version, "5.0")
|
||||||
|
|
||||||
|
version = AppVersion.from("5.0.0_333")!
|
||||||
|
|
||||||
|
XCTAssertEqual(version.tagged, "5.0")
|
||||||
|
XCTAssertEqual(version.version, "5.0.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_can_compare_version_numbers() {
|
||||||
|
// Build is newer
|
||||||
|
XCTAssertTrue(AppVersion.from("5.0_101")! > AppVersion.from("5.0_100")!)
|
||||||
|
|
||||||
|
// Version and build is the same
|
||||||
|
XCTAssertFalse(AppVersion.from("5.0.0_100")! > AppVersion.from("5.0_100")!)
|
||||||
|
|
||||||
|
// Version is newer
|
||||||
|
XCTAssertTrue(AppVersion.from("5.1_100")! > AppVersion.from("5.0_100")!)
|
||||||
|
|
||||||
|
// Build is older
|
||||||
|
XCTAssertFalse(AppVersion.from("5.0_101")! > AppVersion.from("5.0_102")!)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,53 @@ class PhpVersionNumberTest: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_can_parse_wildcard() throws {
|
||||||
|
let version = VersionNumber.make(from: "7.*", type: .wildCardMinor)
|
||||||
|
XCTAssertNotNil(version)
|
||||||
|
XCTAssertEqual(version!.major, 7)
|
||||||
|
XCTAssertEqual(version!.minor, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func test_can_check_wildcard_version_constraint() throws {
|
||||||
|
// Wildcard for patch only
|
||||||
|
XCTAssertEqual(
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["7.4.10", "7.3.10", "7.3.9"])
|
||||||
|
.matching(constraint: "7.3.*", strict: false),
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["7.3.10", "7.3.9"]).all
|
||||||
|
)
|
||||||
|
|
||||||
|
// Wildcard for minor
|
||||||
|
XCTAssertEqual(
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["8.0.0", "7.4.10", "7.3.10", "7.3.9"])
|
||||||
|
.matching(constraint: "7.*", strict: false),
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["7.4.10", "7.3.10", "7.3.9"]).all
|
||||||
|
)
|
||||||
|
|
||||||
|
// Full wildcard
|
||||||
|
XCTAssertEqual(
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"])
|
||||||
|
.matching(constraint: "*", strict: false),
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"]).all
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_can_check_any_version_constraint() throws {
|
||||||
|
XCTAssertEqual(
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"])
|
||||||
|
.matching(constraint: "*", strict: false),
|
||||||
|
PhpVersionNumberCollection
|
||||||
|
.make(from: ["7.4.10", "7.3.10", "7.2.10", "7.1.10", "7.0.10"]).all
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func test_can_check_fixed_constraints() throws {
|
func test_can_check_fixed_constraints() throws {
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
PhpVersionNumberCollection
|
PhpVersionNumberCollection
|
||||||
|
Reference in New Issue
Block a user