mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
b0de0c04c6 | |||
f27e07fc78 | |||
9fceab3e2e | |||
03fdf23f0a | |||
412b7bad5c |
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,5 +2,4 @@ phpmon.xcodeproj/project.xcworkspace
|
||||
phpmon.xcodeproj/xcuserdata
|
||||
PHP Monitor.xcodeproj/project.xcworkspace
|
||||
PHP Monitor.xcodeproj/xcuserdata
|
||||
phpmon-updater/PHP Monitor Self-Updater.app
|
||||
.DS_Store
|
@ -182,6 +182,9 @@
|
||||
C469E700294CF7B200A82AB2 /* 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 */; };
|
||||
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 */; };
|
||||
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
|
||||
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
|
||||
@ -321,6 +324,7 @@
|
||||
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
|
||||
C471E84728F9BB650021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.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 */; };
|
||||
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
|
||||
@ -410,6 +414,7 @@
|
||||
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
|
||||
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.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 */; };
|
||||
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
|
||||
@ -506,17 +511,6 @@
|
||||
C48D6C70279CD2AC00F26D7E /* 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 */; };
|
||||
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 */; };
|
||||
C4927F0C27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
|
||||
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4930849279F331F009C240B /* AddSiteVC.swift */; };
|
||||
@ -839,6 +833,8 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -862,11 +858,6 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -1149,7 +1140,6 @@
|
||||
C4F5FBCC28218C93001065C5 /* .swiftlint.yml */,
|
||||
C4E713572570151400007428 /* docs */,
|
||||
C41C1B3522B0097F00E7CF16 /* phpmon */,
|
||||
C491998829902061001F3A21 /* phpmon-updater */,
|
||||
C471E79628F9B4260021E251 /* tests */,
|
||||
C41C1B3422B0097F00E7CF16 /* Products */,
|
||||
C4D309E72770EF2F00958BCF /* Frameworks */,
|
||||
@ -1310,7 +1300,6 @@
|
||||
C459B4BF27F6094100E9B4B4 /* brew */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C491997829901DE2001F3A21 /* phpmon-dev.rb */,
|
||||
C4E2E85228FC256B003B070C /* brew-services-normal.json */,
|
||||
C4E2E85128FC256B003B070C /* brew-services-sudo.json */,
|
||||
C43A8A1F25D9D1D700591B77 /* brew-formula.json */,
|
||||
@ -1455,14 +1444,6 @@
|
||||
path = "PHP Version";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C491998829902061001F3A21 /* phpmon-updater */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C491998929902089001F3A21 /* PHP Monitor Self-Updater.app */,
|
||||
);
|
||||
path = "phpmon-updater";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C4AF9F6A275445C900D44ED0 /* Valet */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1490,7 +1471,6 @@
|
||||
C4AF9F6C275445D900D44ED0 /* Homebrew */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C491997A29901DF7001F3A21 /* CaskFile.swift */,
|
||||
C4F2E4362752F0870020E974 /* HomebrewDiagnostics.swift */,
|
||||
);
|
||||
path = Homebrew;
|
||||
@ -1511,8 +1491,8 @@
|
||||
C4EED88827A48778006D7272 /* InterAppHandler.swift */,
|
||||
C4D8016522B1584700C6DA1B /* Startup.swift */,
|
||||
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */,
|
||||
C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */,
|
||||
C40FE736282ABA4F00A302C2 /* AppVersion.swift */,
|
||||
C491997F29901E0F001F3A21 /* AppUpdater.swift */,
|
||||
C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */,
|
||||
);
|
||||
path = App;
|
||||
@ -1600,7 +1580,6 @@
|
||||
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */,
|
||||
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */,
|
||||
C4551656297AED18009B8466 /* ValetRcTest.swift */,
|
||||
C491997629901DD6001F3A21 /* CaskFileParserTest.swift */,
|
||||
);
|
||||
path = Parsers;
|
||||
sourceTree = "<group>";
|
||||
@ -1613,6 +1592,7 @@
|
||||
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */,
|
||||
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */,
|
||||
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */,
|
||||
C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */,
|
||||
);
|
||||
path = Versions;
|
||||
sourceTree = "<group>";
|
||||
@ -1923,7 +1903,6 @@
|
||||
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */,
|
||||
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */,
|
||||
C405A4D124B9B9140062FAFA /* InternetAccessPolicy.plist in Resources */,
|
||||
C491998A29902089001F3A21 /* PHP Monitor Self-Updater.app in Resources */,
|
||||
C44C1991276E44CB0072762D /* ProgressWindow.storyboard in Resources */,
|
||||
C4232EE52612526500158FC6 /* Credits.html in Resources */,
|
||||
54FCFD26276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
|
||||
@ -1979,7 +1958,6 @@
|
||||
C455165B297AEDB5009B8466 /* valetrc.broken in Resources */,
|
||||
54A18D40282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test in Resources */,
|
||||
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */,
|
||||
C491997929901DE2001F3A21 /* phpmon-dev.rb in Resources */,
|
||||
C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */,
|
||||
C4E2E85428FC256B003B070C /* brew-services-sudo.json in Resources */,
|
||||
);
|
||||
@ -2092,7 +2070,6 @@
|
||||
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
|
||||
C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
||||
54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */,
|
||||
C491997B29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||
C4297F7A28970D59004C4630 /* WarningView.swift in Sources */,
|
||||
C4C0E8E227F88B13002D32A9 /* ValetDomainScanner.swift in Sources */,
|
||||
C42F26732805B4B400938AC7 /* ValetListable.swift in Sources */,
|
||||
@ -2104,6 +2081,7 @@
|
||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
|
||||
C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */,
|
||||
C41CA5ED2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */,
|
||||
C46E206D28299B3800D909D6 /* AppUpdateChecker.swift in Sources */,
|
||||
C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */,
|
||||
03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */,
|
||||
C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */,
|
||||
@ -2169,7 +2147,6 @@
|
||||
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
|
||||
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */,
|
||||
C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */,
|
||||
C491998029901E0F001F3A21 /* AppUpdater.swift in Sources */,
|
||||
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -2201,13 +2178,13 @@
|
||||
C471E84228F9BB650021E251 /* AppDelegate+InterApp.swift in Sources */,
|
||||
C471E84328F9BB650021E251 /* App.swift in Sources */,
|
||||
C4E2E85E28FC282B003B070C /* TestableConfiguration.swift in Sources */,
|
||||
C491997D29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||
C45E2A7529199248005C7CFD /* InternalSwitcherTest.swift in Sources */,
|
||||
C471E84428F9BB650021E251 /* App+ActivationPolicy.swift in Sources */,
|
||||
C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */,
|
||||
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */,
|
||||
C471E84728F9BB650021E251 /* Startup.swift in Sources */,
|
||||
C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */,
|
||||
C471E84928F9BB650021E251 /* AppUpdateChecker.swift in Sources */,
|
||||
C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */,
|
||||
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */,
|
||||
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */,
|
||||
@ -2249,7 +2226,6 @@
|
||||
C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */,
|
||||
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
|
||||
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
|
||||
C491998229901E0F001F3A21 /* AppUpdater.swift in Sources */,
|
||||
C4D3660D29113F20006BD146 /* System.swift in Sources */,
|
||||
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
|
||||
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||
@ -2374,6 +2350,7 @@
|
||||
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */,
|
||||
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */,
|
||||
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */,
|
||||
C471E8AC28F9BB8F0021E251 /* AppUpdateChecker.swift in Sources */,
|
||||
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */,
|
||||
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */,
|
||||
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */,
|
||||
@ -2467,7 +2444,6 @@
|
||||
C471E81028F9BAE80021E251 /* StringExtension.swift in Sources */,
|
||||
C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
|
||||
C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */,
|
||||
C491997E29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
|
||||
C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */,
|
||||
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
||||
@ -2481,7 +2457,6 @@
|
||||
C471E7D228F9BA630021E251 /* ActiveFileSystem.swift in Sources */,
|
||||
C471E80028F9BAD10021E251 /* Xdebug.swift in Sources */,
|
||||
C471E7F528F9BAC80021E251 /* PhpEnv.swift in Sources */,
|
||||
C491998329901E0F001F3A21 /* AppUpdater.swift in Sources */,
|
||||
C471E7ED28F9BAC30021E251 /* Process.swift in Sources */,
|
||||
C471E81128F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
|
||||
C471E7CC28F9BA5B0021E251 /* TestableShell.swift in Sources */,
|
||||
@ -2549,7 +2524,6 @@
|
||||
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
||||
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
|
||||
C4F780CE25D80B75000DBC97 /* LocalNotification.swift in Sources */,
|
||||
C491997C29901DF7001F3A21 /* CaskFile.swift in Sources */,
|
||||
C40C7F2927721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */,
|
||||
C485707A28BF457800539B36 /* WarningListView.swift in Sources */,
|
||||
C4C0E8E827F88B41002D32A9 /* DomainScanner.swift in Sources */,
|
||||
@ -2600,7 +2574,6 @@
|
||||
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */,
|
||||
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */,
|
||||
C41E871B2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
|
||||
C491998129901E0F001F3A21 /* AppUpdater.swift in Sources */,
|
||||
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */,
|
||||
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
|
||||
C4AD38B328ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */,
|
||||
@ -2627,6 +2600,7 @@
|
||||
C4E2E86528FC2F1B003B070C /* XCPMApplication.swift in Sources */,
|
||||
C4E49DE828F764050026AC4E /* ActiveCommand.swift in Sources */,
|
||||
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */,
|
||||
C46E20702829D27F00D909D6 /* AppUpdaterCheckTest.swift in Sources */,
|
||||
C485707D28BF45A200539B36 /* WarningView.swift in Sources */,
|
||||
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */,
|
||||
C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
|
||||
@ -2649,7 +2623,6 @@
|
||||
C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */,
|
||||
C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
||||
C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */,
|
||||
C491997729901DD6001F3A21 /* CaskFileParserTest.swift in Sources */,
|
||||
C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */,
|
||||
C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */,
|
||||
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */,
|
||||
@ -2694,6 +2667,7 @@
|
||||
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */,
|
||||
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */,
|
||||
C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */,
|
||||
C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -2857,7 +2831,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1060;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -2869,7 +2843,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -2886,7 +2860,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1060;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -2898,7 +2872,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -3114,7 +3088,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1060;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@ -3125,7 +3099,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -3224,7 +3198,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1060;
|
||||
CURRENT_PROJECT_VERSION = 1040;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@ -3235,7 +3209,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 5.8;
|
||||
MARKETING_VERSION = 5.7.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -91,7 +91,7 @@
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "--cli"
|
||||
isEnabled = "NO">
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "--configuration:~/.phpmon_fconf_working.json"
|
||||
|
16
README.md
16
README.md
@ -43,24 +43,22 @@ valet install
|
||||
valet trust
|
||||
```
|
||||
|
||||
#### Manual installation (first time only)
|
||||
Once that's done, you can install PHP Monitor via Homebrew (recommended), or (alternatively) you may download the latest release on GitHub.
|
||||
|
||||
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:
|
||||
To install via Homebrew, run:
|
||||
|
||||
```sh
|
||||
brew tap nicoverbruggen/homebrew-cask
|
||||
brew install --cask phpmon
|
||||
```
|
||||
|
||||
## ⬆️ How to update
|
||||
To upgrade your existing installation, run:
|
||||
|
||||
The recommended method of updating your app to the latest version is to use **the built-in updater**.
|
||||
```sh
|
||||
brew upgrade phpmon
|
||||
```
|
||||
|
||||
If that doesn't work or you prefer Homebrew, you can also upgrade via those methods.
|
||||
(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.)
|
||||
|
||||
## ⚡️ Launchers (Alfred, Raycast)
|
||||
|
||||
|
@ -13,21 +13,21 @@ class Actions {
|
||||
// MARK: - Services
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
await brew("services stop \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
|
||||
await brew("services stop \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
|
||||
}
|
||||
|
||||
public static func fixHomebrewPermissions() throws {
|
||||
@ -54,9 +54,10 @@ class Actions {
|
||||
+ " && "
|
||||
+ cellarCommands.joined(separator: " && ")
|
||||
|
||||
let appleScript = NSAppleScript(
|
||||
source: "do shell script \"\(script)\" with administrator privileges"
|
||||
)
|
||||
let source = "do shell script \"\(script)\" with administrator privileges"
|
||||
|
||||
Log.perf(source)
|
||||
let appleScript = NSAppleScript(source: source)
|
||||
|
||||
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 elevated: Bool
|
||||
|
||||
var description: String {
|
||||
return name
|
||||
}
|
||||
|
||||
init(_ name: String, elevated: Bool = true) {
|
||||
self.name = name
|
||||
self.elevated = elevated
|
||||
|
@ -41,24 +41,21 @@ class RealFileSystem: FileSystemProtocol {
|
||||
}
|
||||
|
||||
func getShallowContentsOfDirectory(_ path: String) throws -> [String] {
|
||||
return try FileManager.default.contentsOfDirectory(atPath: path.replacingTildeWithHomeDirectory)
|
||||
return try FileManager.default.contentsOfDirectory(atPath: path)
|
||||
}
|
||||
|
||||
func getDestinationOfSymlink(_ path: String) throws -> String {
|
||||
return try FileManager.default.destinationOfSymbolicLink(atPath: path.replacingTildeWithHomeDirectory)
|
||||
return try FileManager.default.destinationOfSymbolicLink(atPath: path)
|
||||
}
|
||||
|
||||
// MARK: - Move & Delete Files
|
||||
|
||||
func move(from path: String, to newPath: String) throws {
|
||||
try FileManager.default.moveItem(
|
||||
atPath: path.replacingTildeWithHomeDirectory,
|
||||
toPath: newPath.replacingTildeWithHomeDirectory
|
||||
)
|
||||
try FileManager.default.moveItem(atPath: path, toPath: newPath)
|
||||
}
|
||||
|
||||
func remove(_ path: String) throws {
|
||||
try FileManager.default.removeItem(atPath: path.replacingTildeWithHomeDirectory)
|
||||
try FileManager.default.removeItem(atPath: path)
|
||||
}
|
||||
|
||||
// MARK: — FS Attributes
|
||||
|
@ -10,8 +10,8 @@ import UserNotifications
|
||||
|
||||
class LocalNotification {
|
||||
|
||||
@MainActor public static func send(title: String, subtitle: String, preference: PreferenceName?) {
|
||||
if preference != nil && !Preferences.isEnabled(preference!) {
|
||||
@MainActor public static func send(title: String, subtitle: String, preference: PreferenceName) {
|
||||
if !Preferences.isEnabled(preference) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,3 @@ public func system(_ command: String) -> String {
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
public func system_quiet(_ command: String) {
|
||||
_ = system(command)
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
import Foundation
|
||||
|
||||
struct HomebrewPackage: Decodable {
|
||||
|
||||
let name: String
|
||||
let full_name: String
|
||||
let aliases: [String]
|
||||
let installed: [HomebrewInstalled]
|
||||
|
@ -115,12 +115,14 @@ class RealShell: ShellProtocol {
|
||||
)!
|
||||
|
||||
if Log.shared.verbosity == .cli {
|
||||
var args = task.arguments ?? []
|
||||
let last = "\"" + (args.popLast() ?? "") + "\""
|
||||
var args = task.arguments
|
||||
let last: String = "\"" + (args?.popLast() ?? "") + "\""
|
||||
let concat = [self.launchPath] + task.arguments! + [last]
|
||||
let command = concat.joined(separator: " ")
|
||||
var log = """
|
||||
|
||||
<~~~~~~~~~~~~~~~~~~~~~~~
|
||||
$ \(([self.launchPath] + args + [last]).joined(separator: " "))
|
||||
$ \(command)
|
||||
|
||||
[OUT]:
|
||||
\(stdOut)
|
||||
|
182
phpmon/Domain/App/AppUpdateChecker.swift
Normal file
182
phpmon/Domain/App/AppUpdateChecker.swift
Normal file
@ -0,0 +1,182 @@
|
||||
//
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
class AppVersion: Comparable {
|
||||
class AppVersion {
|
||||
var version: String
|
||||
var build: Int?
|
||||
var build: String?
|
||||
var suffix: String?
|
||||
|
||||
init(version: String, build: String?, suffix: String? = nil) {
|
||||
self.version = version
|
||||
self.build = Int(build ?? "0")
|
||||
self.build = build
|
||||
self.suffix = suffix
|
||||
}
|
||||
|
||||
@ -75,27 +75,11 @@ class AppVersion: Comparable {
|
||||
}
|
||||
|
||||
var computerReadable: String {
|
||||
return "\(version)_\(build ?? 0)"
|
||||
return "\(version)_\(build ?? "0")"
|
||||
}
|
||||
|
||||
var humanReadable: String {
|
||||
return "\(version) (\(build ?? 0))"
|
||||
return "\(version) (\(build ?? "???"))"
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public class EnvironmentManager {
|
||||
|
||||
// Failure condition #1: does not contain Laravel Valet
|
||||
if !output.contains("Laravel Valet") {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
// Extract the version number
|
||||
@ -25,7 +25,6 @@ public class EnvironmentManager {
|
||||
|
||||
// Get the actual version
|
||||
return Valet.shared.version == nil
|
||||
|
||||
}() // returns true if none of the failure conditions are met
|
||||
}
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
}
|
@ -112,15 +112,12 @@ extension MainMenu {
|
||||
}
|
||||
}
|
||||
|
||||
await AppUpdater().checkForUpdates(interactive: false)
|
||||
await AppUpdateChecker.checkIfNewerVersionIsAvailable()
|
||||
}
|
||||
|
||||
// Check if the linked version has changed between launches of phpmon
|
||||
Stats.evaluateLastLinkedPhpVersion()
|
||||
|
||||
// Check if an update was performed earlier
|
||||
AppUpdater.checkIfUpdateWasPerformed()
|
||||
|
||||
// We are ready!
|
||||
Log.info("PHP Monitor is ready to serve!")
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
}
|
||||
|
||||
@objc func checkForUpdates() {
|
||||
Task { await AppUpdater().checkForUpdates(interactive: true) }
|
||||
Task { await AppUpdateChecker.checkIfNewerVersionIsAvailable(initiatedFromBackground: false) }
|
||||
}
|
||||
|
||||
// MARK: - Menu Delegate
|
||||
|
@ -617,8 +617,9 @@ COMMON TROUBLESHOOTING TIPS
|
||||
|
||||
"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.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.direct" = "The recommended method of installing updates to PHP Monitor is to simply press 'Install Update'.";
|
||||
"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" = "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" = "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.is_latest_version.title" = "PHP Monitor is up-to-date!";
|
||||
@ -628,8 +629,6 @@ 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.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.install" = "Install Update";
|
||||
"updater.alerts.buttons.dismiss" = "Dismiss";
|
||||
|
||||
// WARNINGS ABOUT NON-DEFAULT TLD
|
||||
|
||||
|
@ -1,53 +0,0 @@
|
||||
//
|
||||
// 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"))
|
||||
}
|
||||
|
||||
}
|
@ -23,11 +23,10 @@ class HomebrewPackageTest: XCTestCase {
|
||||
[HomebrewPackage].self, from: json.data(using: .utf8)!
|
||||
).first!
|
||||
|
||||
XCTAssertEqual(package.name, "php")
|
||||
XCTAssertEqual(package.full_name, "php")
|
||||
XCTAssertEqual(package.aliases.first!, "php@8.1")
|
||||
XCTAssertEqual(package.aliases.first!, "php@8.2")
|
||||
XCTAssertEqual(package.installed.contains(where: { installed in
|
||||
installed.version.starts(with: "8.1")
|
||||
installed.version.starts(with: "8.2")
|
||||
}), true)
|
||||
}
|
||||
|
||||
|
@ -1,69 +1,77 @@
|
||||
[
|
||||
{
|
||||
"name": "php",
|
||||
"full_name": "php",
|
||||
"tap": "homebrew/core",
|
||||
"oldname": null,
|
||||
"aliases": [
|
||||
"php@8.1"
|
||||
"php@8.2"
|
||||
],
|
||||
"versioned_formulae": [
|
||||
"php@8.1",
|
||||
"php@8.0",
|
||||
"php@7.4",
|
||||
"php@7.3",
|
||||
"php@7.2"
|
||||
"php@7.4"
|
||||
],
|
||||
"desc": "General-purpose scripting language",
|
||||
"license": "PHP-3.01",
|
||||
"homepage": "https://www.php.net/",
|
||||
"versions": {
|
||||
"stable": "8.1.10",
|
||||
"stable": "8.2.2",
|
||||
"head": "HEAD",
|
||||
"bottle": true
|
||||
},
|
||||
"urls": {
|
||||
"stable": {
|
||||
"url": "https://www.php.net/distributions/php-8.1.10.tar.xz",
|
||||
"url": "https://www.php.net/distributions/php-8.2.2.tar.xz",
|
||||
"tag": null,
|
||||
"revision": null
|
||||
"revision": null,
|
||||
"checksum": "bdc4aa38e652bac86039601840bae01c0c3653972eaa6f9f93d5f71953a7ee33"
|
||||
},
|
||||
"head": {
|
||||
"url": "https://github.com/php/php-src.git",
|
||||
"branch": "master"
|
||||
}
|
||||
},
|
||||
"revision": 1,
|
||||
"revision": 0,
|
||||
"version_scheme": 0,
|
||||
"bottle": {
|
||||
"stable": {
|
||||
"rebuild": 0,
|
||||
"root_url": "https://ghcr.io/v2/homebrew/core",
|
||||
"files": {
|
||||
"arm64_ventura": {
|
||||
"cellar": "/opt/homebrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:ad2e6a6f1cdc65c22b39bd607cbb7305958951cf58ee87d5060717be5a8b5a45",
|
||||
"sha256": "ad2e6a6f1cdc65c22b39bd607cbb7305958951cf58ee87d5060717be5a8b5a45"
|
||||
},
|
||||
"arm64_monterey": {
|
||||
"cellar": "/opt/homebrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:dcee33c9f445db3026a7e867805eb8f6d82e9e5599599b8c6cd8645475f7961c",
|
||||
"sha256": "dcee33c9f445db3026a7e867805eb8f6d82e9e5599599b8c6cd8645475f7961c"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:27069c973e63f38a3cb4fad1c7a2e17853bcffe318c8a957ff96a1026dff0cac",
|
||||
"sha256": "27069c973e63f38a3cb4fad1c7a2e17853bcffe318c8a957ff96a1026dff0cac"
|
||||
},
|
||||
"arm64_big_sur": {
|
||||
"cellar": "/opt/homebrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:e0590064cd32f2baa4102fa49c80056f3886a0a89aec0589d0134ecbf0e7923e",
|
||||
"sha256": "e0590064cd32f2baa4102fa49c80056f3886a0a89aec0589d0134ecbf0e7923e"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:ceef280bcd57e5f794ae59cc75e83d407c9704aa3d238b282bda52cbc644d0dd",
|
||||
"sha256": "ceef280bcd57e5f794ae59cc75e83d407c9704aa3d238b282bda52cbc644d0dd"
|
||||
},
|
||||
"ventura": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:22f733b7b0b0ed95cd6b0a1534b9eca4cf63fe54647394c3f7e7ac019eb019ff",
|
||||
"sha256": "22f733b7b0b0ed95cd6b0a1534b9eca4cf63fe54647394c3f7e7ac019eb019ff"
|
||||
},
|
||||
"monterey": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:62481320613b19c6ff310bf6ed50c7d2a2253cdbf403af12ec97bccd8a97a84c",
|
||||
"sha256": "62481320613b19c6ff310bf6ed50c7d2a2253cdbf403af12ec97bccd8a97a84c"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:9ff8f5e1df5e849567cdb2ddea6d3c2a2b9cae024842c9ac65b35a01657bfc37",
|
||||
"sha256": "9ff8f5e1df5e849567cdb2ddea6d3c2a2b9cae024842c9ac65b35a01657bfc37"
|
||||
},
|
||||
"big_sur": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:b34d96f7aad3c580a7cbdaadb8054fb9b6872111a5eec8e1bcb4a529970c8e03",
|
||||
"sha256": "b34d96f7aad3c580a7cbdaadb8054fb9b6872111a5eec8e1bcb4a529970c8e03"
|
||||
},
|
||||
"catalina": {
|
||||
"cellar": "/usr/local/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:cc0b85dcfdd60e1d8d7fa74c9f53be5d249d068835dbc7a81edacb7a076b6c76",
|
||||
"sha256": "cc0b85dcfdd60e1d8d7fa74c9f53be5d249d068835dbc7a81edacb7a076b6c76"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:11fd1ea6da8ef728b7cacd4da8a51ed125069595abf4e37ae1552d418560c5fb",
|
||||
"sha256": "11fd1ea6da8ef728b7cacd4da8a51ed125069595abf4e37ae1552d418560c5fb"
|
||||
},
|
||||
"x86_64_linux": {
|
||||
"cellar": "/home/linuxbrew/.linuxbrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:b934a5a4ad2d29b629f83962b57f638a654801d1ba21ba659a42da2e5afe3fae",
|
||||
"sha256": "b934a5a4ad2d29b629f83962b57f638a654801d1ba21ba659a42da2e5afe3fae"
|
||||
"url": "https://ghcr.io/v2/homebrew/core/php/blobs/sha256:baaa41e60f9e8125fe8f549d4813a8476a8947a1f10d7817a2ee36d8baa625f3",
|
||||
"sha256": "baaa41e60f9e8125fe8f549d4813a8476a8947a1f10d7817a2ee36d8baa625f3"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,34 +135,35 @@
|
||||
"conflicts_with": [
|
||||
|
||||
],
|
||||
"caveats": "To enable PHP in Apache add the following to httpd.conf and restart Apache:\n LoadModule php_module $(brew --prefix)/opt/php/lib/httpd/modules/libphp.so\n\n <FilesMatch \\.php$>\n SetHandler application/x-httpd-php\n </FilesMatch>\n\nFinally, check DirectoryIndex includes index.php\n DirectoryIndex index.php index.html\n\nThe php.ini and php-fpm.ini file can be found in:\n $(brew --prefix)/etc/php/8.1/\n",
|
||||
"caveats": "To enable PHP in Apache add the following to httpd.conf and restart Apache:\n LoadModule php_module $(brew --prefix)/opt/php/lib/httpd/modules/libphp.so\n\n <FilesMatch \\.php$>\n SetHandler application/x-httpd-php\n </FilesMatch>\n\nFinally, check DirectoryIndex includes index.php\n DirectoryIndex index.php index.html\n\nThe php.ini and php-fpm.ini file can be found in:\n $(brew --prefix)/etc/php/8.2/\n",
|
||||
"installed": [
|
||||
{
|
||||
"version": "8.1.10_1",
|
||||
"version": "8.2.2",
|
||||
"used_options": [
|
||||
|
||||
],
|
||||
"built_as_bottle": true,
|
||||
"poured_from_bottle": true,
|
||||
"time": 1675654665,
|
||||
"runtime_dependencies": [
|
||||
{
|
||||
"full_name": "apr",
|
||||
"version": "1.7.0",
|
||||
"version": "1.7.2",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "ca-certificates",
|
||||
"version": "2022-07-19",
|
||||
"version": "2023-01-10",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "openssl@1.1",
|
||||
"version": "1.1.1q",
|
||||
"version": "1.1.1s",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "apr-util",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.3",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -182,24 +191,24 @@
|
||||
"version": "1.0.9",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "gettext",
|
||||
"version": "0.21",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libunistring",
|
||||
"version": "1.0",
|
||||
"version": "1.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "gettext",
|
||||
"version": "0.21.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libidn2",
|
||||
"version": "2.3.3",
|
||||
"version": "2.3.4",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "libnghttp2",
|
||||
"version": "1.49.0",
|
||||
"version": "1.51.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -224,7 +233,7 @@
|
||||
},
|
||||
{
|
||||
"full_name": "xz",
|
||||
"version": "5.2.6",
|
||||
"version": "5.4.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -234,7 +243,7 @@
|
||||
},
|
||||
{
|
||||
"full_name": "curl",
|
||||
"version": "7.85.0",
|
||||
"version": "7.87.0",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -249,12 +258,12 @@
|
||||
},
|
||||
{
|
||||
"full_name": "freetds",
|
||||
"version": "1.3.13",
|
||||
"version": "1.3.17",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libpng",
|
||||
"version": "1.6.37",
|
||||
"version": "1.6.39",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -264,12 +273,12 @@
|
||||
},
|
||||
{
|
||||
"full_name": "fontconfig",
|
||||
"version": "2.14.0",
|
||||
"version": "2.14.2",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "jpeg-turbo",
|
||||
"version": "2.1.4",
|
||||
"version": "2.1.5",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -278,13 +287,13 @@
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "imath",
|
||||
"version": "3.1.5",
|
||||
"full_name": "highway",
|
||||
"version": "1.0.3",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "openexr",
|
||||
"version": "3.1.5",
|
||||
"full_name": "imath",
|
||||
"version": "3.1.6",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -292,14 +301,24 @@
|
||||
"version": "4.4.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "little-cms2",
|
||||
"version": "2.14",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "openexr",
|
||||
"version": "3.1.5",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "webp",
|
||||
"version": "1.2.4",
|
||||
"version": "1.3.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "jpeg-xl",
|
||||
"version": "0.6.1",
|
||||
"version": "0.8.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -309,12 +328,12 @@
|
||||
},
|
||||
{
|
||||
"full_name": "aom",
|
||||
"version": "3.4.0",
|
||||
"version": "3.5.0",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "libavif",
|
||||
"version": "0.10.1",
|
||||
"version": "0.11.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
@ -329,17 +348,17 @@
|
||||
},
|
||||
{
|
||||
"full_name": "icu4c",
|
||||
"version": "71.1",
|
||||
"version": "72.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "krb5",
|
||||
"version": "1.20",
|
||||
"version": "1.20.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "libpq",
|
||||
"version": "14.5",
|
||||
"version": "15.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -359,17 +378,17 @@
|
||||
},
|
||||
{
|
||||
"full_name": "pcre2",
|
||||
"version": "10.40",
|
||||
"version": "10.42",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
"full_name": "readline",
|
||||
"version": "8.1.2",
|
||||
"version": "8.2.1",
|
||||
"declared_directly": false
|
||||
},
|
||||
{
|
||||
"full_name": "sqlite",
|
||||
"version": "3.39.2",
|
||||
"version": "3.40.1",
|
||||
"declared_directly": true
|
||||
},
|
||||
{
|
||||
@ -382,7 +401,7 @@
|
||||
"installed_on_request": true
|
||||
}
|
||||
],
|
||||
"linked_keg": "8.1.10_1",
|
||||
"linked_keg": "8.2.2",
|
||||
"pinned": false,
|
||||
"outdated": false,
|
||||
"deprecated": false,
|
||||
@ -390,6 +409,8 @@
|
||||
"deprecation_reason": null,
|
||||
"disabled": false,
|
||||
"disable_date": null,
|
||||
"disable_reason": null
|
||||
"disable_reason": null,
|
||||
"tap_git_head": "0bbb89420e74756a5a5c145ed7efa4a32f7e7e7c"
|
||||
}
|
||||
]
|
||||
|
||||
]
|
||||
|
@ -1,14 +0,0 @@
|
||||
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
|
||||
|
47
tests/unit/Versions/AppUpdaterCheckTest.swift
Normal file
47
tests/unit/Versions/AppUpdaterCheckTest.swift
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// 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)
|
||||
XCTAssertEqual("1.0.0", version?.version)
|
||||
XCTAssertEqual(600, version?.build)
|
||||
XCTAssertEqual("600", version?.build)
|
||||
XCTAssertEqual(nil, version?.suffix)
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ class AppVersionTest: XCTestCase {
|
||||
|
||||
XCTAssertNotNil(version)
|
||||
XCTAssertEqual("1.0.0", version?.version)
|
||||
XCTAssertEqual(870, version?.build)
|
||||
XCTAssertEqual("870", version?.build)
|
||||
XCTAssertEqual("dev", version?.suffix)
|
||||
}
|
||||
|
||||
@ -55,48 +55,8 @@ class AppVersionTest: XCTestCase {
|
||||
|
||||
XCTAssertNotNil(version)
|
||||
XCTAssertEqual("1.0.0", version?.version)
|
||||
XCTAssertEqual(870, version?.build)
|
||||
XCTAssertEqual("870", version?.build)
|
||||
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")!)
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user