1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-08 04:20:07 +02:00

Compare commits

...

73 Commits

Author SHA1 Message Date
cb504cc3f0 🔧 Bump build 2023-02-24 19:37:41 +01:00
7c08a2fdfe 👌 Improve PHP Doctor w/ async code
- This fixes an issue with PHP Doctor's "Scan Again" button not working.
- This also adds a new check which verifies if "php.ini", "php-fpm.conf"
  and "php-fpm.d/valet-fpm.conf" exist (all required files).
2023-02-24 19:36:12 +01:00
2f47610c85 🔧 Use macOS 12.4 deployment target 2023-02-21 02:27:03 +01:00
cc6324b692 ♻️ PHP Guard changes 2023-02-20 18:15:12 +01:00
15d75a7f98 🔧 Bump build 2023-02-17 17:21:13 +01:00
c7c5311ff9 🐛 Ensure checkbox shows correct initial state 2023-02-17 17:19:56 +01:00
c93f047909 🔧 Bump build 2023-02-15 20:32:56 +01:00
f82a2120f7 🔧 Add display name 2023-02-15 20:32:37 +01:00
857cba9f45 On macOS 13 and newer, add "Start at login" (#210) 2023-02-15 20:24:01 +01:00
ec49257bcc 🔧 Bump build 2023-02-13 17:43:52 +01:00
9c6a21008a 🐛 Adjusted for new Homebrew JSON output (#235) 2023-02-13 17:38:09 +01:00
5dffbf57d1 👌 Do not load identity asynchronously 2023-02-11 20:46:05 +01:00
21a1d6576e 🔧 Bump build 2023-02-10 19:36:42 +01:00
b08912ce11 Add support for wildcard constraints (#224) 2023-02-10 19:31:07 +01:00
7285d24ef3 👌 Improve first launch onboarding experience 2023-02-07 22:02:34 +01:00
ac60c66bb9 🐛 Add missing strings for update 2023-02-06 19:33:41 +01:00
9a7575790a 🔧 Bump build 2023-02-06 19:12:34 +01:00
cd5cbccb04 🐛 Fix generated script (#231) 2023-02-06 19:10:10 +01:00
20291bf034 📝 Update README about new updater 2023-02-05 18:53:24 +01:00
2c40f433d3 Add updater to project
If you want to see the source code to the updater, you can find it here:
https://github.com/nicoverbruggen/phpmon-updater

Starting with version 6.0, the code of the updater will be included
in this repository.
2023-02-05 18:37:18 +01:00
5ac4817048 👌 Add built app to .gitignore 2023-02-05 18:17:07 +01:00
1216fe4974 🐛 Avoid duplicate verbose mode output 2023-01-31 18:20:44 +01:00
147407666d 🔥 main branch cleanup
After the last merge, there was one file I accidentally included that
doesn't need to be here: the legacy ServicesManager class! In order to
ensure that 5.7, 6.0 and `main` branches are somewhat in order and
easy to merge, I have now removed this file.
2023-01-31 18:15:00 +01:00
4568f03a65 🚀 Version 5.7.2 2023-01-30 19:54:09 +01:00
2eda8d6382 📝 Update about verbose logging 2023-01-30 19:24:46 +01:00
dd330fecce 🔧 Bump build 2023-01-30 19:12:03 +01:00
aaa7c636db 👌 Remove unneeded print() statement 2023-01-30 19:11:47 +01:00
ff75fb7be3 🐛 Fix version parsing (#227) 2023-01-30 19:11:08 +01:00
4d7b01831b Extra verbose logging
You can start extra verbose logging by running: `touch ~/.config/phpmon/verbose`

Once this file exists, you can find the latest log in: `~/.config/phpmon/last_session.log`.
2023-01-30 19:10:52 +01:00
0fceb852bb Add test to validate Valet version number with deprecations 2023-01-30 13:08:23 +01:00
9fb5f33770 🔧 Extra CLI mode (--cli) 2023-01-30 13:07:37 +01:00
2f658ee569 🚀 Version 5.7.1 2023-01-29 15:00:09 +01:00
ad179a325a 🔧 Bump build 2023-01-29 14:59:52 +01:00
4baeaea85f 🐛 Fix services not shutting down (#225) 2023-01-29 14:58:09 +01:00
9e25254ec8 🚀 Version 5.7 2023-01-26 20:49:47 +01:00
e623207844 🔧 New build 2023-01-26 20:32:39 +01:00
f60ecb877c ♻️ Cleanup 2023-01-26 20:30:00 +01:00
66393094b0 Correctly parse .valetrc files 2023-01-24 19:47:28 +01:00
b5d2fef184 🏗 WIP: Add test for feature to be implemented 2023-01-20 16:42:50 +01:00
44bc07c9dc 🏗 WIP: Parsing .valetrc file 2023-01-20 16:36:56 +01:00
93790f3951 👌 Update copyright message 2023-01-19 18:09:42 +01:00
d3b1afe9fd 🐛 Fix bug related to "?" not showing up 2023-01-19 18:03:00 +01:00
00cc6711a1 🚀 Version 5.6.6 2022-12-10 13:04:16 +01:00
209244e162 🔧 Bump build 2022-12-09 18:27:19 +01:00
e48d8ed98b 👌 Add warning about https proxy subjects 2022-12-09 18:26:56 +01:00
834f76e5a1 📝 Updated README about PHP compatibility 2022-12-09 18:08:05 +01:00
7e48893247 📝 Update README 2022-12-09 18:04:05 +01:00
e29ca9e1ad 🚀 Version 5.6.5 2022-11-27 14:37:15 +01:00
40e05d9445 🔧 Bump build 2022-11-27 14:04:15 +01:00
3ebf51b319 👌 Fix threading issue with Composer update (#212) 2022-11-27 14:03:46 +01:00
4b8ad911f1 Add support for nginx-full (#211) 2022-11-21 18:10:33 +01:00
efd902b4f3 🚀 Version 5.6.4 2022-11-18 18:39:00 +01:00
918e272da7 🔧 Bump build 2022-11-18 18:37:31 +01:00
272a9182d3 🔥 Remove reference to LatestStablePhpVersion 2022-11-18 18:37:20 +01:00
63f85aff91 🐛 Fix issue when using services quick toggle 2022-11-18 18:32:38 +01:00
581c2d1974 📝 Update supported PHP versions in README 2022-11-07 20:45:58 +01:00
4deef64537 📝 Update SECURITY.md 2022-11-02 21:08:57 +01:00
bedabaa3bb 👌 PHP 8.2 release, PHP 8.3-dev support 2022-11-02 21:06:36 +01:00
9da3772212 🚀 Version 5.6.3 2022-10-22 17:34:53 +02:00
e62b03d070 👌 Style fix 2022-10-22 16:43:05 +02:00
9a11d2efed 🔧 Bump build 2022-10-22 16:42:26 +02:00
b134e62328 🐛 Handle empty output for brew info 2022-10-22 16:41:54 +02:00
5c69133c42 👌 Add brew tap homebrew/services instruction
This now recommends the appropriate solution for #208.
2022-10-20 20:44:44 +02:00
f4448e0640 🔧 Bump version number 2022-10-10 21:49:51 +02:00
7fd30d7c54 Add preference to disable TLD alert (#206) 2022-10-10 21:49:43 +02:00
2c57dea97f 🔀 Merge branch 'main' into dev/5.6 2022-10-09 22:00:36 +02:00
a77fa5557a 📝 Update README for Login Items on Ventura 2022-10-09 21:56:13 +02:00
45704fc736 🚀 Version 5.6.2 2022-10-02 13:28:58 +02:00
f28354e634 🐛 Use valet secure sitename (#197) 2022-10-02 13:28:01 +02:00
8055a32bde 🐛 Fix ComposerWindow deinit not firing 2022-09-29 18:50:40 +02:00
5b3054326e 🔧 Bump version number 2022-09-28 18:24:26 +02:00
e7f3c7e59c 🐛 Fix an issue with missing separator item 2022-09-28 18:24:01 +02:00
a407515534 🚀 Version 5.6.1 2022-09-24 12:56:14 +02:00
196 changed files with 1541 additions and 703 deletions

View File

@ -29,5 +29,10 @@ If applicable, add screenshots to help explain your problem.
- OS: [e.g. macOS Monterey]
- PHP Monitor version [e.g. v5.0.1]
**Additional log**
You can help me figure out even more information by sending me your verbose log for your latest session of PHP Monitor. Logging is disabled by default.
You can start extra verbose logging by running: `touch ~/.config/phpmon/verbose` and restarting PHP Monitor. You can find the latest log in: `~/.config/phpmon/last_session.log`. Please attach it here!
**Additional context**
Add any other context about the problem here.

1
.gitignore vendored
View File

@ -2,4 +2,5 @@ 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

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2019-2022 Nico Verbruggen
Copyright (c) 2019-2023 Nico Verbruggen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -112,12 +112,17 @@
C43A8A1A25D9CD1000591B77 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A1925D9CD1000591B77 /* Utility.swift */; };
C43A8A2025D9D1D700591B77 /* brew-formula.json in Resources */ = {isa = PBXBuildFile; fileRef = C43A8A1F25D9D1D700591B77 /* brew-formula.json */; };
C43A8A2425D9D20D00591B77 /* HomebrewPackageTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */; };
C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C43FDBE829A932B0003D85EC /* PhpConfigChecker.swift */; };
C44067F527E2582B0045BD4E /* DomainListNameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F427E2582B0045BD4E /* DomainListNameCell.swift */; };
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */; };
C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */; };
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */; };
C4463FCC29804BCB007B93D5 /* RCFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4463FCB29804BCB007B93D5 /* RCFile.swift */; };
C4463FCD29804BCB007B93D5 /* RCFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4463FCB29804BCB007B93D5 /* RCFile.swift */; };
C4463FCE29804BCB007B93D5 /* RCFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4463FCB29804BCB007B93D5 /* RCFile.swift */; };
C4463FCF29804BCB007B93D5 /* RCFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4463FCB29804BCB007B93D5 /* RCFile.swift */; };
C449B4F027EE7FB800C47E8A /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
C449B4F127EE7FC200C47E8A /* DomainListNameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F427E2582B0045BD4E /* DomainListNameCell.swift */; };
C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
@ -143,6 +148,9 @@
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
C451AFF82969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
C451AFF92969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
C4551657297AED18009B8466 /* ValetRcTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4551656297AED18009B8466 /* ValetRcTest.swift */; };
C4551659297AED7D009B8466 /* valetrc.valid in Resources */ = {isa = PBXBuildFile; fileRef = C4551658297AED7D009B8466 /* valetrc.valid */; };
C455165B297AEDB5009B8466 /* valetrc.broken in Resources */ = {isa = PBXBuildFile; fileRef = C455165A297AEDB5009B8466 /* valetrc.broken */; };
C4570C3A28FC355300D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
C4570C3B28FC355300D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
C4570C3C28FC355400D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
@ -175,9 +183,6 @@
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 */; };
@ -317,7 +322,6 @@
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 */; };
@ -407,7 +411,6 @@
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 */; };
@ -479,6 +482,10 @@
C47699EF28A2F2A30060FEB8 /* WarningManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47699EE28A2F2A30060FEB8 /* WarningManager.swift */; };
C47699F128A2F3150060FEB8 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47699F028A2F3150060FEB8 /* Warning.swift */; };
C476FF9822B0DD830098105B /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C476FF9722B0DD830098105B /* Alert.swift */; };
C47DF1AF299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; };
C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; };
C47DF1B1299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; };
C47DF1B2299D5A3B0007055D /* LoginItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */; };
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2322D70A4700B5F6B3 /* App.swift */; };
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* PrefsVC.swift */; };
@ -504,6 +511,17 @@
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 */; };
@ -540,6 +558,10 @@
C4B97B79275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B97B77275CF1B5003F3378 /* App+ActivationPolicy.swift */; };
C4B97B7B275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */; };
C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */; };
C4BB39392981AFC700F8E797 /* PhpVersionSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BB39382981AFC700F8E797 /* PhpVersionSource.swift */; };
C4BB393A2981AFC700F8E797 /* PhpVersionSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BB39382981AFC700F8E797 /* PhpVersionSource.swift */; };
C4BB393B2981AFC700F8E797 /* PhpVersionSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BB39382981AFC700F8E797 /* PhpVersionSource.swift */; };
C4BB393C2981AFC700F8E797 /* PhpVersionSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BB39382981AFC700F8E797 /* PhpVersionSource.swift */; };
C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BF56AA2949381100379603 /* FakeValetInteractor.swift */; };
C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BF56AA2949381100379603 /* FakeValetInteractor.swift */; };
C4BF56AD2949381100379603 /* FakeValetInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BF56AA2949381100379603 /* FakeValetInteractor.swift */; };
@ -790,12 +812,14 @@
C43A8A1925D9CD1000591B77 /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = "<group>"; };
C43A8A1F25D9D1D700591B77 /* brew-formula.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "brew-formula.json"; sourceTree = "<group>"; };
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewPackageTest.swift; sourceTree = "<group>"; };
C43FDBE829A932B0003D85EC /* PhpConfigChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigChecker.swift; sourceTree = "<group>"; };
C44067F427E2582B0045BD4E /* DomainListNameCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListNameCell.swift; sourceTree = "<group>"; };
C44067F627E258410045BD4E /* DomainListPhpCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListPhpCell.swift; sourceTree = "<group>"; };
C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTypeCell.swift; sourceTree = "<group>"; };
C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; };
C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; };
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; };
C4463FCB29804BCB007B93D5 /* RCFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RCFile.swift; sourceTree = "<group>"; };
C44A874728905BB000498BC4 /* ProgressVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressVC.swift; sourceTree = "<group>"; };
C44AD3F62912EF7100997FF4 /* RealFileSystemTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealFileSystemTest.swift; sourceTree = "<group>"; };
C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeIntervalExtension.swift; sourceTree = "<group>"; };
@ -806,6 +830,9 @@
C44F868D2835BD8D005C353A /* phpmon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "phpmon-config.json"; sourceTree = "<group>"; };
C450C8C528C919EC002A2B4B /* PreferenceName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferenceName.swift; sourceTree = "<group>"; };
C451AFF52969E40F0078E617 /* HelpButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpButton.swift; sourceTree = "<group>"; };
C4551656297AED18009B8466 /* ValetRcTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetRcTest.swift; sourceTree = "<group>"; };
C4551658297AED7D009B8466 /* valetrc.valid */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = valetrc.valid; sourceTree = "<group>"; };
C455165A297AEDB5009B8466 /* valetrc.broken */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = valetrc.broken; sourceTree = "<group>"; };
C459B4BC27F6093700E9B4B4 /* nginx-proxy.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-proxy.test"; sourceTree = "<group>"; };
C45B9148295607F400F4EC78 /* Service.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Service.swift; sourceTree = "<group>"; };
C45B914D295608E300F4EC78 /* ValetServicesManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetServicesManager.swift; sourceTree = "<group>"; };
@ -818,8 +845,6 @@
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>"; };
@ -838,11 +863,17 @@
C47699EE28A2F2A30060FEB8 /* WarningManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarningManager.swift; sourceTree = "<group>"; };
C47699F028A2F3150060FEB8 /* Warning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Warning.swift; sourceTree = "<group>"; };
C476FF9722B0DD830098105B /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = "<group>"; };
C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginItemManager.swift; sourceTree = "<group>"; };
C4811D2322D70A4700B5F6B3 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenu.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>"; };
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>"; };
@ -865,6 +896,7 @@
C4B97B74275CF08C003F3378 /* AppDelegate+MenuOutlets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+MenuOutlets.swift"; sourceTree = "<group>"; };
C4B97B77275CF1B5003F3378 /* App+ActivationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "App+ActivationPolicy.swift"; sourceTree = "<group>"; };
C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "App+GlobalHotkey.swift"; sourceTree = "<group>"; };
C4BB39382981AFC700F8E797 /* PhpVersionSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpVersionSource.swift; sourceTree = "<group>"; };
C4BF56AA2949381100379603 /* FakeValetInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeValetInteractor.swift; sourceTree = "<group>"; };
C4C0E8DE27F88AEB002D32A9 /* FakeDomainScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeDomainScanner.swift; sourceTree = "<group>"; };
C4C0E8E127F88B13002D32A9 /* ValetDomainScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetDomainScanner.swift; sourceTree = "<group>"; };
@ -1124,6 +1156,7 @@
C4F5FBCC28218C93001065C5 /* .swiftlint.yml */,
C4E713572570151400007428 /* docs */,
C41C1B3522B0097F00E7CF16 /* phpmon */,
C491998829902061001F3A21 /* phpmon-updater */,
C471E79628F9B4260021E251 /* tests */,
C41C1B3422B0097F00E7CF16 /* Products */,
C4D309E72770EF2F00958BCF /* Frameworks */,
@ -1188,6 +1221,7 @@
C422DDAB28A2DAA100CEAC97 /* Warnings */ = {
isa = PBXGroup;
children = (
C43FDBE729A9329A003D85EC /* Services */,
C47699F028A2F3150060FEB8 /* Warning.swift */,
C47699EE28A2F2A30060FEB8 /* WarningManager.swift */,
C422DDAC28A2DAC600CEAC97 /* WarningsWindowController.swift */,
@ -1213,6 +1247,14 @@
path = Warning;
sourceTree = "<group>";
};
C43FDBE729A9329A003D85EC /* Services */ = {
isa = PBXGroup;
children = (
C43FDBE829A932B0003D85EC /* PhpConfigChecker.swift */,
);
path = Services;
sourceTree = "<group>";
};
C44067F327E256560045BD4E /* Cells */ = {
isa = PBXGroup;
children = (
@ -1226,6 +1268,14 @@
path = Cells;
sourceTree = "<group>";
};
C4463FD029804C13007B93D5 /* Common */ = {
isa = PBXGroup;
children = (
C4463FCB29804BCB007B93D5 /* RCFile.swift */,
);
path = Common;
sourceTree = "<group>";
};
C44A874628905B8500498BC4 /* Onboarding */ = {
isa = PBXGroup;
children = (
@ -1276,6 +1326,7 @@
C459B4BF27F6094100E9B4B4 /* brew */ = {
isa = PBXGroup;
children = (
C491997829901DE2001F3A21 /* phpmon-dev.rb */,
C4E2E85228FC256B003B070C /* brew-services-normal.json */,
C4E2E85128FC256B003B070C /* brew-services-sudo.json */,
C43A8A1F25D9D1D700591B77 /* brew-formula.json */,
@ -1287,6 +1338,8 @@
C459B4C027F6096300E9B4B4 /* valet */ = {
isa = PBXGroup;
children = (
C455165A297AEDB5009B8466 /* valetrc.broken */,
C4551658297AED7D009B8466 /* valetrc.valid */,
C4AF9F70275445FF00D44ED0 /* valet-config.json */,
);
path = valet;
@ -1403,6 +1456,7 @@
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
C4D3660A29113F20006BD146 /* System.swift */,
C4D36614291160A1006BD146 /* WIP.swift */,
C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */,
);
path = Helpers;
sourceTree = "<group>";
@ -1418,6 +1472,14 @@
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 = (
@ -1433,6 +1495,7 @@
C4AF9F6B275445D300D44ED0 /* Integrations */ = {
isa = PBXGroup;
children = (
C4463FD029804C13007B93D5 /* Common */,
C4C0E8DA27F887CC002D32A9 /* Nginx */,
C4D89BC42783C98800A02B68 /* Composer */,
C4AF9F6C275445D900D44ED0 /* Homebrew */,
@ -1444,6 +1507,7 @@
C4AF9F6C275445D900D44ED0 /* Homebrew */ = {
isa = PBXGroup;
children = (
C491997A29901DF7001F3A21 /* CaskFile.swift */,
C4F2E4362752F0870020E974 /* HomebrewDiagnostics.swift */,
);
path = Homebrew;
@ -1464,8 +1528,8 @@
C4EED88827A48778006D7272 /* InterAppHandler.swift */,
C4D8016522B1584700C6DA1B /* Startup.swift */,
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */,
C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */,
C40FE736282ABA4F00A302C2 /* AppVersion.swift */,
C491997F29901E0F001F3A21 /* AppUpdater.swift */,
C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */,
);
path = App;
@ -1522,7 +1586,7 @@
children = (
C4E4404527C56F4700D225E1 /* ValetSite.swift */,
C41C02A827E61A65009F26CB /* FakeValetSite.swift */,
C4C0E8E427F88B1F002D32A9 /* SiteScanner */,
C4BB39382981AFC700F8E797 /* PhpVersionSource.swift */,
);
path = Sites;
sourceTree = "<group>";
@ -1544,13 +1608,6 @@
path = Nginx;
sourceTree = "<group>";
};
C4C0E8E427F88B1F002D32A9 /* SiteScanner */ = {
isa = PBXGroup;
children = (
);
path = SiteScanner;
sourceTree = "<group>";
};
C4C1019727C65A11001FACC2 /* Parsers */ = {
isa = PBXGroup;
children = (
@ -1559,6 +1616,8 @@
C46FA98A2822F08F00D78807 /* PhpConfigurationTest.swift */,
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */,
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */,
C4551656297AED18009B8466 /* ValetRcTest.swift */,
C491997629901DD6001F3A21 /* CaskFileParserTest.swift */,
);
path = Parsers;
sourceTree = "<group>";
@ -1571,7 +1630,6 @@
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */,
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */,
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */,
C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */,
);
path = Versions;
sourceTree = "<group>";
@ -1882,6 +1940,7 @@
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 */,
@ -1920,6 +1979,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C4551659297AED7D009B8466 /* valetrc.valid in Resources */,
C4570C3C28FC355400D18420 /* Localizable.strings in Resources */,
54FCFD27276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */,
@ -1933,8 +1993,10 @@
C44C1992276E44CB0072762D /* ProgressWindow.storyboard in Resources */,
C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */,
C4F30B08278E195800755FCE /* brew-services.json in Resources */,
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 */,
);
@ -1971,6 +2033,7 @@
files = (
C47699EF28A2F2A30060FEB8 /* WarningManager.swift in Sources */,
C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */,
C47DF1AF299D5A3B0007055D /* LoginItemManager.swift in Sources */,
C4D3661A291173EA006BD146 /* DictionaryExtension.swift in Sources */,
C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */,
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */,
@ -2009,6 +2072,7 @@
C4E2E85C28FC282B003B070C /* TestableConfiguration.swift in Sources */,
C4C0E8DF27F88AEB002D32A9 /* FakeDomainScanner.swift in Sources */,
C44B3A4628E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */,
C4463FCC29804BCB007B93D5 /* RCFile.swift in Sources */,
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */,
C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */,
C4F2E4372752F0870020E974 /* HomebrewDiagnostics.swift in Sources */,
@ -2025,6 +2089,7 @@
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */,
C4FACE80288F1C0D00FC478F /* PreferencesWindowController+Hotkey.swift in Sources */,
C415D3B72770F294005EF286 /* Actions.swift in Sources */,
C4BB39392981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C4C3643928AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */,
C4AC51FC27E27F47008528CA /* DomainListKindCell.swift in Sources */,
C4CDA893288F1A71007CE25F /* Keys.swift in Sources */,
@ -2045,6 +2110,7 @@
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 */,
@ -2056,7 +2122,6 @@
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 */,
@ -2101,6 +2166,7 @@
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
C4FACE83288F1F9700FC478F /* OnboardingWindowController.swift in Sources */,
C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */,
C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */,
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */,
@ -2122,6 +2188,7 @@
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;
@ -2136,6 +2203,7 @@
C471E83028F9BB650021E251 /* Application.swift in Sources */,
C471E83128F9BB650021E251 /* LocalNotification.swift in Sources */,
C471E83228F9BB650021E251 /* MenuBarImageGenerator.swift in Sources */,
C4BB393B2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C471E83328F9BB650021E251 /* PMWindowController.swift in Sources */,
C471E83428F9BB650021E251 /* VersionExtractor.swift in Sources */,
C471E83528F9BB650021E251 /* ValetProxy.swift in Sources */,
@ -2152,13 +2220,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 */,
@ -2175,6 +2243,7 @@
C4D36617291160A1006BD146 /* WIP.swift in Sources */,
C471E85728F9BB650021E251 /* DomainListTLSCell.swift in Sources */,
C471E85828F9BB650021E251 /* DomainListNameCell.swift in Sources */,
C47DF1B1299D5A3B0007055D /* LoginItemManager.swift in Sources */,
C471E85928F9BB650021E251 /* DomainListPhpCell.swift in Sources */,
C471E85A28F9BB650021E251 /* DomainListTypeCell.swift in Sources */,
C471E85B28F9BB650021E251 /* DomainListKindCell.swift in Sources */,
@ -2190,6 +2259,7 @@
C471E86328F9BB650021E251 /* PMTableView.swift in Sources */,
C471E86428F9BB650021E251 /* Warning.swift in Sources */,
C40175BA2903108900763A68 /* ValetInteractor.swift in Sources */,
C4463FCE29804BCB007B93D5 /* RCFile.swift in Sources */,
C45B9150295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
C471E86528F9BB650021E251 /* WarningManager.swift in Sources */,
C471E86628F9BB650021E251 /* WarningsWindowController.swift in Sources */,
@ -2199,6 +2269,7 @@
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 */,
@ -2304,6 +2375,7 @@
C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */,
C471E89628F9BB8F0021E251 /* PMWindowController.swift in Sources */,
C471E89728F9BB8F0021E251 /* VersionExtractor.swift in Sources */,
C47DF1B2299D5A3B0007055D /* LoginItemManager.swift in Sources */,
C4E2E86728FC2F1B003B070C /* XCPMApplication.swift in Sources */,
C471E89828F9BB8F0021E251 /* ValetProxy.swift in Sources */,
C471E89A28F9BB8F0021E251 /* DomainScanner.swift in Sources */,
@ -2323,7 +2395,6 @@
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 */,
@ -2401,6 +2472,7 @@
C4CE7F9929683B43000102CF /* PhpVersionNumberCollection.swift in Sources */,
C471E7FC28F9BACE0021E251 /* HomebrewPackage.swift in Sources */,
C471E7CF28F9BA600021E251 /* ActiveShell.swift in Sources */,
C4BB393C2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C471E7F628F9BAC80021E251 /* PhpHelper.swift in Sources */,
C471E7EE28F9BAC30021E251 /* Constants.swift in Sources */,
C471E80E28F9BAE80021E251 /* DateExtension.swift in Sources */,
@ -2416,18 +2488,21 @@
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 */,
C4D3660E29113F20006BD146 /* System.swift in Sources */,
C471E80428F9BAD40021E251 /* PhpExtension.swift in Sources */,
C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
C4463FCF29804BCB007B93D5 /* RCFile.swift in Sources */,
C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */,
C471E82828F9BB310021E251 /* HomebrewDiagnostics.swift in Sources */,
C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */,
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 */,
@ -2495,6 +2570,7 @@
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 */,
@ -2510,6 +2586,7 @@
C4AF9F7B2754499000D44ED0 /* Valet.swift in Sources */,
C4C1019C27C65C6F001FACC2 /* Process.swift in Sources */,
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */,
C47DF1B0299D5A3B0007055D /* LoginItemManager.swift in Sources */,
C4F780C025D80B6E000DBC97 /* Startup.swift in Sources */,
C45B914A295607F400F4EC78 /* Service.swift in Sources */,
C4C0E8E327F88B13002D32A9 /* ValetDomainScanner.swift in Sources */,
@ -2532,6 +2609,7 @@
C485707B28BF458900539B36 /* VersionPopoverView.swift in Sources */,
C4E2E85D28FC282B003B070C /* TestableConfiguration.swift in Sources */,
C485706E28BF451C00539B36 /* OnboardingWindowController.swift in Sources */,
C4BB393A2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C4CB6E66292C362C002E9027 /* Homebrew.swift in Sources */,
C43603A1275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */,
C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */,
@ -2544,6 +2622,7 @@
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 */,
@ -2570,7 +2649,6 @@
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 */,
@ -2593,6 +2671,7 @@
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 */,
@ -2603,6 +2682,7 @@
C44AD3F72912EF7100997FF4 /* RealFileSystemTest.swift in Sources */,
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */,
C4C0E8E027F88AEB002D32A9 /* FakeDomainScanner.swift in Sources */,
C4463FCD29804BCB007B93D5 /* RCFile.swift in Sources */,
C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */,
C4B56362276AB0A500F12CCB /* VersionExtractorTest.swift in Sources */,
C4B585452770FE3900DA4FBE /* RealCommand.swift in Sources */,
@ -2628,6 +2708,7 @@
C4A81CA528C67101008DD9D1 /* PMTableView.swift in Sources */,
C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */,
C4D36602291132B7006BD146 /* ValetScanners.swift in Sources */,
C4551657297AED18009B8466 /* ValetRcTest.swift in Sources */,
C464ADAD275A7A3F003FCD53 /* DomainListWindowController.swift in Sources */,
C40C7F1F2772136000DDDCDC /* PhpEnv.swift in Sources */,
C464ADB0275A7A6A003FCD53 /* DomainListVC.swift in Sources */,
@ -2635,7 +2716,6 @@
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */,
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */,
C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */,
C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2724,7 +2804,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
@ -2781,7 +2861,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
@ -2799,19 +2879,20 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1026;
CURRENT_PROJECT_VERSION = 1074;
DEAD_CODE_STRIPPING = YES;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = phpmon/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -2828,19 +2909,20 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1026;
CURRENT_PROJECT_VERSION = 1074;
DEAD_CODE_STRIPPING = YES;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = phpmon/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -3038,7 +3120,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
@ -3056,18 +3138,19 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1026;
CURRENT_PROJECT_VERSION = 1074;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = phpmon/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor DEV";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
PRODUCT_NAME = "$(TARGET_NAME) DEV";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -3147,7 +3230,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
@ -3166,18 +3249,19 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1026;
CURRENT_PROJECT_VERSION = 1074;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = phpmon/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor DEV";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7;
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -89,6 +89,10 @@
argument = "--v"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--cli"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "--configuration:~/.phpmon_fconf_working.json"
isEnabled = "NO">

View File

@ -24,7 +24,7 @@ You can also add new domains as links, isolate sites, manage various services, a
PHP Monitor is a universal application that runs natively on Apple Silicon **and** Intel-based Macs.
* Your user account can administer your computer (required for some functionality, e.g. certificate generation)
* macOS 11 Big Sur or later
* macOS 12.4 or later (Monterey and Ventura are supported)
* Homebrew is installed in `/usr/local/homebrew` or `/opt/homebrew`
* Homebrew `php` formula is installed
* Laravel Valet (works with Valet v2, v3 and v4)
@ -43,22 +43,24 @@ valet install
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
brew tap nicoverbruggen/homebrew-cask
brew install --cask phpmon
```
To upgrade your existing installation, run:
## ⬆️ How to update
```sh
brew upgrade phpmon
```
The recommended method of updating your app to the latest version is to use **the built-in updater**.
(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)
@ -553,6 +555,10 @@ If you would like to report a crash, please include the associated **log files**
To find the logs, take a look in `~/Library/Logs/DiagnosticReports` (in Finder) and see if there's any (log) files that start with "PHP Monitor".
Additionally, you can help me figure out even more information by sending me your verbose log for your latest session of PHP Monitor. Logging is disabled by default.
You can start extra verbose logging by running: `touch ~/.config/phpmon/verbose` and restarting PHP Monitor. You can find the latest log in: `~/.config/phpmon/last_session.log`. Please attach it to the relevant bug report.
</details>
## 📝 Having another issue?

View File

@ -6,7 +6,7 @@ Generally speaking, only the latest version of **PHP Monitor** is supported, exc
| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 5.7 | ✅ Universal binary | ✅ Yes | Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0) | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x*) | 3.0 or higher recommended<br/> 2.16.2 minimum |
| 5.8 | ✅ Universal binary | ✅ Yes | Monterey (12.4+)<br/>Ventura (13.0+) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x*) | 3.0 or higher recommended<br/> 2.16.2 minimum |
(*) Preliminary listing. Valet 4 hasn't been released yet and the versions of PHP Valet can work with might still change.
@ -16,6 +16,7 @@ These versions of PHP Monitor are no longer supported, but if youre using an
| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Minimum Required Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 5.7 | ✅ Universal binary | ❌ | Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0)* | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x) | 3.0 recommended<br/> 2.16.2 minimum |
| 5.6 | ✅ Universal binary | ❌ | Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0)* | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x) | 3.0 recommended<br/> 2.16.2 minimum |
| 4.1 | ✅ Universal binary | ❌ | Big Sur (11.0)<br/>Monterey (12.0) | macOS 11+ | PHP 5.6—PHP 8.2 | 2.16.2 |
| 4.0 | ✅ Universal binary | ❌ | Big Sur (11.0)<br/>Monterey (12.0) | macOS 10.14+ | PHP 5.6—PHP 8.2 | 2.13 |

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 12/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 12/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,7 +2,7 @@
// Command.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -2,7 +2,7 @@
// Services.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -13,15 +13,15 @@ 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 {
@ -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)

View File

@ -2,7 +2,7 @@
// Constants.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 23/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 24/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
// MARK: Common Shell Commands

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 21/11/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -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

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 21/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -12,47 +12,76 @@ class Log {
static var shared = Log()
var logFilePath = "~/.config/phpmon/last_session.log"
var logExists = false
enum Verbosity: Int {
case error = 1,
warning = 2,
info = 3,
performance = 4
performance = 4,
cli = 5
public func isApplicable() -> Bool {
return Log.shared.verbosity.rawValue >= self.rawValue
}
}
var verbosity: Verbosity = .warning
public func prepareLogFile() {
if !isRunningTests && Verbosity.cli.isApplicable() {
_ = system("mkdir -p ~/.config/phpmon 2> /dev/null")
_ = system("rm ~/.config/phpmon/last_session.log 2> /dev/null")
_ = system("touch ~/.config/phpmon/last_session.log 2> /dev/null")
self.logExists = FileSystem.fileExists(self.logFilePath)
}
}
var verbosity: Verbosity = .warning {
didSet {
self.prepareLogFile()
}
}
static func err(_ item: Any) {
if Verbosity.error.isApplicable() {
print("[E] \(item)")
Log.shared.log("[E] \(item)")
}
}
static func warn(_ item: Any) {
if Verbosity.warning.isApplicable() {
print("[W] \(item)")
Log.shared.log("[W] \(item)")
}
}
static func info(_ item: Any) {
if Verbosity.info.isApplicable() {
print("\(item)")
Log.shared.log("\(item)")
}
}
static func perf(_ item: Any) {
if Verbosity.performance.isApplicable() {
print("[P] \(item)")
Log.shared.log("[P] \(item)")
}
}
static func separator(as verbosity: Verbosity = .info) {
if verbosity.isApplicable() {
print("==================================")
Log.shared.log("==================================")
}
}
private func log(_ text: String) {
print(text)
if logExists && Verbosity.cli.isApplicable() {
let logFile = URL(string: self.logFilePath.replacingTildeWithHomeDirectory)!
if let fileHandle = try? FileHandle(forWritingTo: logFile) {
fileHandle.seekToEndOfFile()
fileHandle.write(text.appending("\n").data(using: .utf8).unsafelyUnwrapped)
fileHandle.closeFile()
}
}
}
}

View File

@ -2,7 +2,7 @@
// Paths.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -16,16 +16,12 @@ public class Paths {
public static let shared = Paths()
internal var baseDir: Paths.HomebrewDir
private var userName: String! = nil
private var userName: String
init() {
baseDir = App.architecture != "x86_64" ? .opt : .usr
}
public func loadUser() async {
let output = await Shell.pipe("id -un").out
userName = String(output.split(separator: "\n")[0])
userName = identity()
Log.info("[ID] The current username is `\(userName)`.")
}
public func detectBinaryPaths() {

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 23/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 06/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 08/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 11/06/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,7 +2,7 @@
// Date.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 01/11/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 14/04/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 18/08/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 17/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,7 +2,7 @@
// StringExtension.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import SwiftUI

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 29/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 04/02/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 08/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 08/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 08/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -41,21 +41,24 @@ class RealFileSystem: FileSystemProtocol {
}
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 {
return try FileManager.default.destinationOfSymbolicLink(atPath: path)
return try FileManager.default.destinationOfSymbolicLink(atPath: path.replacingTildeWithHomeDirectory)
}
// MARK: - Move & Delete Files
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 {
try FileManager.default.removeItem(atPath: path)
try FileManager.default.removeItem(atPath: path.replacingTildeWithHomeDirectory)
}
// MARK: FS Attributes

View File

@ -2,7 +2,7 @@
// Alert.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 07/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,7 +2,7 @@
// LocalNotification.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -10,8 +10,8 @@ import UserNotifications
class LocalNotification {
@MainActor public static func send(title: String, subtitle: String, preference: PreferenceName) {
if !Preferences.isEnabled(preference) {
@MainActor public static func send(title: String, subtitle: String, preference: PreferenceName?) {
if preference != nil && !Preferences.isEnabled(preference!) {
return
}

View File

@ -0,0 +1,25 @@
//
// LoginItemManager.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 15/02/2023.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import AppKit
import ServiceManagement
@available(macOS 13.0, *)
class LoginItemManager {
func loginItemIsEnabled() -> Bool {
return SMAppService.mainApp.status == .enabled
}
func disableLoginItem() {
try? SMAppService.mainApp.unregister()
}
func enableLoginItem() {
try? SMAppService.mainApp.register()
}
}

View File

@ -2,7 +2,7 @@
// ImageGenerator.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 05/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 01/11/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -26,3 +26,31 @@ public func system(_ command: String) -> String {
return output
}
/** Same as the `system` command, but does not return the output. */
public func system_quiet(_ command: String) {
_ = system(command)
}
/**
Retrieves the username for the currently signed in user via `/usr/bin/id`.
This cannot fail or the application will crash.
*/
public func identity() -> String {
let task = Process()
task.launchPath = "/usr/bin/id"
task.arguments = ["-un"]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
guard let output = String(
data: pipe.fileHandleForReading.readDataToEndOfFile(),
encoding: String.Encoding.utf8
) else {
fatalError("Could not retrieve username via `id -un`!")
}
return output.trimmingCharacters(in: .whitespacesAndNewlines)
}

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -40,5 +40,4 @@ class VersionExtractor {
return nil
}
}
}

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 01/11/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,7 +2,7 @@
// ActivePhpInstallation.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 01/05/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,14 +2,12 @@
// HomebrewPackage.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
struct HomebrewPackage: Decodable {
let name: String
let full_name: String
let aliases: [String]
let installed: [HomebrewInstalled]

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 11/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 21/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 17/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -35,6 +35,7 @@ public struct PhpVersionNumberCollection: Equatable {
- 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.
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
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
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
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
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).
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.)
*/
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) {
// Strict constraint (e.g. "7.0") -> returns specific version
return self.versions.filter { $0.isSameAs(version, strict) }

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 23/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -39,6 +39,8 @@ public struct VersionNumber: Equatable, Hashable {
public enum MatchType: String {
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 tildeVersionRange = #"^~(?<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)
).first
if match != nil {
let major = Int(
versionString[Range(match!.range(withName: "major"), in: versionString)!]
)!
let minor = Int(
versionString[Range(match!.range(withName: "minor"), in: versionString)!]
)!
var patch: Int?
if let minorRange = Range(match!.range(withName: "patch"), in: versionString) {
patch = Int(versionString[minorRange])
}
return Self(major: major, minor: minor, patch: patch)
guard let match else { return nil }
let major = Int(versionString[Range(match.range(withName: "major"), in: versionString)!])!
var minor: Int = 0
var patch: Int?
if let minorRange = Range(match.range(withName: "minor"), in: versionString) {
let value = versionString[minorRange] as String
// Zero is the fallback if a wildcard was used
minor = Int(value) ?? 0
}
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
@ -93,6 +99,10 @@ public struct VersionNumber: Equatable, Hashable {
&& (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 {
return (
self.major > version.major ||

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 04/05/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 31/01/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 28/11/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 24/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -22,7 +22,6 @@ class InternalSwitcher: PhpSwitcher {
*/
func performSwitch(to version: String) async {
Log.info("Switching to \(version), unlinking all versions...")
let versions = getVersionsToBeHandled(version)
await withTaskGroup(of: String.self, body: { group in

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 24/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 15/05/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 20/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 21/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -68,6 +68,7 @@ class RealShell: ShellProtocol {
let task = Process()
task.launchPath = self.launchPath
task.arguments = ["--noprofile", "-norc", "--login", "-c", completeCommand]
return task
}
@ -113,6 +114,33 @@ class RealShell: ShellProtocol {
encoding: .utf8
)!
if Log.shared.verbosity == .cli {
var args = task.arguments ?? []
let last = "\"" + (args.popLast() ?? "") + "\""
var log = """
<~~~~~~~~~~~~~~~~~~~~~~~
$ \(([self.launchPath] + args + [last]).joined(separator: " "))
[OUT]:
\(stdOut)
"""
if !stdErr.isEmpty {
log.append("""
[ERR]:
\(stdErr)
""")
}
log.append("""
~~~~~~~~~~~~~~~~~~~~~~~~>
""")
Log.info(log)
}
return .out(stdOut, stdErr)
}

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 21/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 12/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 04/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 21/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 05/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 05/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -2,7 +2,7 @@
// StateManager.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 20/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 05/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 06/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,7 +2,7 @@
// AppDelegate.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa
@ -56,10 +56,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
When the application initializes, create all singletons.
*/
override init() {
logger.verbosity = .info
#if DEBUG
logger.verbosity = .performance
if let profile = CommandLine.arguments.first(where: { $0.matches(pattern: "--configuration:*") }) {
Self.initializeTestingProfile(profile.replacingOccurrences(of: "--configuration:", with: ""))
}
@ -70,6 +69,16 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
Log.info("Extra verbose mode has been activated.")
}
if CommandLine.arguments.contains("--cli") {
logger.verbosity = .cli
Log.info("Extra CLI mode has been activated via --cli flag.")
}
if FileSystem.fileExists("~/.config/phpmon/verbose") {
logger.verbosity = .cli
Log.info("Extra CLI mode is on (`~/.config/phpmon/verbose` exists).")
}
Log.separator(as: .info)
Log.info("PHP MONITOR by Nico Verbruggen")
Log.info("Version \(App.version)")
@ -102,7 +111,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
// Make sure notifications will work
setupNotifications()
Task { // Make sure the menu performs its initial checks
await paths.loadUser()
await menu.startup()
}
}

View File

@ -1,182 +0,0 @@
//
// Updater.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 09/05/2022.
// Copyright © 2022 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()
}
}
}

View 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")
}
}
}

View File

@ -3,19 +3,19 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 10/05/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
class AppVersion {
class AppVersion: Comparable {
var version: String
var build: String?
var build: Int?
var suffix: String?
init(version: String, build: String?, suffix: String? = nil) {
self.version = version
self.build = build
self.build = Int(build ?? "0")
self.suffix = suffix
}
@ -75,11 +75,27 @@ class AppVersion {
}
var computerReadable: String {
return "\(version)_\(build ?? "0")"
return "\(version)_\(build ?? 0)"
}
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
}
}

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 10/08/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 14/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -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
}
}

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 28/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 23/12/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 23/12/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 11/06/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 23/12/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -2,7 +2,7 @@
// Environment.swift
// PHP Monitor
//
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -242,7 +242,7 @@ class Startup {
.components(separatedBy: "Laravel Valet")[1]
.trimmingCharacters(in: .whitespaces)
// Extract the version number
Valet.shared.version = try! VersionNumber.parse(VersionExtractor.from(output)!)
Valet.shared.version = try! VersionNumber.parse(VersionExtractor.from(versionString)!)
// Get the actual version
return Valet.shared.version == nil
},

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 24/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 24/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 03/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa
@ -28,7 +28,7 @@ class DomainListPhpCell: NSTableCellView, DomainListCellProtocol {
imageViewPhpVersionOK.toolTip = nil
imageViewPhpVersionOK.contentTintColor = site.composerPhpCompatibleWithLinked
imageViewPhpVersionOK.contentTintColor = site.isCompatibleWithPreferredPhpVersion
? NSColor(named: "IconColorGreen")
: NSColor(named: "IconColorRed")
@ -37,9 +37,10 @@ class DomainListPhpCell: NSTableCellView, DomainListCellProtocol {
imageViewPhpVersionOK.image = NSImage(named: "Isolated")
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.isolated".localized(site.servingPhpVersion)
} else {
imageViewPhpVersionOK.isHidden = (site.composerPhp == "???" || !site.composerPhpCompatibleWithLinked)
imageViewPhpVersionOK.isHidden = (site.preferredPhpVersion == "???"
|| !site.isCompatibleWithPreferredPhpVersion)
imageViewPhpVersionOK.image = NSImage(named: "Checkmark")
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.checkmark".localized(site.composerPhp)
imageViewPhpVersionOK.toolTip = "domain_list.tooltips.checkmark".localized(site.preferredPhpVersion)
}
}
@ -58,7 +59,7 @@ class DomainListPhpCell: NSTableCellView, DomainListCellProtocol {
return []
}
return PhpEnv.shared.validVersions(for: site.composerPhp).filter({ version in
return PhpEnv.shared.validVersions(for: site.preferredPhpVersion).filter({ version in
version.short != PhpEnv.phpInstall.version.short
})
}

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 16/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa
@ -25,7 +25,7 @@ class DomainListTypeCell: NSTableCellView, DomainListCellProtocol {
}
// PHP version
labelPhpVersion.stringValue = site.composerPhp == "???" ? "Any PHP" : "PHP \(site.composerPhp)"
labelPhpVersion.stringValue = site.preferredPhpVersion == "???" ? "Any PHP" : "PHP \(site.preferredPhpVersion)"
}
func populateCell(with proxy: ValetProxy) {

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 23/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 10/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 30/03/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 03/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 05/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 14/04/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -0,0 +1,48 @@
//
// RCFile.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 24/01/2023.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
struct RCFile {
let path: String?
let fields: [String: String]
static func fromPath(_ path: String) -> RCFile? {
do {
let text = try String(contentsOf: URL(fileURLWithPath: path), encoding: .utf8)
return RCFile(path: path, contents: text)
} catch {
return nil
}
}
init(path: String? = nil, contents: String) {
var fields: [String: String] = [:]
contents
.split(separator: "\n")
.forEach({ line in
if line.contains("=") {
let content = line.split(separator: "=")
let key = String(content[0])
.trimmingCharacters(in: .whitespaces)
.replacingOccurrences(of: "\"", with: "")
if key.starts(with: "#") {
return
}
let value = String(content[1])
.trimmingCharacters(in: .whitespaces)
.replacingOccurrences(of: "\"", with: "")
fields[key] = value
}
})
self.path = path
self.fields = fields
}
}

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 04/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
@ -40,7 +40,7 @@ struct ComposerJson: Decodable {
Checks what the PHP version constraint is.
Returns a tuple (constraint, location of constraint).
*/
public func getPhpVersion() -> (String, ValetSite.VersionSource) {
public func getPhpVersion() -> (String, PhpVersionSource) {
// Check if in platform
if configuration?.platform?.php != nil {
return (configuration!.platform!.php!, .platform)

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 08/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View File

@ -3,7 +3,7 @@
// PHP Monitor
//
// Created by Nico Verbruggen on 26/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation

View 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)
}
}

Some files were not shown because too many files have changed in this diff Show More