1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-08 12:29:54 +02:00

Compare commits

..

81 Commits

Author SHA1 Message Date
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
2fa50a7dc4 🔧 Bump build for new pre-release build 2023-01-19 17:33:55 +01:00
18b62ecc3f 👌 Adjust SECURITY and support matrix for Valet 4
This commit ensures that PHP Monitor knows about which versions of
PHP are supported by the upcoming Valet 4.0: PHP 7.1 and higher.

Ensures compatibility with https://github.com/laravel/valet/pull/1318
2023-01-19 17:30:21 +01:00
2d59b8c6e8 👌 Improve onboarding 2023-01-18 20:42:24 +01:00
450d7ec001 👌 Fixed onboarding for initial launch 2023-01-18 20:27:02 +01:00
b6b1174ca3 👌 More compact ServicesView 2023-01-18 19:56:54 +01:00
e509f6b59d 📝 TL QC Pass 1 2023-01-18 19:22:45 +01:00
6014320441 📝 Update information about supported PHP versions 2023-01-18 19:18:25 +01:00
a0d80423e9 📝 Update documentation
* Updated README
* Updated SECURITY
* Revert the minimum Valet version to v2.16
2023-01-18 19:10:43 +01:00
35b19efc3e 👌 Use specific theme colors for services status 2023-01-17 18:05:22 +01:00
9a175e7291 🔧 Bump build for new pre-release build 2023-01-16 21:10:58 +01:00
d53e92ce94 👌 Sort PHP versions, amend message 2023-01-16 21:09:25 +01:00
3344fdb1dc 👌 Update support matrix 2023-01-13 20:01:09 +01:00
020a0260f1 Tell users about older unsupported PHP versions 2023-01-13 19:48:02 +01:00
3ce7e8f48b 🔧 Keep track of unsupported (but installed) PHP versions 2023-01-13 19:13:43 +01:00
ae7e13de9b 🔧 Bump build for new pre-release build 2023-01-12 17:20:58 +01:00
c82ea1fac1 🐛 Fix concurrency crashes with @objc methods 2023-01-12 17:20:15 +01:00
d6258f54a9 🐛 Fix crash when Valet.shared is nil 2023-01-11 22:23:39 +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
198 changed files with 1531 additions and 728 deletions

View File

@@ -29,5 +29,10 @@ If applicable, add screenshots to help explain your problem.
- OS: [e.g. macOS Monterey] - OS: [e.g. macOS Monterey]
- PHP Monitor version [e.g. v5.0.1] - 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** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

1
.gitignore vendored
View File

@@ -2,4 +2,5 @@ phpmon.xcodeproj/project.xcworkspace
phpmon.xcodeproj/xcuserdata phpmon.xcodeproj/xcuserdata
PHP Monitor.xcodeproj/project.xcworkspace PHP Monitor.xcodeproj/project.xcworkspace
PHP Monitor.xcodeproj/xcuserdata PHP Monitor.xcodeproj/xcuserdata
phpmon-updater/PHP Monitor Self-Updater.app
.DS_Store .DS_Store

View File

@@ -14,6 +14,16 @@ It also automatically runs when you try to build the project. You'll get a warni
swiftlint --fix swiftlint --fix
``` ```
## ⚙️ Preferences
You can find the persisted configuration file in `~/Library/Preferences/com.nicoverbruggen.phpmon.plist`
These values are cached by the OS. You can clear this cache by running:
```
defaults delete com.nicoverbruggen.phpmon && killall cfprefsd
```
## 🔧 Build instructions ## 🔧 Build instructions
<img src="./docs/build.png" width="404px" alt="build button in Xcode"/> <img src="./docs/build.png" width="404px" alt="build button in Xcode"/>

View File

