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

Compare commits

..

8 Commits

10 changed files with 95 additions and 40 deletions

View File

@@ -2799,7 +2799,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 = 1025;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG = YES; DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
@@ -2828,7 +2828,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 = 1025;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG = NO; DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
@@ -3056,7 +3056,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 = 1025;
DEBUG = NO; DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -3166,7 +3166,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 = 1025;
DEBUG = YES; DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;

View File

@@ -20,9 +20,18 @@ struct Constants {
/** /**
* 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-v7.3
[ [
"7.4", "7.4",
"8.0", "8.1", "8.2", "8.3" "8.0", "8.1", "8.2",
"8.3" // dev
] ]
] ]

View File

@@ -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

@@ -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

@@ -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

@@ -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

@@ -109,6 +109,24 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
} }
} }
@objc func showIncompatiblePhpVersionsAlert() {
Task { @MainActor in
BetterAlert().withInformation(
title: "startup.unsupported_versions_explanation.title".localized,
subtitle: "startup.unsupported_versions_explanation.subtitle".localized(
PhpEnv.shared.incompatiblePhpVersions
.map({ version in
return "• PHP \(version)"
})
.joined(separator: "\n")
),
description: "startup.unsupported_versions_explanation.desc".localized
)
.withPrimary(text: "generic.ok".localized)
.show()
}
}
/** Reloads the menu in the background, using `asyncExecution`. */ /** Reloads the menu in the background, using `asyncExecution`. */
@objc func reloadPhpMonitorMenuInBackground() { @objc func reloadPhpMonitorMenuInBackground() {
asyncExecution({ asyncExecution({

View File

@@ -30,7 +30,7 @@ extension StatusMenu {
return return
} }
if PhpEnv.shared.availablePhpVersions.isEmpty { return } if PhpEnv.shared.availablePhpVersions.isEmpty && PhpEnv.shared.incompatiblePhpVersions.isEmpty { return }
addSwitchToPhpMenuItems() addSwitchToPhpMenuItems()
self.addItem(NSMenuItem.separator()) self.addItem(NSMenuItem.separator())
@@ -49,8 +49,7 @@ extension StatusMenu {
func addSwitchToPhpMenuItems() { func addSwitchToPhpMenuItems() {
var shortcutKey = 1 var shortcutKey = 1
for index in (0..<PhpEnv.shared.availablePhpVersions.count).reversed() { for index in (0..<PhpEnv.shared.availablePhpVersions.count) {
// Get the short and long version // Get the short and long version
let shortVersion = PhpEnv.shared.availablePhpVersions[index] let shortVersion = PhpEnv.shared.availablePhpVersions[index]
let longVersion = PhpEnv.shared.cachedPhpInstallations[shortVersion]!.versionNumber let longVersion = PhpEnv.shared.cachedPhpInstallations[shortVersion]!.versionNumber
@@ -72,6 +71,16 @@ extension StatusMenu {
addItem(menuItem) addItem(menuItem)
} }
if !PhpEnv.shared.incompatiblePhpVersions.isEmpty {
addItem(NSMenuItem.separator())
addItem(NSMenuItem(
title: "⚠️ " + "mi_php_unsupported".localized(
"\(PhpEnv.shared.incompatiblePhpVersions.count)"
),
action: #selector(MainMenu.showIncompatiblePhpVersionsAlert)
))
}
} }
func addCoreMenuItems() { func addCoreMenuItems() {

View File

@@ -12,6 +12,7 @@
"mi_unsure" = "We are not sure what version of PHP you are running."; "mi_unsure" = "We are not sure what version of PHP you are running.";
"mi_php_version" = "Global PHP version: PHP"; "mi_php_version" = "Global PHP version: PHP";
"mi_php_switch" = "Switch to PHP"; "mi_php_switch" = "Switch to PHP";
"mi_php_unsupported" = "Some installed PHP versions are not displayed.";
"mi_php_broken_1" = "Oof! It appears your PHP installation is broken..."; "mi_php_broken_1" = "Oof! It appears your PHP installation is broken...";
"mi_php_broken_2" = "Try running `php -v` in your terminal."; "mi_php_broken_2" = "Try running `php -v` in your terminal.";
"mi_php_broken_3" = "You could also try switching to another version."; "mi_php_broken_3" = "You could also try switching to another version.";
@@ -525,7 +526,7 @@ If you are seeing this message but are confused why this folder has gone missing
// Valet version too new or old // Valet version too new or old
"startup.errors.valet_version_not_supported.title" = "This version of Valet is not supported"; "startup.errors.valet_version_not_supported.title" = "This version of Valet is not supported";
"startup.errors.valet_version_not_supported.subtitle" = "You are running a version of Valet that is currently not supported (%@). PHP Monitor currently works with Valet v2, v3 and v4. In order to avoid causing issues on your system, PHP Monitor cannot start."; "startup.errors.valet_version_not_supported.subtitle" = "You are running a version of Valet that is currently not supported. PHP Monitor currently works with Valet v2, v3 and v4. In order to avoid causing issues on your system, PHP Monitor cannot start.";
"startup.errors.valet_version_not_supported.desc" = "You must install a version of Valet that is compatible with PHP Monitor, or you may need to upgrade to a newer version of PHP Monitor which may include compatibility for this version of Valet (consult the latest release notes for more info)."; "startup.errors.valet_version_not_supported.desc" = "You must install a version of Valet that is compatible with PHP Monitor, or you may need to upgrade to a newer version of PHP Monitor which may include compatibility for this version of Valet (consult the latest release notes for more info).";
/// Brew & sudoers /// Brew & sudoers
@@ -560,8 +561,16 @@ If you are seeing this message but are confused why this folder has gone missing
"startup.version_mismatch.button_switch_back" = "Switch back to PHP %@"; "startup.version_mismatch.button_switch_back" = "Switch back to PHP %@";
"startup.version_mismatch.button_stay" = "Keep using PHP %@"; "startup.version_mismatch.button_stay" = "Keep using PHP %@";
// SPONSOR ENCOURAGEMENT // Warning about unsupported PHP versions
"startup.unsupported_versions_explanation.title" = "One or more PHP installed versions are not supported.";
"startup.unsupported_versions_explanation.subtitle" = "The following versions of PHP are installed on your system but are not supported by this version of Valet.
%@
Valet might break if you link these PHP versions so PHP Monitor won't let you switch to them.";
"startup.unsupported_versions_explanation.desc" = "If you need support for older versions of PHP, you may need to downgrade to an older versions of Valet. Otherwise, it might be a good idea to uninstall any outdated versions that are not in use. This message will only be removed after restarting PHP Monitor.";
// Sponsor encouragement
"startup.sponsor_encouragement.title" = "If PHP Monitor has been useful to you or your company, please consider leaving a tip."; "startup.sponsor_encouragement.title" = "If PHP Monitor has been useful to you or your company, please consider leaving a tip.";
"startup.sponsor_encouragement.subtitle" = "To be 100% transparent: I plan to keep PHP Monitor open source and free. Your support makes this decision very easy.\n\n(You will only see this prompt once.)"; "startup.sponsor_encouragement.subtitle" = "To be 100% transparent: I plan to keep PHP Monitor open source and free. Your support makes this decision very easy.\n\n(You will only see this prompt once.)";
"startup.sponsor_encouragement.desc" = "If you have already donated, then YOU are the reason why the app was able to get all these updates. In that case, this is a THANK YOU message to you. I appreciate the support."; "startup.sponsor_encouragement.desc" = "If you have already donated, then YOU are the reason why the app was able to get all these updates. In that case, this is a THANK YOU message to you. I appreciate the support.";

View File

@@ -24,11 +24,10 @@ class PhpVersionDetectionTest: XCTestCase {
"php@5.6", // should be omitted, not supported "php@5.6", // should be omitted, not supported
"php@5.4" // should be omitted, not supported "php@5.4" // should be omitted, not supported
], ],
supported: ["7.0", "8.0", "8.1", "8.2"],
checkBinaries: false, checkBinaries: false,
generateHelpers: false generateHelpers: false
) )
XCTAssertEqual(outcome, ["8.0", "7.0"]) XCTAssertEqual(outcome, ["8.0", "7.0", "5.6"])
} }
} }