mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
00cc6711a1 | |||
209244e162 | |||
e48d8ed98b | |||
834f76e5a1 | |||
7e48893247 | |||
e29ca9e1ad | |||
40e05d9445 | |||
3ebf51b319 | |||
4b8ad911f1 | |||
efd902b4f3 | |||
918e272da7 | |||
272a9182d3 | |||
63f85aff91 | |||
581c2d1974 | |||
4deef64537 | |||
bedabaa3bb |
@ -244,6 +244,8 @@
|
|||||||
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
||||||
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
|
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
|
||||||
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
||||||
|
C4D27F24292BDF630081B38F /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D27F23292BDF630081B38F /* Homebrew.swift */; };
|
||||||
|
C4D27F25292BDF630081B38F /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D27F23292BDF630081B38F /* Homebrew.swift */; };
|
||||||
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
||||||
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
||||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
||||||
@ -462,6 +464,7 @@
|
|||||||
C4CDA892288F1A71007CE25F /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; };
|
C4CDA892288F1A71007CE25F /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; };
|
||||||
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Switcher.swift"; sourceTree = "<group>"; };
|
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Switcher.swift"; sourceTree = "<group>"; };
|
||||||
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerWindow.swift; sourceTree = "<group>"; };
|
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerWindow.swift; sourceTree = "<group>"; };
|
||||||
|
C4D27F23292BDF630081B38F /* Homebrew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Homebrew.swift; sourceTree = "<group>"; };
|
||||||
C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; };
|
C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; };
|
||||||
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
|
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
|
||||||
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
|
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
|
||||||
@ -644,6 +647,7 @@
|
|||||||
C4C1019A27C65C6F001FACC2 /* Process.swift */,
|
C4C1019A27C65C6F001FACC2 /* Process.swift */,
|
||||||
C40C7F2F27722E8D00DDDCDC /* Logger.swift */,
|
C40C7F2F27722E8D00DDDCDC /* Logger.swift */,
|
||||||
C417DC73277614690015E6EE /* Helpers.swift */,
|
C417DC73277614690015E6EE /* Helpers.swift */,
|
||||||
|
C4D27F23292BDF630081B38F /* Homebrew.swift */,
|
||||||
);
|
);
|
||||||
path = Core;
|
path = Core;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1413,6 +1417,7 @@
|
|||||||
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
|
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
|
||||||
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
|
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
|
||||||
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
|
||||||
|
C4D27F24292BDF630081B38F /* Homebrew.swift in Sources */,
|
||||||
C485707028BF452300539B36 /* WarningsWindowController.swift in Sources */,
|
C485707028BF452300539B36 /* WarningsWindowController.swift in Sources */,
|
||||||
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */,
|
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */,
|
||||||
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
||||||
@ -1555,6 +1560,7 @@
|
|||||||
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */,
|
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */,
|
||||||
C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */,
|
C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */,
|
||||||
C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */,
|
C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */,
|
||||||
|
C4D27F25292BDF630081B38F /* Homebrew.swift in Sources */,
|
||||||
C40B24F227A310770018C7D2 /* Events.swift in Sources */,
|
C40B24F227A310770018C7D2 /* Events.swift in Sources */,
|
||||||
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */,
|
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */,
|
||||||
C4C0E8E027F88AEB002D32A9 /* FakeSiteScanner.swift in Sources */,
|
C4C0E8E027F88AEB002D32A9 /* FakeSiteScanner.swift in Sources */,
|
||||||
@ -1741,7 +1747,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 = 980;
|
CURRENT_PROJECT_VERSION = 992;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = YES;
|
DEBUG = YES;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -1752,7 +1758,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 5.6.3;
|
MARKETING_VERSION = 5.6.6;
|
||||||
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 = "";
|
||||||
@ -1769,7 +1775,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 = 980;
|
CURRENT_PROJECT_VERSION = 992;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG = NO;
|
DEBUG = NO;
|
||||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||||
@ -1780,7 +1786,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||||
MARKETING_VERSION = 5.6.3;
|
MARKETING_VERSION = 5.6.6;
|
||||||
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 = "";
|
||||||
|
49
README.md
49
README.md
@ -80,19 +80,50 @@ If you're still having issues, here's a few common questions & answers, as well
|
|||||||
<summary><strong>Which versions of PHP are supported?</strong></summary>
|
<summary><strong>Which versions of PHP are supported?</strong></summary>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>PHP 5.6 (only if you are running Valet 2)</li>
|
<li>PHP 5.6 (backport + only if you are running Valet 2)</li>
|
||||||
<li>PHP 7.0</li>
|
<li>PHP 7.0 (backport)</li>
|
||||||
<li>PHP 7.1</li>
|
<li>PHP 7.1 (backport)</li>
|
||||||
<li>PHP 7.2</li>
|
<li>PHP 7.2 (backport)</li>
|
||||||
<li>PHP 7.3</li>
|
<li>PHP 7.3 (backport)</li>
|
||||||
<li>PHP 7.4</li>
|
<li>PHP 7.4 (backport)</li>
|
||||||
<li>PHP 8.0</li>
|
<li>PHP 8.0 (official support)</li>
|
||||||
<li>PHP 8.1</li>
|
<li>PHP 8.1 (official support)</li>
|
||||||
<li>PHP 8.2 (experimental)</li>
|
<li>PHP 8.2 (latest version)</li>
|
||||||
|
<li>PHP 8.3-dev (experimental)</li>
|
||||||
</ul>
|
</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.
|
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.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>How do I install additional versions of PHP, including legacy versions?</strong></summary>
|
||||||
|
|
||||||
|
Assuming you have installed the `php` formula, the latest stable version of PHP is installed. At the time of writing, this is PHP 8.2.
|
||||||
|
|
||||||
|
You can install other supported versions of PHP out of the box, so `php@8.0` and `php@8.1` at the time of writing.
|
||||||
|
|
||||||
|
If you wish to install older (officially unsupported) versions of PHP for local use, you can do so by using [Shivam Mathur's tap](https://github.com/shivammathur/homebrew-php):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
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 can then install those older versions:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew install php@7.0
|
||||||
|
brew install php@7.1
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Always make sure to restart PHP Monitor after installing or upgrading PHP versions!**
|
||||||
|
|
||||||
|
> *Note*: Using this tap may cause [temporary alias conflicts](https://github.com/nicoverbruggen/phpmon/issues/54#issuecomment-979789724) while the core tap alias and the tap's alias refer to a different version of PHP, but this is generally speaking a minor inconvenience, since this normally only applies when a new PHP version releases.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
@ -6,9 +6,7 @@ Generally speaking, only the latest version of **PHP Monitor** is supported, exc
|
|||||||
|
|
||||||
| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version |
|
| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version |
|
||||||
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
|
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
|
||||||
| 5.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) | 3.0 recommended<br/> 2.16.2 minimum |
|
| 5.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) | 3.0 recommended<br/> 2.16.2 minimum |
|
||||||
|
|
||||||
_(*) macOS Ventura (13.0) is not officially supported until it officially releases._
|
|
||||||
|
|
||||||
## Legacy versions
|
## Legacy versions
|
||||||
|
|
||||||
|
@ -13,37 +13,35 @@ class Actions {
|
|||||||
// MARK: - Services
|
// MARK: - Services
|
||||||
|
|
||||||
public static func restartPhpFpm() {
|
public static func restartPhpFpm() {
|
||||||
brew("services restart \(PhpEnv.phpInstall.formula)", sudo: true)
|
brew("services restart \(Homebrew.Formulae.php)", sudo: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func restartNginx() {
|
public static func restartNginx() {
|
||||||
brew("services restart nginx", sudo: true)
|
brew("services restart \(Homebrew.Formulae.nginx)", sudo: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func restartDnsMasq() {
|
public static func restartDnsMasq() {
|
||||||
brew("services restart dnsmasq", sudo: true)
|
brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func stopValetServices() {
|
public static func stopValetServices() {
|
||||||
brew("services stop \(PhpEnv.phpInstall.formula)", sudo: true)
|
brew("services stop \(Homebrew.Formulae.php)", sudo: true)
|
||||||
brew("services stop nginx", sudo: true)
|
brew("services stop \(Homebrew.Formulae.nginx)", sudo: true)
|
||||||
brew("services stop dnsmasq", sudo: true)
|
brew("services stop \(Homebrew.Formulae.dnsmasq)", sudo: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func fixHomebrewPermissions() throws {
|
public static func fixHomebrewPermissions() throws {
|
||||||
var servicesCommands = [
|
var servicesCommands = [
|
||||||
"\(Paths.brew) services stop nginx",
|
"\(Paths.brew) services stop \(Homebrew.Formulae.nginx)",
|
||||||
"\(Paths.brew) services stop dnsmasq"
|
"\(Paths.brew) services stop \(Homebrew.Formulae.dnsmasq)"
|
||||||
]
|
]
|
||||||
var cellarCommands = [
|
var cellarCommands = [
|
||||||
"chown -R \(Paths.whoami):admin \(Paths.cellarPath)/nginx",
|
"chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(Homebrew.Formulae.nginx)",
|
||||||
"chown -R \(Paths.whoami):admin \(Paths.cellarPath)/dnsmasq"
|
"chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(Homebrew.Formulae.dnsmasq)"
|
||||||
]
|
]
|
||||||
|
|
||||||
PhpEnv.shared.availablePhpVersions.forEach { version in
|
PhpEnv.shared.availablePhpVersions.forEach { version in
|
||||||
let formula = version == PhpEnv.brewPhpVersion
|
let formula = version == PhpEnv.brewPhpVersion ? "php" : "php@\(version)"
|
||||||
? "php"
|
|
||||||
: "php@\(version)"
|
|
||||||
servicesCommands.append("\(Paths.brew) services stop \(formula)")
|
servicesCommands.append("\(Paths.brew) services stop \(formula)")
|
||||||
cellarCommands.append("chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(formula)")
|
cellarCommands.append("chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(formula)")
|
||||||
}
|
}
|
||||||
@ -145,9 +143,9 @@ class Actions {
|
|||||||
*/
|
*/
|
||||||
public static func fixMyValet(completed: @escaping () -> Void) {
|
public static func fixMyValet(completed: @escaping () -> Void) {
|
||||||
InternalSwitcher().performSwitch(to: PhpEnv.brewPhpVersion, completion: {
|
InternalSwitcher().performSwitch(to: PhpEnv.brewPhpVersion, completion: {
|
||||||
brew("services restart dnsmasq", sudo: true)
|
brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: true)
|
||||||
brew("services restart php", sudo: true)
|
brew("services restart \(Homebrew.Formulae.php)", sudo: true)
|
||||||
brew("services restart nginx", sudo: true)
|
brew("services restart \(Homebrew.Formulae.nginx)", sudo: true)
|
||||||
completed()
|
completed()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,6 @@ import Cocoa
|
|||||||
|
|
||||||
struct Constants {
|
struct Constants {
|
||||||
|
|
||||||
/**
|
|
||||||
* The latest PHP version that is considered to be stable at the time of release.
|
|
||||||
* This version number is currently not used (only as a default fallback).
|
|
||||||
*/
|
|
||||||
static let LatestStablePhpVersion = "8.1"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The minimum version of Valet that is recommended.
|
The minimum version of Valet that is recommended.
|
||||||
If the installed version is older, a notification will be shown
|
If the installed version is older, a notification will be shown
|
||||||
@ -42,13 +36,14 @@ struct Constants {
|
|||||||
"7.4",
|
"7.4",
|
||||||
"8.0",
|
"8.0",
|
||||||
"8.1",
|
"8.1",
|
||||||
|
"8.2",
|
||||||
|
|
||||||
// ====================
|
// ====================
|
||||||
// EXPERIMENTAL SUPPORT
|
// EXPERIMENTAL SUPPORT
|
||||||
// ====================
|
// ====================
|
||||||
// Every release that supports the next release will always support the next
|
// Every release that supports the next release will always support the next
|
||||||
// dev release. In this case, that means that the version below is detected.
|
// dev release. In this case, that means that the version below is detected.
|
||||||
"8.2"
|
"8.3"
|
||||||
]
|
]
|
||||||
|
|
||||||
struct Urls {
|
struct Urls {
|
||||||
|
25
phpmon/Common/Core/Homebrew.swift
Normal file
25
phpmon/Common/Core/Homebrew.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Homebrew.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 21/11/2022.
|
||||||
|
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class Homebrew {
|
||||||
|
struct Formulae {
|
||||||
|
static var php: String {
|
||||||
|
return PhpEnv.phpInstall.formula
|
||||||
|
}
|
||||||
|
|
||||||
|
static var nginx: String {
|
||||||
|
return HomebrewDiagnostics.usesNginxFullFormula ? "nginx-full" : "nginx"
|
||||||
|
}
|
||||||
|
|
||||||
|
static var dnsmasq: String {
|
||||||
|
return "dnsmasq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -46,7 +46,7 @@ class InternalSwitcher: PhpSwitcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log.info("Restarting nginx, just to be sure!")
|
Log.info("Restarting nginx, just to be sure!")
|
||||||
brew("services restart nginx", sudo: true)
|
brew("services restart \(Homebrew.Formulae.nginx)", sudo: true)
|
||||||
|
|
||||||
Log.info("The new version(s) have been linked!")
|
Log.info("The new version(s) have been linked!")
|
||||||
completion()
|
completion()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||||
<capability name="Image references" minToolsVersion="12.0"/>
|
<capability name="Image references" minToolsVersion="12.0"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Search Toolbar Item" minToolsVersion="12.0" minSystemVersion="11.0"/>
|
<capability name="Search Toolbar Item" minToolsVersion="12.0" minSystemVersion="11.0"/>
|
||||||
@ -1112,17 +1112,17 @@ Gw
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController storyboardIdentifier="newProxyLink" id="dwh-CF-6iv" customClass="AddProxyVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
|
<viewController storyboardIdentifier="newProxyLink" id="dwh-CF-6iv" customClass="AddProxyVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<view key="view" id="U5U-QR-YXS">
|
<view key="view" id="U5U-QR-YXS">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="480" height="286"/>
|
<rect key="frame" x="0.0" y="0.0" width="540" height="286"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="kkd-UV-SnA">
|
<box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="kkd-UV-SnA">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="480" height="286"/>
|
<rect key="frame" x="0.0" y="0.0" width="540" height="286"/>
|
||||||
<view key="contentView" id="IXW-35-8NJ">
|
<view key="contentView" id="IXW-35-8NJ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="480" height="286"/>
|
<rect key="frame" x="0.0" y="0.0" width="540" height="286"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QCK-Z9-w7g">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QCK-Z9-w7g">
|
||||||
<rect key="frame" x="20" y="196" width="440" height="21"/>
|
<rect key="frame" x="20" y="196" width="500" height="21"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="http://127.0.0.1:80" placeholderString="http://127.0.0.1:80" drawsBackground="YES" id="muS-8M-KSy">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="http://127.0.0.1:80" placeholderString="http://127.0.0.1:80" drawsBackground="YES" id="muS-8M-KSy">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -1149,7 +1149,7 @@ Gw
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNw-oQ-bnb">
|
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNw-oQ-bnb">
|
||||||
<rect key="frame" x="20" y="147" width="440" height="21"/>
|
<rect key="frame" x="20" y="147" width="500" height="21"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter a domain name here." drawsBackground="YES" id="gTQ-Y2-Y9w">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter a domain name here." drawsBackground="YES" id="gTQ-Y2-Y9w">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -1176,7 +1176,7 @@ Gw
|
|||||||
<color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</box>
|
</box>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4Vi-cN-ude">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4Vi-cN-ude">
|
||||||
<rect key="frame" x="317" y="13" width="150" height="32"/>
|
<rect key="frame" x="377" y="13" width="150" height="32"/>
|
||||||
<buttonCell key="cell" type="push" title="[i18n] Create Proxy" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="H2Z-c5-5Vk">
|
<buttonCell key="cell" type="push" title="[i18n] Create Proxy" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="H2Z-c5-5Vk">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -1205,7 +1205,10 @@ Gw
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSZ-x8-Pqi">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSZ-x8-Pqi">
|
||||||
<rect key="frame" x="18" y="128" width="444" height="14"/>
|
<rect key="frame" x="18" y="128" width="504" height="14"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="500" id="sF1-RG-URI"/>
|
||||||
|
</constraints>
|
||||||
<textFieldCell key="cell" title="[i18n] Preview text here" id="ISE-9R-ncQ">
|
<textFieldCell key="cell" title="[i18n] Preview text here" id="ISE-9R-ncQ">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -1223,7 +1226,7 @@ Gw
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5x7-ll-2f7">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5x7-ll-2f7">
|
||||||
<rect key="frame" x="18" y="60" width="444" height="28"/>
|
<rect key="frame" x="18" y="60" width="504" height="28"/>
|
||||||
<textFieldCell key="cell" title="[i18n] Securing a domain requires administrative privileges.
You may be prompted for your password or Touch ID." id="IMB-O5-ZOy">
|
<textFieldCell key="cell" title="[i18n] Securing a domain requires administrative privileges.
You may be prompted for your password or Touch ID." id="IMB-O5-ZOy">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -1239,7 +1242,7 @@ Gw
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="w0k-CK-0u4">
|
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="w0k-CK-0u4">
|
||||||
<rect key="frame" x="131" y="23" width="180" height="14"/>
|
<rect key="frame" x="191" y="23" width="180" height="14"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="That domain name already exists." id="4sH-94-UJl">
|
<textFieldCell key="cell" lineBreakMode="clipping" title="That domain name already exists." id="4sH-94-UJl">
|
||||||
<font key="font" metaFont="smallSystem"/>
|
<font key="font" metaFont="smallSystem"/>
|
||||||
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
|
||||||
@ -1293,7 +1296,7 @@ Gw
|
|||||||
</viewController>
|
</viewController>
|
||||||
<customObject id="VaP-ZM-OcY" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
<customObject id="VaP-ZM-OcY" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="210" y="1524"/>
|
<point key="canvasLocation" x="220" y="1522"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Window Controller-->
|
<!--Window Controller-->
|
||||||
<scene sceneID="5Gf-7O-tdA">
|
<scene sceneID="5Gf-7O-tdA">
|
||||||
|
@ -18,9 +18,9 @@ class ServicesManager: ObservableObject {
|
|||||||
|
|
||||||
public static func loadHomebrewServices(completed: (() -> Void)? = nil) {
|
public static func loadHomebrewServices(completed: (() -> Void)? = nil) {
|
||||||
let rootServiceNames = [
|
let rootServiceNames = [
|
||||||
PhpEnv.phpInstall.formula,
|
Homebrew.Formulae.php,
|
||||||
"nginx",
|
Homebrew.Formulae.nginx,
|
||||||
"dnsmasq"
|
Homebrew.Formulae.dnsmasq
|
||||||
]
|
]
|
||||||
|
|
||||||
DispatchQueue.global(qos: .background).async {
|
DispatchQueue.global(qos: .background).async {
|
||||||
@ -39,9 +39,7 @@ class ServicesManager: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let userServiceNames = Preferences.custom.services else {
|
let userServiceNames = Preferences.custom.services ?? []
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
DispatchQueue.global(qos: .background).async {
|
DispatchQueue.global(qos: .background).async {
|
||||||
let data = Shell
|
let data = Shell
|
||||||
|
@ -160,7 +160,7 @@ class Startup {
|
|||||||
// Verify if the Homebrew services are running (as root).
|
// Verify if the Homebrew services are running (as root).
|
||||||
// =================================================================================
|
// =================================================================================
|
||||||
EnvironmentCheck(
|
EnvironmentCheck(
|
||||||
command: { return HomebrewDiagnostics.cannotLoadService() },
|
command: { return HomebrewDiagnostics.cannotLoadService("dnsmasq") },
|
||||||
name: "`sudo \(Paths.brew) services info` JSON loaded",
|
name: "`sudo \(Paths.brew) services info` JSON loaded",
|
||||||
titleText: "startup.errors.services_json_error.title".localized,
|
titleText: "startup.errors.services_json_error.title".localized,
|
||||||
subtitleText: "startup.errors.services_json_error.subtitle".localized,
|
subtitleText: "startup.errors.services_json_error.subtitle".localized,
|
||||||
|
@ -157,8 +157,14 @@ class AddProxyVC: NSViewController, NSTextFieldDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
previewText.stringValue = "domain_list.add.proxy_available"
|
var translationKey = "domain_list.add.proxy_available"
|
||||||
.localized(
|
|
||||||
|
if inputProxySubject.stringValue.starts(with: "https://") {
|
||||||
|
translationKey = "domain_list.add.proxy_https_warning"
|
||||||
|
}
|
||||||
|
|
||||||
|
previewText.stringValue =
|
||||||
|
translationKey.localized(
|
||||||
inputProxySubject.stringValue,
|
inputProxySubject.stringValue,
|
||||||
buttonSecure.state == .on ? "https" : "http",
|
buttonSecure.state == .on ? "https" : "http",
|
||||||
inputDomainName.stringValue,
|
inputDomainName.stringValue,
|
||||||
|
@ -113,9 +113,7 @@ class ComposerWindow {
|
|||||||
|
|
||||||
private func removeBusyStatus() {
|
private func removeBusyStatus() {
|
||||||
PhpEnv.shared.isBusy = false
|
PhpEnv.shared.isBusy = false
|
||||||
DispatchQueue.main.async { [self] in
|
menu?.updatePhpVersionInStatusBar()
|
||||||
menu?.updatePhpVersionInStatusBar()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Alert
|
// MARK: Alert
|
||||||
|
@ -29,6 +29,21 @@ class HomebrewDiagnostics {
|
|||||||
return installedTaps.contains("nicoverbruggen/cask")
|
return installedTaps.contains("nicoverbruggen/cask")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
/**
|
||||||
|
Determines whether to use the regular `nginx` or `nginx-full` formula.
|
||||||
|
*/
|
||||||
|
public static var usesNginxFullFormula: Bool = {
|
||||||
|
guard let destination = try? FileManager.default
|
||||||
|
.destinationOfSymbolicLink(atPath: "\(Paths.binPath)/nginx") else { return false }
|
||||||
|
|
||||||
|
return
|
||||||
|
// Verify that the `nginx` binary is symlinked to a directory that includes `nginx-full`.
|
||||||
|
destination.contains("/nginx-full/")
|
||||||
|
// Verify that the formula exists.
|
||||||
|
&& !Shell.pipe("\(Paths.brew) info nginx-full --json")
|
||||||
|
.contains("Error: No available formula")
|
||||||
|
}()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
It is possible to have the `shivammathur/php` tap installed, and for the core homebrew information to be outdated.
|
It is possible to have the `shivammathur/php` tap installed, and for the core homebrew information to be outdated.
|
||||||
This will then result in two different aliases claiming to point to the same formula (`php`).
|
This will then result in two different aliases claiming to point to the same formula (`php`).
|
||||||
@ -128,10 +143,10 @@ class HomebrewDiagnostics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
In order to see if we support the --json syntax, we'll query nginx.
|
In order to see if we support the --json syntax, we'll query dnsmasq.
|
||||||
If the JSON response cannot be parsed, Homebrew is probably out of date.
|
If the JSON response cannot be parsed, Homebrew is probably out of date.
|
||||||
*/
|
*/
|
||||||
public static func cannotLoadService(_ name: String = "nginx") -> Bool {
|
public static func cannotLoadService(_ name: String) -> Bool {
|
||||||
let serviceInfo = try? JSONDecoder().decode(
|
let serviceInfo = try? JSONDecoder().decode(
|
||||||
[HomebrewService].self,
|
[HomebrewService].self,
|
||||||
from: Shell.pipe(
|
from: Shell.pipe(
|
||||||
|
@ -29,12 +29,16 @@ extension MainMenu {
|
|||||||
When the environment is all clear and the app can run, let's go.
|
When the environment is all clear and the app can run, let's go.
|
||||||
*/
|
*/
|
||||||
private func onEnvironmentPass() {
|
private func onEnvironmentPass() {
|
||||||
// Determine install method
|
|
||||||
Log.info(HomebrewDiagnostics.customCaskInstalled
|
Log.info(HomebrewDiagnostics.customCaskInstalled
|
||||||
? "The app has probably been installed via Homebrew Cask."
|
? "The app has probably been installed via Homebrew Cask."
|
||||||
: "The app has probably been installed directly."
|
: "The app has probably been installed directly."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Log.info(HomebrewDiagnostics.usesNginxFullFormula
|
||||||
|
? "The app will be using the `nginx-full` formula."
|
||||||
|
: "The app will be using the `nginx` formula."
|
||||||
|
)
|
||||||
|
|
||||||
// Attempt to find out more info about Valet
|
// Attempt to find out more info about Valet
|
||||||
if Valet.shared.version != nil {
|
if Valet.shared.version != nil {
|
||||||
Log.info("PHP Monitor has extracted the version number of Valet: \(Valet.shared.version!)")
|
Log.info("PHP Monitor has extracted the version number of Valet: \(Valet.shared.version!)")
|
||||||
|
@ -17,9 +17,9 @@ struct ServicesView: View {
|
|||||||
static func asMenuItem(perRow: Int = 3) -> NSMenuItem {
|
static func asMenuItem(perRow: Int = 3) -> NSMenuItem {
|
||||||
let item = NSMenuItem()
|
let item = NSMenuItem()
|
||||||
var services = [
|
var services = [
|
||||||
PhpEnv.phpInstall.formula,
|
Homebrew.Formulae.php,
|
||||||
"nginx",
|
Homebrew.Formulae.nginx,
|
||||||
"dnsmasq"
|
Homebrew.Formulae.dnsmasq
|
||||||
]
|
]
|
||||||
|
|
||||||
if Preferences.custom.hasServices() {
|
if Preferences.custom.hasServices() {
|
||||||
|
@ -139,6 +139,9 @@
|
|||||||
"domain_list.add.domain_name" = "Domain name";
|
"domain_list.add.domain_name" = "Domain name";
|
||||||
"domain_list.add.create_proxy" = "Create Proxy";
|
"domain_list.add.create_proxy" = "Create Proxy";
|
||||||
"domain_list.add.proxy_available" = "%@ will be proxied and will be available via: %@://%@.%@";
|
"domain_list.add.proxy_available" = "%@ will be proxied and will be available via: %@://%@.%@";
|
||||||
|
"domain_list.add.proxy_https_warning" = "%@ will be proxied and will be available via: %@://%@.%@.
|
||||||
|
|
||||||
|
(!) IMPORTANT: This proxy may not work until you manually add `proxy_ssl_verify off;` to the nginx configuration file for this domain. It is recommended that you use an unsecured domain as the proxy subject.";
|
||||||
|
|
||||||
// ADD SITE TO DOMAINS LIST
|
// ADD SITE TO DOMAINS LIST
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user