mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50:08 +02:00
👌 Allow PHP Monitor to run without linked PHP
This commit is contained in:
@ -16,7 +16,6 @@ class Homebrew {
|
||||
}
|
||||
|
||||
guard let install = PhpEnv.phpInstall else {
|
||||
Log.info("Assuming the formula is `php` since none seems to be linked.")
|
||||
return HomebrewFormula("php", elevated: true)
|
||||
}
|
||||
|
||||
|
@ -37,13 +37,20 @@ class ActivePhpInstallation {
|
||||
|
||||
// MARK: - Initializer
|
||||
|
||||
public static func load() -> ActivePhpInstallation? {
|
||||
if !FileSystem.fileExists(Paths.phpConfig) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ActivePhpInstallation()
|
||||
}
|
||||
|
||||
init() {
|
||||
// Show information about the current version
|
||||
do {
|
||||
try determineVersion()
|
||||
} catch {
|
||||
// TODO: In future versions of PHP Monitor, this should not crash
|
||||
fatalError("Could not determine or parse PHP version; aborting")
|
||||
fatalError("Could not determine or parse PHP version; aborting!")
|
||||
}
|
||||
|
||||
// Initialize the list of ini files that are loaded
|
||||
|
@ -13,7 +13,7 @@ class PhpEnv {
|
||||
// MARK: - Initializer
|
||||
|
||||
init() {
|
||||
self.currentInstall = ActivePhpInstallation()
|
||||
self.currentInstall = ActivePhpInstallation.load()
|
||||
}
|
||||
|
||||
func determinePhpAlias() async {
|
||||
@ -90,9 +90,17 @@ class PhpEnv {
|
||||
public func detectPhpVersions() async -> [String] {
|
||||
let files = await Shell.pipe("ls \(Paths.optPath) | grep php@").out
|
||||
|
||||
let supported: [String] = {
|
||||
guard let version = Valet.shared.version else {
|
||||
return []
|
||||
}
|
||||
|
||||
return Constants.ValetSupportedPhpVersionMatrix[version.major] ?? []
|
||||
}()
|
||||
|
||||
var versionsOnly = await extractPhpVersions(
|
||||
from: files.components(separatedBy: "\n"),
|
||||
supported: Constants.ValetSupportedPhpVersionMatrix[Valet.shared.version.major] ?? []
|
||||
supported: supported
|
||||
)
|
||||
|
||||
// Make sure the aliased version is detected
|
||||
|
@ -99,12 +99,96 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
startup procedure.
|
||||
*/
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
self.watchHomebrewBinFolder()
|
||||
/*
|
||||
// Make sure notifications will work
|
||||
setupNotifications()
|
||||
Task { // Make sure the menu performs its initial checks
|
||||
await paths.loadUser()
|
||||
await menu.startup()
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func watchHomebrewBinFolder() {
|
||||
Log.info("Watching Homebrew's bin folder")
|
||||
FSWatch2.shared = FSWatch2(
|
||||
for: URL(fileURLWithPath: Paths.binPath),
|
||||
eventMask: .all,
|
||||
onChange: {
|
||||
print("Something has changed")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class FSWatch2 {
|
||||
public static var shared: FSWatch2! = nil
|
||||
|
||||
let queue = DispatchQueue(label: "FSWatch2Queue", attributes: .concurrent)
|
||||
|
||||
var lastUpdate: TimeInterval?
|
||||
var linked: Bool
|
||||
|
||||
private var fileDescriptor: CInt = -1
|
||||
private var dispatchSource: DispatchSourceFileSystemObject?
|
||||
|
||||
internal let url: URL
|
||||
|
||||
init(for url: URL, eventMask: DispatchSource.FileSystemEvent, onChange: () -> Void) {
|
||||
self.url = url
|
||||
|
||||
self.linked = FileSystem.fileExists(Paths.php)
|
||||
print("Initial PHP linked state: \(linked)")
|
||||
|
||||
fileDescriptor = open(url.path, O_EVTONLY)
|
||||
|
||||
dispatchSource = DispatchSource.makeFileSystemObjectSource(
|
||||
fileDescriptor: fileDescriptor,
|
||||
eventMask: eventMask,
|
||||
queue: self.queue
|
||||
)
|
||||
|
||||
dispatchSource?.setEventHandler(handler: {
|
||||
let distance = self.lastUpdate?.distance(to: Date().timeIntervalSince1970)
|
||||
|
||||
if distance == nil || distance != nil && distance! > 1.00 {
|
||||
print("FS event fired, checking in 1s, no duplicate FS events will be acted upon")
|
||||
|
||||
self.lastUpdate = Date().timeIntervalSince1970
|
||||
|
||||
Task {
|
||||
await delay(seconds: 1)
|
||||
|
||||
let newLinked = FileSystem.fileExists(Paths.php)
|
||||
|
||||
if newLinked != self.linked {
|
||||
self.linked = newLinked
|
||||
|
||||
Log.info("The status of the PHP binary has changed!")
|
||||
|
||||
if newLinked {
|
||||
Log.info("php is linked")
|
||||
} else {
|
||||
Log.info("php is not linked")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
dispatchSource?.setCancelHandler(handler: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
close(self.fileDescriptor)
|
||||
self.fileDescriptor = -1
|
||||
self.dispatchSource = nil
|
||||
})
|
||||
|
||||
dispatchSource?.resume()
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("deallocing watcher")
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +99,7 @@ class Startup {
|
||||
buttonText: "alert.homebrew_missing.quit".localized,
|
||||
requiresAppRestart: true
|
||||
),
|
||||
/*
|
||||
// =================================================================================
|
||||
// The PHP binary must exist.
|
||||
// =================================================================================
|
||||
@ -109,6 +110,7 @@ class Startup {
|
||||
subtitleText: "startup.errors.php_binary.subtitle".localized,
|
||||
descriptionText: "startup.errors.php_binary.desc".localized(Paths.php)
|
||||
),
|
||||
*/
|
||||
// =================================================================================
|
||||
// Make sure we can detect one or more PHP installations.
|
||||
// =================================================================================
|
||||
@ -216,6 +218,7 @@ class Startup {
|
||||
// =================================================================================
|
||||
// Determine that Valet works correctly (no issues in platform detected)
|
||||
// =================================================================================
|
||||
/*
|
||||
EnvironmentCheck(
|
||||
command: {
|
||||
return await Shell.pipe("valet --version").out
|
||||
@ -264,5 +267,6 @@ class Startup {
|
||||
subtitleText: "startup.errors.valet_version_not_supported.subtitle".localized,
|
||||
descriptionText: "startup.errors.valet_version_not_supported.desc".localized
|
||||
)
|
||||
*/
|
||||
]
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class Valet {
|
||||
static let shared = Valet()
|
||||
|
||||
/// The version of Valet that was detected.
|
||||
var version: VersionNumber! = nil
|
||||
var version: VersionNumber? = nil
|
||||
|
||||
/// The Valet configuration file.
|
||||
var config: Valet.Configuration!
|
||||
@ -142,6 +142,11 @@ class Valet {
|
||||
in use. This allows PHP Monitor to do different things when Valet 3.0 is enabled.
|
||||
*/
|
||||
public func evaluateFeatureSupport() {
|
||||
guard let version = self.version else {
|
||||
Log.err("Cannot determine features, as the version was not determined.")
|
||||
return
|
||||
}
|
||||
|
||||
switch version.major {
|
||||
case 2:
|
||||
Log.info("You are running Valet v2. Support for site isolation is disabled.")
|
||||
@ -159,12 +164,21 @@ class Valet {
|
||||
installed is not recent enough.
|
||||
*/
|
||||
public func validateVersion() {
|
||||
guard let version = self.version else {
|
||||
Log.err("Cannot validate Valet version if no Valet version was determined.")
|
||||
return
|
||||
}
|
||||
|
||||
if PhpEnv.phpInstall == nil {
|
||||
Log.info("Cannot validate Valet version if no PHP version is linked.")
|
||||
return
|
||||
}
|
||||
|
||||
// 1. Evaluate feature support
|
||||
Valet.shared.evaluateFeatureSupport()
|
||||
|
||||
// 2. Notify user if the version is too old (but major version is OK)
|
||||
if version.text.versionCompare(Constants.MinimumRecommendedValetVersion) == .orderedAscending {
|
||||
let version = version!
|
||||
let recommended = Constants.MinimumRecommendedValetVersion
|
||||
Log.warn("Valet version \(version.text) is too old! (recommended: \(recommended))")
|
||||
Task { @MainActor in
|
||||
|
@ -71,7 +71,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
/** Reloads which PHP versions is currently active. */
|
||||
@objc func refreshActiveInstallation() {
|
||||
if !PhpEnv.shared.isBusy {
|
||||
PhpEnv.shared.currentInstall = ActivePhpInstallation()
|
||||
PhpEnv.shared.currentInstall = ActivePhpInstallation.load()
|
||||
updatePhpVersionInStatusBar()
|
||||
} else {
|
||||
Log.perf("Skipping version refresh due to busy status!")
|
||||
|
@ -13,7 +13,18 @@ import Cocoa
|
||||
extension StatusMenu {
|
||||
|
||||
func addPhpVersionMenuItems() {
|
||||
if PhpEnv.phpInstall == nil || PhpEnv.phpInstall!.hasErrorState {
|
||||
if PhpEnv.phpInstall == nil {
|
||||
addItem(HeaderView.asMenuItem(text: "⚠️ " + "mi_no_php_linked".localized, minimumWidth: 280))
|
||||
addItems([
|
||||
// TODO: Make sure these buttons do something
|
||||
NSMenuItem.separator(),
|
||||
NSMenuItem(title: "mi_fix_php_link".localized),
|
||||
NSMenuItem(title: "mi_no_php_linked_explain".localized)
|
||||
])
|
||||
return
|
||||
}
|
||||
|
||||
if PhpEnv.phpInstall!.hasErrorState {
|
||||
let brokenMenuItems = ["mi_php_broken_1", "mi_php_broken_2", "mi_php_broken_3", "mi_php_broken_4"]
|
||||
return addItems(brokenMenuItems.map { NSMenuItem(title: $0.localized) })
|
||||
}
|
||||
@ -30,7 +41,13 @@ extension StatusMenu {
|
||||
return
|
||||
}
|
||||
|
||||
if PhpEnv.shared.availablePhpVersions.isEmpty { return }
|
||||
if PhpEnv.shared.availablePhpVersions.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
if PhpEnv.shared.currentInstall == nil {
|
||||
return
|
||||
}
|
||||
|
||||
addSwitchToPhpMenuItems()
|
||||
self.addItem(NSMenuItem.separator())
|
||||
|
@ -12,27 +12,27 @@ class StatusMenu: NSMenu {
|
||||
addPhpVersionMenuItems()
|
||||
addItem(NSMenuItem.separator())
|
||||
|
||||
if Preferences.isEnabled(.displayGlobalVersionSwitcher) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayGlobalVersionSwitcher) {
|
||||
addPhpActionMenuItems()
|
||||
addItem(NSMenuItem.separator())
|
||||
}
|
||||
|
||||
if Preferences.isEnabled(.displayServicesManager) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayServicesManager) {
|
||||
addServicesManagerMenuItem()
|
||||
addItem(NSMenuItem.separator())
|
||||
}
|
||||
|
||||
if Preferences.isEnabled(.displayValetIntegration) {
|
||||
if Valet.shared.version != nil && Preferences.isEnabled(.displayValetIntegration) {
|
||||
addValetMenuItems()
|
||||
addItem(NSMenuItem.separator())
|
||||
}
|
||||
|
||||
if Preferences.isEnabled(.displayPhpConfigFinder) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayPhpConfigFinder) {
|
||||
addConfigurationMenuItems()
|
||||
addItem(NSMenuItem.separator())
|
||||
}
|
||||
|
||||
if Preferences.isEnabled(.displayComposerToolkit) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayComposerToolkit) {
|
||||
addComposerMenuItems()
|
||||
addItem(NSMenuItem.separator())
|
||||
}
|
||||
@ -41,12 +41,12 @@ class StatusMenu: NSMenu {
|
||||
return
|
||||
}
|
||||
|
||||
if Preferences.isEnabled(.displayLimitsWidget) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayLimitsWidget) {
|
||||
addStatsMenuItem()
|
||||
addItem(NSMenuItem.separator())
|
||||
}
|
||||
|
||||
if Preferences.isEnabled(.displayExtensions) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayExtensions) {
|
||||
addExtensionsMenuItems()
|
||||
NSMenuItem.separator()
|
||||
|
||||
@ -55,11 +55,11 @@ class StatusMenu: NSMenu {
|
||||
|
||||
addPhpDoctorMenuItem()
|
||||
|
||||
if Preferences.isEnabled(.displayPresets) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayPresets) {
|
||||
addPresetsMenuItem()
|
||||
}
|
||||
|
||||
if Preferences.isEnabled(.displayMisc) {
|
||||
if PhpEnv.phpInstall != nil && Preferences.isEnabled(.displayMisc) {
|
||||
addFirstAidAndServicesMenuItems()
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
"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_4" = "Running `brew reinstall php` (or for the equivalent version) might help.";
|
||||
"mi_no_php_linked" = "No PHP version linked!";
|
||||
"mi_fix_php_link" = "Fix Automatically...";
|
||||
"mi_no_php_linked_explain" = "What's This?";
|
||||
|
||||
"mi_diagnostics" = "Diagnostics";
|
||||
"mi_active_services" = "Active Services";
|
||||
|
Reference in New Issue
Block a user