mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 20:10:08 +02:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
9a175e7291 | |||
d53e92ce94 | |||
3344fdb1dc | |||
020a0260f1 | |||
3ce7e8f48b | |||
ae7e13de9b | |||
c82ea1fac1 | |||
d6258f54a9 |
@ -2799,7 +2799,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1020;
|
||||
CURRENT_PROJECT_VERSION = 1025;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -2828,7 +2828,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1020;
|
||||
CURRENT_PROJECT_VERSION = 1025;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -3056,7 +3056,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1020;
|
||||
CURRENT_PROJECT_VERSION = 1025;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@ -3166,7 +3166,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1020;
|
||||
CURRENT_PROJECT_VERSION = 1025;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
|
@ -20,9 +20,18 @@ struct Constants {
|
||||
|
||||
/**
|
||||
* 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
|
||||
[
|
||||
"5.6",
|
||||
@ -32,12 +41,14 @@ struct Constants {
|
||||
3: // Valet v3 dropped support for v5.6
|
||||
[
|
||||
"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",
|
||||
"8.0", "8.1", "8.2", "8.3"
|
||||
"8.0", "8.1", "8.2",
|
||||
"8.3" // dev
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -33,8 +33,8 @@ class Application {
|
||||
Attempt to open a specific directory in the app of choice.
|
||||
(This will open the app if it isn't open yet.)
|
||||
*/
|
||||
@objc public func openDirectory(file: String) async {
|
||||
return await Shell.quiet("/usr/bin/open -a \"\(name)\" \"\(file)\"")
|
||||
@objc public func openDirectory(file: String) {
|
||||
Task { await Shell.quiet("/usr/bin/open -a \"\(name)\" \"\(file)\"") }
|
||||
}
|
||||
|
||||
/** Checks if the app is installed. */
|
||||
|
@ -38,9 +38,12 @@ class PhpEnv {
|
||||
/** Whether the switcher is busy performing any actions. */
|
||||
var isBusy: Bool = false
|
||||
|
||||
/** All available versions of PHP. */
|
||||
/** All versions of PHP that are currently supported. */
|
||||
var availablePhpVersions: [String] = []
|
||||
|
||||
/** All versions of PHP that are currently installed but not compatible. */
|
||||
var incompatiblePhpVersions: [String] = []
|
||||
|
||||
/** Cached information about the PHP installations. */
|
||||
var cachedPhpInstallations: [String: PhpInstallation] = [:]
|
||||
|
||||
@ -87,13 +90,14 @@ class PhpEnv {
|
||||
/**
|
||||
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
|
||||
|
||||
var versionsOnly = await extractPhpVersions(
|
||||
from: files.components(separatedBy: "\n"),
|
||||
supported: Constants.ValetSupportedPhpVersionMatrix[Valet.shared.version.major] ?? []
|
||||
)
|
||||
let versions = await extractPhpVersions(from: files.components(separatedBy: "\n"))
|
||||
|
||||
let supportedByValet = Constants.ValetSupportedPhpVersionMatrix[Valet.shared.version.major] ?? []
|
||||
|
||||
var supportedVersions = versions.intersection(supportedByValet)
|
||||
|
||||
// Make sure the aliased version is detected
|
||||
// The user may have `php` installed, but not e.g. `php@8.0`
|
||||
@ -101,13 +105,18 @@ class PhpEnv {
|
||||
let phpAlias = homebrewPackage.version
|
||||
|
||||
// Avoid inserting a duplicate
|
||||
if !versionsOnly.contains(phpAlias) && FileSystem.fileExists("\(Paths.optPath)/php/bin/php") {
|
||||
versionsOnly.append(phpAlias)
|
||||
if !supportedVersions.contains(phpAlias) && FileSystem.fileExists("\(Paths.optPath)/php/bin/php") {
|
||||
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] = [:]
|
||||
|
||||
@ -117,7 +126,7 @@ class PhpEnv {
|
||||
|
||||
cachedPhpInstallations = mappedVersions
|
||||
|
||||
return versionsOnly
|
||||
return supportedVersions
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,11 +138,11 @@ class PhpEnv {
|
||||
*/
|
||||
public func extractPhpVersions(
|
||||
from versions: [String],
|
||||
supported: [String],
|
||||
checkBinaries: Bool = true,
|
||||
generateHelpers: Bool = true
|
||||
) async -> [String] {
|
||||
var output: [String] = []
|
||||
) async -> Set<String> {
|
||||
let supported = Constants.DetectedPhpVersions
|
||||
var output: Set<String> = []
|
||||
versions.filter { (version) -> Bool in
|
||||
// Omit everything that doesn't start with php@
|
||||
// (e.g. something-php@8.0 won't be detected)
|
||||
@ -145,7 +154,7 @@ class PhpEnv {
|
||||
if !output.contains(version)
|
||||
&& supported.contains(version)
|
||||
&& (checkBinaries ? FileSystem.fileExists("\(Paths.optPath)/php@\(version)/bin/php") : true) {
|
||||
output.append(version)
|
||||
output.insert(version)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ class Startup {
|
||||
},
|
||||
name: "valet version is supported",
|
||||
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
|
||||
)
|
||||
]
|
||||
|
@ -30,17 +30,17 @@ extension DomainListVC {
|
||||
NSWorkspace.shared.open(url)
|
||||
}
|
||||
|
||||
@objc func openInFinder() async {
|
||||
await Shell.quiet("open '\(selectedSite!.absolutePath)'")
|
||||
@objc func openInFinder() {
|
||||
Task { return await Shell.quiet("open '\(selectedSite!.absolutePath)'") }
|
||||
}
|
||||
|
||||
@objc func openInTerminal() async {
|
||||
await Shell.quiet("open -b com.apple.terminal '\(selectedSite!.absolutePath)'")
|
||||
@objc func openInTerminal() {
|
||||
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 }
|
||||
await editor.openDirectory(file: selectedSite!.absolutePath)
|
||||
editor.openDirectory(file: selectedSite!.absolutePath)
|
||||
}
|
||||
|
||||
// MARK: - UI interaction
|
||||
|
@ -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`. */
|
||||
@objc func reloadPhpMonitorMenuInBackground() {
|
||||
asyncExecution({
|
||||
|
@ -30,7 +30,7 @@ extension StatusMenu {
|
||||
return
|
||||
}
|
||||
|
||||
if PhpEnv.shared.availablePhpVersions.isEmpty { return }
|
||||
if PhpEnv.shared.availablePhpVersions.isEmpty && PhpEnv.shared.incompatiblePhpVersions.isEmpty { return }
|
||||
|
||||
addSwitchToPhpMenuItems()
|
||||
self.addItem(NSMenuItem.separator())
|
||||
@ -49,8 +49,7 @@ extension StatusMenu {
|
||||
|
||||
func addSwitchToPhpMenuItems() {
|
||||
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
|
||||
let shortVersion = PhpEnv.shared.availablePhpVersions[index]
|
||||
let longVersion = PhpEnv.shared.cachedPhpInstallations[shortVersion]!.versionNumber
|
||||
@ -72,6 +71,16 @@ extension StatusMenu {
|
||||
|
||||
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() {
|
||||
|
@ -12,6 +12,7 @@
|
||||
"mi_unsure" = "We are not sure what version of PHP you are running.";
|
||||
"mi_php_version" = "Global PHP version: 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_2" = "Try running `php -v` in your terminal.";
|
||||
"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
|
||||
"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).";
|
||||
|
||||
/// 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_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.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.";
|
||||
|
@ -24,11 +24,10 @@ class PhpVersionDetectionTest: XCTestCase {
|
||||
"php@5.6", // should be omitted, not supported
|
||||
"php@5.4" // should be omitted, not supported
|
||||
],
|
||||
supported: ["7.0", "8.0", "8.1", "8.2"],
|
||||
checkBinaries: false,
|
||||
generateHelpers: false
|
||||
)
|
||||
|
||||
XCTAssertEqual(outcome, ["8.0", "7.0"])
|
||||
XCTAssertEqual(outcome, ["8.0", "7.0", "5.6"])
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user