@@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -118,6 +118,10 @@
C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; }; C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */; }; C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */; };
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BF2850BD2A007400F1 /* VersionPopoverView.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 */; }; C449B4F027EE7FB800C47E8A /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
C449B4F127EE7FC200C47E8A /* DomainListNameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F427E2582B0045BD4E /* DomainListNameCell.swift */; }; C449B4F127EE7FC200C47E8A /* DomainListNameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F427E2582B0045BD4E /* DomainListNameCell.swift */; };
C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; }; C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
@@ -143,6 +147,9 @@
C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; }; C451AFF72969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
C451AFF82969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; }; C451AFF82969E40F0078E617 /* HelpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C451AFF52969E40F0078E617 /* HelpButton.swift */; };
C451AFF92969E40F0078E617 /* 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 */; }; C4570C3A28FC355300D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
C4570C3B28FC355300D18420 /* 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 */; }; C4570C3C28FC355400D18420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
@@ -175,9 +182,6 @@
C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; }; C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
C469E701294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; }; C469E701294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
C469E706294CFDF700A82AB2 /* DomainsListTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E702294CFDF700A82AB2 /* DomainsListTest.swift */; }; C469E706294CFDF700A82AB2 /* DomainsListTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E702294CFDF700A82AB2 /* DomainsListTest.swift */; };
C46E206D28299B3800D909D6 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
C46E20702829D27F00D909D6 /* AppUpdaterCheckTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */; };
C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; }; C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; }; C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; }; C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
@@ -317,7 +321,6 @@
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; }; C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
C471E84728F9BB650021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; }; C471E84728F9BB650021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; }; C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
C471E84928F9BB650021E251 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; }; C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; }; C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; }; C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
@@ -407,7 +410,6 @@
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; }; C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EED88827A48778006D7272 /* InterAppHandler.swift */; };
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; }; C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; }; C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */; };
C471E8AC28F9BB8F0021E251 /* AppUpdateChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */; };
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; }; C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE736282ABA4F00A302C2 /* AppVersion.swift */; };
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; }; C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; }; C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */; };
@@ -504,6 +506,17 @@
C48D6C70279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; }; C48D6C70279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; };
C48D6C71279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; }; C48D6C71279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; };
C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */; }; C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */; };
C491997729901DD6001F3A21 /* CaskFileParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997629901DD6001F3A21 /* CaskFileParserTest.swift */; };
C491997929901DE2001F3A21 /* phpmon-dev.rb in Resources */ = {isa = PBXBuildFile; fileRef = C491997829901DE2001F3A21 /* phpmon-dev.rb */; };
C491997B29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
C491997C29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
C491997D29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
C491997E29901DF7001F3A21 /* CaskFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997A29901DF7001F3A21 /* CaskFile.swift */; };
C491998029901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
C491998129901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
C491998229901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
C491998329901E0F001F3A21 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C491997F29901E0F001F3A21 /* AppUpdater.swift */; };
C491998A29902089001F3A21 /* PHP Monitor Self-Updater.app in Resources */ = {isa = PBXBuildFile; fileRef = C491998929902089001F3A21 /* PHP Monitor Self-Updater.app */; };
C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; }; C4927F0B27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
C4927F0C27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; }; C4927F0C27B2DFC200C55AFD /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4927F0A27B2DFC200C55AFD /* Errors.swift */; };
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4930849279F331F009C240B /* AddSiteVC.swift */; }; C493084A279F331F009C240B /* AddSiteVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4930849279F331F009C240B /* AddSiteVC.swift */; };
@@ -540,6 +553,10 @@
C4B97B79275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B97B77275CF1B5003F3378 /* App+ActivationPolicy.swift */; }; 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 */; }; 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 */; }; 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 */; }; C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BF56AA2949381100379603 /* FakeValetInteractor.swift */; };
C4BF56AC2949381100379603 /* 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 */; }; C4BF56AD2949381100379603 /* FakeValetInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BF56AA2949381100379603 /* FakeValetInteractor.swift */; };
@@ -796,6 +813,7 @@
C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; }; C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; };
C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; }; C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; };
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; }; C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; };
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>"; }; 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>"; }; 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>"; }; C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeIntervalExtension.swift; sourceTree = "<group>"; };
@@ -806,6 +824,9 @@
C44F868D2835BD8D005C353A /* phpmon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "phpmon-config.json"; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; C45B914D295608E300F4EC78 /* ValetServicesManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetServicesManager.swift; sourceTree = "<group>"; };
@@ -818,8 +839,6 @@
C464ADB1275A87CA003FCD53 /* DomainListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListCellProtocol.swift; sourceTree = "<group>"; }; C464ADB1275A87CA003FCD53 /* DomainListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListCellProtocol.swift; sourceTree = "<group>"; };
C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeValetProxy.swift; sourceTree = "<group>"; }; C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeValetProxy.swift; sourceTree = "<group>"; };
C469E702294CFDF700A82AB2 /* DomainsListTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainsListTest.swift; sourceTree = "<group>"; }; C469E702294CFDF700A82AB2 /* DomainsListTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainsListTest.swift; sourceTree = "<group>"; };
C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdateChecker.swift; sourceTree = "<group>"; };
C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppUpdaterCheckTest.swift; sourceTree = "<group>"; };
C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = "<group>"; }; C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = "<group>"; };
C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = "<group>"; }; C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = "<group>"; };
C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = "<group>"; }; C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = "<group>"; };
@@ -843,6 +862,11 @@
C48D0C9225CC804200CC7490 /* XibLoadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XibLoadable.swift; sourceTree = "<group>"; }; C48D0C9225CC804200CC7490 /* XibLoadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XibLoadable.swift; sourceTree = "<group>"; };
C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionNumber.swift; sourceTree = "<group>"; }; C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionNumber.swift; sourceTree = "<group>"; };
C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpVersionNumberTest.swift; sourceTree = "<group>"; }; C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpVersionNumberTest.swift; sourceTree = "<group>"; };
C491997629901DD6001F3A21 /* CaskFileParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaskFileParserTest.swift; sourceTree = "<group>"; };
C491997829901DE2001F3A21 /* phpmon-dev.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = "phpmon-dev.rb"; sourceTree = "<group>"; };
C491997A29901DF7001F3A21 /* CaskFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaskFile.swift; sourceTree = "<group>"; };
C491997F29901E0F001F3A21 /* AppUpdater.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppUpdater.swift; sourceTree = "<group>"; };
C491998929902089001F3A21 /* PHP Monitor Self-Updater.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = "PHP Monitor Self-Updater.app"; sourceTree = "<group>"; };
C4927F0A27B2DFC200C55AFD /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; }; C4927F0A27B2DFC200C55AFD /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
C4930849279F331F009C240B /* AddSiteVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSiteVC.swift; sourceTree = "<group>"; }; C4930849279F331F009C240B /* AddSiteVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSiteVC.swift; sourceTree = "<group>"; };
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentCheck.swift; sourceTree = "<group>"; }; C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentCheck.swift; sourceTree = "<group>"; };
@@ -865,6 +889,7 @@
C4B97B74275CF08C003F3378 /* AppDelegate+MenuOutlets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+MenuOutlets.swift"; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; C4C0E8E127F88B13002D32A9 /* ValetDomainScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetDomainScanner.swift; sourceTree = "<group>"; };
@@ -1124,6 +1149,7 @@
C4F5FBCC28218C93001065C5 /* .swiftlint.yml */, C4F5FBCC28218C93001065C5 /* .swiftlint.yml */,
C4E713572570151400007428 /* docs */, C4E713572570151400007428 /* docs */,
C41C1B3522B0097F00E7CF16 /* phpmon */, C41C1B3522B0097F00E7CF16 /* phpmon */,
C491998829902061001F3A21 /* phpmon-updater */,
C471E79628F9B4260021E251 /* tests */, C471E79628F9B4260021E251 /* tests */,
C41C1B3422B0097F00E7CF16 /* Products */, C41C1B3422B0097F00E7CF16 /* Products */,
C4D309E72770EF2F00958BCF /* Frameworks */, C4D309E72770EF2F00958BCF /* Frameworks */,
@@ -1226,6 +1252,14 @@
path = Cells; path = Cells;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C4463FD029804C13007B93D5 /* Common */ = {
isa = PBXGroup;
children = (
C4463FCB29804BCB007B93D5 /* RCFile.swift */,
);
path = Common;
sourceTree = "<group>";
};
C44A874628905B8500498BC4 /* Onboarding */ = { C44A874628905B8500498BC4 /* Onboarding */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -1276,6 +1310,7 @@
C459B4BF27F6094100E9B4B4 /* brew */ = { C459B4BF27F6094100E9B4B4 /* brew */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C491997829901DE2001F3A21 /* phpmon-dev.rb */,
C4E2E85228FC256B003B070C /* brew-services-normal.json */, C4E2E85228FC256B003B070C /* brew-services-normal.json */,
C4E2E85128FC256B003B070C /* brew-services-sudo.json */, C4E2E85128FC256B003B070C /* brew-services-sudo.json */,
C43A8A1F25D9D1D700591B77 /* brew-formula.json */, C43A8A1F25D9D1D700591B77 /* brew-formula.json */,
@@ -1287,6 +1322,8 @@
C459B4C027F6096300E9B4B4 /* valet */ = { C459B4C027F6096300E9B4B4 /* valet */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C455165A297AEDB5009B8466 /* valetrc.broken */,
C4551658297AED7D009B8466 /* valetrc.valid */,
C4AF9F70275445FF00D44ED0 /* valet-config.json */, C4AF9F70275445FF00D44ED0 /* valet-config.json */,
); );
path = valet; path = valet;
@@ -1418,6 +1455,14 @@
path = "PHP Version"; path = "PHP Version";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C491998829902061001F3A21 /* phpmon-updater */ = {
isa = PBXGroup;
children = (
C491998929902089001F3A21 /* PHP Monitor Self-Updater.app */,
);
path = "phpmon-updater";
sourceTree = "<group>";
};
C4AF9F6A275445C900D44ED0 /* Valet */ = { C4AF9F6A275445C900D44ED0 /* Valet */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -1433,6 +1478,7 @@
C4AF9F6B275445D300D44ED0 /* Integrations */ = { C4AF9F6B275445D300D44ED0 /* Integrations */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C4463FD029804C13007B93D5 /* Common */,
C4C0E8DA27F887CC002D32A9 /* Nginx */, C4C0E8DA27F887CC002D32A9 /* Nginx */,
C4D89BC42783C98800A02B68 /* Composer */, C4D89BC42783C98800A02B68 /* Composer */,
C4AF9F6C275445D900D44ED0 /* Homebrew */, C4AF9F6C275445D900D44ED0 /* Homebrew */,
@@ -1444,6 +1490,7 @@
C4AF9F6C275445D900D44ED0 /* Homebrew */ = { C4AF9F6C275445D900D44ED0 /* Homebrew */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C491997A29901DF7001F3A21 /* CaskFile.swift */,
C4F2E4362752F0870020E974 /* HomebrewDiagnostics.swift */, C4F2E4362752F0870020E974 /* HomebrewDiagnostics.swift */,
); );
path = Homebrew; path = Homebrew;
@@ -1464,8 +1511,8 @@
C4EED88827A48778006D7272 /* InterAppHandler.swift */, C4EED88827A48778006D7272 /* InterAppHandler.swift */,
C4D8016522B1584700C6DA1B /* Startup.swift */, C4D8016522B1584700C6DA1B /* Startup.swift */,
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */, C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */,
C46E206C28299B3800D909D6 /* AppUpdateChecker.swift */,
C40FE736282ABA4F00A302C2 /* AppVersion.swift */, C40FE736282ABA4F00A302C2 /* AppVersion.swift */,
C491997F29901E0F001F3A21 /* AppUpdater.swift */,
C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */, C4A6957528D23EE300A14CF8 /* EnvironmentManager.swift */,
); );
path = App; path = App;
@@ -1522,7 +1569,7 @@
children = ( children = (
C4E4404527C56F4700D225E1 /* ValetSite.swift */, C4E4404527C56F4700D225E1 /* ValetSite.swift */,
C41C02A827E61A65009F26CB /* FakeValetSite.swift */, C41C02A827E61A65009F26CB /* FakeValetSite.swift */,
C4C0E8E427F88B1F002D32A9 /* SiteScanner */, C4BB39382981AFC700F8E797 /* PhpVersionSource.swift */,
); );
path = Sites; path = Sites;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1544,13 +1591,6 @@
path = Nginx; path = Nginx;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C4C0E8E427F88B1F002D32A9 /* SiteScanner */ = {
isa = PBXGroup;
children = (
);
path = SiteScanner;
sourceTree = "<group>";
};
C4C1019727C65A11001FACC2 /* Parsers */ = { C4C1019727C65A11001FACC2 /* Parsers */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -1559,6 +1599,8 @@
C46FA98A2822F08F00D78807 /* PhpConfigurationTest.swift */, C46FA98A2822F08F00D78807 /* PhpConfigurationTest.swift */,
C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */, C43A8A2325D9D20D00591B77 /* HomebrewPackageTest.swift */,
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */, C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */,
C4551656297AED18009B8466 /* ValetRcTest.swift */,
C491997629901DD6001F3A21 /* CaskFileParserTest.swift */,
); );
path = Parsers; path = Parsers;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1571,7 +1613,6 @@
C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */, C4B56360276AB0A500F12CCB /* VersionExtractorTest.swift */,
C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */, C4AF9F7C275454A900D44ED0 /* ValetVersionExtractorTest.swift */,
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */, C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */,
C46E206F2829D27F00D909D6 /* AppUpdaterCheckTest.swift */,
); );
path = Versions; path = Versions;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1882,6 +1923,7 @@
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */, C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */,
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */, C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */,
C405A4D124B9B9140062FAFA /* InternetAccessPolicy.plist in Resources */, C405A4D124B9B9140062FAFA /* InternetAccessPolicy.plist in Resources */,
C491998A29902089001F3A21 /* PHP Monitor Self-Updater.app in Resources */,
C44C1991276E44CB0072762D /* ProgressWindow.storyboard in Resources */, C44C1991276E44CB0072762D /* ProgressWindow.storyboard in Resources */,
C4232EE52612526500158FC6 /* Credits.html in Resources */, C4232EE52612526500158FC6 /* Credits.html in Resources */,
54FCFD26276C883F004CE748 /* SelectPreferenceView.xib in Resources */, 54FCFD26276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
@@ -1920,6 +1962,7 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C4551659297AED7D009B8466 /* valetrc.valid in Resources */,
C4570C3C28FC355400D18420 /* Localizable.strings in Resources */, C4570C3C28FC355400D18420 /* Localizable.strings in Resources */,
54FCFD27276C883F004CE748 /* SelectPreferenceView.xib in Resources */, 54FCFD27276C883F004CE748 /* SelectPreferenceView.xib in Resources */,
54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */, 54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */,
@@ -1933,8 +1976,10 @@
C44C1992276E44CB0072762D /* ProgressWindow.storyboard in Resources */, C44C1992276E44CB0072762D /* ProgressWindow.storyboard in Resources */,
C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */, C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */,
C4F30B08278E195800755FCE /* brew-services.json in Resources */, C4F30B08278E195800755FCE /* brew-services.json in Resources */,
C455165B297AEDB5009B8466 /* valetrc.broken in Resources */,
54A18D40282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test in Resources */, 54A18D40282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test in Resources */,
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */, C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */,
C491997929901DE2001F3A21 /* phpmon-dev.rb in Resources */,
C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */, C459B4BD27F6093700E9B4B4 /* nginx-proxy.test in Resources */,
C4E2E85428FC256B003B070C /* brew-services-sudo.json in Resources */, C4E2E85428FC256B003B070C /* brew-services-sudo.json in Resources */,
); );
@@ -2009,6 +2054,7 @@
C4E2E85C28FC282B003B070C /* TestableConfiguration.swift in Sources */, C4E2E85C28FC282B003B070C /* TestableConfiguration.swift in Sources */,
C4C0E8DF27F88AEB002D32A9 /* FakeDomainScanner.swift in Sources */, C4C0E8DF27F88AEB002D32A9 /* FakeDomainScanner.swift in Sources */,
C44B3A4628E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */, C44B3A4628E5C70100718CB1 /* TimeIntervalExtension.swift in Sources */,
C4463FCC29804BCB007B93D5 /* RCFile.swift in Sources */,
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */, C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */,
C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */, C4E9D2C02878B336008FFDAD /* OnboardingView.swift in Sources */,
C4F2E4372752F0870020E974 /* HomebrewDiagnostics.swift in Sources */, C4F2E4372752F0870020E974 /* HomebrewDiagnostics.swift in Sources */,
@@ -2025,6 +2071,7 @@
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */, C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */,
C4FACE80288F1C0D00FC478F /* PreferencesWindowController+Hotkey.swift in Sources */, C4FACE80288F1C0D00FC478F /* PreferencesWindowController+Hotkey.swift in Sources */,
C415D3B72770F294005EF286 /* Actions.swift in Sources */, C415D3B72770F294005EF286 /* Actions.swift in Sources */,
C4BB39392981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C4C3643928AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */, C4C3643928AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */,
C4AC51FC27E27F47008528CA /* DomainListKindCell.swift in Sources */, C4AC51FC27E27F47008528CA /* DomainListKindCell.swift in Sources */,
C4CDA893288F1A71007CE25F /* Keys.swift in Sources */, C4CDA893288F1A71007CE25F /* Keys.swift in Sources */,
@@ -2045,6 +2092,7 @@
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */, C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */,
C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */, C4F30B03278E16BA00755FCE /* HomebrewService.swift in Sources */,
54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */, 54D9E0B427E4F51E003B9AD9 /* Key.swift in Sources */,
C491997B29901DF7001F3A21 /* CaskFile.swift in Sources */,
C4297F7A28970D59004C4630 /* WarningView.swift in Sources */, C4297F7A28970D59004C4630 /* WarningView.swift in Sources */,
C4C0E8E227F88B13002D32A9 /* ValetDomainScanner.swift in Sources */, C4C0E8E227F88B13002D32A9 /* ValetDomainScanner.swift in Sources */,
C42F26732805B4B400938AC7 /* ValetListable.swift in Sources */, C42F26732805B4B400938AC7 /* ValetListable.swift in Sources */,
@@ -2056,7 +2104,6 @@
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */, C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */, C40C7F3027722E8D00DDDCDC /* Logger.swift in Sources */,
C41CA5ED2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */, C41CA5ED2774F8EE00A2C80E /* DomainListVC+Actions.swift in Sources */,
C46E206D28299B3800D909D6 /* AppUpdateChecker.swift in Sources */,
C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */, C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */,
03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */, 03E36FE728D9219000636F7F /* ActiveShell.swift in Sources */,
C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */, C4D9ADBF277610E1007277F4 /* PhpSwitcher.swift in Sources */,
@@ -2122,6 +2169,7 @@
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */, C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */, C493084A279F331F009C240B /* AddSiteVC.swift in Sources */,
C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */, C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */,
C491998029901E0F001F3A21 /* AppUpdater.swift in Sources */,
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */, C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -2136,6 +2184,7 @@
C471E83028F9BB650021E251 /* Application.swift in Sources */, C471E83028F9BB650021E251 /* Application.swift in Sources */,
C471E83128F9BB650021E251 /* LocalNotification.swift in Sources */, C471E83128F9BB650021E251 /* LocalNotification.swift in Sources */,
C471E83228F9BB650021E251 /* MenuBarImageGenerator.swift in Sources */, C471E83228F9BB650021E251 /* MenuBarImageGenerator.swift in Sources */,
C4BB393B2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C471E83328F9BB650021E251 /* PMWindowController.swift in Sources */, C471E83328F9BB650021E251 /* PMWindowController.swift in Sources */,
C471E83428F9BB650021E251 /* VersionExtractor.swift in Sources */, C471E83428F9BB650021E251 /* VersionExtractor.swift in Sources */,
C471E83528F9BB650021E251 /* ValetProxy.swift in Sources */, C471E83528F9BB650021E251 /* ValetProxy.swift in Sources */,
@@ -2152,13 +2201,13 @@
C471E84228F9BB650021E251 /* AppDelegate+InterApp.swift in Sources */, C471E84228F9BB650021E251 /* AppDelegate+InterApp.swift in Sources */,
C471E84328F9BB650021E251 /* App.swift in Sources */, C471E84328F9BB650021E251 /* App.swift in Sources */,
C4E2E85E28FC282B003B070C /* TestableConfiguration.swift in Sources */, C4E2E85E28FC282B003B070C /* TestableConfiguration.swift in Sources */,
C491997D29901DF7001F3A21 /* CaskFile.swift in Sources */,
C45E2A7529199248005C7CFD /* InternalSwitcherTest.swift in Sources */, C45E2A7529199248005C7CFD /* InternalSwitcherTest.swift in Sources */,
C471E84428F9BB650021E251 /* App+ActivationPolicy.swift in Sources */, C471E84428F9BB650021E251 /* App+ActivationPolicy.swift in Sources */,
C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */, C471E84528F9BB650021E251 /* App+GlobalHotkey.swift in Sources */,
C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */, C471E84628F9BB650021E251 /* InterAppHandler.swift in Sources */,
C471E84728F9BB650021E251 /* Startup.swift in Sources */, C471E84728F9BB650021E251 /* Startup.swift in Sources */,
C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */, C471E84828F9BB650021E251 /* EnvironmentCheck.swift in Sources */,
C471E84928F9BB650021E251 /* AppUpdateChecker.swift in Sources */,
C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */, C471E84A28F9BB650021E251 /* AppVersion.swift in Sources */,
C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */, C471E84B28F9BB650021E251 /* ServicesManager.swift in Sources */,
C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */, C471E84C28F9BB650021E251 /* EnvironmentManager.swift in Sources */,
@@ -2190,6 +2239,7 @@
C471E86328F9BB650021E251 /* PMTableView.swift in Sources */, C471E86328F9BB650021E251 /* PMTableView.swift in Sources */,
C471E86428F9BB650021E251 /* Warning.swift in Sources */, C471E86428F9BB650021E251 /* Warning.swift in Sources */,
C40175BA2903108900763A68 /* ValetInteractor.swift in Sources */, C40175BA2903108900763A68 /* ValetInteractor.swift in Sources */,
C4463FCE29804BCB007B93D5 /* RCFile.swift in Sources */,
C45B9150295608E300F4EC78 /* ValetServicesManager.swift in Sources */, C45B9150295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
C471E86528F9BB650021E251 /* WarningManager.swift in Sources */, C471E86528F9BB650021E251 /* WarningManager.swift in Sources */,
C471E86628F9BB650021E251 /* WarningsWindowController.swift in Sources */, C471E86628F9BB650021E251 /* WarningsWindowController.swift in Sources */,
@@ -2199,6 +2249,7 @@
C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */, C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */,
C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */, C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */,
C471E86C28F9BB650021E251 /* Preferences.swift in Sources */, C471E86C28F9BB650021E251 /* Preferences.swift in Sources */,
C491998229901E0F001F3A21 /* AppUpdater.swift in Sources */,
C4D3660D29113F20006BD146 /* System.swift in Sources */, C4D3660D29113F20006BD146 /* System.swift in Sources */,
C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */, C471E86D28F9BB650021E251 /* CustomPrefs.swift in Sources */,
C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */, C4E2E84C28FC1E70003B070C /* DataExtension.swift in Sources */,
@@ -2323,7 +2374,6 @@
C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */, C471E8A928F9BB8F0021E251 /* InterAppHandler.swift in Sources */,
C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */, C471E8AA28F9BB8F0021E251 /* Startup.swift in Sources */,
C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */, C471E8AB28F9BB8F0021E251 /* EnvironmentCheck.swift in Sources */,
C471E8AC28F9BB8F0021E251 /* AppUpdateChecker.swift in Sources */,
C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */, C471E8AD28F9BB8F0021E251 /* AppVersion.swift in Sources */,
C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */, C471E8AE28F9BB8F0021E251 /* ServicesManager.swift in Sources */,
C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */, C471E8AF28F9BB8F0021E251 /* EnvironmentManager.swift in Sources */,
@@ -2401,6 +2451,7 @@
C4CE7F9929683B43000102CF /* PhpVersionNumberCollection.swift in Sources */, C4CE7F9929683B43000102CF /* PhpVersionNumberCollection.swift in Sources */,
C471E7FC28F9BACE0021E251 /* HomebrewPackage.swift in Sources */, C471E7FC28F9BACE0021E251 /* HomebrewPackage.swift in Sources */,
C471E7CF28F9BA600021E251 /* ActiveShell.swift in Sources */, C471E7CF28F9BA600021E251 /* ActiveShell.swift in Sources */,
C4BB393C2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C471E7F628F9BAC80021E251 /* PhpHelper.swift in Sources */, C471E7F628F9BAC80021E251 /* PhpHelper.swift in Sources */,
C471E7EE28F9BAC30021E251 /* Constants.swift in Sources */, C471E7EE28F9BAC30021E251 /* Constants.swift in Sources */,
C471E80E28F9BAE80021E251 /* DateExtension.swift in Sources */, C471E80E28F9BAE80021E251 /* DateExtension.swift in Sources */,
@@ -2416,18 +2467,21 @@
C471E81028F9BAE80021E251 /* StringExtension.swift in Sources */, C471E81028F9BAE80021E251 /* StringExtension.swift in Sources */,
C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */, C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */, C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */,
C491997E29901DF7001F3A21 /* CaskFile.swift in Sources */,
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */, C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */, C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */,
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */, C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
C4D3660E29113F20006BD146 /* System.swift in Sources */, C4D3660E29113F20006BD146 /* System.swift in Sources */,
C471E80428F9BAD40021E251 /* PhpExtension.swift in Sources */, C471E80428F9BAD40021E251 /* PhpExtension.swift in Sources */,
C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */, C471E7F728F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
C4463FCF29804BCB007B93D5 /* RCFile.swift in Sources */,
C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */, C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */,
C471E82828F9BB310021E251 /* HomebrewDiagnostics.swift in Sources */, C471E82828F9BB310021E251 /* HomebrewDiagnostics.swift in Sources */,
C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */, C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */,
C471E7D228F9BA630021E251 /* ActiveFileSystem.swift in Sources */, C471E7D228F9BA630021E251 /* ActiveFileSystem.swift in Sources */,
C471E80028F9BAD10021E251 /* Xdebug.swift in Sources */, C471E80028F9BAD10021E251 /* Xdebug.swift in Sources */,
C471E7F528F9BAC80021E251 /* PhpEnv.swift in Sources */, C471E7F528F9BAC80021E251 /* PhpEnv.swift in Sources */,
C491998329901E0F001F3A21 /* AppUpdater.swift in Sources */,
C471E7ED28F9BAC30021E251 /* Process.swift in Sources */, C471E7ED28F9BAC30021E251 /* Process.swift in Sources */,
C471E81128F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */, C471E81128F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */,
C471E7CC28F9BA5B0021E251 /* TestableShell.swift in Sources */, C471E7CC28F9BA5B0021E251 /* TestableShell.swift in Sources */,
@@ -2495,6 +2549,7 @@
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */, C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */, C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
C4F780CE25D80B75000DBC97 /* LocalNotification.swift in Sources */, C4F780CE25D80B75000DBC97 /* LocalNotification.swift in Sources */,
C491997C29901DF7001F3A21 /* CaskFile.swift in Sources */,
C40C7F2927721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */, C40C7F2927721FF600DDDCDC /* ActivePhpInstallation+Checks.swift in Sources */,
C485707A28BF457800539B36 /* WarningListView.swift in Sources */, C485707A28BF457800539B36 /* WarningListView.swift in Sources */,
C4C0E8E827F88B41002D32A9 /* DomainScanner.swift in Sources */, C4C0E8E827F88B41002D32A9 /* DomainScanner.swift in Sources */,
@@ -2532,6 +2587,7 @@
C485707B28BF458900539B36 /* VersionPopoverView.swift in Sources */, C485707B28BF458900539B36 /* VersionPopoverView.swift in Sources */,
C4E2E85D28FC282B003B070C /* TestableConfiguration.swift in Sources */, C4E2E85D28FC282B003B070C /* TestableConfiguration.swift in Sources */,
C485706E28BF451C00539B36 /* OnboardingWindowController.swift in Sources */, C485706E28BF451C00539B36 /* OnboardingWindowController.swift in Sources */,
C4BB393A2981AFC700F8E797 /* PhpVersionSource.swift in Sources */,
C4CB6E66292C362C002E9027 /* Homebrew.swift in Sources */, C4CB6E66292C362C002E9027 /* Homebrew.swift in Sources */,
C43603A1275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */, C43603A1275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */,
C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */, C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */,
@@ -2544,6 +2600,7 @@
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */, C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */,
C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */, C495F5B028A42E080087F70A /* EnvironmentCheck.swift in Sources */,
C41E871B2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */, C41E871B2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
C491998129901E0F001F3A21 /* AppUpdater.swift in Sources */,
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */, C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */,
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */, C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
C4AD38B328ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */, C4AD38B328ECD9D300FA8D83 /* TestableFileSystem.swift in Sources */,
@@ -2570,7 +2627,6 @@
C4E2E86528FC2F1B003B070C /* XCPMApplication.swift in Sources */, C4E2E86528FC2F1B003B070C /* XCPMApplication.swift in Sources */,
C4E49DE828F764050026AC4E /* ActiveCommand.swift in Sources */, C4E49DE828F764050026AC4E /* ActiveCommand.swift in Sources */,
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */, C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */,
C46E20702829D27F00D909D6 /* AppUpdaterCheckTest.swift in Sources */,
C485707D28BF45A200539B36 /* WarningView.swift in Sources */, C485707D28BF45A200539B36 /* WarningView.swift in Sources */,
C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */, C4F7809C25D80344000DBC97 /* CommandTest.swift in Sources */,
C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */, C44CCD4127AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
@@ -2593,6 +2649,7 @@
C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */, C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */,
C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */, C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */,
C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */, C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */,
C491997729901DD6001F3A21 /* CaskFileParserTest.swift in Sources */,
C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */, C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */,
C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */, C4BF56AC2949381100379603 /* FakeValetInteractor.swift in Sources */,
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */, C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */,
@@ -2603,6 +2660,7 @@
C44AD3F72912EF7100997FF4 /* RealFileSystemTest.swift in Sources */, C44AD3F72912EF7100997FF4 /* RealFileSystemTest.swift in Sources */,
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */, C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */,
C4C0E8E027F88AEB002D32A9 /* FakeDomainScanner.swift in Sources */, C4C0E8E027F88AEB002D32A9 /* FakeDomainScanner.swift in Sources */,
C4463FCD29804BCB007B93D5 /* RCFile.swift in Sources */,
C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */, C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */,
C4B56362276AB0A500F12CCB /* VersionExtractorTest.swift in Sources */, C4B56362276AB0A500F12CCB /* VersionExtractorTest.swift in Sources */,
C4B585452770FE3900DA4FBE /* RealCommand.swift in Sources */, C4B585452770FE3900DA4FBE /* RealCommand.swift in Sources */,
@@ -2628,6 +2686,7 @@
C4A81CA528C67101008DD9D1 /* PMTableView.swift in Sources */, C4A81CA528C67101008DD9D1 /* PMTableView.swift in Sources */,
C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */, C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */,
C4D36602291132B7006BD146 /* ValetScanners.swift in Sources */, C4D36602291132B7006BD146 /* ValetScanners.swift in Sources */,
C4551657297AED18009B8466 /* ValetRcTest.swift in Sources */,
C464ADAD275A7A3F003FCD53 /* DomainListWindowController.swift in Sources */, C464ADAD275A7A3F003FCD53 /* DomainListWindowController.swift in Sources */,
C40C7F1F2772136000DDDCDC /* PhpEnv.swift in Sources */, C40C7F1F2772136000DDDCDC /* PhpEnv.swift in Sources */,
C464ADB0275A7A6A003FCD53 /* DomainListVC.swift in Sources */, C464ADB0275A7A6A003FCD53 /* DomainListVC.swift in Sources */,
@@ -2635,7 +2694,6 @@
C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */, C46EBC4B28DB966A007ACC74 /* TestableShell.swift in Sources */,
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */, C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */,
C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */, C4F780C625D80B75000DBC97 /* XibLoadable.swift in Sources */,
C46E206E28299B3800D909D6 /* AppUpdateChecker.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -2799,7 +2857,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1020; CURRENT_PROJECT_VERSION = 1065;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG = YES; DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
@@ -2811,7 +2869,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7; MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2828,7 +2886,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1020; CURRENT_PROJECT_VERSION = 1065;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG = NO; DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
@@ -2840,7 +2898,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7; MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -3056,7 +3114,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1020; CURRENT_PROJECT_VERSION = 1065;
DEBUG = NO; DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -3067,7 +3125,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7; MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
PRODUCT_NAME = "$(TARGET_NAME) DEV"; PRODUCT_NAME = "$(TARGET_NAME) DEV";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -3166,7 +3224,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1020; CURRENT_PROJECT_VERSION = 1065;
DEBUG = YES; DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -3177,7 +3235,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.7; MARKETING_VERSION = 5.8;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

View File

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

View File

@@ -27,24 +27,40 @@ PHP Monitor is a universal application that runs natively on Apple Silicon **and
* macOS 11 Big Sur or later * macOS 11 Big Sur or later
* Homebrew is installed in `/usr/local/homebrew` or `/opt/homebrew` * Homebrew is installed in `/usr/local/homebrew` or `/opt/homebrew`
* Homebrew `php` formula is installed * Homebrew `php` formula is installed
* Laravel Valet 3 recommended (but compatible with Valet 2) * Laravel Valet (works with Valet v2, v3 and v4)
_You may need to update your Valet installation to keep everything working if a major version update of PHP has been released. You can do this by running `composer global update && valet install`. Some features are not supported when running Valet 2._ _You may need to update your Valet installation to keep everything working if a major version update of PHP has been released. You can do this by running `composer global update && valet install`. Some features are not supported when running Valet 2._
For more information, please see [SECURITY.md](./SECURITY.md) to find out which version of the app is currently supported.
## 🚀 How to install ## 🚀 How to install
Again, make sure you have **Laravel Valet** installed first. Once that's done, you can install via Homebrew (recommended), or may download the latest release on GitHub. Again, make sure you have **[Laravel Valet](https://laravel.com/docs/master/valet)** installed first:
To install via Homebrew, run: ```sh
composer global require laravel/valet
valet install
valet trust
```
#### Manual installation (first time only)
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 tap nicoverbruggen/homebrew-cask
brew install --cask phpmon brew install --cask phpmon
```
To upgrade your existing installation, run: ## ⬆️ How to update
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) ## ⚡️ Launchers (Alfred, Raycast)
@@ -79,36 +95,14 @@ If you're still having issues, here's a few common questions & answers, as well
<details> <details>
<summary><strong>Which versions of PHP are supported?</strong></summary> <summary><strong>Which versions of PHP are supported?</strong></summary>
The following versions of PHP are officially supported: All stable and supported PHP versions are also supported by PHP Monitor. However, depending on which version of Valet you have installed, which versions of PHP that are made available for switching purposes may differ.
<ul> > **Note**
<li>PHP 7.4</li> > If you have versions of PHP installed that can be detected by PHP Monitor but is *not* supported by the currently active version of Valet, you will be alerted by an item in the menu with an exclamation mark emoji. (⚠️)
<li>PHP 8.0</li>
<li>PHP 8.1</li>
<li>PHP 8.2</li>
</ul>
The following versions have some support via backport and/or dev version:
<ul>
<li>PHP 5.6 (Valet 2 only)</li>
<li>PHP 7.0 (Valet 2 and 3 only)</li>
<li>PHP 7.1 (Valet 2 and 3 only)</li>
<li>PHP 7.2 (Valet 2 and 3 only)</li>
<li>PHP 7.3 (Valet 2 and 3 only)</li>
</ul>
Additionally, the following dev version is also available:
<ul>
<li>PHP 8.3-dev (experimental)</li>
</ul>
For more details, consult the [constants file](https://github.com/nicoverbruggen/phpmon/blob/main/phpmon/Common/Core/Constants.swift#L16) file to see which versions are supported.
Backports are available via [this tap](https://github.com/shivammathur/homebrew-php). For more information about those backports, please see the next FAQ entry. Backports are available via [this tap](https://github.com/shivammathur/homebrew-php). For more information about those backports, please see the next FAQ entry.
For maximum compatibility with older PHP versions, you may wish to keep using Valet 2 or 3. For maximum compatibility with older PHP versions, you may wish to keep using Valet 2 or 3. For more information, please see [SECURITY.md](./SECURITY.md) to find out which versions of PHP are supported with different versions of Valet.
</details> </details>
@@ -127,12 +121,12 @@ brew tap shivammathur/php
You may find that this tap is already in use: if you've used Valet before, it automatically uses this tap for legacy versions of PHP. You may find that this tap is already in use: if you've used Valet before, it automatically uses this tap for legacy versions of PHP.
You can then install those older versions:
```sh ```sh
brew install php@7.0 brew install shivammathur/php/php@7.4
brew install php@7.1 brew install shivammathur/php/php@7.3
... brew install shivammathur/php/php@7.2
brew install shivammathur/php/php@7.1
brew install shivammathur/php/php@7.0
``` ```
**Always make sure to restart PHP Monitor after installing or upgrading PHP versions!** **Always make sure to restart PHP Monitor after installing or upgrading PHP versions!**
@@ -561,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". 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> </details>
## 📝 Having another issue? ## 📝 Having another issue?

View File

@@ -6,7 +6,9 @@ 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 | | Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ---- | ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 6.x | ✅ 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.4-PHP 8.2 (w/ Valet 4.x) | 3.0 or higher recommended<br/> 2.16.2 minimum | | 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 |
(*) Preliminary listing. Valet 4 hasn't been released yet and the versions of PHP Valet can work with might still change.
## Legacy versions ## Legacy versions

View File

@@ -7,7 +7,7 @@
"alpha" : "1.000", "alpha" : "1.000",
"blue" : "0.988", "blue" : "0.988",
"green" : "0.580", "green" : "0.580",
"red" : "0.277" "red" : "0.278"
} }
}, },
"idiom" : "universal" "idiom" : "universal"

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.501",
"green" : "0.697",
"red" : "0.247"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.501",
"green" : "0.765",
"red" : "0.247"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.180",
"green" : "0.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.426",
"green" : "0.363",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.180",
"green" : "0.841",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.426",
"green" : "0.809",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
// Services.swift // Services.swift
// PHP Monitor // PHP Monitor
// //
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -13,15 +13,15 @@ class Actions {
// MARK: - Services // MARK: - Services
public static func restartPhpFpm() async { public static func restartPhpFpm() async {
await brew("services restart \(Homebrew.Formulae.php.name)", sudo: Homebrew.Formulae.php.elevated) await brew("services restart \(Homebrew.Formulae.php)", sudo: Homebrew.Formulae.php.elevated)
} }
public static func restartNginx() async { public static func restartNginx() async {
await brew("services restart \(Homebrew.Formulae.nginx.name)", sudo: Homebrew.Formulae.nginx.elevated) await brew("services restart \(Homebrew.Formulae.nginx)", sudo: Homebrew.Formulae.nginx.elevated)
} }
public static func restartDnsMasq() async { public static func restartDnsMasq() async {
await brew("services restart \(Homebrew.Formulae.dnsmasq.name)", sudo: Homebrew.Formulae.dnsmasq.elevated) await brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: Homebrew.Formulae.dnsmasq.elevated)
} }
public static func stopValetServices() async { public static func stopValetServices() async {
@@ -54,9 +54,10 @@ class Actions {
+ " && " + " && "
+ cellarCommands.joined(separator: " && ") + cellarCommands.joined(separator: " && ")
let appleScript = NSAppleScript( let source = "do shell script \"\(script)\" with administrator privileges"
source: "do shell script \"\(script)\" with administrator privileges"
) Log.perf(source)
let appleScript = NSAppleScript(source: source)
let eventResult: NSAppleEventDescriptor? = appleScript?.executeAndReturnError(nil) let eventResult: NSAppleEventDescriptor? = appleScript?.executeAndReturnError(nil)

View File

@@ -2,7 +2,7 @@
// Constants.swift // Constants.swift
// PHP Monitor // PHP Monitor
// //
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Cocoa import Cocoa
@@ -14,15 +14,24 @@ struct Constants {
If the installed version is older, a notification will be shown If the installed version is older, a notification will be shown
every time the app launches (with a recommendation to upgrade). every time the app launches (with a recommendation to upgrade).
See also: https://github.com/laravel/valet/releases/tag/v3.1.10 See also: https://github.com/laravel/valet/releases/tag/v2.16.2
*/ */
static let MinimumRecommendedValetVersion = "3.1.10" static let MinimumRecommendedValetVersion = "2.16.2"
/** /**
* The PHP versions supported by this application. * The PHP versions supported by this application.
* Depends on what version of Valet is installed. * Any other PHP versions are considered invalid.
*/ */
static let ValetSupportedPhpVersionMatrix = [ static let DetectedPhpVersions: Set = [
"5.6",
"7.0", "7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2", "8.3"
]
/**
The PHP versions supported by each version of Valet.
*/
static let ValetSupportedPhpVersionMatrix: [Int: Set] = [
2: // Valet v2 has the broadest legacy support 2: // Valet v2 has the broadest legacy support
[ [
"5.6", "5.6",
@@ -32,12 +41,14 @@ struct Constants {
3: // Valet v3 dropped support for v5.6 3: // Valet v3 dropped support for v5.6
[ [
"7.0", "7.1", "7.2", "7.3", "7.4", "7.0", "7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2", "8.3" "8.0", "8.1", "8.2",
"8.3" // dev
], ],
4: // Valet v4 dropped support for <v7.4 4: // Valet v4 dropped support for v7.0
[ [
"7.4", "7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2", "8.3" "8.0", "8.1", "8.2",
"8.3" // dev
] ]
] ]

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 24/12/2021. // 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 // MARK: Common Shell Commands

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 21/11/2022. // Created by Nico Verbruggen on 21/11/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -36,10 +36,14 @@ class Homebrew {
} }
} }
class HomebrewFormula: Equatable, Hashable { class HomebrewFormula: Equatable, Hashable, CustomStringConvertible {
let name: String let name: String
let elevated: Bool let elevated: Bool
var description: String {
return name
}
init(_ name: String, elevated: Bool = true) { init(_ name: String, elevated: Bool = true) {
self.name = name self.name = name
self.elevated = elevated self.elevated = elevated

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 21/12/2021. // Created by Nico Verbruggen on 21/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -12,47 +12,76 @@ class Log {
static var shared = Log() static var shared = Log()
var logFilePath = "~/.config/phpmon/last_session.log"
var logExists = false
enum Verbosity: Int { enum Verbosity: Int {
case error = 1, case error = 1,
warning = 2, warning = 2,
info = 3, info = 3,
performance = 4 performance = 4,
cli = 5
public func isApplicable() -> Bool { public func isApplicable() -> Bool {
return Log.shared.verbosity.rawValue >= self.rawValue 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) { static func err(_ item: Any) {
if Verbosity.error.isApplicable() { if Verbosity.error.isApplicable() {
print("[E] \(item)") Log.shared.log("[E] \(item)")
} }
} }
static func warn(_ item: Any) { static func warn(_ item: Any) {
if Verbosity.warning.isApplicable() { if Verbosity.warning.isApplicable() {
print("[W] \(item)") Log.shared.log("[W] \(item)")
} }
} }
static func info(_ item: Any) { static func info(_ item: Any) {
if Verbosity.info.isApplicable() { if Verbosity.info.isApplicable() {
print("\(item)") Log.shared.log("\(item)")
} }
} }
static func perf(_ item: Any) { static func perf(_ item: Any) {
if Verbosity.performance.isApplicable() { if Verbosity.performance.isApplicable() {
print("[P] \(item)") Log.shared.log("[P] \(item)")
} }
} }
static func separator(as verbosity: Verbosity = .info) { static func separator(as verbosity: Verbosity = .info) {
if verbosity.isApplicable() { 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 // Paths.swift
// PHP Monitor // PHP Monitor
// //
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -16,16 +16,12 @@ public class Paths {
public static let shared = Paths() public static let shared = Paths()
internal var baseDir: Paths.HomebrewDir internal var baseDir: Paths.HomebrewDir
private var userName: String
private var userName: String! = nil
init() { init() {
baseDir = App.architecture != "x86_64" ? .opt : .usr baseDir = App.architecture != "x86_64" ? .opt : .usr
} userName = identity()
Log.info("[ID] The current username is `\(userName)`.")
public func loadUser() async {
let output = await Shell.pipe("id -un").out
userName = String(output.split(separator: "\n")[0])
} }
public func detectBinaryPaths() { public func detectBinaryPaths() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 08/10/2022. // Created by Nico Verbruggen on 08/10/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -41,21 +41,24 @@ class RealFileSystem: FileSystemProtocol {
} }
func getShallowContentsOfDirectory(_ path: String) throws -> [String] { func getShallowContentsOfDirectory(_ path: String) throws -> [String] {
return try FileManager.default.contentsOfDirectory(atPath: path) return try FileManager.default.contentsOfDirectory(atPath: path.replacingTildeWithHomeDirectory)
} }
func getDestinationOfSymlink(_ path: String) throws -> String { func getDestinationOfSymlink(_ path: String) throws -> String {
return try FileManager.default.destinationOfSymbolicLink(atPath: path) return try FileManager.default.destinationOfSymbolicLink(atPath: path.replacingTildeWithHomeDirectory)
} }
// MARK: - Move & Delete Files // MARK: - Move & Delete Files
func move(from path: String, to newPath: String) throws { func move(from path: String, to newPath: String) throws {
try FileManager.default.moveItem(atPath: path, toPath: newPath) try FileManager.default.moveItem(
atPath: path.replacingTildeWithHomeDirectory,
toPath: newPath.replacingTildeWithHomeDirectory
)
} }
func remove(_ path: String) throws { func remove(_ path: String) throws {
try FileManager.default.removeItem(atPath: path) try FileManager.default.removeItem(atPath: path.replacingTildeWithHomeDirectory)
} }
// MARK: FS Attributes // MARK: FS Attributes

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 07/12/2021. // Created by Nico Verbruggen on 07/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -33,8 +33,8 @@ class Application {
Attempt to open a specific directory in the app of choice. Attempt to open a specific directory in the app of choice.
(This will open the app if it isn't open yet.) (This will open the app if it isn't open yet.)
*/ */
@objc public func openDirectory(file: String) async { @objc public func openDirectory(file: String) {
return await Shell.quiet("/usr/bin/open -a \"\(name)\" \"\(file)\"") Task { await Shell.quiet("/usr/bin/open -a \"\(name)\" \"\(file)\"") }
} }
/** Checks if the app is installed. */ /** Checks if the app is installed. */

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 01/11/2022. // Created by Nico Verbruggen on 01/11/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -26,3 +26,31 @@ public func system(_ command: String) -> String {
return output 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 // PHP Monitor
// //
// Created by Nico Verbruggen on 16/12/2021. // Created by Nico Verbruggen on 16/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -40,5 +40,4 @@ class VersionExtractor {
return nil return nil
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 11/01/2022. // Created by Nico Verbruggen on 11/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -44,7 +44,7 @@ final class HomebrewService: Sendable, Decodable {
/** /**
Dummy data for preview purposes. Dummy data for preview purposes.
*/ */
public static func dummy(named service: String, enabled: Bool) -> HomebrewService { public static func dummy(named service: String, enabled: Bool, status: String? = nil) -> HomebrewService {
return HomebrewService( return HomebrewService(
name: service, name: service,
service_name: service, service_name: service,
@@ -52,7 +52,7 @@ final class HomebrewService: Sendable, Decodable {
loaded: enabled, loaded: enabled,
pid: nil, pid: nil,
user: nil, user: nil,
status: nil, status: status,
log_path: nil, log_path: nil,
error_log_path: nil error_log_path: nil
) )

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 21/12/2021. // Created by Nico Verbruggen on 21/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -38,9 +38,12 @@ class PhpEnv {
/** Whether the switcher is busy performing any actions. */ /** Whether the switcher is busy performing any actions. */
var isBusy: Bool = false var isBusy: Bool = false
/** All available versions of PHP. */ /** All versions of PHP that are currently supported. */
var availablePhpVersions: [String] = [] var availablePhpVersions: [String] = []
/** All versions of PHP that are currently installed but not compatible. */
var incompatiblePhpVersions: [String] = []
/** Cached information about the PHP installations. */ /** Cached information about the PHP installations. */
var cachedPhpInstallations: [String: PhpInstallation] = [:] var cachedPhpInstallations: [String: PhpInstallation] = [:]
@@ -87,13 +90,14 @@ class PhpEnv {
/** /**
Detects which versions of PHP are installed. Detects which versions of PHP are installed.
*/ */
public func detectPhpVersions() async -> [String] { public func detectPhpVersions() async -> Set<String> {
let files = await Shell.pipe("ls \(Paths.optPath) | grep php@").out let files = await Shell.pipe("ls \(Paths.optPath) | grep php@").out
var versionsOnly = await extractPhpVersions( let versions = await extractPhpVersions(from: files.components(separatedBy: "\n"))
from: files.components(separatedBy: "\n"),
supported: Constants.ValetSupportedPhpVersionMatrix[Valet.shared.version.major] ?? [] let supportedByValet = Constants.ValetSupportedPhpVersionMatrix[Valet.shared.version.major] ?? []
)
var supportedVersions = versions.intersection(supportedByValet)
// Make sure the aliased version is detected // Make sure the aliased version is detected
// The user may have `php` installed, but not e.g. `php@8.0` // The user may have `php` installed, but not e.g. `php@8.0`
@@ -101,13 +105,18 @@ class PhpEnv {
let phpAlias = homebrewPackage.version let phpAlias = homebrewPackage.version
// Avoid inserting a duplicate // Avoid inserting a duplicate
if !versionsOnly.contains(phpAlias) && FileSystem.fileExists("\(Paths.optPath)/php/bin/php") { if !supportedVersions.contains(phpAlias) && FileSystem.fileExists("\(Paths.optPath)/php/bin/php") {
versionsOnly.append(phpAlias) supportedVersions.insert(phpAlias)
} }
Log.info("The PHP versions that were detected are: \(versionsOnly)") availablePhpVersions = Array(supportedVersions)
.sorted(by: { $0.versionCompare($1) == .orderedDescending })
availablePhpVersions = versionsOnly incompatiblePhpVersions = Array(versions.subtracting(supportedByValet))
.sorted(by: { $0.versionCompare($1) == .orderedDescending })
Log.info("The PHP versions that were detected are: \(availablePhpVersions)")
Log.info("The PHP versions that were unsupported are: \(incompatiblePhpVersions)")
var mappedVersions: [String: PhpInstallation] = [:] var mappedVersions: [String: PhpInstallation] = [:]
@@ -117,7 +126,7 @@ class PhpEnv {
cachedPhpInstallations = mappedVersions cachedPhpInstallations = mappedVersions
return versionsOnly return supportedVersions
} }
/** /**
@@ -129,11 +138,11 @@ class PhpEnv {
*/ */
public func extractPhpVersions( public func extractPhpVersions(
from versions: [String], from versions: [String],
supported: [String],
checkBinaries: Bool = true, checkBinaries: Bool = true,
generateHelpers: Bool = true generateHelpers: Bool = true
) async -> [String] { ) async -> Set<String> {
var output: [String] = [] let supported = Constants.DetectedPhpVersions
var output: Set<String> = []
versions.filter { (version) -> Bool in versions.filter { (version) -> Bool in
// Omit everything that doesn't start with php@ // Omit everything that doesn't start with php@
// (e.g. something-php@8.0 won't be detected) // (e.g. something-php@8.0 won't be detected)
@@ -145,7 +154,7 @@ class PhpEnv {
if !output.contains(version) if !output.contains(version)
&& supported.contains(version) && supported.contains(version)
&& (checkBinaries ? FileSystem.fileExists("\(Paths.optPath)/php@\(version)/bin/php") : true) { && (checkBinaries ? FileSystem.fileExists("\(Paths.optPath)/php@\(version)/bin/php") : true) {
output.append(version) output.insert(version)
} }
} }

View File

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

View File

@@ -35,6 +35,7 @@ public struct PhpVersionNumberCollection: Equatable {
- Parameter strict: Whether the patch version check is strict. See more below. - Parameter strict: Whether the patch version check is strict. See more below.
The strict mode does not matter if a patch version is provided for all versions in the collection. The strict mode does not matter if a patch version is provided for all versions in the collection.
It also does not matter for certain comparisons (e.g. when dealing with wildcards).
Strict mode assumes that any PHP version lacking precise patch information, e.g. inferred Strict mode assumes that any PHP version lacking precise patch information, e.g. inferred
from Homebrew corresponds to the .0 patch version of that version. The default, which is imprecise, from Homebrew corresponds to the .0 patch version of that version. The default, which is imprecise,
@@ -45,6 +46,7 @@ public struct PhpVersionNumberCollection: Equatable {
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in strict mode only 8.1.? will Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in strict mode only 8.1.? will
be considered valid (8.0 translates to 8.0.0 and as such is older than 8.0.1, 8.1.0 is OK). be considered valid (8.0 translates to 8.0.0 and as such is older than 8.0.1, 8.1.0 is OK).
When checking against actual PHP versions installed by the user (with patch precision), use When checking against actual PHP versions installed by the user (with patch precision), use
strict mode. strict mode.
@@ -52,11 +54,26 @@ public struct PhpVersionNumberCollection: Equatable {
Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in non-strict mode version 8.0 Given versions 8.0.? and 8.1.?, but the requirement is ^8.0.1, in non-strict mode version 8.0
is assumed to be equal to version 8.0.999, which is actually fine if 8.0.1 is the required version. is assumed to be equal to version 8.0.999, which is actually fine if 8.0.1 is the required version.
In non-strict mode, the patch version is ignored for regular version checks (no caret / tilde). In non-strict mode, the patch version is ignored for regular version checks (no caret / tilde).
If checking compatibility with general Homebrew versions of PHP, do NOT use strict mode, since If checking compatibility with general Homebrew versions of PHP, do NOT use strict mode, since
the patch version there is not used. (The formula php@8.0 suffices for ^8.0.1.) the patch version there is not used. (The formula php@8.0 suffices for ^8.0.1.)
*/ */
public func matching(constraint: String, strict: Bool = false) -> [VersionNumber] { public func matching(constraint: String, strict: Bool = false) -> [VersionNumber] {
if constraint == "*" {
return self.versions
}
if let version = VersionNumber.make(from: constraint, type: .wildCardPatch) {
// Wildcard for patch (e.g. "7.4.*") must match major and minor (any patch)
return self.versions.filter { $0.hasSameMajorAndMinor(version) }
}
if let version = VersionNumber.make(from: constraint, type: .wildCardMinor) {
// Strict constraint (e.g. "7.*") -> must only match major (any patch, minor)
return self.versions.filter { $0.isSameMajorVersionAs(version) }
}
if let version = VersionNumber.make(from: constraint, type: .versionOnly) { if let version = VersionNumber.make(from: constraint, type: .versionOnly) {
// Strict constraint (e.g. "7.0") -> returns specific version // Strict constraint (e.g. "7.0") -> returns specific version
return self.versions.filter { $0.isSameAs(version, strict) } return self.versions.filter { $0.isSameAs(version, strict) }

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 23/01/2022. // Created by Nico Verbruggen on 23/01/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -39,6 +39,8 @@ public struct VersionNumber: Equatable, Hashable {
public enum MatchType: String { public enum MatchType: String {
case versionOnly = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"# case versionOnly = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
case wildCardPatch = #"^(?<major>\d+).(?<minor>\d+).?(?<patch>\*)?\z"#
case wildCardMinor = #"^(?<major>\d+).(?<minor>\*)?\z"#
case caretVersionRange = #"^\^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"# case caretVersionRange = #"^\^(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
case tildeVersionRange = #"^~(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"# case tildeVersionRange = #"^~(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
case greaterThanOrEqual = #"^>=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"# case greaterThanOrEqual = #"^>=(?<major>\d+).(?<minor>\d+).?(?<patch>\d+)?\z"#
@@ -64,21 +66,25 @@ public struct VersionNumber: Equatable, Hashable {
range: NSRange(location: 0, length: versionString.count) range: NSRange(location: 0, length: versionString.count)
).first ).first
if match != nil { guard let match else { return nil }
let major = Int(
versionString[Range(match!.range(withName: "major"), in: versionString)!] let major = Int(versionString[Range(match.range(withName: "major"), in: versionString)!])!
)! var minor: Int = 0
let minor = Int(
versionString[Range(match!.range(withName: "minor"), in: versionString)!]
)!
var patch: Int? var patch: Int?
if let minorRange = Range(match!.range(withName: "patch"), in: versionString) {
patch = Int(versionString[minorRange]) if let minorRange = Range(match.range(withName: "minor"), in: versionString) {
} let value = versionString[minorRange] as String
return Self(major: major, minor: minor, patch: patch) // 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 // MARK: Comparison Logic
@@ -93,6 +99,10 @@ public struct VersionNumber: Equatable, Hashable {
&& (strict ? self.patch(strict, version) == version.patch(strict) : true) && (strict ? self.patch(strict, version) == version.patch(strict) : true)
} }
internal func hasSameMajorAndMinor(_ version: VersionNumber) -> Bool {
return self.major == version.major && self.minor == version.minor
}
internal func isNewerThan(_ version: VersionNumber, _ strict: Bool) -> Bool { internal func isNewerThan(_ version: VersionNumber, _ strict: Bool) -> Bool {
return ( return (
self.major > version.major || self.major > version.major ||

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 21/09/2022. // Created by Nico Verbruggen on 21/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -68,6 +68,7 @@ class RealShell: ShellProtocol {
let task = Process() let task = Process()
task.launchPath = self.launchPath task.launchPath = self.launchPath
task.arguments = ["--noprofile", "-norc", "--login", "-c", completeCommand] task.arguments = ["--noprofile", "-norc", "--login", "-c", completeCommand]
return task return task
} }
@@ -113,6 +114,33 @@ class RealShell: ShellProtocol {
encoding: .utf8 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) return .out(stdOut, stdErr)
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
// AppDelegate.swift // AppDelegate.swift
// PHP Monitor // PHP Monitor
// //
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Cocoa import Cocoa
@@ -56,10 +56,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
When the application initializes, create all singletons. When the application initializes, create all singletons.
*/ */
override init() { override init() {
logger.verbosity = .info
#if DEBUG #if DEBUG
logger.verbosity = .performance logger.verbosity = .performance
if let profile = CommandLine.arguments.first(where: { $0.matches(pattern: "--configuration:*") }) { if let profile = CommandLine.arguments.first(where: { $0.matches(pattern: "--configuration:*") }) {
Self.initializeTestingProfile(profile.replacingOccurrences(of: "--configuration:", with: "")) Self.initializeTestingProfile(profile.replacingOccurrences(of: "--configuration:", with: ""))
} }
@@ -70,6 +69,16 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
Log.info("Extra verbose mode has been activated.") 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.separator(as: .info)
Log.info("PHP MONITOR by Nico Verbruggen") Log.info("PHP MONITOR by Nico Verbruggen")
Log.info("Version \(App.version)") Log.info("Version \(App.version)")
@@ -102,7 +111,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
// Make sure notifications will work // Make sure notifications will work
setupNotifications() setupNotifications()
Task { // Make sure the menu performs its initial checks Task { // Make sure the menu performs its initial checks
await paths.loadUser()
await menu.startup() 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 // PHP Monitor
// //
// Created by Nico Verbruggen on 10/05/2022. // Created by Nico Verbruggen on 10/05/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
class AppVersion { class AppVersion: Comparable {
var version: String var version: String
var build: String? var build: Int?
var suffix: String? var suffix: String?
init(version: String, build: String?, suffix: String? = nil) { init(version: String, build: String?, suffix: String? = nil) {
self.version = version self.version = version
self.build = build self.build = Int(build ?? "0")
self.suffix = suffix self.suffix = suffix
} }
@@ -75,11 +75,27 @@ class AppVersion {
} }
var computerReadable: String { var computerReadable: String {
return "\(version)_\(build ?? "0")" return "\(version)_\(build ?? 0)"
} }
var humanReadable: String { var humanReadable: String {
return "\(version) (\(build ?? "???"))" return "\(version) (\(build ?? 0))"
} }
// MARK: - Comparable Protocol
static func < (lhs: AppVersion, rhs: AppVersion) -> Bool {
let comparisonResult = lhs.version.versionCompare(rhs.version)
if comparisonResult == .orderedAscending {
return true
}
return lhs.build ?? 0 < rhs.build ?? 0
}
static func == (lhs: AppVersion, rhs: AppVersion) -> Bool {
lhs.version.versionCompare(rhs.version) == .orderedSame
&& lhs.build == rhs.build
}
} }

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 14/09/2022. // Created by Nico Verbruggen on 14/09/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -17,7 +17,7 @@ public class EnvironmentManager {
// Failure condition #1: does not contain Laravel Valet // Failure condition #1: does not contain Laravel Valet
if !output.contains("Laravel Valet") { if !output.contains("Laravel Valet") {
return true return false
} }
// Extract the version number // Extract the version number
@@ -25,7 +25,6 @@ public class EnvironmentManager {
// Get the actual version // Get the actual version
return Valet.shared.version == nil return Valet.shared.version == nil
}() // returns true if none of the failure conditions are met }() // returns true if none of the failure conditions are met
} }
} }

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 23/12/2022. // Created by Nico Verbruggen on 23/12/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -41,9 +41,14 @@ class FakeServicesManager: ServicesManager {
private func reapplyServices() { private func reapplyServices() {
let services = self.formulae.map { let services = self.formulae.map {
let dummy = HomebrewService.dummy(
named: $0.name,
enabled: self.fixedStatus == .active,
status: self.fixedStatus == .error ? "error" : nil
)
let wrapper = Service( let wrapper = Service(
formula: $0, formula: $0,
service: HomebrewService.dummy(named: $0.name, enabled: self.fixedStatus == .active) service: dummy
) )
return wrapper return wrapper
} }

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 11/06/2022. // Created by Nico Verbruggen on 11/06/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -66,7 +66,7 @@ class ServicesManager: ObservableObject {
public var statusColor: Color { public var statusColor: Color {
if self.services.isEmpty || !self.firstRunComplete { if self.services.isEmpty || !self.firstRunComplete {
return .yellow return Color("StatusColorYellow")
} }
let statuses = self.services[0...2].map { $0.status } let statuses = self.services[0...2].map { $0.status }
@@ -74,10 +74,10 @@ class ServicesManager: ObservableObject {
if statuses.contains(.missing) if statuses.contains(.missing)
|| statuses.contains(.inactive) || statuses.contains(.inactive)
|| statuses.contains(.error) { || statuses.contains(.error) {
return .red return Color("StatusColorRed")
} }
return .green return Color("StatusColorGreen")
} }
/** /**

View File

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

View File

@@ -2,7 +2,7 @@
// Environment.swift // Environment.swift
// PHP Monitor // PHP Monitor
// //
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -242,7 +242,7 @@ class Startup {
.components(separatedBy: "Laravel Valet")[1] .components(separatedBy: "Laravel Valet")[1]
.trimmingCharacters(in: .whitespaces) .trimmingCharacters(in: .whitespaces)
// Extract the version number // 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 // Get the actual version
return Valet.shared.version == nil return Valet.shared.version == nil
}, },
@@ -261,7 +261,7 @@ class Startup {
}, },
name: "valet version is supported", name: "valet version is supported",
titleText: "startup.errors.valet_version_not_supported.title".localized, titleText: "startup.errors.valet_version_not_supported.title".localized,
subtitleText: "startup.errors.valet_version_not_supported.subtitle".localized(Valet.shared.version.text), subtitleText: "startup.errors.valet_version_not_supported.subtitle".localized,
descriptionText: "startup.errors.valet_version_not_supported.desc".localized descriptionText: "startup.errors.valet_version_not_supported.desc".localized
) )
] ]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 16/03/2022. // Created by Nico Verbruggen on 16/03/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Cocoa import Cocoa
@@ -25,7 +25,7 @@ class DomainListTypeCell: NSTableCellView, DomainListCellProtocol {
} }
// PHP version // 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) { func populateCell(with proxy: ValetProxy) {

View File

@@ -3,7 +3,7 @@
// PHP Monitor // PHP Monitor
// //
// Created by Nico Verbruggen on 23/12/2021. // Created by Nico Verbruggen on 23/12/2021.
// Copyright © 2022 Nico Verbruggen. All rights reserved. // Copyright © 2023 Nico Verbruggen. All rights reserved.
// //
import Foundation import Foundation
@@ -30,17 +30,17 @@ extension DomainListVC {
NSWorkspace.shared.open(url) NSWorkspace.shared.open(url)
} }
@objc func openInFinder() async { @objc func openInFinder() {
await Shell.quiet("open '\(selectedSite!.absolutePath)'") Task { return await Shell.quiet("open '\(selectedSite!.absolutePath)'") }
} }
@objc func openInTerminal() async { @objc func openInTerminal() {
await Shell.quiet("open -b com.apple.terminal '\(selectedSite!.absolutePath)'") Task { await Shell.quiet("open -b com.apple.terminal '\(selectedSite!.absolutePath)'") }
} }
@objc func openWithEditor(sender: EditorMenuItem) async { @objc func openWithEditor(sender: EditorMenuItem) {
guard let editor = sender.editor else { return } guard let editor = sender.editor else { return }
await editor.openDirectory(file: selectedSite!.absolutePath) editor.openDirectory(file: selectedSite!.absolutePath)
} }
// MARK: - UI interaction // MARK: - UI interaction

View File

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

View File

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

View File

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

View File

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

View File

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

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